2012年11月29日木曜日

CakePHPで The requested address not found

CakePHPでいかのようなエラーが出た場合、

Error: The requested address ' ' was not found on this server.

core.phpの

Configure::write('debug', 0);

を0から1に変更したらなおった

root権限の付与

昔はこんなことしなくてよかったような気がするけど
毎回忘れるので

> su
> visudo

でviで設定ファイルが開かれ編集する。

root     ALL=(ALL)  ALL

のようにユーザーごとにsudoの権限を設定してやらないといけない

2012年10月29日月曜日

CoreDataのデータを全て削除


(BOOL)resetDatastore
{
    [[self managedObjectContext] lock];
    [[self managedObjectContext] reset];
    NSPersistentStore *store = [[[self persistentStoreCoordinator] persistentStores] lastObject]; 
    BOOL resetOk = NO;

    if (store)
    {
        NSURL *storeUrl = store.URL;
        NSError *error;

        if ([[self persistentStoreCoordinator] removePersistentStore:store error:&error])
        {
            [[self persistentStoreCoordinator] release];
            __persistentStoreCoordinator = nil;
            [[self managedObjectContext] release];
            __managedObjectContext = nil;

            if (![[NSFileManager defaultManager] removeItemAtPath:storeUrl.path error:&error])
            {
                NSLog(@"\nresetDatastore. Error removing file of persistent store: %@",
                  [error localizedDescription]);
                resetOk = NO;
            }
            else
            {
                //now recreate persistent store
                [self persistentStoreCoordinator];
                [[self managedObjectContext] unlock];
                resetOk = YES;
            }
        }
        else
        {
            NSLog(@"\nresetDatastore. Error removing persistent store: %@",
              [error localizedDescription]);
            resetOk = NO;
        }
        return resetOk;
    }
    else
    {
        NSLog(@"\nresetDatastore. Could not find the persistent store");
        return resetOk;
    }
}

2012年10月28日日曜日

半透明のviewを重ねる

半透明のviewの上にviewを以下のように重ねると
子のviewのalphaも親のalphaに引きづられてしまい、子のviewのalphaを1.0に設定してもどちらも半透明になってしまう。


    UIView* view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 100,100)];
    view.alpha = 0.5;
    [self.navigationController.view addSubview:view];
    
    UIView* childView = [[UIView alloc] initWithFrame:CGRectMake(25, 25, 50,50)];
    childView.backgroundColor = [UIColor whiteColor];
    childView.alpha = 1.0;

