「XCode4.6 で TEST_AFTER_BUILD を使って xcodebuild を実行時にテストを実行するようにするまで」でテストが xcodebuild で動くようになったので、それを Travis CI で動かそうと思います。
追記 2013-04-21 16:01:01
どうやら Travis CI の VM にバグがあったみたいで以下の方法が必要になっていたみたいです。
既に修正されてるみたいなので before_install のブロックはいらなくなっています。
というかこの記事をみずに「XCode4.6 で TEST_AFTER_BUILD を使って xcodebuild を実行時にテストを実行するようにするまで」のとおりで動きます。
詳細はここ
なのでバグがあった際はこうすれば動いていたよというログが以下となります。
追記おわり
基本的には「iOSのライブラリにTravis CIを導入する」に書かれている通りで当初問題なく動いていたのですが、何度か動かしている間に動かなくなってしまいました。
原因としては初期化の際に rvm が使用されるようになって cocopods がみつからなくて失敗していました。以下のように .travis.yml を書けば解決しました。重要なのが before_install のブロックです。
.travis.yml
language: objective-c
before_install:
- gem install cocoapods -r
- pod setup
script: make test |
下の画像は Travis Ci でビルドに失敗したログです。

travis-ci/travis-build/example を見るとbuild_objective_c.* は全て rvm が使われてるみたいなので ISRefreshControl もこけそうなんですけど、なぜだかはよくわかりません。 #6 までは必要なくテストが動いているんですけどね。
これらを見て before_install がフックされる時には rvm default ~ が実行された後なので、
before_install で cocoapods をインストールしてやれば解決しました。
cocoapods が見つからないとエラーが表示されて Travis CI でこける人は試してみてください。
/Library/Ruby/Site/1.8/rubygems/dependency.rb:247:in `to_specs': Could not find cocoapods (>= 0) amongst [bundler-1.3.5, rake-10.0.4, rubygems-bundler-1.1.1, rvm-1.11.3.7] (Gem::LoadError)
from /Library/Ruby/Site/1.8/rubygems/dependency.rb:256:in `to_spec'
from /Library/Ruby/Site/1.8/rubygems.rb:1231:in `gem'
from /usr/bin/pod:22
The command "pod install" failed and exited with 1 during install. |
Travis CI で動くようになるまでの差分です。
これで安心して push 時に CI がまわるようになりました。
おしまいおしまい。
Xcode 4.5 command line unit testingとかを見てもらえればわかりますが Run Script を修正し、ios-sim というのを用いればできることは知っていました。
なので jenkins を用いて CI する際には stackoverflow にあるような設定をやっていました。
homebrew による依存もあるため、めんどくさいですよね。
先日「iOSのライブラリにTravis CIを導入する」 を見て、TEST_AFTER_BUILD が動いてる!!!!
と、思ったので試してみました。
ついでに Travis CI で iOS-FakeWeb を動かしてみました。
TEST_AFTER_BUILD が動くようになるまでの差分がこれ。
以下、対応するまでの手順をまとめました。
1. + マークをクリックし、新たに FakeWebTests scheme を追加
2. FakeWebTests スキームに変更し、FakeWeb Targets を削除
3. FakeWebTests Target に全てチェックをいれる


これで準備は万端です。あとは xcodebuild で実行。
実行コマンド
$ xcodebuild \
sdk iphonesimulator \
workspace FakeWeb.xcworkspace \
scheme FakeWebTests \
configuration Debug \
clean build \
ONLY_ACTIVE_ARCH=NO \
TEST_AFTER_BUILD=YES |
これでめでたくビルド後にテストが実行されるというわけですね。
本来なら FakeWeb scheme で target を FakeWebTests で指定して実行すればいけそうな気がするんですけど xcodebuild: error: You cannot specify targets with a workspace. といって怒られてしまいます。xcodebuild -list だと見えているんですけどね。
Travis CI にも対応したのでですがそれは次回にでも書こうかと思います。
参考資料
Running Xcode 4 unit tests from the command line
[Building Xcode 4 projects from the command line](http://blog.carbonfive.com/2011/04/06/building-xcode–4-projects-from-the-command-line/
Xcode 4: Run tests from the command line (xcodebuild)?
UIActivityCollection に登録できる Activity 一覧が syu223/UIActivityCollection にまとめられています。とても便利ですね。
その中に Pocket が NNNetwork というリポジトリであります。
とはいえ自前で OAuth の認証をしているため、アイパスを入力させるのもなと使うのためらっていた次第です。
あとでアプリケーション側と連動するのもめんどくさかったのもあります。
もっとお手軽な感じで登録したいではありませんか。
アプリは切り替わりますが Pocket の場合はクリップボードに URL をコピーしアプリを起動すれば下の方にアラートが表示され追加することができます。
というわけでそれをそのままする Activity をつくりました。
今まで copy して自分でアプリを起動させていたので大分楽になりましたとさ。

dealforest/DFPocketActivityLite
ただいかんせんこれでもめんどくさい感じるようになってしまったので
さっさと SDK 連携しろということですね。はい。
おしまい。おしまい。
UIView Background Queue Debugging をみてこれいいなと思ってたんですけど、 swizzle を使ってたり別途クラスを定義したりとしてたのでもっと手軽にできたりしないのかなーと思ってたところで「BlockInjectionで元のソースコードを汚さないで振る舞い追加」を見てこれだ!!
となったわけでさっそく試してみました。
インストールも Cocoapods を使えば簡単にいけますね。
[BILib injectToSelector:@selector(setNeedsLayout) forClass:[UIView class] preprocess:^(UIView *view) {
if (dispatch_get_current_queue() != dispatch_get_main_queue())
NSLog(@"[%@ setNeedsLayout] being called on background queue.", NSStringFromClass([view class]));
}];
[BILib injectToSelector:@selector(setNeedsDisplay) forClass:[UIView class] preprocess:^(UIView *view) {
if (dispatch_get_current_queue() != dispatch_get_main_queue())
NSLog(@"[%@ setNeedsDisplay] being called on background queue.", NSStringFromClass([view class]));
}];
[BILib injectToSelector:@selector(setNeedsDisplayInRect:) forClass:[UIView class] preprocess:^(UIView *view, CGRect frame) {
if (dispatch_get_current_queue() != dispatch_get_main_queue())
NSLog(@"[%@ setNeedsDisplayInRect:%@] being called on background queue.", NSStringFromClass([view class]), NSStringFromCGRect(frame));
}]; |
これを application:didFinishLaunchingWithOptions:launchOptions で定義して使っています。
ついでにブレークポイントをしかけてクラッシュ前に捕まえられて状況を把握できるのでデバッグも効率的にできるわけですね。
地味に再現がめんどくさかったりするのでこういうのは助かりますね。
あと dispatch_get_current_queue は iOS6 から duplicated になっています。
Queue 名をつけて dispatch_get_specific で取得するようにしないといけなくなったのが少しめんどくさいですね
デバッグ時にも役立つし効果測定のコードも Controller から分離できそうなんでしばらく使ってみようかなと思います。
Xcode のコンソールには OS が出力したりと視認性がそこまでよくありません。
というわけで色付けできないかなと思ったらすぐにできたので紹介したいとおもいます。
robbiehanson/XcodeColors を clone してきて build するとインストールされます。
Xcode を再起動すると準備は万端です。
robbiehanson/CocoaLumberjack を使うとカラーリングやログレベルに応じた出力などが簡単にできて便利です。
みなさんよく使ってると思いますが、呼び出し元、行数を同時に出力するようなデバッグマクロを見やすくしてみようと思います。
これは自分で書いたメッセージをパっと見で分からないのがいけてないなと思ってました。
なのでカラーリングして見やすくしています。
結構みやすくなって個人的には気にいってます。
#define LOG(A, ...) \
NSLog( \
@"\033[fg255,255,0;" @"%s" "\033[fg0,255,0;" @"@L%d " @"\033[;" @"%@", \
__PRETTY_FUNCTION__, \
__LINE__, \
[NSString stringWithFormat:A, ## __VA_ARGS__] \
); |

これのおかげで”!!!!!!!!”とかプレフィクスつけてログの中で目立つようにしてたのでいらなくなりました。
使い出すとやみつきになりそうですね。
ただXcode のコンソールで実機デバッグする際はカラーリングされますが
organizer 経由でログを見た時はバケてるように見えるので気をつける必要があります。
実機に配布したりする際にはオフった方がよいみたいなので少し改良してこのようにしてます。
#define LOG(A, ...) \
NSLog( \
((getenv("XcodeColors") && (strcmp(getenv("XcodeColors"), "YES") == 0)) ? @"\033[fg255,255,0;" @"%s" "\033[fg0,255,0;" @"@L%d " @"\033[;" @"%@" : @"%s@L%d %@"), \
__PRETTY_FUNCTION__, \
__LINE__, \
[NSString stringWithFormat:A, ## __VA_ARGS__] \
); |
環境変数に XcodeColors が YES で登録されてる際のみ色をつけるようにしてます。
これは CocoaLumberjack でカラーリングする際にもこの環境変数を参照するようになっているため
同じようにしました。
これで実機にビルドする際は環境変数を設定しないようにすれば安心ですね。
設定方法はここをみるとわかりやすいと思います。
それではナイスなカラーリングライフを!