Alcatraz — The package manager for Xcode
Links to Git Flow
Swift and CoreMIDI
Swift で CoreMIDI を扱おうとした場合、CoreMIDI で定義されているデータ型が 32-bit でビルドする場合と 64-bit でビルドする場合で異なっていることに注意しなければなりません。この違いは、例えば iOS Simulator で iPhone 5 と iPhone 6 それぞれでビルドしてみると分かります。またソース上のシンボル、例えば MIDIEndpointRef
を shift-click した場合に表示される情報や、command-click して表示されるヘッダファイルの内容も異なります。
ちなみにこれは iOS でのお話で、OS X でどうなのかはわかりません。
Objective-C でのブロックの宣言
Objective-C でのブロックの宣言の書き方がわかりづらいので、ウェブで探していると気に入ったところがあったので紹介しておきます。Objective-C に限ったことではなく C 由来の言語は宣言文の書き方がわかりづらくなりやすいのが玉にきず。
pod install でエラーになる場合の対処法
$ pod install
すると、
[!] Pod::Executable pull --no-rebase --no-commit
A ABContactHelper/0.1/ABContactHelper.podspec
(途中省略)
A zipzap/6.0/zipzap.podspec
Pull is not possible because you have unmerged files.
Please, fix them up in the work tree, and then use 'git add/rm
as appropriate to mark resolution, or use 'git commit -a'.
のようなエラーとなりました。
以下を参考に、
http://qiita.com/hirayaCM/items/19b8d44c6ff3ab54458d
$ pod repo remove master
Removing spec repo master
$ pod setup
Setting up CocoaPods master repo
Setup completed (read-only access)
を行い、再度、
$ pod install
を行うとエラーは発生しなくなりました。
stringByReplacingPercentEscapesUsingEncoding: が期待する結果を返さないことがある
パーセントエンコーディングされた ISO-2022-JP 文字列
@"%1B%24B%3CL%3F%3F%1B%28B.PNG"
を NSString
のメソッド stringByReplacingPercentEscapesUsingEncoding:
でデコードしようとすると
1 2 |
NSString *string = @"%1B%24B%3CL%3F%3F%1B%28B.PNG"; NSString *decoded = [string stringByReplacingPercentEscapesUsingEncoding:NSISO2022JPStringEncoding]; |
@"$B<L??(B.PNG"
が返ってきます。期待している結果は @"写真.PNG"
なのですが、どうもうまくデコードしてくれません。
試しに、パーセントエンコーディングされた文字列を
@"%1B%24%42%3C%4C%3F%3F%1B%28%42.PNG"
にしてデコードしてみると、期待通りの結果が返ってきます。
どうやら、%24B, %3CL, %28B
がお気に召さないようです。
http://ja.wikipedia.org/wiki/URLエンコード
を読むと、お気に召さない文字列は仕様上間違いではないようですが、上記メソッドでは期待通りにはデコードしてくれません。
仕方がないので、気に入ってもらえるよう、
@"%1B%24B%3CL%3F%3F%1B%28B.PNG"
を
@"%1B%24%42%3C%4C%3F%3F%1B%28%42.PNG"
に変換して、デコードしてもらうようにします。
とりあえず、以下のコードで変換してみることにしました。
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 |
NSString *(^adjustedPercentEscapedString)(NSString *) = ^(NSString *percentEscapedString) { NSMutableString *adjustedString = [NSMutableString string]; const char *cString = [percentEscapedString cStringUsingEncoding:NSASCIIStringEncoding]; NSUInteger offsetFromPercent = NSNotFound; for (NSUInteger i=0; i<strlen(cString); i++) { const char c = cString[i]; if (c == '%') { [adjustedString appendFormat:@"%c", c]; offsetFromPercent = 0; } else { if (offsetFromPercent != NSNotFound) { ++offsetFromPercent; if (offsetFromPercent > 2) { [adjustedString appendFormat:@"%%%02X", c]; offsetFromPercent = NSNotFound; } else { [adjustedString appendFormat:@"%c", c]; } } else { [adjustedString appendFormat:@"%%%02X", c]; } } } return adjustedString; }; NSString *adjustedString = adjustedPercentEscapedString(@"%1B%24B%3CL%3F%3F%1B%28B.PNG"); |
もう少し、appendFormat: の呼び出しを減らしたい気もしますが、
とりあえずうまくいっているので、ひとまずはこれで良しとします。
iOS アプリのための Crashlytics
– Crashlytics 登録からクラッシュログ確認までの 29 ステップ –
アプリはクラッシュしない。それがベストです。しかし現実は様々な理由からクラッシュは発生してしまいます。勘違い、想定外、iOSのバグ、ケアレスミス、エトセトラ、エトセトラ。睡眠時間を削って、休日をつぶして、テストにテストを重ねても、クラッシュの発生はゼロになったと胸を張って言うことはできません。限りなくゼロに近づいているとしか言えないのです。それがプログラマの悲しい現実です。
クラッシュが発生した場合にプログラマにできること。それはクラッシュの原因を素早く特定し、問題をフィックスすること。そのためにはユーザが遭遇したクラッシュの状況を少しでも把握することができる糸口を手に入れることが重要です。その糸口となるのがクラッシュログ。アプリがクラッシュするとクラッシュログが生成されるので、これをなんとか手に入れたい。しかし残念なことに Apple が提供しているサービスではすべてのクラッシュログがプログラマの手に渡ることはありません。
そこで登場するのが Crashlytics。このサービスを使えば失われたクラッシュログがプログラマの手に届きます。(届くはずです ^^;)このサービスは無料で利用できるので、まずは導入して試してみるのが手っ取り早い方法です。ダメならやめればいいのだから。
Crashlytics を利用して、見つかったクラッシュの原因をつぶしていき、少しでも安定したアプリにしていきましょう。
以下に Crashlytics 登録からクラッシュログ確認までのプロセスを説明してあります。2014年1月17日における手順を説明していますので、最新の状況と異なることもあります。29 ステップもありますが、Xcode の使用方法をご存知の方であれば実際の作業にかかる時間はそんなに長くありません。それと作業を実際に行う前に全ステップを一読されることをお勧めします。
- http://try.crashlytics.com をブラウザで表示後、メールアドレスを入力し、Try Crashlytics ボタンをクリックします。
- General Info で Name に自分の名前、Company に自分の会社名を入力し、Put me on top! ボタンをクリックします。
- 1. で入力したメールアドレス宛に Crashlytics から You’re on the list to get Crashlytics というサブジェクトのメールが届きます。
- 届いたメールの Wait! Give me priority access! ボタンをクリックしても、You’re on The List と表示されるウェブページが表示されるだけなので、Crashlytics からレスポンスが返ってくるまで、しばらく待っていましょう。
- (私の場合)約9時間後に、Crashlytics private access (need reply) というサブジェクトのメールが届きました。
- 続いて、Invitation to Join Crashlytics というサブジェクトのメールも届くので、このメールの Sign in ボタンをクリックします。
- Crashlytics のウェブページが 1. で入力されたメールアドレスとともに表示されるので、自分の名前と Crashlytics にログインする時に使用したいパスワードを入力し、Create Account をボタンをクリックします。(Crashlytics – Welcome to the Club というサブジェクトのメールが届きます)
- ウェブページが更新され、会社名の入力を促されるので、会社名を入力し、Done ボタンをクリックします。
- 次に、使用したい IDE を選択するページが表示されるので、Xcode をクリックします。
- Mac 用アプリをダウンロードする必要があるので、I agree to the Terms of Service にチェックをつけ、Download ボタンをクリックします。
- ダウンロードしたファイル Crashlytics-latest.zip を展開し、Crashlytics アプリをアプリケーションフォルダに移動しておきます。
- Crashlytics アプリを起動します。起動後、メニューバーに Crashlytics アイコンが表示されます。
- メニューバーの Crashlytics アイコンをクリックすると、クラッシュログを収集したいアプリの Xcode プロジェクトを指定する画面が表示されるので、ここで Crashlytics に登録したいプロジェクトを選択し、Next ボタンをクリックします。今回は My1stCrashlytics という Crashlytics 確認のためのプロジェクトを作成し、これを選択しました。このプロジェクトは Xcode テンプレートにある Single View Application を選択して作成しています。
- 画面が変わり、指定した Xcode プロジェクトの Run Script Build Phase に指定したコマンドを設定するように促されるので、設定を行います。
- 設定を終えたら、command-B でプロジェクトをビルドしてください。
- ビルドが終わると Crashlytics アプリの画面が変わり、今度は Crashlytics.framework を Xcode プロジェクトに追加するように促されます。画面の赤いツールボックス画像をドラッグし、Xcode プロジェクトの Frameworks へドロップします。
- Crashlytics.framework を追加し終えたら、Crashlytics アプリの画面の Next ボタンをクリックします。
- 次に Crashlytics SDK の初期化コードの記述を行います。Crashlytics アプリの画面にある指示通りに、UIApplicationDelegate の
-application:didFinishLaunchingWithOptions:
メソッド内にコードを1行挿入し、続いて#import <Crashlytics/Crashlytics.h>
も挿入します。 - ソースコードの編集が終わったら、command-R でアプリをビルドし、実行します。(今回は iOS シミュレータ上で実行します)
- 今回指定した Xcode プロジェクトにはクラッシュする部分はないので、Crashlytics アプリの画面に Congrats! There are no open issues. と表示されます。
- ここまでくると、My1stCrashlytics was just successfully added というサブジェクトのメールが届きます。もちろんサブジェクトの最初はあなたが指定したプロジェクトのアプリ名になります。
- Crashlytics はアプリがクラッシュしたときに有用なサービスですので、アプリがクラッシュしないと意味がありません。アプリをクラッシュさせるには?心配いりません。Crashlytics アプリの画面に Want to force a crash? と表示されていますよね。これをクリックします。
- すると、簡単にクラッシュさせる方法が説明されている Web ページがブラウザで表示されるので、そこに記述されている方法を用いて My1stCrashlytics をクラッシュさせることができます。ではやってみましょう。
- Xcode に戻って、コードを1行ソースに追加します。追加するコードは、
[[Crashlytics sharedInstance] crash];
で、これを画面上の Crash ボタンをタップした時にクラッシュするように仕込んでみます。#import <Crashlytics/Crashlytics.h>
を追加するのを忘れないように。 - command-R で実行します。(先ほどと同様 iOS シミュレータ上で実行します)
- 実行し、Crash ボタンをタップするとアプリはクラッシュするのですが、Xcode のデバッガが動いているのでクラッシュしたところで実行が止まってしまいます。一旦 Xcode の Stop ボタンをクリックして実行を中止しましょう。
- 今度は My1stCrashlytics アプリを Xcode からではなく iOS シミュレータ上のアイコンをクリックして起動し、Crash ボタンをタップしアプリをクラッシュさせます。
- これで、ブラウザから https://www.crashlytics.com/login にログインすると、クラッシュの状況を確認することができます。
- また New Issue Discovered in My1stCrashlytics 1.0 というサブジェクトのメールも届くので、メールのチェックをしていればアプリがクラッシュしたかどうかがわかります。数百人のユーザしか持たないアプリでもクラッシュが頻発する下手なアプリをリリースしてしまうと、受信するメール数がとても多くなることが予想されるので、心配な人は Crashlytics 専用のメールアカウントを用意した方が良いかもしれません。(メールを受け取らない設定があるかもしれませんが、まだそこまでは確認していません)
とりあえずここまでで、Crashlytics に登録、アプリにコードを埋め込み、クラッシュレポートの確認までができたと思います。
うまくいきました?
うまくいったのなら、おめでとう。そしておつかれさま。
iOS Team Provisioning Profile: * を復活させる方法
iOS Provisioning Portal から iOS Team Provisioning Profile: * を削除してしまった場合、以下の方法で再作成できます。
Xcode の Organizer ウィンドウを開き、ウィンドウ左のペインにリストされているデバイス名を Control-Click します。表示されたポップアップメニューから Add Device to Provisioning Portal を選択します。
あとは Xcode が処理してくれます。
既に Provisioning Portal に登録済みのデバイスに対し、Add Device to Provisioning Portal を行っても問題はないようです。
Xcode ビルド設定で利用できる変数の確認
$(SRCROOT) や $(CONFIGURATION) など忘れたときには、
Xcode Build Setting Reference を参照しましょう。
手っ取り早く、
1 |
$ xcodebuild -showBuildSettings |
で確認できたりもします。
NSTimer と UIScrollView
1 |
+[NSTimer scheduledTimerWithTimeInterval:target:selector:userInfo:repeats:] |
で作成したタイマーは、UIScrollView のスクロール中に指定時間が経過しても selector を呼び出してくれません。
この場合は
1 |
+[NSTimer timerWithTimeInterval:target:selector:userInfo:repeats:] |
でタイマーを作成し、
1 |
-[NSRunLoop addTimer:forMode:] |
で NSRunLoop にタイマーを追加してください。
このとき forMode には NSRunLoopCommonModes を指定します。