iOS9 で [NSLocale preferredLanguages] の返値が,”ja” から “ja-JP” になっている件

日本語の判断を以下のようにやっていて,iOS9 で正しく判断できていなかった.

原因は,掲題の通り.

以前の判定方法

1
2
3
4
5
NSArray *languages = [NSLocale preferredLanguages];
NSString *currentLanguage = [languages objectAtIndex:0];
 
if ([currentLanguage isEqual:@"ja"]) {
    :

iOS9 に対応した判定方法

1
2
3
if ([currentLanguage isEqualToString:@"ja"] || 	// iOS8 以前
    [currentLanguage hasPrefix:@"ja-"]) { 	// iOS9 対応
    :

参考:
[iOS] iOS9 日本語環境の判断コードの変更が必要に [NSLocale preferredLanguages]

[iPhoneプログラミング]iPhoneの言語設定関連の情報取得についての解説

iOS9 シミュレータと iOS9 実機で異なる動作に遭遇した件

シミュレータと実機はどうしても処理結果に差が出ることがあります.
例えば,使用しているフォントが違うため,文字列処理まわりとかですね.

理屈では分かってはいても,実機で確認することを忘れていて,あとで「アッ」てことがあります.

先日,UIButton の titleEdgeInsets を調整して,シミュレータでしか確認していなかったため,痛い目にあいました.
iOS9 から新しいフォントが適用されているので,要注意ですね.

ちなみに,UIButton では,
titleEdgeInsets : タイトル位置を調整
imageEdgeInsets : 画像の位置を調整 ができます.

1
2
3
4
5
6
7
// 平行移動をしたい場合は,一方に + (内側に入り込む),反対側に - (外側に出る) を設定する必要があります. 
UIEdgeInsetsMake(0, 100, 0, -100)
 
 
typedef struct UIEdgeInsets {
    CGFloat top, left, bottom, right;  // specify amount to inset (positive) for each of the edges. values can be negative to 'outset'
} UIEdgeInsets;

参考: UIButtonで、画像とタイトルの位置を入れ替える時にハマった話 (UIEdgeInsets)

Xcode7 ベータで,pod install に失敗する場合の対処方法

Xcode7 ベータ版を使用しているプロジェクトで,$ pod install した際に以下のエラーメッセージが出力され,pods プロジェクトの生成に失敗するようになった.

Generating Pods project
2015-09-04 11:04:30.691 ruby[26957:488641] [MT] DVTAssertions: ASSERTION FAILURE in /Library/Caches/com.apple.xbs/Sources/IDEFrameworks/IDEFrameworks-8208.9/IDEFoundation/Initialization/IDEInitialization.m:590
Details:  Assertion failed: _initializationCompletedSuccessfully
Function: BOOL IDEIsInitializedForUserInteraction()
Thread:   {number = 1, name = main}
Hints: None
Backtrace:
  0  0x00000001022278a8 -[DVTAssertionHandler handleFailureInFunction:fileName:lineNumber:assertionSignature:messageFormat:arguments:] (in DVTFoundation)
  1  0x0000000102227035 _DVTAssertionHandler (in DVTFoundation)
  2  0x00000001022272a1 _DVTAssertionFailureHandler (in DVTFoundation)
  3  0x0000000102227203 _DVTAssertionFailureHandler (in DVTFoundation)
  4  0x0000000103ec6c4c IDEIsInitializedForUserInteraction (in IDEFoundation)
  5  0x0000000106b1fd39 +[PBXProject projectWithFile:errorHandler:readOnly:] (in DevToolsCore)
  6  0x0000000106b218be +[PBXProject projectWithFile:errorHandler:] (in DevToolsCore)
  7  0x00007fff85776f44 ffi_call_unix64 (in libffi.dylib)
Abort trap: 6

【対処方法】
Xcode7 ベータの [Preferences…]-[Locations]-[Command Line Tools:] を [Xcode 6.4] にすることで対処できた.
xcode_command_lline_tools
‘xcode-select’ コマンドでもできるみたい.

Xcode 7.0 GM で「’-init’ not found」と警告が出力された場合の対処方法

NSObject を継承したクラスを使用していて,以下のメッセージが出力された.

Method override for the designated initializer of the superclass '-init' not found

たしかに,継承したクラスでは,init をオーバーライドしていないが,所定のメソッド内で [super init] は行っている.
この警告に対処するには,いくつかの方法があると思うが,今回は以下の方法で対処した.
間違って [foo alloc] init]; した場合,コンパイルエラーとすることができる.

- (id)init __attribute__((unavailable("init is not available.")));

unavailable: 指定OSプラットフォームでメソッドが使えないことを示す.

【参考】
objcでinitの呼び出しを抑制するAdd Star
[Objective-C]__attribute__ディレクティブを使ってみる

iOS9 の新機能について

iOS9 には新機能が追加されていますが,アプリの対応調査をしていて気づいた点をメモしておきます.

Bitcode エラー対応方法は?

iOS の場合,”Enable bitcode”をオフにすることでエラーは回避できる.
OFF にした場合,アプリが App Thinning 対応にならない.

Bitcode とは?

Xcode7 の新機能「App Thinning」に対応するための設定項目.
設定項目は,プロジェクトファイル – TARGETS – Build Settings – Build Options – Enable Bitcode に項目がある.

watchOS Developer Library – プレリリース より
App Thinning (iOS, watchOS)
デバイスに最適化されたサイズのアプリをダウンロード可能とするための技術.
以下の3つの要素で構成される.

  • Slicing (iOS) デバイスに適したアプリバンドルとする.
  • Bitcode (iOS, watchOS) コンパイルされたプログラムの中間表現.
  • On-Demand Resources (iOS) 必要になったタイミングで,リソースを追加ダウンロードする.

参考: https://developer.apple.com/library/prerelease/watchos/documentation/IDEs/Conceptual/AppDistributionGuide/AppThinning/AppThinning.html

Note: For iOS apps, bitcode is the default, but optional. If you provide bitcode, all apps and frameworks in the app bundle need to include bitcode. 
For watchOS apps, bitcode is required.

ちなみに,iOS はオプション、 watchOS は必須とのこと.

以下にていねいな説明がありました.
参考: App Thinning メモ

Bitcode を生成するには?

AppStore への提出時に,ビルド済みのバイナリではなく,中間形式でアップロードする.

検索API とは?

iOS9 の Spotlight や Safari の検索機能で,アプリや Web コンテンツから情報が見つけられるようになる.
“Universal Links”という仕組みでアプリ,Web へユーザを誘導することができる.

iOS9 では,以下の3つの検索用APIが提供されている.

  • NSUserActivity アプリに関連したユーザのアクティビティを記録して,検索対象とする.
  • Core Spotlight アプリのコンテンツへのリンクを可能とする.
  • Web Markup Webサイトを適切にマークアップすれば,コンテンツが検索可能となる.Smart App Banner を追加すれば,Webサイトからアプリへ誘導することが可能となる.

いろいろ紹介されているみたいです.
参考: iOS 9はディープリンク機能のある検索APIを提供…ほかのアプリのコンテンツも検索

GenerateDSYMFile の警告について

最近,アプリの iOS9 上での動作検証のために,Xcode7 beta5 を使用している.
そこで,出力された以下の警告について少し調べてみました.

warning: Could not resolve external type ………

上記の警告を回避するには,以下の設定で開発時にはとりあえず,抑止することができるようです.

Xcodeの "Build Settings"→"Build Options"→"Debug Information Format" の項目を
"DWARF with dSYM file" から "DWARF" に設定する.

dSYM を作成しないのだから,出力はされないのでしょう.

ですが,dSYM bundle は本番リリース後のクラッシュ解析には必要です.
開発時には利用することがないので,ビルドの “Debug Information Format” を “DWARF with dSYM File” から “DWARF” に変更すると,ビルド時間が短縮できる.といった紹介がネット上では良くされているようです.

ちなみに DWARF とは、広く使われているデバッグ用データフォーマットの規格です.
参考: DWARF

.dSYMファイルとは?

.dSYMファイルは,デバックシンボル群を保存するファイルで,このファイルがあればアドレスしか書かれていない.crash ファイルからシンボルを確認することができます.

ビルド時に生成されるものなので,.crashのログが出力されたバイナリと同じビルドで生成された.dSYMファイルでなければ解析できないため,注意が必要.
以下のリンクには丁寧な説明があります.

参考: [iOS] アプリのクラッシュログを解析する方法

iOS9 で通信プロトコルを https → http とする方法

開発している iOS アプリの iOS9 対応を行っていて、気づいた点をメモ。

既存のアプリが iOS9 環境で通信できない場合,通信プロトコルが http → https とされるていないか?確認する.
通信が https に強制されることが原因で通信できていない場合は,info.plist に以下の設定を追記することで回避することができる.

1
2
3
4
5
<key>NSAppTransportSecurity</key>
	<dict>
	<key>NSAllowsArbitraryLoads</key>
	<true/>
</dict>

【参考】
App Transport Security

iOS9でHTTP通信がSSL通信になるのを防ぐ方法