2013/10/30

iOS6からTwitter.frameworkが非推奨になりました。 将来的なことを考えて「Social.framework」に移行する必要があります。

といってもframeworkの読み込めば、名称変更するだけで従来の機能が利用できます。

SLComposeViewController *composeViewController = [SLComposeViewController composeViewControllerForServiceType:SLServiceTypeTwitter];
    
    [composeViewController setInitialText:[self createTweetComment]];
    [self presentViewController:composeViewController animated:YES completion:NULL];
    
    composeViewController.completionHandler =
    ^(SLComposeViewControllerResult result) {
        switch (result) {
            case SLComposeViewControllerResultDone:
                NSLog(@"SLComposeViewControllerResultDone");
                //[self completeTweet];
                break;
            case SLComposeViewControllerResultCancelled:
                NSLog(@"SLComposeViewControllerResultCancelled");
                break;
            default:
                NSLog(@"error");
                break;
        }
        [self hideLoadingDialog];
        [self dismissViewControllerAnimated:YES completion:NULL];
    };

  2013/10/30

iOS6から、Viewを遷移する「presentModalViewController」や「dismissModalViewControllerAnimated」等が非推奨になっています。

iOS6からのView遷移

[ccp] [self presentViewController:leaderboardController animated:YES completion:NULL]; [self dismissViewControllerAnimated:YES completion:NULL]; [ccp]

「completion:」で画面遷移後の処理をblock文で記述します。 前からこの機能が欲しかったですよね。

  2013/10/30

Xcodeが全く操作できないくらい遅くなりました。

Indexingの無効

調べたら、コード補完用の検索インデックス(Indexing)で負荷がかかっているみたいです。

defaults write com.apple.dt.Xcode IDEIndexDisable 1

Xcode再起動後に、動作が軽くなりました!

が、しかしコード補完自体はできるのですが、ヒエラルキー「Symbol Not Found」とかで使えません。 これでは不便なので、元に戻します。

defaults write com.apple.dt.XCode IDEIndexDisable 0

Xcode再起動後Indexingが再度行われて、現状軽いままXcodeは動作しています。

indexに無駄な情報が蓄積されるのが原因なんでしょうか?

プロジェクト単体

プロジェクト単体で重い場合は、Organizerで不要ファイルを削除します。 Xcode Organizer

参考

Xcode や Emacs が重いと感じたら最初に試してみるコマンド

  2013/09/26

HTML5エキスパートで有名な吉川さん(同性w)からCodeIQの問題があったので挑戦!

DOM操作の最適化によるJavaScriptチューニングにチャレンジ!

