最近、iOSアプリの開発でも継続的インテグレーション(CI)を取り入れていくプロジェクトが増加傾向にあるようで、各種ツールやライブラリ、ノウハウが出回ってきているように感じられます。そこで私も早速iOSアプリ開発でのCI導入を試してみることにしました。今回の導入試験では、以下のような環境を想定して行いました。 iOSアプリの開発を、Xcode 4.X系のプロジェクトとして行う。 VCSにはgitを採用し、githubの公開リポジトリをリポジトリサーバーとして使用する。 CIサーバにはMacを採用し、プロジェクトをビルドするためにXcode 4.Xをインストールしておく。 ■必要なツールを準備する CIといったら、まずは何はなくともJenkinsです。 http://jenkins-ci.org/ ここでは導入について詳しくは挙げませんが、私は以下の本を参考にしました。 https://gi
条件付きコンパイル プリプロセッサディレクティブ¶ プリプロセッサディレクティブは、プログラムの一部を条件によって選択してコンパイルする命令です。
XCodeにデフォルトで含まれるユニットテストフレームワーク「SenTestingKit」をiPhoneアプリ開発で利用する方法を忘れないようにメモ。大枠の設定&実行まで、コーディングレベルのアサーションの種類や使い方は別途書く。 参考記事 iOS Development Guide: Unit Testing Applications まずプロジェクトの作成。任意のプロジェクトでユニットテストが可能(プロダクト用とユニットテスト用のプロジェクトを分ける必要がなく後述するターゲットで分ける)、なので適当にWindow-based Applicationを選択。 プロジェクト名は任意でOK、「UnitTestSample」として保存。 初期状態のプロジェクトリソースはこんな感じ。 ユニットテストはビルド時にXcodeで行う「Logical Tests」と、実機で行う「Applicati
また、テストを書く。 最近 iOS 界隈のテストのベストプラクティスについて調べているのですが、そこで目に留まった文章があるのでまずそれを紹介します。 How comfortable are you on a bike without a helmet? Writing code without tests is like riding a bike without a helmet. You might feel free and indestructible for now, but one day you’ll fall and it’s going to hurt. http://paulsolt.com/2010/11/iphone-unit-testing-explained-part-1/ ヘルメットを付けずに自転車を漕ぐのはとても快適ですね。でも、ふとしたある日に取り返しの
Info.plistや、ビルド設定をいじっていると、こんな文字列に出くわすかと思います。 $(PRODUCT_NAME) $(TARGET_TEMP_DIR) $(SRCROOT) これらはそれぞれ特別な意味を持ち、Xcode がビルド時だか何だかのタイミングでプロダクト名とか環境に応じたパスとかに置き換えたりしてくれるものです。 が、 「SRCROOTってどこだっけ?プロジェクト直下?それともその一つ下?」 「Library Search Path を指定したいけどこの場所を指定するのにどのマクロを使っていいかわからない」 みたいなことになることが度々あるのではないでしょうか?(僕はあります) そして困ったことに、これらを網羅したAppleのドキュメントもありません。 (※というのは間違いで、バッチリありました。末尾の追記をご参照ください) 最近やっとその「Xcode で使用しているマク
テストを書く。 最近、色々なプロジェクトで Jenkins をはじめとした継続的インテグレーション(CI)という単語を良く聞くようになりました。 僕自身といえば、iOS 開発では 「Xcode 4 から Unit Test 全面サポートがはじまった!」位しかキャッチアップできていませんでした。 なので開発中にデグレが発生したりすると、モデルから一つずつデバッグを繰り返して、気付いたら2時間経ってるみたいなことも多々ありました。 何してるんだろうみたいな感じになって、流石に危機感を覚えたので一旦手を止めて Xcode 開発に所謂今流行っているテスト手法を組み込もうと思いました。 今回は初歩の初歩ということで、Xcode に付属されている Unit Testing フレームワークである SenTestKit を用いた単体テスト環境の構築を行います。 全てを通して Xcode は 4.3 を使用
iOSでのTest SenTestingKitについて 概要 iOSでのテストに使える、SenTestingKitの導入と解説 SenTestingKitとは http://developer.apple.com/tools/unittest.html iOSで使えるテスト用のフレームワーク。デフォルトで入っている。 ソースコードでテストを書き、ビルド時にテストを行う。 実行時ではないのがポイント。 手順 1.ターゲットを作る ターゲットの作成が完了するとウインドウが開く。 ここで、このターゲットが依存する実行可能ターゲットとか決められるんだけど、 説明が長くなるのでパス。閉じる。 2.アクティブなターゲットをSomethingTestに設定する 3.テストのソースコード書く .hと.mに別れるのが好ましくないので、SomethingTest.mという名前のソースのみ作成。 ソース:Som
UITableViewCell の accessoryView というプロパティについてです。それほどマイナーなプロパティでもないので、実は当たり前なのかもしれませんが、最近便利さに気付いたので紹介します。 UITableViewCell には accessoryType というプロパティがあって、3種類のアクセサリが付けられます。 accessoryView は、これをカスタムな見た目にしたい時に使うぐらいのものだという認識でした。実際そうなのですが、よく考えたら UIView ならなんでも入れられるわけで、UISwitch だって入れられるんだなと。設定画面でスイッチがよく出てくるのですが、今まで contentView に addSubview していて、位置を合わせるのが面倒だと思っていました。でも accessoryView なら次のコードで終わりです。frame の origi
コンビニエンスコンストラクタがいまいち理解しにくいので、現時点での理解をまとめてみる。 コンビニエンスコンストラクタは、クラスの(一時的な)インスタンス(実体)を生成して初期化する イニシャライザはインスタンスの生成は行わない 一時的なインスタンスは自動開放プールがreleaseされたら消滅するため、必要に応じてretainする だから、クラスのインスタンス変数はallocしてから指定イニシャライザを呼ぶか、コンビニエンスコンストラクタを呼んでインスタンスを生成するかしないといけない。 実体のないインスタンス変数からいきなり指定イニシャライザを呼ぶのはもってのほか。 /* Testクラスのコンビニエンスコンストラクタ */ + (id)testWithA:(int)a{ id s = [[self alloc] initWithA:a]; return [s autorelease]; }
Mountain Lion発表とともにリリースされたXcode4.4。OSX Lionでも使える様になっています。Xcode4.4から、llvm (コンパイラ)のバージョンが4.0になっています。 それによってObjective-Cの書き方にかなりの改善が加えられたので、それを簡単にまとめておきたいと思います。これらの改善は、iOS6に関係なく動作するので、いま作っている、iOS5用のコードにも使用出来ます。 synthesize by default コンパイラが@synthesizeを補完してくれる様になったため、基本的な状況では、@synthesizeを書かなくてよくなりました。また、synthesizeされる相手のivarも、同名の変数ではなくて、アンダーバーを最初に付けた物がデフォルトとなります。これまで議論されて来たことがappleのコンパイラによって、これからは定義されている
指定したクラスの、実装されているメソッドを列挙する - すぎゃーんメモの、続きのようなもの。 クラスに実装されているメソッドの一覧を取り出すことはできたので、今度は一つ一つのメソッドについての詳細を調べる。 例えばNSIndexPathの中にある"initWithIndexes:length:"というメソッドについて知りたいとき。 #import <Foundation/Foundation.h> #import <objc/runtime.h> int main(int argc, char *argv[]) { NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; unsigned int i; size_t buf_size = 256; char *buffer = malloc(buf_size); // ターゲッ
メソッドを構成する要素の最後になる、メソッドの実装を取り上げよう。IMP (implementation) 型になる。これを利用すると、劇的な高速化も可能だ。 IMP型の定義 メソッドの実装を表すIMP型について、前にも紹介したが、もう一度説明しよう。メソッドを表す構造体は、Method構造体。この中にmethod_impという名前の、IMP型のフィールドがある。このIMP型の定義は、objc.hにある。 objc.h typedef id (*IMP)(id, SEL, ...); つまり、C言語の関数である。Objective-Cでは、メソッドの実際の処理を行っている実装はどこにあるのかと、追いかけていけば、このC関数にたどり着く。 この関数には、2つの引数があらかじめ定義されてある。これが、前々回に紹介した、メソッドに渡される暗黙の変数だ。すべてのメソッドで、この変数を利用できる。
Objective-Cで、Method構造体からCレベルの関数ポインタを取得する方法のメモです。 以前は、 1 Method *method = class_getInstanceMethod(class, selector); 2 IMP imp = method->method_imp;
以下の関数を呼び出すことにより メソッドのSELオブジェクトから、関数へのポインタを取得することができます。 // クラスメソッド、インスタンスメソッド兼用 - (IMP) methodForSelector: (SEL)aSelector // インスタンスメソッド専用 - (IMP) instanceMethodForSelector: (SEL)aSelector IMP型の定義は下記のような関数へのポインタのtypedefになっています。 // id:呼び出し元オブジェクト // SEL:関数のセレクタ // ...:引数リスト typedef id (*IMP)(id, SEL, ... ); // [obj method: param1 p2:param2 ] 通常の呼び出し //関数へのポインタ経由の関数呼び出し。 SEL selector = @selector(meth
リリース、障害情報などのサービスのお知らせ
最新の人気エントリーの配信
処理を実行中です
j次のブックマーク
k前のブックマーク
lあとで読む
eコメント一覧を開く
oページを開く