アプリをiOS8に対応する際に確認しておく項目をまとめました。
はじめに
iOS8対応とはざっくり言うとXcode6でアプリをビルドする事を差します。(厳密にはBaseSDK 8.0以上でビルドしたアプリ)
BaseSDKが上がる事により、既存のAPIがDeprecated(非推奨)になったり、新しいメソッドが追加されることによって今まで通りの実装では動作しなくなったり挙動が変わったりします。
本記事では上記によって実装に変更が入った部分や、アプリの運用上気をつけておく事について解説していきます。
言語はObjective-Cでの実装を解説します。Swiftでは言語仕様上、SDKとの連携などで不具合がある箇所が存在するため、別解説記事などと合わせて読んでいただく事をオススメします。
1.申請周り
先日、Appleは2015年2月1日より申請されるアプリについてiOS8と64bitアーキテクチャに対応する事を義務付けました。
現段階ではXcode5.1.1(iOS7)以降なので、対応せずともアプリの申請は可能ですが、
早めに対応をしておいた方が良さそうです。
本章ではそれらの対応方法について解説します。
1.1 64bit(arm64)アーキテクチャ対応
iPhone 5Sで搭載されたApple A7プロセッサ(+ iOS7)から64bitでの動作をサポートしました。(それまでは32bitでの動作)
これによって、いままでよりも多くのデータや処理を扱う事ができるようになりました。
現状の各デバイスのスペックについては下記ページが参考になりました。
詳細についてはAppleから移行ガイドが配布されているのでそちらを参考にしてください。
本記事では64bitの要点のみを解説します。
Valid Architecturesの設定
Valid Architecturesにarm64
のアーキテクチャを追加します
場所 : projectファイル > Build Settings > Architectures > Valid Architectures
${ARCHS_STANDARD}
とすでに登録されていればXcode6に最適化した際に自動で追加されているはずです。
以前は${ARCHS_STANDARD_INCLUDING_64_BIT}
というのもありましたが、Xcode6ではどちらも同じアーキテクチャが指定されます。
Xcode6で新しくプロジェクトを作成した場合はarm64
、armv7
、armv7s
がそれぞれ個別で登録されています。
${ARCHS_STANDARD}
にarmv7s
が入っていないですが、必要であれば個別で登録します。
Build Errorへの対処
アプリ内部で使用している外部ライブラリが64bitに対応していない場合、Linker Errorなどが発生する場合があります。
その場合は各ライブラリを更新するなどの対処が必要ですが、サポートされていない場合もありますので注意が必要です。
Warningへの対処
64bit対応により整数型のバイト長が変わるため、実装によってはWarningがでます。
対応方法については他の方々が詳しく解説されているのでここでは割愛します。
- 32bitと64bit、共通で使えるNSLogとかのフォーマット指定子 - Qiita
- 【iOS7】64ビット対応について調べてみた - Qiita
- iOSアプリ 64bit 対応メモ - Qiita
1.2 iOS8ビルド
iOS8ビルドについてはXcode6でビルドすれば良いので、特に気にする必要はありません。
プロジェクト設定のBase SDKが8.0以上であればOKです。
ビルド時の注意箇所については2章にて詳しく解説します。
1.3 アプリバージョン
こちらは主にiTunes Connect周りでの注意事項ですが、申請方法の変更によりアプリバージョンとビルド番号の運用方法に気をつける必要があります。(特にVersionとBuildを同じ値で運用しているアプリ)
申請方法が変更になったことにより、リジェクトされたり、バイナリを差し戻したりして再度申請する時に同じBuildバージョンでの再提出ができなくなりました。
そのため、再提出にはBuildバージョンを上げたりするのが一般的ですが、VersionとBuildを同じ値で運用していると混乱しやすくなります。
Version部分に対応するのがCFBundleShortVersion
Build部分に対応するのがCFBundleVersion
です。
自分も最近まで勘違いしていたのですが、アプリバージョンを取得する方法を調べているとCFBundleVersion
で取得している所が多いのですが、実際にはCFBundleShortVersion
を使うべきなんですね。
// Version
[[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleShortVersionString"];
// Build
[[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleVersion"];
運用としてはVersionには1.0.1などのこれまでの記載をして、build部分は1.0.1.1などとVersionの末尾にビルド番号を付与していく方法が良さそうです。
2.iOS8
本章ではiOS8 SDKでビルドした際に旧SDKと影響が大きい部分についての解説をします。
2.1 Push Notification (プッシュ通知)
iOS8からプッシュ通知のデバイストークンの取得方法が変更になりました。
それにより正しい設定をしていないとプッシュ通知の登録ができません。
いままで使用していたregisterForRemoteNotificationTypes:
がDeprecatedとなりregisterUserNotificationSettings:
を使用するようになります。
詳しい設定方法については以前Qiitaに投稿したものがあるのでそちらを参考にしてください。
2.2 Local Notification (ローカル通知)
Push Notification同様にLocal NotificationにおいてもiOS8において仕様が変更になりました。
ローカル通知において、通知を表示するためにはユーザー認証が必要となり、通知を表示することをアプリ内で明記する必要があります。
ユーザー認証を行うにはiOS8から追加されたUIUserNotificationSettings
クラスで設定を登録します。
新しいクラスとなるため、旧バージョンのOSをサポートする場合は処理の分岐が必要となります。
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
if (version_greater_than(@"8.0")) {
UIUserNotificationType types = UIUserNotificationTypeBadge|
UIUserNotificationTypeSound|
UIUserNotificationTypeAlert;
UIUserNotificationSettings *mySettings = [UIUserNotificationSettings settingsForTypes:types categories:nil];
[application registerUserNotificationSettings:mySettings];
}
}
2.3 Location (位置情報)
iOS8から位置情報の利用設定をユーザーが細かく制御できるようになり、ソースコード上での制御方法が変更になりました。
また、位置情報を取得する理由を明示することが必須になりました。
Authorization Status
これまで位置情報の認証ステータスは[CLLocationManager authorizationStatus]
がkCLAuthorizationStatusAuthorized
かそうでないかで判定していましたが、iOS8からDeprecatedになり、下記の認証ステータスが追加になりました。
- kCLAuthorizationStatusAuthorizedAlways
- kCLAuthorizationStatusAuthorizedWhenInUse
ただし、上記ステータスはiOS8から追加のためiOS7をサポートする場合はバージョンでの分岐が必要となります。
-(BOOL)isLocationServiceAuthorized{
CLAuthorizationStatus status = [CLLocationManager authorizationStatus];
if (version_greater_than_equals(@"8.0")) {
if (status == kCLAuthorizationStatusAuthorizedWhenInUse ||
status == kCLAuthorizationStatusAuthorizedAlways)
return YES;
}else{
if ([CLLocationManager authorizationStatus] == kCLAuthorizationStatusAuthorized)
return YES;
}
return NO;
}
Info.plist
Info.plist内に位置情報を取得する理由を記述します。
常時許可と使用中のみ許可でそれぞれ用意します。
(初回利用時の確認ダイアログにこのメッセージが表示されます。)
3.Xcode6
Xcode6になってXcode5から動作が変わった部分(主にプロジェクト新規作成時)
3.1 LaunchScreen
iOS8から起動スクリーンにxibファイルを指定できるようになりました。
ただし、iOS7以前のバージョンもサポートするアプリの場合、当然起動スクリーンにxibを指定する事ができないため表示がおかしくなります。
その場合、xibではなくAsset Catalogを指定します。(両方セットする事もできるみたいです。)
3.2 Prefix Header
Xcode5以前ではプロジェクト作成時にPrefix Header(.pchファイル)が自動で追加されていましたが、Xcode6からは追加されなくなりました。
無くても困らないですが、下記の手順で手動追加ができます。
File > New > iOS > Other からPCH File
を選択して作成
プロジェクト設定のPrefix Header
に作成したヘッダーファイルのパスを登録します。
$(SRCROOT)/$(PRODUCT_NAME)/PrefixHeader.pch
などとすると良いです。
3.3 その他
4.iPhone6,iPhone6 Plus
画面解像度をiPhone6,iPhone6 Plusに対応するにはそれらの画面サイズに対応する起動スクリーンを用意する事で対応できます。
主な方法は2つ
- Launch Screen Fileの追加
- Launch Imageに4.7,5.5インチ画面用の起動画像を追加
Launch Screen Fileの追加
3.1であるようにxibを起動スクリーンに設定します。
これを指定するだけでXcodeはAuto Layoutに対応しているとみなされ、複数の画面サイズが有効になります。
Launch Imageに4.7,5.5インチ画面用の起動画像を追加
Asset Catalogに4.7と5.5インチ画面用の起動画面を追加すると有効になります。
iOS 8.0 and Later
のチェックボックスにチェックを入れるとRetina HD 5.5
とRetina HD 4.7
の起動画像を追加できるようになります。
画面サイズ一覧
tips
処理の分岐
本記事では処理の出し分けにOSバージョンを判定していますが、多用しすぎると実装上美しくないのと、今後どんどんバージョンが増えていくとカオスな事になりかねないので、クラスやメソッドの有無などで判定することをオススメします。
- メソッドが存在するかどうか: respondsToSelector:
- クラスが存在するかどうか: [Class class]
上記の2だけでも使えれば十分かと思います。
おわりに
64bit対応,iOS8対応,iPhone6(Plus)対応とやらなければならない事がたくさんありますが、ちょっとした見落としなどで大きな不具合につながってしまう恐れがあるので注意して開発を進めたいところです。
まだまだ他にもやるべき事がある気がしてますが、気づいたら追加していきます。