オリジナル


    var button = document.querySelector('button'),
        ul = document.querySelector('#output'),
        itemCount = 0;

    function addItems() {
      for ( var i = 0; i < 10; i++ ) {
        itemCount++;
        ul.innerHTML += '
  • ' + '

    アイテム' + itemCount + '

    ' + '

    詳細' + itemCount + '

    ' + '
  • '; } }

    30分くらいでざっとコーディングして提出

    提出コード

    
        var button = document.querySelector('button'),
            ul = document.getElementById('output'),
            itemId = 0;
    
        var itemTemplate = '';
        var addCount = 10;
        var output = document.getElementById("output");
    
        function createItem() {
            itemId++;
            var item = new Object();
            item.title = 'アイテム' + itemId;
            item.detail = '詳細' + itemId;
            return item;
        }
    
        function loadItemTemplate(item) {
            var li = document.createElement('li'); 
            var article = document.createElement('article');
            var h1 = document.createElement('h1');
            var p = document.createElement('p');
    
            article.setAttribute('class', 'item');
            h1.setAttribute('class', 'title');
            p.setAttribute('class', 'detail');
    
            h1.textContent = item.title;
            p.textContent = item.detail;
    
            article.appendChild(h1);
            article.appendChild(p);
            li.appendChild(article);
            return li;
        }
    
        function addItems() {
          for ( var i = 0; i < addCount; i++ ) {
            itemTemplate = loadItemTemplate(createItem());
            document.getElementById('output').appendChild(itemTemplate);
          }
        }
    

    テンプレートのHTML生成がループしてるので無駄だなと思いつつ、この程度だと計測時間が変わらなかったのでとりあえず。

    丁寧にアドバイスを頂きました。

    • Document Fragmentを経由
    • getElementById()は高コストなのでキャッシュする

    提出コード

    
        var button = document.querySelector('button'),
            ul = document.getElementById('output'),
            itemId = 0;
    
        var template;
        var addCount = 10;
        var li;
        var article;
        var h1;
        var p;
    
        loadItemTemplate();
    
        function createItem() {
            itemId++;
            var item = new Object();
            item.title = 'アイテム' + itemId;
            item.detail = '詳細' + itemId;
            return item;
        }
    
        function loadItemTemplate() {
            template = document.createElement('li'); 
            article = document.createElement('article');
            h1 = document.createElement('h1');
            p = document.createElement('p');
    
            article.setAttribute('class', 'item');
            h1.setAttribute('class', 'title');
            p.setAttribute('class', 'detail');
    
            article.appendChild(h1);
            article.appendChild(p);
            template.appendChild(article);
        }
    
        function bindItem(item) {
            h1.textContent = item.title;
            p.textContent = item.detail;
            var itemRow = template.cloneNode(true);
            ul.appendChild(itemRow);
        }
    
        function addItems() {
          for ( var i = 0; i < addCount; i++ ) {
              bindItem(createItem());
          }
        }
    

    cloneNode()を利用してみたけど、なんかViewの分離がちょっと汚くなっちゃたかな? insertNode()とかを使って、ツリーを操作した方がスムーズなのかも。

      2013/08/12

    http://www.moongift.jp/2013/08/20130810-2/

      2013/07/29

    Leap Motion」を手に入れたのでXcodeで試してみた。 LeapMotion

    海外がお得

    国内で買うと倍くらいしてしまうので、海外で買った方がお得で、意外と早く届きます(3日で届いた)。

    セットアップ

    https://www.leapmotion.com/setupから「Leap Motion Installer」をダウンロードして、インストールします。 非常にわかりやすいセットアップナビゲーションです。

    アプリ管理は「AirSpace」

    アプリ管理は「AirSpace」で行います。 https://airspace.leapmotion.com/にアクセスすると、iTunesStore、GooglePlayのようにアプリが購入できます。 フリーのソフトもあるので、ざっと試す事ができます。

    開発環境

    Leap Motionは、色々な言語に対応しているので自分の得意分野で開発かと思います。 (自分は XCode、Objective-Cで開発)

    SDKは、https://developer.leapmotion.com/downloads からダウンロードできます。

    ダウンロードしたSDKは、自分の管理しやすいパスに配置します。 LeapMotion ※自分は「/Users/ユーザ/leap/LeapSDK/」にしました

    XCode、Objective-Cで開発

    Xcode、Objective-Cで開発するにはいくつか準備が必要です。

    (1) libLeap.dylib (2) Leap、LeapMathヘッダファイル (3) LeapObjectiveC

    プロジェクト作成

    Cocoa Applicationでプロジェクト作成 LeapMotion

    ARCで作成してみる LeapMotion

    Build Settingsの設定

    「LeapSDK」のライブラリを利用するには、パスを通してやる必要があります。

    まず、配置したLeapSDKのパス定義 LeapMotion ※「LEAPSDK_PATH」としました

    headerファイルのパス定義 LeapMotion $(LEAPSDK_PATH)/inclulde

    libraryファイルのパス定義 LeapMotion $(LEAPSDK_PATH)/lib

    includeファイルの追加

    「Leap.h」「LeapMath.h」「LeapObjectiveC.h」「LeapObjectiveC.mm」をプロジェクトにドラッグ&ドロップ LeapMotion

    LeapMotion

    libLeap.dylib

    「libLeap.dylib」をプロジェクトにドラッグ&ドロップ LeapMotion

    Build Phasesで、ファイルが追加されるのを確認 LeapMotion

    DEMO

    メインプログラムは「LeapSDK/samples/Sample.cpp」をそのまま記述しました。

    LeapTest.h

    #import 
    #import "LeapObjectiveC.h"
    
    @interface LeapTest : NSObject
    
    - (void)run;
    
    @end
    

    「LeapObjectiveC.h」を読み込んで、「LeapListener」で拡張

    LeapTest.m

    #import "LeapTest.h"
    
    @implementation LeapTest
    {
        LeapController *controller;
    }
    
    - (void)run
    {
        controller = [[LeapController alloc] init];
        [controller addListener:self];
        NSLog(@"running");
    }
    
    - (void)onInit:(NSNotification *)notification
    {
        NSLog(@"Initialized");
    }
    
    - (void)onConnect:(NSNotification *)notification
    {
        NSLog(@"Connected");
        LeapController *aController = (LeapController *)[notification object];
        [aController enableGesture:LEAP_GESTURE_TYPE_CIRCLE enable:YES];
        [aController enableGesture:LEAP_GESTURE_TYPE_KEY_TAP enable:YES];
        [aController enableGesture:LEAP_GESTURE_TYPE_SCREEN_TAP enable:YES];
        [aController enableGesture:LEAP_GESTURE_TYPE_SWIPE enable:YES];
    }
    
    - (void)onDisconnect:(NSNotification *)notification
    {
        //Note: not dispatched when running in a debugger.
        NSLog(@"Disconnected");
    }
    
    - (void)onExit:(NSNotification *)notification
    {
        NSLog(@"Exited");
    }
    
    - (void)onFrame:(NSNotification *)notification
    {
        LeapController *aController = (LeapController *)[notification object];
        LeapFrame *frame = [aController frame:0];
        
        NSLog(@"Frame id: %lld, timestamp: %lld, hands: %ld, fingers: %ld, tools: %ld, gestures: %ld",
              [frame id], [frame timestamp], [[frame hands] count],
              [[frame fingers] count], [[frame tools] count], [[frame gestures:nil] count]);
        
        if ([[frame hands] count] != 0) {
            LeapHand *hand = [[frame hands] objectAtIndex:0];
            
            NSArray *fingers = [hand fingers];
            if ([fingers count] != 0) {
                LeapVector *avgPos = [[LeapVector alloc] init];
                for (int i = 0; i < [fingers count]; i++) {
                    LeapFinger *finger = [fingers objectAtIndex:i];
                    avgPos = [avgPos plus:[finger tipPosition]];
                }
                avgPos = [avgPos divide:[fingers count]];
                NSLog(@"Hand has %ld fingers, average finger tip position %@",
                      [fingers count], avgPos);
            }
            
            NSLog(@"Hand sphere radius: %f mm, palm position: %@",
                  [hand sphereRadius], [hand palmPosition]);
            
            const LeapVector *normal = [hand palmNormal];
            const LeapVector *direction = [hand direction];
            
            NSLog(@"Hand pitch: %f degrees, roll: %f degrees, yaw: %f degrees\n",
                  [direction pitch] * LEAP_RAD_TO_DEG,
                  [normal roll] * LEAP_RAD_TO_DEG,
                  [direction yaw] * LEAP_RAD_TO_DEG);
        }
        
        NSArray *gestures = [frame gestures:nil];
        for (int g = 0; g < [gestures count]; g++) {
            LeapGesture *gesture = [gestures objectAtIndex:g];
            switch (gesture.type) {
                case LEAP_GESTURE_TYPE_CIRCLE: {
                    LeapCircleGesture *circleGesture = (LeapCircleGesture *)gesture;
                    
                    NSString *clockwiseness;
                    if ([[[circleGesture pointable] direction] angleTo:[circleGesture normal]] <= LEAP_PI/4) {
                        clockwiseness = @"clockwise";
                    } else {
                        clockwiseness = @"counterclockwise";
                    }
                    
                    float sweptAngle = 0;
                    if(circleGesture.state != LEAP_GESTURE_STATE_START) {
                        LeapCircleGesture *previousUpdate = (LeapCircleGesture *)[[aController frame:1] gesture:gesture.id];
                        sweptAngle = (circleGesture.progress - previousUpdate.progress) * 2 * LEAP_PI;
                    }
                    
                    NSLog(@"Circle id: %d, %@, progress: %f, radius %f, angle: %f degrees %@",
                          circleGesture.id, [LeapTest stringForState:gesture.state],
                          circleGesture.progress, circleGesture.radius,
                          sweptAngle * LEAP_RAD_TO_DEG, clockwiseness);
                    break;
                }
                case LEAP_GESTURE_TYPE_SWIPE: {
                    LeapSwipeGesture *swipeGesture = (LeapSwipeGesture *)gesture;
                    NSLog(@"Swipe id: %d, %@, position: %@, direction: %@, speed: %f",
                          swipeGesture.id, [LeapTest stringForState:swipeGesture.state],
                          swipeGesture.position, swipeGesture.direction, swipeGesture.speed);
                    break;
                }
                case LEAP_GESTURE_TYPE_KEY_TAP: {
                    LeapKeyTapGesture *keyTapGesture = (LeapKeyTapGesture *)gesture;
                    NSLog(@"Key Tap id: %d, %@, position: %@, direction: %@",
                          keyTapGesture.id, [LeapTest stringForState:keyTapGesture.state],
                          keyTapGesture.position, keyTapGesture.direction);
                    break;
                }
                case LEAP_GESTURE_TYPE_SCREEN_TAP: {
                    LeapScreenTapGesture *screenTapGesture = (LeapScreenTapGesture *)gesture;
                    NSLog(@"Screen Tap id: %d, %@, position: %@, direction: %@",
                          screenTapGesture.id, [LeapTest stringForState:screenTapGesture.state],
                          screenTapGesture.position, screenTapGesture.direction);
                    break;
                }
                default:
                    NSLog(@"Unknown gesture type");
                    break;
            }
        }
        
        if (([[frame hands] count] > 0) || [[frame gestures:nil] count] > 0) {
            NSLog(@" ");
        }
    }
    
    - (void)onFocusGained:(NSNotification *)notification
    {
        NSLog(@"Focus Gained");
    }
    
    - (void)onFocusLost:(NSNotification *)notification
    {
        NSLog(@"Focus Lost");
    }
    
    + (NSString *)stringForState:(LeapGestureState)state
    {
        switch (state) {
            case LEAP_GESTURE_STATE_INVALID:
                return @"STATE_INVALID";
            case LEAP_GESTURE_STATE_START:
                return @"STATE_START";
            case LEAP_GESTURE_STATE_UPDATE:
                return @"STATE_UPDATED";
            case LEAP_GESTURE_STATE_STOP:
                return @"STATE_STOP";
            default:
                return @"STATE_INVALID";
        }
    }
    @end
    

    サイクルは以下の種類があり、NSNotificationで検知して処理するようです。

    • (void)onInit:(NSNotification *)notification
    • (void)onConnect:(NSNotification *)notification
    • (void)onDisconnect:(NSNotification *)notification
    • (void)onExit:(NSNotification *)notification
    • (void)onFrame:(NSNotification *)notification
    • (void)onFocusGained:(NSNotification *)notification

    ジェスチャーはonFrame()で主に処理してやる必要がありますが、普通に書いてしまうと分岐の嵐になりそうですね。

    最後に、AppDelegateでメインプログラムを処理します。 ※ARCで書いたので「LeapTest.h」は@classでなくimportにしています

    AppDelegate.h

    #import 
    #import "LeapTest.h"
    
    @interface AppDelegate : NSObject 
    
    @property (assign) IBOutlet NSWindow *window;
    @property (nonatomic)LeapTest *leapTest;
    
    @end
    

    AppDelegate.m

    #import "AppDelegate.h"
    
    @implementation AppDelegate
    
    - (void)applicationDidFinishLaunching:(NSNotification *)aNotification
    {
        _leapTest = [[LeapTest alloc]init];
        [_leapTest run];
    }
    @end
    

    ビルドして動かすと、ジェスチャーとともにログが変化するのが確認できます。 LeapMotion

    と、とりあず動作確認程度ですが、ここからが大変そうですね。

    css

      2013/07/23

    http://codepen.io/picks/

      2013/07/04

    「crontab -e」でpicoとかのエディタが開いてしまう場合、「.bashrc」にviのパスを通してやる。

    export EDITOR=/usr/bin/vi

      2013/07/04

    OSX上にVirtualBoxでLinuxを利用してる場合、VirtualBoxのイメージバックアップもいいですけど、結構時間がかかって面倒だったりします。

    ローカル内なら、日常的ディレクトリバックアップは、やっぱりrsyncが便利かな?と。 OS自体はVirtualBoxの再セットアップ自体はそんなに時間かからないし。 と言う事で、大事なデータだけSSH経由でrsyncバックアップをすることに。

    SSHの自動認証

    rsyncはコマンドなので、SSHを経由する場合は自動認証が必要です。

    公開鍵作成(バックアップ元:Linux)

    ssh-keygen -t rsa

    秘密鍵:id_dsa 公開鍵:id_dsa.pub

    公開鍵設定(バックアップ先 :OSX)

    作成した公開鍵「id_dsa.pub」を「authrized_keys」で、バックアップ元の「.ssh/」に配置する。 複数のキーでアクセスする場合は、authrized_keysに公開鍵を行毎にコピー&ペーストで動作します。

    rsync

    rsyncは、色々オプションがありますが今回は簡易的に「アーカイブモード(-a)」「途中経過(-v)」だけ設定します。

    rsync -av -e ssh /home/yoo/ yoo@192.168.1.51:/Users/yoo/Debian/

    あとはcronとかで定期実行すれば、差し当たりのバックアップは作成できます。

    pngファイルの軽量化
    Google DriveのIconを再起的に削除
    php-markdownでバニラPHPなコードブロック処理
    laravel-ffmpeg を使う
    2021年版 Ubuntu + certbot + Let's Encrypt でサーバ証明書設定
    GihHub のデフォルトでない master ブランチを checkout する
    マルチログインで未認証のリダイレクト
    Homebrew で Redis をインストール
    CSS だけでスムーズスクロール
    EC-CUBE4 で Gmail の smtp を利用する
    Amazon Linux 2 の amazon-linux-extras とは
    UNIQUE カラムのバリデーションで自分自身を除外して更新
    フォーム有効期限切れで Page Expired をリダイレクト
    ログを日付でローテーションやクリアや削除
    Homebrew で PHP8.0 から PHP7.4 にダウングレード
    Big sur で zsh 移行と Homebrew アップグレード
    Mac に minikube をインストール
    途中から .gitignore に追加する
    Larevel 6.x から Laravel 8.x にバージョンアップ
    Composer で Allowed memory size (メモリ不足)エラー
    Blade でカスタムクラスを利用する
    git push git pull にブランチ指定せずに実行する
    git pull や git push できなくなったとき
    Docker のコンテナからホストOS に接続
    Mac で ローカル IP アドレス(ipv4)のみを表示する
    ホストOS から Docker の MySQLコンテナに接続
    caching_sha2_password のエラー
    node-config で環境設定ファイルを利用する
    rootパスワードを初期化(再設定)する
    Git から clone したときのエラー対処
    Mac に MySQL をインストール
    Mac に PostgreSQL をインストール
    Laravel 環境構築 - Mac ネイティブ編
    Firebase 入門 - Firebase とは
    Firebase 入門 - CLI インストールとデータベースの設定
    AWS 無料枠(t2.micro)で容量とメモリエラー
    Cloud9 を起動する -初心者編-
    gcloud で GCEインスタンスを起動してみる
    AWS CLI と jq でインスタンス一覧を整形して表示
    React と Laravel7 のプロジェクトを作成する
    Homebrewインストール-2020年版
    3直線で囲まれた範囲塗りつぶし
    PuLP で線形最適化問題を解く
    カスタムのペジネーションを作る
    node-sass を使って sass をコンパイルする
    Log ファサードでSQLログを分離して書き出す
    いちから始める Docker - 複数のコンテナを使う - (2020年)
    いちから始める Docker - docker-compose を使う - (2020年)
    AWS ECR を使ってみる
    Laravel7 でマルチ認証