これを解決するにはviewではなく、background colorのUIColorのalphaを変える必要がある。

    UIView* view = [[UIView allocinitWithFrame:CGRectMake(00, 100,100)];
    view.backgroundColor = [[UIColor blackColorcolorWithAlphaComponent:0.5];
    [self.navigationController.view addSubview:view];
    
    UIView* childView = [[UIView allocinitWithFrame:CGRectMake(252550,50)];
    childView.backgroundColor = [UIColor whiteColor];





2012年10月14日日曜日

iOS6変わったとこなど

相当すぎてますが、NDAも解禁ということで、、

UIViewControllerでメソッドがDeprecateされた

http://developer.apple.com/library/ios/#documentation/uikit/reference/UIViewController_Class/DeprecationAppendix/AppendixADeprecatedAPI.html

modalView系が他のメソッドに完全に置き換わったのと、回転系のメソッドが変わったのと、unload系が呼ばれなくなってます。

Deprecateされたメソッドとその対策

廃止:modalViewController
代替手段:presentedViewController

廃止:automaticallyForwardAppearanceAndRotationMethodsToChildViewControllers
代替手段:shouldAutomaticallyForwardRotationMethods とshouldAutomaticallyForwardAppearanceMethods

廃止:dismissModalViewControllerAnimated:
代替手段:dismissViewControllerAnimated:completion:

廃止:presentModalViewController:animate
代替手段:presentViewController:animated:completion:

廃止:shouldAutorotateToInterfaceOrientation:
代替手段:supportedInterfaceOrientations と preferredInterfaceOrientationForPresentation をオーバーライド
廃止:viewDidUnload

廃止:viewWillUnload

viewUnload系はメモリが少なくなった場合でも呼ばれなくなった。

view**Unloadについてはこちらによく書かれています。
メモリワーニング対応としてはdidReceiveMemoryWarningでどうにかするしかないですね
http://www.zero4racer.com/blog/929
回転についてはこちらなど

縦長対応

iPhone5が 640 * 1136 になったのでそれに対応せねばならない。

スプラッシュ画像の対応
以下の名前のファイルを追加すればいい

Default-568h@2x.png

storyboardの変更
storyboardの画面右下の画面の ○ボタンを押せば画面が縦長になる


armv7sの追加

3rdParty性のライブラリを使ってたりしない限りはあまり関係ないですが、使っている場合はそのライブラリがarmv7s用のバイナリを含んでいない場合は、ビルドするときにarmv7sを消さないとだめです。

UICollectionViewが追加
データの一覧表示するのにこれまではTableViewしかなかったのが、UICollectionViewという別の表現手段が用意されました。使い方はパッと見UITableViewとかなり酷似しているのでそれほど難しくはなさそう。


UIRefreshControlが追加

引っ張って更新するのがフレームワークに導入された

これまではEGOTableViewPullRefreshさんにお世話になってましたが、iOS6からはオワコンになります。
UIRefreshControlはもちろんiOS6でしか動かないので、しばらくはまだオープンソースのほうが使われるでしょう。

NSHashTable, NSMapTable, NSPointerArray, NSPointerFunctions,とか増えた

この理解であっているかはちと怪しいが

NSHashTableはNSSetのweak reference版
NSMapTableはNSDictionaryのweak reference版
NSPointerArrayはNSArrayのweak reference版(ただしARC環境ではサポートしないと書いてある)

2012年9月18日火曜日

Objective-Cのクラスメソッドの差し替え

テストのときにUIAlertViewの表示を消してくれるライブラリで
どうやってUIAlertViewのメソッドをフックしてるのかと調べてみたところ
method_exchangeImplementations()を使って実装されてた。


+ (void)swapInstanceMethodsForClass: (Class) cls selector: (SEL)sel1 andSelector: (SEL)sel2 {
    Method method1 = class_getInstanceMethod(cls, sel1);
    Method method2 = class_getInstanceMethod(cls, sel2);
    method_exchangeImplementations(method1, method2);
}
method_exchangeImplementations()を使えばこのようにクラスメソッドを差し替えられるのでテストでは便利。

2012年9月16日日曜日

XP祭り2012に参加してきた

XP祭り2012に参加してきました。

去年は参加だけだったので、今回はアウトプットをしようということで
LTで登壇してきました。


Xp祭り2012 lt leanstartup from Yasuharu Yanamura

これはUT Startup gymという半年間でアイデアをローンチまでするというプログラムの一プロジェクトとして僕が体験したことを簡単にお話しました。

実際のところ僕らのサービスは、まだローンチまでには至っていないので「やった」とはいいきれないし、
リーンスタートアップを教科書通りにやったわけではなく、考え方などを参考にしてやった程度なので、いろいろつっこみどころはあるとは思いますが、それでも実際にやってみたことで思ったとおりにはいかないことはたくさんあったので、「ひとつの失敗事例」としては他の人にも価値があるのではないかと考え発表させていただきました。

リーンスタートアップもアジャイルもこれといった答えはなく、あくまで「考え方」や「姿勢」のフレームワークだと僕は思っているので、この発表でお話した、「こうすればよかった」や「こうすべき」という意見は、あくまで「この家計簿プロジェクトに限る話」なので、全てに通じるわけでは全くないと思っています。

ソフトウェア開発と同様にスタートアップにも銀の弾丸はないので、試行錯誤してやっていくしかない。なので「超早く回す」ってことが一番重要だと思いますので、実際リーンスタートアップなことをやる場合はそうしたほうがいいのではないかと思います。

2012年9月14日金曜日

iOSでKiwiでテストする【基本編2】

つぎはテストコードの中身の書き方です。

it のBlocksの中にテストコードを書きます。

[テスト対象のオブジェクト should] マッチャー:期待される値];

という書き方が基本です。

マッチャーはequalなどですが、詳細はこちらを参照してください。
https://github.com/allending/Kiwi/wiki/Expectations

注意する点としては、
Objective-Cではプリミティブな型(intなど)はオブジェクトではないので、
theValue()で囲ってやることによってオブジェクトにしないとだめです。

SPEC_BEGIN(NSDateSpec)

describe (@"NSDate", ^{
    context (@"When October", ^{
        describe (@"NSDate#lastDate", ^{
            context (@"With year:2012", ^{
                it (@"should be 30", ^{
                        // ここにテストコードを書く
                        NSDate* date = [NSDate dateWithGivenYear:2012 month:10];
                        [[theValue([date lastDay]) should] equal:theValue(30)];

                });
            });
        });
    });

});

SPEC_END

・各テストで共通の前処理、後処理の書き方

以下を必要な階層に入れればよいはずです。

 beforeAll(^{ // Occurs once }); 

 afterAll(^{ // Occurs once }); 

 beforeEach(^{ // Occurs before each enclosed "it" variable = [MyClass instance];     }); 

 afterEach(^{ // Occurs after each enclosed "it" });

・ヘルパーメソッドの書き方

例えばこのような場合青字のところはヘルパーメソッドに置き換えたいといった場合の対応ですが、

SPEC_BEGIN(NSDateSpec)

describe (@"NSDate", ^{
    context (@"When October", ^{
        describe (@"NSDate#lastDate", ^{
            context (@"With year:2012", ^{
                it (@"should be 30", ^{
                        NSDate* date = [NSDate dateWithGivenYear:2012 month:10]; 
                        // 何か処理がいろいろ
                        // ...
                        [[theValue([date lastDay]) should] equal:theValue(30)];
                });
            });


            context (@"With year:1979", ^{
                it (@"should be 30", ^{
                        NSDate* date = [NSDate dateWithGivenYear:1979 month:10]; 
                        // 何か処理がいろいろ
                        // ...
                        [[theValue([date lastDay]) should] equal:theValue(30)];                });
            });
        });
    });

});

SPEC_END

これはBlocksを定義して、呼び出せばよいです。

SPEC_BEGIN(NSDateSpec)

describe (@"NSDate", ^{
    context (@"When October", ^{
        describe (@"NSDate#lastDate", ^{

            //Helper Method.
            NSNumber* (^helpMethodWithCount)(int) = ^NSNumber* (int count) {
                // 何か処理がいろいろ
                // ...
            };            
            context (@"With year:2012", ^{
                it (@"should be 30", ^{
                        NSDate* date = dateWithGivenYear:2012 month:10]; 
                        helpMethodWithCount(100);
                        [[theValue([date lastDay]) should] equal:theValue(30)];
                });
            });


            context (@"With year:1979", ^{
                it (@"should be 30", ^{
                        NSDate* date = dateWithGivenYear:1979 month:10]; 
                        helpMethodWithCount(10);
                        [[theValue([date lastDay]) should] equal:theValue(30)];
                });
            });
        });
    });

});

SPEC_END


^{}で囲まれているところは、そのまんまBlocksなので、その中に値を定義すれば、Blocksから参照できますので、ヘルパーメソッドに限らず定義できます。

iOSでKiwiでテストする【基本編1】

詳細はこちら。
http://www.kiwi-lib.info/specs.html

RSpecのObjective-C実装といったところで、
やはりRSpecと比べるとかなり機能が少なく最小限のようです。

基本的な書き方は、ほぼRSpecと同じなので、RSpecの本とか読めば参考になりそう。


使い方

テンプレートはこんな感じで、

#import "Kiwi.h"

SPEC_BEGIN(Spec名)

describe {@"テスト対象", ^{
    context {@"状態", ^{
        describe @"テスト対象メソッド", ^{
            context @"与える入力", ^{
                it @"期待する出力", ^{
                }
            }
        }
    }

}

SPEC_END

実際に書くと

SPEC_BEGIN(NSDateSpec)

describe (@"NSDate", ^{
    context (@"When October", ^{
        describe (@"NSDate#lastDate", ^{
            context (@"With xxx", ^{
                it (@"should be 30", ^{
                        // ここにテストコードを書く
                });
            });
        });
    });

});

SPEC_END

ちょっと例が悪かったのでインプットが思いつかなかったのですが、、
こんな風に書けばよいはずです。

あとはインプットや状態によって以下のようにテストを増やしていけばいいのです。

SPEC_BEGIN(NSDateSpec)

describe (@"NSDate", ^{
    context (@"When October", ^{
        describe (@"NSDate#lastDate", ^{
            context (@"With xxx", ^{
                it (@"should be 30", ^{
                        // ここにテストコードを書く
                });
            });
            context (@"With xxxxx", ^{
                it (@"should be 31", ^{
                        // ここにテストコードを書く
                });
            });
        });
        describe (@"NSDate#firstDate", ^{
            it (@"should be 1", ^{
                    // ここにテストコードを書く
            });
 

        });
    });
    context (@"When February", ^{
        describe (@"NSDate#lastDate", ^{
            context (@"With xxx", ^{
                it (@"should be 28", ^{
                        // ここにテストコードを書く
                });
            });
    });
});

SPEC_END

なにがよいかというと、テストを実行してみるとわかると思いますが、
出力を見てなんのテストが実行されているのかがわかりやすいのがメリットです。
xUnitでもやろうと思ったらできると思いますが、コピペを繰り返すことになるので、
このように階層構造でわけられるので便利だし、見やすいです。

2012年8月25日土曜日

iphone_dev_jp東京 mac/iphone Hackathonに参加してきた

使えるライブラリを作ろう!というハッカソンに参加してきました。

個人的に家計簿アプリを作っていてNSDateがかなりいけていない(面倒なのが多い)のでそれを楽にするものを作りました。

https://github.com/yanamura3/NSDateHelper

実装自体は自分のソースコードからライブラリ化したいものをひっぱってくるだけだったのでほぼ一瞬で終わってしまい、大半はKiwi使ってテスト書いてました。

できたものはライブラリというかカテゴリになってしまいましたが。

問題はカテゴリを組み込むのにgitsubmoduleやcocoapodsだと2つファイル読みこめばいいだけなのに無駄にプロジェクトファイル毎取り込まなければいけないのがなんだなぁと。この辺りもなにかうまいやりかたを考えていく必要がありそうです。

結構時間があまったのでOCMockitoというモックライブラリで足りない機能があったので追加してみました。

https://github.com/yanamura3/OCMockito

追加したのはスタブのメソッドが呼ばれた際に指定したblocksを呼ぶことができるようにする拡張で、

[given([mock somemethod]) answer:^{ /** 処理 */ } ]

と書けば somemethodが呼ばれるとanswerに渡したblocksが実行されます。

NSProxyのforwardInvocationの勉強にもなったので結構役に立ちました。


最後は発表があったのですが、あまりにもやったことが地味すぎたので
今度ハッカソンに参加するときはもうちょい見た目にインパクトあるものを考えて参加しようと思いました・・・


Togetter
http://togetter.com/li/361912

中島さんの問題

中島聡さんのブログにでていたザッカーバーグの面接試験解いてみました。

問題その1
http://satoshi.blogs.com/life/2012/08/block.html

回答
https://github.com/yanamura3/HTTPLoader

GCDを使って同期リクエストをラップして非同期に見せかけるという一番シンプル(実装の少なくて済む)なやり方で実装で実装しました。
問題としてはキャンセルはできないのでキャンセルもしたい場合は別のやり方のほうがいいです。


問題その2
http://satoshi.blogs.com/life/2012/08/zack2.html

回答
https://gist.github.com/3426890

これはretainカウントを別の用途に使うといった発想でおもしろいやり方だなぁと思いましたが、複数人でやるようなプロジェクトでこういう一見わからない実装を入れると間違った使い方がひょいと混入しそうで怖い感じがします。

2012年8月22日水曜日

【Ruby最低限の知識編】Ruby素人が「たのしい開発スタートアップRuby」を実践

結構ざっくりとした説明しか書かれていませんが、他の言語を使ったことがあると用意に理解できると思うので、短い割にちょうど良い程度の説明の仕方だなと思いました。
ただこれまで経験したことのないものがポンとでてくるとちょっと理解に苦しみましたがそこはちゃんとした言語の本を読んで、ここではこんなもんかとさらっと流すほうがいいかなと。

以下感想。

・変数を使う
 いたって普通
・四則演算
 いたって普通
・すべてがオブジェクト
 Java,C系統のようなプリミティブはない。動的型付けだとそうですよね
・文字列
 ' ' or " "
   + で連結できて楽
 #{ } で囲めば文字列の中に変数の値とかをぶっこめる
・メソッド呼び出し
 オブジェクト.メソッド Java、C#とかと同じ
 BOOLを返すメソッドは最後に ? をつける。いままではisとかhasのプレフィックスつけてたので新鮮。言語としてお作法が決まっているのはいいこと。
 メソッド() の()は略していいようだ(ただし()なしで解釈できる場合に限る・・)
・配列
 [] の中に型とか気にせずにつっこめる
 +で配列もつなげれる
 ーで差分をとれる
 * で繰り返しができたり
・ハッシュ
 { key => value , , }
・シンボル
 軽く理解に苦しむ。
 keyに文字列よりはシンボルを使うようだ、書き方がJSONっぽい
・コメント
 #
・真偽
 true, false, nil
・条件分岐
 ここはちょっと気持ち悪い、なぜこうしたし。
 elsifをタイポしそうだ・・
   switchではない

 if
   elsif
   else
   end

 case
   when
   when
 else
   end

   ifの1行での記載は他の言語でもみたことないしかなり読みづらい。これ嫌い。
 でもifを前にもってきても{}つけないから余計見づらいのか、なんなのか。
 だいたい1行で書く系は可読性犠牲にしているのでしょうがないか。

・繰り返し処理とイテレーション
 for文によるfor eachの書き方はC#,Objective-Cとかと同じ。

 each do ブロック end でなんぞこれ・・・
 each { | | 処理 } のほうが初見では理解できた。eachの引数に{}渡して毎回{}内が実行されるんだろうなと。
 
 ブロックをObjective-Cのblocksと同じと考えることで理解。
 Objective-Cだと ^(引数) { 処理 } なので
 rubyは | 引数 | 処理 ってことなんすね、たぶん。

2012年8月21日火曜日

【Rubyインストール編】Ruby素人が「たのしい開発スタートアップRuby」を実践

まずはインストール

環境:Mac OS X 10.7.4


$ ruby -v

ruby 1.8.7 (2011-12-28 patchlevel 357) [universal-darwin11.0]


Homebrewを使ってやってみます

$ brew install ruby
Warning: It appears you have MacPorts or Fink installed.
Software installed with other package managers causes known problems for
Homebrew. If a formula fails to build, uninstall MacPorts/Fink and try again.
==> Installing ruby dependency: readline
==> Downloading http://ftpmirror.gnu.org/readline/readline-6.2.tar.gz
######################################################################## 100.0%
==> Downloading patches
######################################################################## 100.0%
######################################################################## 100.0%
==> Patching
patching file vi_mode.c
patching file callback.c
patching file support/shobj-conf
patching file patchlevel
==> ./configure --prefix=/usr/local/Cellar/readline/6.2.2 --mandir=/usr/local/Cellar/readline/6.2.2
==> make install
==> Caveats
This formula is keg-only, so it was not symlinked into /usr/local.

OS X provides the BSD libedit library, which shadows libreadline.
In order to prevent conflicts when programs look for libreadline we are
defaulting this GNU Readline installation to keg-only.

Generally there are no consequences of this for you.
If you build your own software and it requires this formula, you'll need
to add its lib & include paths to your build variables:

    LDFLAGS  -L/usr/local/Cellar/readline/6.2.2/lib
    CPPFLAGS -I/usr/local/Cellar/readline/6.2.2/include
==> Summary
/usr/local/Cellar/readline/6.2.2: 30 files, 1.6M, built in 25 seconds
==> Installing ruby dependency: gdbm
==> Downloading http://ftpmirror.gnu.org/gdbm/gdbm-1.10.tar.gz
######################################################################## 100.0%
==> ./configure --prefix=/usr/local/Cellar/gdbm/1.10 --mandir=/usr/local/Cellar/gdbm/1.10/share/man
==> make install
/usr/local/Cellar/gdbm/1.10: 10 files, 224K, built in 11 seconds
==> Installing ruby dependency: libyaml
==> Downloading http://pyyaml.org/download/libyaml/yaml-0.1.4.tar.gz
######################################################################## 100.0%
==> ./configure --prefix=/usr/local/Cellar/libyaml/0.1.4
==> make install
/usr/local/Cellar/libyaml/0.1.4: 7 files, 328K, built in 10 seconds
==> Installing ruby
==> Downloading http://ftp.ruby-lang.org/pub/ruby/1.9/ruby-1.9.3-p194.tar.gz
######################################################################## 100.0%
==> ./configure --prefix=/usr/local/Cellar/ruby/1.9.3-p194 --enable-shared
==> make
==> make install
==> Caveats
NOTE: By default, gem installed binaries will be placed into:
  /usr/local/Cellar/ruby/1.9.3-p194/bin

You may want to add this to your PATH.
==> Summary
/usr/local/Cellar/ruby/1.9.3-p194: 14688 files, 74M, built in 4.3 minutes

うまくいったっぽい。
念のため確認してみると


$ ruby -v
ruby 1.8.7 (2011-12-28 patchlevel 357) [universal-darwin11.0]

変わってない。。。だと。。。

以下本には書いていないこと。

$ which ruby
/usr/bin/ruby

/usr/bin/rubyのほうを見に行ってます。
ログをよくみると



NOTE: By default, gem installed binaries will be placed into:
  /usr/local/Cellar/ruby/1.9.3-p194/bin

You may want to add this to your PATH.

こっちにパスを張りやがれと書いてあるのでパスを追加します。
以下bashの例。

$ emacs .bash_profile

export PATH=/usr/local/Cellar/ruby/1.9.3-p194/bin:$PATH

$ source .bash_profile

$ echo $PATH

でちゃんとPATHが通ってるか確認

$ ruby -v

ruby 1.9.3p194 (2012-04-20 revision 35410) [x86_64-darwin11.4.0]

これでOK。

2012年8月20日月曜日

Objective-Cのシングルトンパターン

Objective-Cのシングルトンの実装ですが、
GCDにdispatch_onceという便利なのがあるので、これを利用するとすっきり書けますし、dispatch_onceだとXcodeによる補完が強力なので書くのも速いです。
http://stackoverflow.com/questions/7568935/how-do-i-implement-an-objective-c-singleton-that-is-compatible-with-arc


+ (MyClass *)sharedInstance
{
    static MyClass *sharedInstance = nil;
    static dispatch_once_t onceToken;

    dispatch_once(&onceToken, ^{
        sharedInstance = [[MyClass alloc] init];
        // Do any other initialisation stuff here
    });
    return sharedInstance;
}

2012年8月13日月曜日

Objective-Cでprivateなインスタンス変数を外部から変更したり参照する方法

UnitTestなどでテスト対象のクラスのprivateな変数(属性)を参照したり変更したりしたい場合があります。
テストのためにアクセッサを追加したりするのはちょっとあれなので何かいい方法がないか調べてみたらObjective-Cだとテストフレームワークの力を借りるまでもなくあっさりできますね・・

Objective-CのKey Value Codingを利用します。

これはざっくり言うとアクセッサーを用意しなくても、
 setValue: forKeyとvalueForKeyを使えば、名前(Key)でクラスの変数にアクセスできるという代物です。

テスト対象はこのPersonというクラス。(メソッド名がひどいのは無視しましょう)


@interface Person : NSObject
{
@private
    NSString* name;
}

- (NSString*)getName;
@end

@implementation Person

- (NSString*)getName {
    return name;
}

@end

テストコードはこのようになります。

- (void)testName {
    Person * person = [[Person alloc] init];
    
    [person setValue:@"Taro" forKey:@"name"];
    
    GHAssertEqualStrings(@"Taro", [person getName], @"not equeal name");
}


2012年8月6日月曜日

Xcode : TODO, FIXMEなどの記述

TODO, FIXMEなどのコメントを以下のようなフォーマットでつけると
control + 6 でのメソッド一覧の表示の際に#pragma markと同様に簡単に見つけられるようになります。(参考

// TODO: "comment"
// FIXME: "comment"
// !!!: "comment"
// ???: "comment"
// MARK: "comment"

Xcode4.4以前はメソッドのなかに記載しても表示されませんでしたが、Xcode4.4以降だとメソッドの中に記載しても表示されるようになったのでTODOなどが使いやすくなりました。

2012年8月5日日曜日

Xcode : #pragma markで見出しをつける

プログラム上でたまに見かける #pragma mark ***  の使い方です。(参考)

#pragma mark を使うことでコードをXcodeで見やすくすることができます。
C#知ってる人はC#のpragma regionと似たような感じに使うことができます。(begin-endはいらない)

・書き方
*** のところに何か文字列を記載します。

#pragma mark ***

例:hogeとつけてみる



"control + 6" でメソッド一覧を表示すると
図のようにpragma markでつけたhogeという文字列が一覧に表示されるようになります。



追記:

#pragma mark - ***

とハイフンをつけることで区切り線を出すことができるので更に見やすくすることができます。

たくさんメソッドがある場合などに探しやすくするのによいと思います。



LL Decade に参加してきた

毎年行われているLLのイベント LL Decadeに参加してきました。

昨年も参加しましたが、昨年はJavascript一色な感じでしたが、今年はバランスがよかったです。

スピーカー陣は@miyagawa,@matzはじめ日本のそうそうたるメンバーが一同に介しとても豪華でした。

特に印象に残ったのが@miyagawaさんの基調講演で、WSGIなど他言語で実装されたよいものをそれ以外の言語にポーティングして取り込むという言語間での交流が増えてきていているというところで、確かにObj-CをやっていてもRubyなどのやり方を取り込んだりしているものがよく見られるのでなるほどと感じるとともに、そういうところはOSSとしてはじめるにはとっつきやすいところなのかなと。
複数の言語が使える人をpolyglotというらしいです、複数の言語を使うことで他言語のよいところや悪いところを知るのによいきっかけができるので、2年に一つくらいは新しい言語に挑戦したほうがよさそうです。

@matzさんの講演ではruby2.0がいよいよruby生誕20周年にあわせてリリースされる予定だそうです。(20年だからだしちゃおうかくらいのノリのようです)
キーワード引数が使えるようになるらしいので楽しみです。
mrubyという組み込み向けのrubyも開発が着々と進められているようで、元組み込みエンジニアとしてはどうなのか結構気になるところです。
まだフットプリントが600kくらいあるそうなのとソフトリアルタイムを実現するためのGCの改善などが課題としてあるみたいです。

Underscore.m

_.m

javascriptのライブラリのUnderscore.jsをObjective-Cへポーティングしたもの。

CocoaControl

CocoaControl

いろいろなカスタムUIコントローラの部品が登録されていて便利そう。

2012年7月5日木曜日

アジャイルサムライ横浜道場「ユーザーストーリーを集める」に参加してきた

アジャイルサムライ横浜道場「ユーザーストーリを集める」に参加してきました。

仕事で抜けられなくて約二ヶ月ぶりの参

流れはいつものように5分の音読+10分議論の4セット+まとめ発表5分。
今回?はまとめ発表が各グループ1分+質疑4分でした。

今回の読書会の内容は第6章「ユーザーストーリーを集める」でした。

文書化は、よく文書化しろとか言われますが、すべて文書で伝えるのは無理で、文書は誤解を与えやすく、コードと同じで完璧な文書というのはありえないです。
網羅しているのか?という質問をされるというお話を聞きましたが、網羅しているかどうかなんて、網羅していることを証明するなんて、スコープをかなり限定しない限り無理ですよね。
ただかと言って、アジャイルでは文書は書かなくていいとかいう勘違いも間違っていて、文書は全く無くてもいいわけでもないです。だったらどれくらい書くのかというと、「場合による」ので自分たちでなにが最適なのか考えないとだめだなわけです。なので思考停止して文書をつくるのが一番やってはいけないことで、何が必要で何が不要なのか考えて書くということが大切だと思います。

今回覚えたのがINVESTという言葉で、
一人で読んでいた時にはあんまり気にしていなかったのですが、
INVESTはソフトウェア開発に似ているという意見にとても同意しました。
独立性、テスタビリティ、見積もれるなど、ソフトウェア開発の手法をユーザーストーリーの抽出に適応させると考えるとけっこうしっくりくるものがありました。

2012年7月1日日曜日

could not locate an NSManagedObjectModel for entity name

"could not locate an NSManagedObjectModel for entity name" というエラーがCoreDataで出た場合の対処方法。

以下のようなコードで、色のついたコードの箇所で止まってしまう場合です。
entity nameはあっているはずなのに・・・と悩んだわけですが、
self.managedObjectContextにちゃんとセットしていないとこのようなエラーがでてしまいます。(エラーの内容が紛らわしい・・)


- (NSFetchedResultsController *)fetchedResultsController
{
    if (__fetchedResultsController != nil) {
        return __fetchedResultsController;
    }
    
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    // Edit the entity name as appropriate.
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Spending" inManagedObjectContext:self.managedObjectContext];
    [fetchRequest setEntity:entity];


gitによる開発フロー

・設定

エディタをviからemacsに変更
git config --global core.editor 'emacs'

・開発フロー
A successful git branching model をベースに開発を行う場合の手順。
http://keijinsonyaban.blogspot.jp/2010/10/successful-git-branching-model.html

・管理者
gitリポジトリをまずつくる
git init

touch README

git add README

git commit -m "initial commit"

git remote add origin http://xxxxxx/xxx.git

git push origin master

developブランチをつくる
git checkout -b develop

developブランチをremoteリポジトリにpush
git push origin develop

・開発者
develop ブランチをブランチしてfeature1を開発する場合

remoteのdevelopブランチをチェックアウト
git checkout origin/develop -b feature1

commitする
git commit -m ""

commitをまとめる
git rebase -i HEAD~5

developの変更を取り込む
git pull --rebase origin develop

競合の解決をする

競合を解決したファイルをadd
git add

rebaseを完了させる
git rebase --continue

pushする
git push origin feature1


2012年6月30日土曜日

iOS:StoryBoard Tips[初期画面を変更する]

StoryBoardありでプロジェクトを作ったりすると最初から初期画面が決まっている(→)がついていたり、空のStoryBoardにViewControllerを追加するとその画面が初期画面になりますが、StoryBoardでひと通り作成したあとに、やっぱりべつのViewControllerを初期画面にするときの設定方法です。

下の図のTabBarControllerが現在初期画面になっていますが、これをViewControllerに変える方法です。

StoryBoard上でViewControllerを選択し、
右の画面のAttribute Inspectorを開きます。
ViewControllerのセクションに"Initial Scene"というチェックボックスがあるので、これをチェックすると初期遷移のSegueが移動します。

2012年6月26日火曜日

iOSでOCMockでテストする【環境構築】

Objective-C用のMockライブラリ OCMockを使うための環境構築

環境:
 Xcode 4.3.2
   OCMock 2.0

まずここからダウンロード。(ソースコードからやるやり方は後日追記予定)
http://ocmock.org/

"Download"のタブからdmgファイルをダウンロードします。
http://ocmock.org/downloads/ocmock-2.0.1.dmg (2012/06/24現在の最新)

ダウンロードしたら開きます。
展開されて、iOS, OSX, Source の3つのディレクトリが現れます。

iOSを開きOCMockのディレクトリをドラックアンドドロップでプロジェクトに追加。

libOCMock.aも同じくプロジェクトに追加。(ここではOCMockディレクトリ内に入れます)

そうするとこのようになるはずです。(注:プロジェクトに追加する際に、Copy items into destination ...にチェックいれるのを忘れないこと)

TargetのBuild Phasesのタブを選択し、Link Binary WIth Librariesのセクションを開きlibOCMock.aを追加します。

#import <OCMock/OCMock.h>を発見できるように、
 Build SettingのHeader Search Pathに$(SRCROOT)を追加。

ライブラリをリンクするために
Build Settingのother linker flagに -ObjC -force_load $(SRCROOT)/OCMock/libOCMock.a を追加。
以上で環境設定は完了です。

試しにテストコード(SenTest)に

#import < OCMock/OCMock.h>


- (void)testExample
{
    id tableViewMock = [OCMockObject mockForClass:[UITableView class]];
}

を記載して、Cmd + Uでテストを実行してみましょう。


2012年6月22日金曜日

OnLab Data Conferenceに参加してきた

Onlab Data Conferenceに参加してきました。

データ分析に使えるサービスはよく知らなかったのでとても勉強になりました。
リーン・スタートアップでも言われていますが、検証するためにはデータが非常に重要で、それを行うためには、何を分析するのかという目的が必要で、さらには分析するためのデータが必要です。そのデータを集めるにはサービスをローンチする際にあらかじめそういった仕掛けを埋め込んでおかなければならないわけで、速くサービスを出すにはこういったデータ解析サービスをうまく活用していくことは必須だと思いました。
データをものすごく見ることも重要ですが、それをやりすぎると局所解に陥ってしまうというところのさじ加減も肝心だなと。
サービスの序盤のようにユーザーが少ないときは、母数も少ないのでデータ解析に頼るよりはユーザー一人ひとりにフォーカスをあてて話をするといったアナログなやり方のほうがいいという意見にはすごく同意でした。

予測分析 Peter Skomoroch(LinkedIn)

予測から戦略を立てるという例で映画シャーロック・ホームズをあげていました。
ストリートファイトでシャーロック・ホームズは予測から戦略を立てて戦っていて、戦い方は日頃から練習でつちかっている。
ビジネスでもストリートファイトのように考える。
データをしっかり見て分析する(例:ヤギと男と男と壁と)
データを壊すくらいデータをみる。
John Rauserのプレゼンを見るといい
平均は見ても意味が無い。大事な特徴的なデータが平滑化されてしまう。
データと直感だけではだめ、アルゴリズムに基づいている必要がある

・データはどのように反映している?
・意思決定へのサジェスチョンに使っている。ある特定のユーザーをとりあげて分析したり、A/Bテストを少数のユーザーに対して行う

データは適切な場所に保存することが重要、これには最初から準備しておく必要がある。
何かを消すときも消さずに消したことを保存しておいたほうがいい。
オートコンプリートを用意しておくことで最初からデータを整形できてデータ整理にもいいし、ユーザーにとてもよい。
一つひとつの数字を深掘りしていくことが重要
まずはユーザを集めてからデータを解析したほうがいい。(母数が小さいと統計が難しい
・データサイエンティストにはどんなひとがむいてる?
・ある程度のコーディングスキルと科学のバックグラウンド

アナリティクス・アクセス解析・KPI設定 Hiten Shah(KISSmetrics)

アクションができるメトリクスにフォーカスする。
GoogleAnalyticsでとれるようなデータはVanity Metricsだ。
例えばPage Viewとか。trafficが多いからといって必ずしもビジネスには役に立たない。
web analyticsでなくcustomer analyticsでないといけない。
すべての経験(ユーザー行動)をトラックする。
データを個々のユーザとひもづけることによって匿名状態でも個人の行動を解析することが可能。
ユーザーは複数のチャネルから来るので、カスタマーベースでトラッキングする必要がある。だれが価値のあるユーザーか(そのユーザーはどこからきてるか)みつけるのに役立つ。
重要なアクションをしたのはなぜか、など全体のカスタマーライフサイクルをトラッキングする。
速く学ぶ必要がある。他より速く学ぶのが勝つ方法。
・生涯価値を予測するには?
・単純な計算でもいいので予測をたてること。すでにあるサービスをモデルにする。
・仮設を立てるところから始め、どういったリスクが伴うのか知っておく

・プロダクトが市場にフィットするか?
・この製品がなくなったらどう思うか考えてみる。

・ユーザーが少ない時は?
・個々の人に落としこむ

HowToListenToYourUsers Pete Koomen (Optimezely)

これが正しいと思ってやるのはナンセンス。
必ずしもうまくいくとは限らない。

最初のサービスは4ヶ月かけてつくったが誰もやらなかったし、お金は全く儲からなかった。
次のサービスは1ヶ月で初歩的なのをつくったがだめだったのでやめた。
OptimizelyはA/Bテストを簡単にできるサービス。

・作る前に10人くらいのユーザの重要な問題にフォーカスする。
モックをつくる。仮設をつくるための情報を集める
・ユーザーと話す。人々は改善への貢献はそんなに嫌がらない。
そして売ることが大切(金を払う価値のあるものをつくる)
中古車屋のセールスマンみたいなのはつかってはだめ
近道するのも重要(例えば、期間毎にライセンス料を変えていたけど、実はライセンスが切れたときの実装は入れていなかったけどだれも気にしなかった)
スケーリングは気にしなくていい
ユーザーが利用をやめたときが分析するいいタイミング。
キャンセルボタンを消して、メールを送らないとキャンセルできないようにして、その時にユーザーになんでやめたのかを聞いたりした。
Flurry,Kontagent,KISSmetricsとかで分析する。
アクションがとれるデータとしてはA/Bテストがある。ただし十分なトラフィックが必要。
ただしRefinement = design decision ではない。

・テスト期間はどれくらい必要?
・最低2週間(トラフィックがある場合)。統計上必要な量で決まる。

QualitativeData and UX  Chrix Palmeiri (AQ)

・UX どう感じ、どう使い、どう説明するのか
 ユーザーテストは対象は知り合いでもいいからやったほうがあいい

・質問票
 ユーザーテストをやるタイミングはユーザーのニーズとギャップがあるとき
 何にわくわくしているかわからないとき
 例えば、サインアップのときになぜ、何に期待してサインアップしたのか簡単な質問をしてプロダクトのフォーカスを決めた

・ユーザービリティテスト
 大きな質問を2,3する。
 スクリプトを作る。
 オープンエンドな質問とクローズタスク
  1.目的を説明
  2.タスクごとにコンテキストを設定する
  3.すべて声に出す(だまったら質問する)
  4.できるだけメモをとる
 以上を短時間でとにかく多くやる

・カードソーティング
 ラベルやカテゴリを決める前にやるといい(初期でやること)

メール配信と分析 Taylor Wakefield (MailGun)

今でもe-mailの利用は圧倒的に多い。だけど90%はスパム。
e-mailの内容はhtmlのみはだめで、画像はデフォルトで消される場合が多い
textは短すぎてもだめで、ストーリー性が必要。
トラフィックが集中しすぎるとスパム判定されるので注意が必要。

パネルディスカッション

データだけでは局所的な最適解になってしまう。
もちろんクリエイティビティが必要。