こんにちは。CYBIRDエンジニア Advent Calendar 6日目のshigetaです。新卒2年目のアプリエンジニアです。
5日目はhosokawa-yutaさんのWordPressを魔改造してたら、もう何がなんだか。でした。
魔改造。なんて中2心がくすぐられるワードなんでしょうか。
##本日の内容
本日はAppleをなめてたら痛い目にあった事象を紹介します。
とはいえ調べてみるとAppleが公式に発表している機能のみしか公開してはいけないらしく、他にも様々な制約が。
詳しくはwebへ => https://www.apple.com/jp/legal/trademark/guidelinesfor3rdparties.html
##なめてたが故にハマった落とし穴
結構前の話ですが、、、iOS8出ましたね。
それに対応するXcode6もリリースされましたよね。
こういう新しいOSやツールがリリースされるときには仕様の変更に注意なんです。
「仕様変更なんて軽く目を通せばいいでしょ。」なんてなめてたら痛い目を見るのです。
ここからは私がハマった落とし穴を紹介できる範囲で紹介したいと思います。
###【落とし穴1】- プッシュ通知
アプリのBuildをXcode6でやってきている人が増えてきていると思います。
というよりXcode5でBuildしている人がかなり少数になってきているんじゃないかな。
なんとXcode6でBuildしたアプリは、今までのXcode5で書いていたプッシュ通知の登録処理ではiOS8系の端末でプッシュ通知が届かないのです!
はい、これでまず痛い目見ました。
ちゃんと仕様に目を通してなかった自分が悪いんですけどね。なめてましたね。
以下がやり方です。
まず、push登録の際に以下のようにOSで処理を切り分けます。(要はiOS8以上かそれ以外かです。)
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0) {
UIUserNotificationType types = UIUserNotificationTypeBadge| UIUserNotificationTypeSound| UIUserNotificationTypeAlert;
UIUserNotificationSettings *mySettings = [UIUserNotificationSettings settingsForTypes:types categories:nil];
[[UIApplication sharedApplication] registerUserNotificationSettings:mySettings];
} else {
[[UIApplication sharedApplication] registerForRemoteNotificationTypes:(UIRemoteNotificationTypeAlert|
UIRemoteNotificationTypeBadge|
UIRemoteNotificationTypeSound)];
}
この処理のいずれかを通った後にiOS8以降の端末ではAppDelegate.mに実装する以下のメソッドが呼ばれます。
// iOS8以降ではdevicetoken取得成功または失敗時に呼ばれるメソッドの前にここを通る
- (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings {
[application registerForRemoteNotifications];
}
そして最後にdevicetokenの発行に成功または失敗した時に呼び出される以下のメソッドに入るのですね。
// デバイストークンの取得に成功
-(void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken{
// 成功した時の処理
}
// デバイストークンの取得に失敗
-(void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error{
// 失敗した時の処理
}
iOS8未満しか対応していないアプリであれば2ブロック目の処理は必要ないですが、iOS8以上を切ったりiOS8未満を切ったりするのはユーザーのシェアを見ていてもなかなか難しいと思うのでこの処理が必要なのではないでしょうか。
###【落とし穴2】- iPhone6/6Plusの解像度問題
俺のアプリは端末の解像度がどう変わっても最適化できるぜっ☆という方には関係のない話なのですが、
Xcode6からiPhone6/6Plusのためのアイコン、スプラッシュ画像の枠が用意されました。
「嘘ぉ!?」と思う人はXcode6を起ち上げて、PROJECT > TARGET > General > App Icons and Launch Images の App Icons Source (アイコン画像)またはLaunch Images Source(スプラッシュ画像)からそれぞれ確認してみてください。(ちなみにFile Inspector上でiOS8にチェックを入れないと枠は出てきません。)
iOS8用のアイコンは問題ないのですが、iOS8用つまりiPhon6,6Plus用のスプラッシュ画像を適用してしまうとその瞬間からそのアプリはiPhone6/6Plusのオリジナルの解像度が適用されるのです。
例えば、UIWebviewクラスを使用するアプリだとweb側で解像度に最適化するようにしていないと普段より小さく見えます。
逆に言うと、iPhon6/6Plus用のスプラッシュ画像を適用しなければiPhone5/5Sの見た目が引き伸ばされて表示されるのでiPhone5/5Sでの見た目と同じものをiPhone6/6Plusでも見ることができるのです。
文章でずらずら説明してもわかりにくいので図を用いたいと思います。
以下の図のように左がスプラッシュ画像を適用していないwebviewの見た目、右がスプラッシュ画像を適用したwebviewの見た目です。
図はあくまで私が作ったイメージですが、スプラッシュ画像を適用するかしないかでこんなに変わるとは予想していませんでした。
これも痛い目見ました。なめてましたねぇ。
「99%WEB側の問題っしょ〜。」とか言ってました。ごめんなさい。
「100%って言わなくて良かった。」と密かに思った自分が情けないです。
ついでに解像度調べてみました。
この解像度が本来のものなのでそりゃ合う訳ないですね。
iPhone4S | iPhone5/5S | iPhone6 | iPhone6 Plus | |
---|---|---|---|---|
解像度 | 640 x 960 | 640 x 1136 | 750 x 1334 | 1080 x 1920 |
この記事を書いている12月4日現在では、iPhone6と6Plusのスプラッシュ画像の適用が義務付けられていませんが、対応しなくてはいけない問題だと思うので最適化できていないものは最適化していきたいですね。
##最後に
アプリエンジニアや申請周りに携わっている人への共有です!
iTunes Connectが12月22日からお休みに入るので、アプリの申請は早めに出しておきましょう。
また、アプリの64bit対応が2015年2月1日以降のアップデートから義務付けられたので、対応していないアプリは早めに対応をしましょう。