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];
    };
Objective-C

  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 + ''
                      + '';
      }
    }
JavaScript

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);
      }
    }
JavaScript

テンプレートの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());
      }
    }
JavaScript

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
Objective-C

「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
Objective-C

サイクルは以下の種類があり、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
Objective-C

AppDelegate.m

#import "AppDelegate.h"

@implementation AppDelegate

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
    _leapTest = [[LeapTest alloc]init];
    [_leapTest run];
}
@end
Objective-C

ビルドして動かすと、ジェスチャーとともにログが変化するのが確認できます。 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 でマルチ認証