cupertino のインストールに失敗した際の対処方法

(nokogiri のインストールに失敗した際の対処方法)

https://github.com/mattt/cupertino
cupertino を利用するとコマンドラインから apple のデベロッパーセンターへアクセスすることができます。
というわけで、早速、cupertino をインストールを試みたが失敗したので、対処した際のメモ。

1. (問題) cupertino のインストールに失敗

$ sudo gem install cupertino

以下のメッセージが出力されて失敗していた。
---------------------------------------------
$ sudo gem install cupertino

Building native extensions.  This could take a while...
ERROR:  Error installing cupertino:
ERROR: Failed to build gem native extension.

/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/bin/ruby extconf.rb
checking for libxml/parser.h... yes
checking for libxslt/xslt.h... yes
checking for libexslt/exslt.h... yes
checking for iconv_open() in iconv.h... no
checking for iconv_open() in -liconv... no
checking for iconv_open() in -liconv... no
checking for libiconv_open() in iconv.h... no
checking for libiconv_open() in -liconv... no
checking for libiconv_open() in -liconv... no
-----
libiconv is missing.  please visit http://nokogiri.org/tutorials/installing_nokogiri.html for help with installing dependencies.
-----
*** extconf.rb failed ***
Could not create Makefile due to some reason, probably lack of
necessary libraries and/or headers.  Check the mkmf.log file for more
details.  You may need configuration options.

Provided configuration options:
	--with-opt-dir
	--without-opt-dir
	--with-opt-include
	--without-opt-include=${opt-dir}/include
	--with-opt-lib
	--without-opt-lib=${opt-dir}/lib
	--with-make-prog
	--without-make-prog
	--srcdir=.
	--curdir
	--ruby=/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/bin/ruby
	--with-zlib-dir
	--without-zlib-dir
	--with-zlib-include
	--without-zlib-include=${zlib-dir}/include
	--with-zlib-lib
	--without-zlib-lib=${zlib-dir}/lib
	--with-iconv-dir
	--without-iconv-dir
	--with-iconv-include
	--without-iconv-include=${iconv-dir}/include
	--with-iconv-lib
	--without-iconv-lib=${iconv-dir}/lib
	--with-xml2-dir
	--without-xml2-dir
	--with-xml2-include
	--without-xml2-include=${xml2-dir}/include
	--with-xml2-lib
	--without-xml2-lib=${xml2-dir}/lib
	--with-xslt-dir
	--without-xslt-dir
	--with-xslt-include
	--without-xslt-include=${xslt-dir}/include
	--with-xslt-lib
	--without-xslt-lib=${xslt-dir}/lib
	--with-libxslt-config
	--without-libxslt-config
	--with-pkg-config
	--without-pkg-config
	--with-libxml-2.0-config
	--without-libxml-2.0-config
	--with-libiconv-config
	--without-libiconv-config
	--with-iconvlib
	--without-iconvlib
	--with-iconvlib
	--without-iconvlib
	--with-iconvlib
	--without-iconvlib
	--with-iconvlib
	--without-iconvlib

Gem files will remain installed in /Library/Ruby/Gems/1.8/gems/nokogiri-1.5.9 for inspection.
Results logged to /Library/Ruby/Gems/1.8/gems/nokogiri-1.5.9/ext/nokogiri/gem_make.out

2. (対処方法)

  1. cupertino インストール中に上記のエラーが出力されていたので、以下の URL で対処方法を調べたところ、nokogiri をインストールするには、libxml2, libxslt をインストールしておく必要があるとのこと。
    これらをインストールしてから、再度、cupertino のインストールを試みたがエラーが出力されたので、
    その他の方法を探した。
  2. http://nokogiri.org/tutorials/installing_nokogiri.html

    $ sudo port install libxml2 libxslt
    $ sudo gem install nokogiri
  3. 以下のコマンドを実行してから、cupertino をインストールすると成功した。
    $ sudo gem install nokogiri -- \
    	--with-xslt-dir=/usr/local/Cellar/libxslt/1.1.26 \
    	--with-xml2-include=/usr/local/Cellar/libxml2/2.7.7/include/libxml2 \
    	--with-xml2-lib=/usr/local/Cellar/libxml2/2.7.7/lib \
    	--with-iconv-dir=/usr

CocoaPods の利用方法

1. インストール方法
$ sudo gem install cocoapods

– CocoaPods で利用可能なライブラリ情報を取得する
$ pod setup

(メモ) gem のバージョンが古い場合は、アップデートする
$ sudo gem update –system

2. 新規プロジェクトを作成する方法
– 任意のディレクトリに xcode プロジェクトを作成する
(プロジェクト名).xcodeproj と同じディレクトリに Podfile を作成する

– Podfile の書式:pod ライブラリ名 バージョン指定

platform :ios, "5.0"
pod 'JSONKit', '~> 1.4'
pod 'BlocksKit'
pod 'FTUtils'
workspace '(アプリ名).xcworkspace'
xcodeproj '(アプリ名).xcodeproj'

参照: cocoapods.org

– podfile に記述されたライブラリのインストール
$ pod install

– 自分で作成したプロジェクトと Podfile で指定したライブラリを格納した workspace ファイルが作成される
– CocoaPods が、ライブラリのリンク設定を行ってくれるので助かる。(^^)

ビルド時にエラーが出力されるようなら以下の点を確認する。
・ライブラリが利用している framework の設定

– CocoaPods がサポートしているライブラリは以下を参照のこと。
参照: CocoaPods/Specs

iOS シミュレータのファイル格納場所

CoreData を利用した開発を行っている場合、実機に格納される SQLite ファイルを参照したことがあります。
シミュレータでは以下のディレクトリに格納されている。

SQLite Database Browser などを利用すればデータベース ファイルを参照することができる。
http://sqlitebrowser.sourceforge.net
→ 編集が容易なツールって他にないのかなぁ?

Finder で shift+cmd+g でフォルダ移動

~/Library/Application Support/iPhone Simulator
iOS シミュレータによりサポートされるバージョン毎にディレクトリが別れている

~/Library/Application Support/iPhone Simulator/(iOS バージョン)/Applications/(UUID)
アプリケーション

~/Library/Application Support/iPhone Simulator/(iOS バージョン)/Applications/(UUID)/Documents
.sqlite ファイルなど格納される

xcode のエディタでカレント行に色を付けるプラグイン

xcode のエディタでカレント行をハイライトさせるプラグインが紹介されていたので、早速使ってみた。

参考:xcode-4-Fixins | Cocoaの日々情報局

設定手順
1. https://github.com/davekeck/Xcode-4-Fixins より、xcode-4-fixins を取得する
2. XCFixin_CurrentLineHighlighter プロジェクトをビルドする
3. xcode を再起動すると以下のメニューが表示されているので選択する
4. カレント行に付ける色を選択すると以下の様にエディタでカレント行に色を付加することができる

プラグインがインストールされる場所:
/Library/Application Support/Developer/Shared/Xcode/Plug-ins

– プラグインがインストールされると xcode にメニューが追加される
current_line_highlight_color1

– コード エディタのカレント行に選択した色が表示される
current_line_highlight_color2

ARC を利用している際に注意すること

ARC を利用していて少し気づきにくい問題に遭遇したのでメモしておく。

例えば、以前は baseViewController に addViewController を addSubView して表示する場合、以下の様なコードを書いていたがコレだと、ARC を利用した場合に BAD_ACCESS が発生する場合がある。

1
2
3
4
5
6
7
8
9
10
11
12
13
// 1. ARC 以前のコード
@implementation baseViewController
 
- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
 
    UIViewController *_tv = [[addViewController alloc] initWithNibName:@"addViewController" bundle:nil];
 
    _tv.view.center = self.view.center;
    [self.view addSubview:_tv.view];
}

retain count を考慮していると上記の様なコードが記述できたが、ARC を利用していると viewDidLoad メソッドを処理を抜けたタイミングで _tv が解放されるため、_tv 上のオブジェクトにアクセするする処理を行うと BAD_ACCESS が発生する。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 2. ARC を利用した際のコード
@interface baseViewController ()
@property(strong, nonatomic) addViewController *tv;
@end
 
@implementation baseViewController
 
- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
 
    _tv = [[addViewController alloc] initWithNibName:@"addViewController" bundle:nil];
 
    _tv.view.center = self.view.center;
    [self.view addSubview:_tv.view];
}

ARC 利用時は _tv が解放されないように包含されるクラスのメンバ変数としておく必要がある。
当たり前といえば当たり前だが、できるだけアクセスしなくてよいメンバ変数は定義しないようにと意識してるとハマります。
この問題最初に遭遇した時、1時間悩みました。(ノД`)

Interface Builder で TableView と Cell を関連づける手順

基本的に Interface Builder は使わない派なのですが、先日必要に迫られて利用した際に TableView と Cell を関連づけるのに苦労したのでメモしておく。

1. Interface Builder で TableView をビューに貼り付ける

1_Interface Builder で TableView をビューに貼り付ける

2. Interface Builder のテーブルビューから右マウスクリックでヘッダに IBOutlet 宣言を作成する

2_Interface Builder のテーブルビューから右マウスクリックでヘッダに IBOutlet 宣言を作成する

3_Interface Builder のテーブルビューから右マウスクリックでヘッダに IBOutlet 宣言を作成する

3. Interface Builder で Empty – .xib ファイルを作成し、テーブルビューのセルを作成する

4_Interface Builder で Empty - .xib ファイルを作成し、テーブルビューのセルを作成する

4. Interface Builder でテーブルビュー セルの”Custom Class – Class”を自クラス名を設定する

5_Interface-Builder-でテーブルビュー-セルの'Custom-Class---Class'を自クラス名を設定する

5. テーブルビューの”datasource”を”File’s Owner”に設定する

6_テーブルビューの%22datasource%22を%22File's Owner%22に設定する

6. テーブルビューに表示するデータ配列を作成する
7. テーブルビューのセル クラスを作成する
8. Interface Builder でテーブルビュー セルの”Table View Cell – Identifier”をソースコードと同じに設定する

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
- (UITableViewCell*)tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath
{
    static NSString* identifier = @"TableViewCell";
 
    TableViewCell* cell = (TableViewCell *)[tableView dequeueReusableCellWithIdentifier:identifier];
    if (nil == cell) {
        cell = (TableViewCell *)[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
                                                       reuseIdentifier:identifier];
        // リソースが NSArray で取得される
        NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"TableViewCell" owner:nil options:nil];
        for (id oneObject in nib) {
            if ([oneObject isKindOfClass:[UITableViewCell class]]) {
                cell = (TableViewCell *)oneObject;
                break;
            }
        }

リソースが NSArray で返されるのでクラスを判定して適切なリソースを適用するようにしなくてはならない。
一つの.xib ファイルに複数のリソースを作成できるようなので、このような手順になるんでしょう。

7_Interface-Builder-でテーブルビュー-セルの'Table-View-Cell---Identifier'をソースコードと同じに設定する

注意点

1. .xib と ソースファイルが紐付けられない場合、File’s Owner のクラス名設定が合致していない場合がある

2. this class is not key value coding-compliant for the key
メッセージが表示される場合、Interface Builder の設定に問題がある
オブジェクトの追加、削除を繰り返していると、不要な設定が残っていることがある。

正直、Interface Builder はプログラマにとってあまりメリットが感じられない。
メリットとしては「モックを早く作る」とか「オブジェクトを配置する際の座標を調べられる」程度かと思います。
オブジェクトへの設定などはコードで行った方があとで検索などでチェックしやすかったり、生成処理を統一できたりメリットがあります。
こういうツールって一見便利そうに見えて実は便利じゃないって感じなんですよね。
一応、今風を知っておくということで触ったが、こういうのを抵抗感なく多用できるタイプではないです。(>_<) 適材適所ってやつが重要ですよね。

Block 構文について

BlocksKit を利用し始めたので、少々 Block 構文を復習しておく。
Block を利用したライブラリを使える知識と構文に慣れるということを目的とする。

とりあえず、以下の事柄がわかってればいいかな?
関数ポインタと Block が同じように使えると気づいておくことが重要で、”関数の返値に Block を使う”表記はなるほどって感じ。

C++/CLI やって以来のハットを使った。(^^)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
// Blocks 構文
^ 返値の型 (引数リスト) {}
 
^ (引数リスト) {}		// 返値の型を省略
^ {}				// 引数リストを省略
 
// C言語 関数ポインタ
int (*funcptr)(int) = &func;
int result = (*funcptr)(10);
 
// Block 型変数に代入
int (^blk)(int) = ^(int val){return val + 1;};
 
// Block 型変数から Block 型変数への代入
int (^blk1)(int) = blk;
 
int (^blk2)(int);
blk2 = blk1;
 
// 関数の引数に Block 型変数を渡す
void func(int (^blk)(int)) {
}
 
typedef int (^blk_t)(int);
void func(blk_t blk) {		// 関数の引数に Block を指定する
}
 
// 関数の返値に Block を使う
int (^func()(int)) {
}
 
typedef int (^blk_t)(int);
blk_t func() {			// 関数の返値に Block を使う
}

参考: エキスパートObjective-Cプログラミング に詳しく説明があります。

補足:
通常ブロック外の変数はブロック内で変更することができない。
変数に「__block」修飾子をつけることでブロック内での変更が可能になる。

App Store で「ほかのアカウントで使用可能なアップデートがあります」と表示される件

先日の xcode Ver.4.5.2 リリースで「iOS 6 (iPhone 5 A6)用のビルドでリンクエラーとなる問題が対処されているようだったので (参照: iPhone5対応アプリのビルド設定にarmv7sが入れられない問題はこれで解決。)、AppStore でアップデートしようとしたら、以下のメッセージが表示されてアップデートできませんでした。(>_<) 「ほかのアカウントで使用可能なアップデートがあります」

その際の対処をメモ。
ネットを検索すると spotlight を再構築など情報がありますが、私の場合、 アプリケーション フォルダから xcode を削除することで対処できました。

iOS 6 (iPhone 5 A6)用のビルドでリンクエラーとなる場合の対処方法

xcode 4.5 で開発しているアプリをビルドすると以下のエラーが出力された。

リンクしているライブラリが A6 アーキテクチャに対応していないのが原因とのこと。
リンクしているのはソースがあるライブラリばかりではないので、とりあえず、以下で対応する。

(エラー内容)
file is universal (3 slices) but does not contain a(n) armv7s slice: /Users/xxxxx/Documents/workspace/xxxxx/(リンクしているライブラリ名)/lib/xxxxx.a for architecture armv7s
clang: error: linker command failed with exit code 1 (use -v to see invocation)

(対処方法)
プロジェクト設定 [TARGETS]-[Build Settings]
Valid Architectures
“armv7 armv7s” を “armv7” とする (ライブラリが対応できるまで (^_^.))

当然といえば当然だが、時間に余裕がないときに直面するとビビるな。

UDID の書式がシュミレータ バージョンによって変わる件

今後、UDID を利用した処理というのは推奨されないことは理解してますが、過去のアプリでは結構使っちゃってますよね。
先日、UDID を利用したコードで、バージョン違いのシミュレータの動作が違うという現象に遭遇し、少しはまったのでメモしておきます。

6.0 シミュレータで UDID を取得した場合 (英小文字。ハイフンがない)
1122bfxxxb4xxx4b33xxx44xxx55xxxa00000000
 
5.1 シュミレータ (英大文字。ハイフンあり)
1122BFXX-XB4X-XX4B-33XX-X44XXX55XXXA
書式:8桁-4桁-4桁-4桁-12桁

UDID をそのまま比較するという処理がある場合、比較できません。(ノД`)