iOS9向けアプリ開発時の注意点
iOS 9がリリースされて少し経ちましたが、iOS 9対応は済んでいますでしょうか?
ウチの場合は、iOS 9がベータ版の時から対応を進めていた為、比較的早めにノウハウを蓄積したつもりでしたが、正式版リリース後も色々と手間取りました。
去年まとめた「iOS8向けアプリ開発時の注意点」には大変多くの反響を頂き、ありがとうございました。
そこで、今年も備忘録を兼ねてiOS 9対応の注意点をまとめたいと思います。
間違い等がありましたならば、ご指摘下さい。
なお、このページに記載されている内容が原因で損害を被ったとしても一切補償はしません。
ちなみに、このページのテキストの原文は、超高機能テキストエディタアプリ「Wrix」と超高機能ファイル管理アプリ「NeoFiler」のテキストエディタ画面にて作成しました!(iPad mini2を使用)
両アプリ共に全機能無料で使えますので、別次元の超快適なテキスト編集環境を体験してみて下さい。
同時に複数の計算ができる多機能電卓アプリ「NeoCalcs」もよろしくお願いします! 無料版の「NeoCalcs Free」も用意してます!
多分、iOSアプリでは唯一「キー操作ができる電卓アプリ」です!(笑)
今回まとめるのは以下の項目です。
他の方がブログ等で頻繁に公開されている様な有名な事では無く、少しマニアックな事が多いかも知れません(笑) しかし、結構盛り沢山です!(笑)
- UITableViewの各セルの左右に余計な余白が出る問題とその解決方法
- バージョン定義マクロがおかしい!?
- 絵文字に関する変更点
- iPadの画面分割(Multitasking)に対応しよう!
- そろそろ画面回転時のdeprecatedなメソッドをなんとかしよう!
- iPadのショートカットバーとソフトキーボードの高さの関係
- iPadのショートカットボタンに対応するには?
- キーショートカットが予約された!?
- ショートカットキーの扱いとUndoボタン
- UIWindowのUIがソフトウェアキーボードの上に表示できなくなった!
- HTTP通信の扱いについて
- UIApplication@canOpenURLの動作が厳密になっている
- BitcodeとApp Thinning
- dylibファイルが赤文字表示になっている!?
- NSLocaleの言語名が変更された!?
- 固定の高さのUINavigationBarの高さがLandscape時に33pts前提で各項目が表示される様になった!?
- 4.7、5.5インチ向けスクリーンショットが必須になった!?
- iOSの設定アプリに反映されない!?
- 新しいiTunes Connectの癖!?
UITableViewの各セルの左右に余計な余白が出る問題とその解決方法
まずは、このiPadのスクリーンショットを見て下さい。UITableViewの各セルの左右に余計な余白がある事がわかるかと思います。
Xcode 7でビルドしてiOS 9で走らせるとUITableViewの各セルの左右に余計な余白が出来るのですよね。特にLandscape時は酷いのですよね。 pic.twitter.com/5Bh1mTLLxY
— SkyArts.com (スカイアーツ) (@SkyArts_dot_com) 2015, 9月 10
このコード自体は、Xcode 6.xでビルドした際には問題は出ません。しかし、Xcode 7でビルドしてiOS 9で走らせると自動的にこの様に無残な表示になります。
ユーザーが頭を動かさずに読める位置に表示させる為の仕様変更の様ですが、iPadでは上の画像の様にデザイン的に酷くなってしまいますね。
詳細はAppleのドキュメント等を参照して貰うとして、この動作を無効にするには、UITableViewの以下のプロパティをNOにします。デフォルトはYESです。
UITableView@cellLayoutMarginsFollowReadableWidth
ただし、iOS 9にて追加されたプロパティの為、iOS 9以降かどうかの判定をしてから設定する必要があるでしょう。
勿論、iOS 9以降専用アプリであればこのチェックは不要です。
注意: バージョン判定時は、以下のバージョン定義マクロの問題に注意して下さい。
バージョン定義マクロがおかしい!?
iOS 9以降で追加されたメソッドやプロパティを使用する際、ソース内にOSのバージョンを見て処理を変更する事は良くあるかと思います。特に毎年大きく変化するiOSの場合は必須ですね。
ソース内でバージョン判定をする際、以下の様なコードでOSのバージョンを切り分ける事になるかと思います。
if (floor(NSFoundationVersionNumber) > NSFoundationVersionNumber_iOS_[バージョン値]) { //iOS9以降の場合の処理 }
普通のコードなので特に変な箇所はありませんね。
Xcode 7.0では、OSバージョンのマクロ定義が8.3まで定義されています。(Xcode 7.1でも同様)
あれっ!? 「iOS 8.xは8.4.1まであったはず!」と思ったあなたは正しいです!(笑)
そうです。iOS 8.4の定義が不足しているのです!
その為、何も疑わずに最後に定義されているマクロを使用して以下の様に判断すると、iOS 8.4.xで誤動作する事になります!
if (floor(NSFoundationVersionNumber) > NSFoundationVersionNumber_iOS_8_3) { //iOS9以降の場合 <- (?_?)? iOS 8.4.xは? }
仕方ないので、今の所は、以下の様なコードで回避するしか無いかも知れません。
if([[[UIDevice currentDevice] systemVersion] floatValue] >= 9.0) { //iOS9以降の場合 }
なお、この問題はBug Report済みです。
絵文字に関する変更点
iOS 9.1では新しい絵文字が追加されました。どんどん新しい絵文字が追加されますね。
ここまでは良いのですが、以前からあった絵文字の内、一部の絵文字のバイト値が変更になっています!
「えっ、何それ?」ですよね(笑)
iOS 7から8になった時にもあったのですが、ソフトキーボードで入力した絵文字のバイト値がiOSのバージョンによって違います。
しかし、今回はメジャーバージョンアップでは無く、iOS 9と9.1で異なるのです!
そんな馬鹿な、という気持ちですが、仕方ない部分かも知れないです。ただ、本来はiOS 9で変更しておくべきだった気もします。
具体的には以下の絵文字のバイト値が異なります。
- 囲み数字0から9まで
- 囲み#と*
これらの絵文字は、iOS 9までは2バイト文字として入力されていました。
しかし、iOS 9.1からは2バイト目に0xFE0Fが入る様になり、3バイト文字になりました。
例えば、囲み数字0の場合、iOS 9.0.xまではソフトウェアキーボードで入力すると
0x0030 0x20E3
でしたが、iOS 9.1からは
0x0030 0xFE0F 0x20E3
に変更されています。
iOS9.1ではどちらの値でも絵文字として表示はできますが、バイト値を見て検索したりする場合はヒットしなくなる可能性が高い為、注意が必要かも知れません。例えば、ユーザー名に絵文字を許可している場合等です。
0xFE0Eと0xFE0Fは、text style、emoji styleを判断するバイトですが、最後に入らない場合もあるのですね。
Unicode.orgを少し見た限りではこのバイトの並びは見当たらなかったのですが、ソフトキーボードで入力されるとこのバイト列が渡されるので、対応せざる終えませんよね(笑)
なお、iOS9.1でもテキストを選択した時にソフトキーボードが表示する変換候補は、0xFE0Fの部分が文字化けの豆腐表示なので、内部処理の統一が出来ていない様です(笑)
iOS 9.1では、囲み数字等の一部絵文字は入力時のバイト値が変更されています。 それらの絵文字を選択した際にソフトキーボードがおかしな変換候補を表示しますが、それはiOS側の問題です。 アプリのせいではありません(笑) pic.twitter.com/I6SjKRJTM9 — SkyArts.com (スカイアーツ) (@SkyArts_dot_com) 2015, 10月 22
ちなみに、iOS 7から8になった時の変化は、text style、emoji styleを判断するバイトの0xFE0Eと0xFE0Fが追加された事です。
iOS 8の時も飛行機の絵文字の最後にこれらのバイトが追加される様になり、iOSにプリインされているメモアプリでは諸々問題が出ました。メモ一覧のタイトルが変になる、選択がおかしい等々。
他にもUITextView、UITextFieldではこれらのバイトがある絵文字のテキスト選択に問題が出ていました。(iOS 9になってやっと修正されました。つまり、iOS8.xでは放置されたままという事です。)
絵文字のバイトを変更すると他で色々と不具合が出るのはいつもの事、という感じでしょうかね(笑)
なぜこんなに絵文字のバイト値の違いが詳細がわかるかと言うと、勿論アプリの絵文字対応する為でもありますが、超高機能テキストエディタアプリ「Wrix」と超高機能ファイル管理アプリ「NeoFiler」のテキストエディタ画面にはカーソル位置の文字のバイト値を表示する機能がある為です!
両アプリ共に全機能が無料で使えますので、文字のバイト値を調べたい時にも使用してみて下さい。別次元の超快適なテキスト編集環境を是非使用してみて下さい。
iPadの画面分割(Multitasking)に対応しよう!
iOS 9からiPadでは画面分割(Multitasking)表示できる様になりました。それぞれ、Slide Over、Split View、Picture-in-Pictureと呼ばれていますね。
iPadの端末によって使える画面分割表示の種類は違いますが、基本的にXcode 7.xでビルドすればiPad対応のアプリであればデフォルトで対応できます。逆に言うとデフォルトで対応させられてしまいます。
メモ: 画面分割(Multitasking)表示に対応したくない場合は、TARGET->General->Deployment Infoの「Requires full screen」のチェックをします。
アプリがMultitaskingに対応する場合、以下の事に注意しないといけません。
- UIScreenから取得できる画面サイズでViewのサイズを指定しない事
- リサイズイベント時に動的に処理をする場合
特に画面サイズに関しては注意が必要です。
画面のサイズは、以下のUIScreenのプロパティで取得できますが、アプリがMultitaskingで表示されてる場合はサイズがおかしくなります。
[UIScreen mainScreen].bounds
最近ではAuto-Layoutを使用している事が多いと思いますので、画面サイズをそのまま使用する事は少ないかとは思います。それでも上記プロパティを使用する場合は、以下のプロパティ等から取得したサイズを使用すると良いかと思います。
UIViewController.view.bounds
今の所、サイズで気にするべきは横幅だけではありますが、今後、高さも何かあるかも知れないですね。
参考: iOSのAutoLayoutの基本的な記述方法とエラーメッセージの種類
今までリサイズイベント時に動的に処理をするのは主に画面回転時のみだったかも知れません。しかし、Multitaskingに対応する場合は画面回転とは関係無くリサイズイベントが発生するので注意が必要です。
リサイズイベントを処理する際には、以下の画面回転時のdeprecatedなメソッド対応を行う事で対応ができるかと思います。
そろそろ画面回転時のdeprecatedなメソッドをなんとかしよう!
iOS 8にてUIViewControllerの画面回転時に呼び出されるメソッドがdeprecatedになりましたね。そろそろ画面回転時のdeprecatedなメソッド対策を考えても良い時期かも知れませんね。
えっ、iOS 8対応の時に既に対応している、ですって!(笑)
そんな方でも少しは興味が出るかも知れませんよ!(笑)
iOS 8にてdeprecatedになったUIViewControllerの画面回転時に呼び出されるメソッドは以下の通りです。
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration - (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
画面回転前に呼び出されるwillRotateToInterfaceOrientationメソッドに関しては、viewWillTransitionToSize:sizeメソッドで代用ができます。しかし、画面回転後に呼び出されるdidRotateFromInterfaceOrientationメソッドに関しては代替メソッドが用意されていません。
大抵の事はwillRotateToInterfaceOrientationメソッドで処理をしてしまえば済む話ではあるのですが、画面回転後にviewのサイズを動的に変更する場合等のアプリの表示サイズが確定していない時には対応するのは難しい事があります。
そこで代わりに以下のメソッドの組み合わせを使用して対応する事ができます。
- (void)viewWillTransitionToSize:(CGSize)size - (void)viewDidLayoutSubviews
画面回転前に呼び出されるwillRotateToInterfaceOrientationメソッドの代わりにviewWillTransitionToSize:sizeメソッドを使います。
そして、画面回転後に呼び出されるdidRotateFromInterfaceOrientationメソッドの代わりにviewDidLayoutSubviewsメソッドを使用します。
ただし、これらのメソッドは、該当のUIViewControllerが最前面に無くても呼び出される為、注意が必要になります。
例えば、別UIViewControllerを表示していても呼び出され続けます。その為、該当のUIViewControllerが最前面にあるかどうかを判断して処理をする様にした方が良いでしょう。
敢えてサンプルコードは提示しませんが(笑)、これで画面回転時のdeprecatedなメソッドは何とかなるかと思います。
iPadのショートカットバーとソフトキーボードの高さの関係
iOS 9では、iPadにショートカットバーが追加されました!
このショートカットバーは、ソフトウェアキーボードの上に表示されます。
そして、このショートカットバーは外付けキーボード使用時にも画面下部に表示される事になります。これがやっかいの元なのです。
iOS 8までは外付けキーボード使用時にはソフトウェアキーボード関連のツールバーは何も表示されませんでした。しかし、iOS 9ではショートカットバーが表示される様になった為、対応が必要な場合が出てきます。
例えば、ソフトウェアキーボードの高さに合わせて画面のサイズを変更している場合です。UIScrollViewのcontentSizeを変更する場合等ですね。
今まではソフトウェアキーボードのframe(CGRect)からheight(高さ)を取得すれば済みました。
この高さは、ソフトウェアキーボードとショートカットバーを合わせたサイズになっています。
という事は「ショートカットバーのサイズはどこで取得するの?」という疑問が湧いて来るかと思います。
そうです。ショートカットバー自体のサイズだけを取る事ができないのです!
その為、ソフトウェアキーボードのサイズで判断する事になります。
注意: ソフトウェアキーボードのサイズは、NSNotificationCenterにソフトウェアキーボードのサイズ変更時の通知を受け取る様に設定しておくと良いかと思います。
しかし、取得できるソフトウェアキーボードのサイズは、「非表示時でも表示時と同じフルサイズのまま」という動作です。非表示だからといってframeサイズを変更してくれる訳ではありません。不親切ですね(笑)
つまり、ソフトウェアキーボードのframe(CGRect)のheight(高さ)を単純に見るだけでは駄目なのです!
さてどうするか。
ソフトウェアキーボードのframe(CGRect)の内、Y座標だけは表示時、非表示時で変化する為、以下の式で計算する事で解決するかと思います。
アプリ自体の高さ - ソフトウェアキーボードのY座標
この式により、外付けキーボード使用時(ソフトウェアキーボード非表示)のショートカットバーの高さがわかります。勿論、ソフトウェアキーボード表示でもソフトウェアキーボードとショートカットバーを合わせた高さがわかります。
そしてこの式はiOS 9より前のバージョンでも使用できます。そもそもソフトウェアキーボードのframe(CGRect)のheight(高さ)で高さを計算するべきでは無かったのかも知れませんね。
注意: アプリ自体の高さは、念の為にUIScreenで取得したサイズは使用しない方が良いかも知れません。
iPadのショートカットボタンに対応するには?
iOS 9にて追加されたiPadのショートカットバーのショートカットボタンは変更が可能です。
実際に変更するには、UIView、UIViewControllerの親クラスであるUIResponderのinputAssistantItemプロパティの値を変更する事で変更できます。
UIResponderのinputAssistantItemプロパティを変更する場合、主にUITextField、UITextViewになると思いますが、左側はUndo、Copy、Paste等で使用されている為、実際に追加するのは右側になると思います。
追加できるボタンは、左右共に最大3つまでの様です。4つ入りそうですが、4つ目は無視されます(笑)
キーショートカットが予約された!?
iOS 9の売りの一つにキーショートカット機能があります。
「テキストエディタを作っている訳では無いのでキーショートカット機能なんて関係無いよ!」と思った方も安心して下さい。iOSのキーショートカット機能は、テキスト編集用UIView(UiTextView、UITextField)以外のUIView、UIViewControllerでも簡単に使用可能なのです!
この実装方法を使う事で外付けキーボード使用時の使う勝手が向上するはずです!
実装方法は別途まとめたいと思いますので、お楽しみに!
ただし、仕様が中途半端なので、過度な期待はしない方が良いかも知れません(笑)
ちなみに、この機能を使用して超高機能テキストエディタアプリ「Wrix」と超高機能ファイル管理アプリ「NeoFiler」ではポップアップメニューを外付けキーボードで操作できる様にしてあります!
多機能電卓アプリ「NeoCalcs」と無料版の「NeoCalcs Free」は、多分iOSアプリでは唯一の「キー操作ができる電卓アプリ」です!
本題に戻ります。
iOS 9でのキーショートカット機能の仕様変更により、色々と問題を引き起こす様になりました。
iOS 7以降、UIKeyInputCommandでキーショートカットを実装する事ができる様になりました。ただし、一部の予約されたキーショートカットだけはOSに予約されており、OSの操作が優先されてUIKeyInputCommandで指定しても上書きは出来ない様になっていました。
iOS 9でもここまでは同じなのですが、iOS 7、8にてOSに予約されていたキーショートカットに加えて以下のキーショートカット等も予約される様になりました。
主にテキスト編集で使用されるキーショートカットですね。
- 「command + C」… コピー
- 「command + V」… ペースト
- 「command + Z」… 元に戻す
- 「command + Shift + Z」… やり直し
- 「command + Tab」… アプリ切り替え
- 「command + Shift + Tab」… アプリ切り替え(逆順)
これらのキーショートカットは、アプリ内でUIKeyInputCommandを使用して上書きしてもOSの操作が優先される事になります。つまり、アプリ内で上書きしても無視されます。
確かに統一感はあるのですが、アプリで変更できないのは考え物ですね。
ちなみに、これらのキーショートカットは、UITextView、UITextFieldでも使用できます。
独自に編集メニュー(UIMenuController)を表示する場合、以下のメソッドをオーバーライドしているかと思います。iOS 9からは上記キーショートカットを使用する場合にも呼び出される様に仕様変更された様です。
- (BOOL)canPerformAction:(SEL)action withSender:(id)sender
もしこのメソッドをオーバーライドしている場合は、元々の使用可能な編集メニューの項目に加え、(NSObject(UIResponderStandardEditActions))で定義されている上記の予約された編集キーショートカット用の編集メソッドの使用するactionに関してはYESを返す必要があります。
予約された編集キーショートカット(NSObject(UIResponderStandardEditActions))のactionの場合、senderがnilで呼び出される為、判断は可能かと思います。
そして、UIKeyInputCommandで定義したショートカットの場合はNOを返さないとUIKeyInputCommandの機能が動作しない様です。UIKeyInputCommandのactionの場合、senderはUIKeyCommandになります。
ショートカットキーの扱いとUndoボタン
少しマニアックな話をします(笑)
独自に「元に戻す」機能を実装している場合の話です。ほとんどの方には関係無い話かも知れませんが、この機能の事を知る事で独自UIViewにキーショートカットでの「元に戻す」処理が実装できるかも知れませんよ!
新たにキーショートカットが予約され、独自にUIMenuControllerクラスを使用して編集メニューを表示する場合にはcanPerformActionメソッドをオーバーライドして使用する際の注意点に付いて触れました。
しかし、以下のキーショートカットだけは別の動作をします。
- 「command + Z」… 元に戻す
- 「command + Shift + Z」… やり直し
注意: iOS7から8まではUIKeyInputCommandクラスを使用する事でこれらのキーショートカットは上書き出来ました。iOS9からはOSに予約されてしまった為、対応する必要があります。
これらのキーショートカットを有効にするには、NSUndoManagerを使用します。
UIView、UIViewController等の親クラスであるUIResponderのundoManagerプロパティ(NSUndoManager型)に用意したNSUndoManagerを設定する事で上記のキーショートカットが正常に動作する様になります。
NSUndoManagerの使い方は独自に調べてみて下さい(笑)
NSUndoManagerをそのまま使うとなかなかの使いづらさですが(笑)、サブクラスを作成し、以下のメソッドをオーバーライドして使えば何とかなると思います。
- (BOOL)canUndo - (BOOL)canRedo - (void)undo - (void)redo
NSUndoManagerの場合、「元に戻す」操作のデータをメモリに保存している様なので、操作データが増える程にメモリ圧迫をしてしまうかも知れません。しかし、サブクラスで別実装でメモリを極力使わない実装にする事は可能だと思います。
この際に注意しないといけないのは、canUndo/canRedoメソッドが呼び出されるタイミングの癖です。別アプリから切り替える等してからNSUndoManagerを使用する画面を表示すると、何故かcanUndo/canRedoメソッドが呼び出されるタイミングが早まります。通常のタイミングと異なる事があるので注意して下さい。変な癖ですよね。
ちなみに、超高機能テキストエディタアプリ「Wrix」や超高機能ファイル管理アプリ「NeoFiler」のテキストエディタ画面では、独自のやり直し処理を使用していたのですが、iOS 9のこの仕様変更により、NSUndoManagerを間接的に使わざる終えなくなりました。
しかし、NSUndoManager対応をした事により、iPad、iPhone 6(s) Plusのソフトウェアキーボードの「Undo」キーや端末を振っての「元に戻す」操作ができる様になりました!
iPadでは端末を振っての「元に戻す」操作はナンセンスなので使わないとは思いますがね(笑)
UIWindowのUIがソフトウェアキーボードの上に表示できなくなった!
UIWindowのUIを使用するケースは物凄く少ないと思いますが、今まではUIWindowのUIを使用するとソフトウェアキーボードの上やステータスバーの上にUIViewを表示する事ができました。この動作が便利で多用していたのですが、iOS 9から仕様が変更されてソフトウェアキーボードの上に表示できなくなりました!
注意: ステータスバーの上は表示可能です。
参照: UIWindowを使用したUIを作成する方法と注意点
この動作については、Appleに「UIWindowは、外部出力時に使用するものなので、iOS9からソフトキーボードの上に表示できないのは仕様」である事は確認済みです。
メモ: Developer Programには毎年2回分のTechnical Support使用権が付いていますので、年会費を払っている方は使用してみると良いかもしれません。
超高機能テキストエディタアプリ「Wrix」、超高機能ファイル管理アプリ「NeoFiler」などのアプリでUIWindowのUIを使用してソフトウェアキーボードの上にも表示できるメニュー等を表示していたのですが、この仕様変更により、色々と修正を迫られました。
急な仕様変更は困りますね。
更に、UIWindowのUIを全画面表示で最前面に表示していたとしても、外付けキーボードからの入力は後ろのUIViewControllerに渡される様になりましたので、使用している方は注意が必要です。使用している方はかなり少ないとは思いますがね(笑)
HTTP通信の扱いについて
iOS 9からApp Transport Security (ATS)の機能により、デフォルトではHTTP通信時にエラーになる様になりました。
HTTP通信をするには、Info.plistにNSAppTransportSecurityの値を追加する必要があります。詳細は省略しますが、「iOS ATS」等のキーワードで検索すればすぐに情報は見付かると思います。
広告SDK等ではApp Transport Security (ATS)をOFF推奨にしている場合もある様です。
参照: Handling App Transport Security in iOS 9
※AdMobのATSに関する設定の説明です。
なお、この機能の設定に関しては、未設定でも警告等が一切出ない為、設定し忘れる可能性がありますので、注意が必要です。
UIApplication@canOpenURLの動作が厳密になっている
アプリ内からURLを開く際、以下の様な感じでUIApplication@canOpenURLで開けるかどうかを確認するかと思います。
if ([[UIApplication sharedApplication] canOpenURL:url]) { //URLを開ける場合 [[UIApplication sharedApplication] openURL:url]; }
iOS 9から、UIApplication@canOpenURLはデフォルトでNOを返す様です。
ただし、Info.plistにLSApplicationQueriesSchemesを追加する事でYESを返す事ができる様です。
参考: 【追記】iOS9でcanOpenURLを有効にする方法
BitcodeとApp Thinning
App Thinningは、アプリを自動で最適化して配信してくれる仕組みですが、その中のBitcodeに関して触れたいと思います。
中間表現であるBitcodeを含めてiTunes Connectにアプリを提出しておく事で、再コンパイルする事無く将来的にバイナリを最適化してくれる様です。
そして、Xcode 7では、デフォルトでBitcodeが有効になっています。
デフォルト有効になっているBitcodeですが、外部ライブラリ等がBitcodeを有効にしてビルドされていない場合、端末にインストールしようとすると以下の様なエラーが出ます。
ld: '/Users/XX/XX/GoogleMobileAds.framework/GoogleMobileAds(GADGestureUtil.o)' does not contain bitcode. You must rebuild it with bitcode enabled (Xcode setting ENABLE_BITCODE), obtain an updated library from the vendor, or disable bitcode for this target. for architecture arm64 clang: error: linker command failed with exit code 1 (use -v to see invocation)
上記エラーが出た場合は、Bitcodeを有効にしてビルドされた外部ライブラリ等を用意するか、Bitcodeを無効にする必要があります。
Bitcodeを無効にするには、Build Settings -> Build Options の Enable Bitcode をNoにします。
Xcode 7でBitcodeを無効にするには Build Settings -> Build Options の Enable Bitcode をNoにすれば良いのですね。 pic.twitter.com/vfqALEpIMO
— SkyArts.com (スカイアーツ) (@SkyArts_dot_com) 2015, 9月 10
ちなみに、CommandLine ToolsでBitcodeを有効にしてビルドする時のビルドオプションは「-fembed-bitcode」です。
dylibファイルが赤文字表示になっている!?
Xcode 7で、Projectを良く見るとdylibファイルがファイル無しエラー状態を表す赤文字になっている事があるかも知れません。
このdylibファイル自体は、iOS SDKに含まれているものをインポートしたものですが、dylibファイルではなく同名のtdbファイルを指定し直さないといけないのだと考えられます。
NSLocaleの言語名が変更された!?
[NSLocale preferredLanguages]で返される値が「ja」(日本語)から「ja-JP」の様に地域名付きに変更された様です。
ロケールの言語で処理を切り分けている場合は、先頭2文字の値で処理を切り分ける必要があるでしょう。
参考: iOS9で日本語のLocalizable.stringが適用されない
固定の高さのUINavigationBarの高さがLandscape時に33pts前提で各項目が表示される様になった!?
レアケースだと思いますが、UINavigationBarを直接UIViewに貼り付けている場合の話です。
直接UIViewにUINavigationBarを貼り付け、高さを44pts程度に固定にしていたとします。44ptsは縦長表示時(Portrait)の基本の高さですね。
iOS 8までは画面の向きに関わらず、UINavigationBarに貼り付けたボタンは縦中央に綺麗に表示されていました。
しかし、iOS 9からは、横長表示時(Landscape)の基本の高さである33ptsに合わせて縦の位置が変更されてしまいます。その為、とても格好悪い表示になります。
メモ: 横長表示時(Landscape)のボタンが下の方に表示されているかと思います。
つまり、UINavigationBarの高さに合わせて ボタンの位置を自動的に変更してくれなくなりました。この問題が出るのは、iPhoneのみでiPadでは出ませんでした。iPadの場合は画面サイズに余裕が有るのでUINavigationBarの高さは自動で変更されない為だと思います。
この問題をAppleに確認したのですが、画面の向きに合わせてUINavigationBarの想定の高さを変更してボタンの位置を変更するのはiOS 9からの仕様である、との事です。
その為、ここは諦めて横長表示時(Landscape)は、アプリ側でUINavigationBar自体の高さを33ptsに変更して使用するしかないかも知れません。
4.7、5.5インチ向けスクリーンショットが必須になった
iTunes Connectで審査へ提出する場合、4.7、5.5インチ向けスクリーンショットが必須になった様です。
厳密には、4.7、5.5インチに対応している場合は、スクリーンショットが必須になった、という言うべきでしょうか。
以前作成したアプリの内、4.7、5.5インチ向けスクリーンショットを用意していないアプリの対応に困りますね。
iOS 9.1の正式版が公開された後、iPad Pro用のスクリーンショットも設定可能になっています。サイズ等は以下の通りです。
2732 x 2048 pixels or 2048 x 2732 pixels in the JPG or PNG format.
iPad向け画像を133%にすればiPad Pro用スクリーンショットにできますが、皆さんはどうしますか?(笑)
そもそもApp Storeで画面サイズ毎のスクリーンショットを用意してもフルサイズ表示はできない気がするのですけれどね。無意味な事をさせられている気がしなくも無いですね。
iOSの設定アプリに反映されない!?
Xcodeから実機にアプリを入れてテストする事は普通に行われるかと思います。
iOSの設定アプリ内にそのアプリの設定を追加する為にSettings.bundleを用意しますが、Xcodeから実機にアプリを入れた際、その設定が消えてしまう事があります。
設定が消えるてしまうので、どこか間違えたかな??と余計な時間を取られる事になりますね。
設定が消えた場合、以下の事を行うと改善されます。
- iOSの設定アプリを再起動する
どうやらiOSの設定アプリが起動されているとアプリの設定が追加されない様です。
新しいiTunes Connectの癖!?
新しいデザインのiTunes Connectには以下の様な癖がある様です。
- 新規バーションを追加後にアプリ一覧に戻るとスクロールバーが消える
- バイナリの処理中の時間が長い
- アプリページのビルドの「+」ボタンを押しても処理中のままで更新されない
- バイナリ詰まり
- Ready for Saleメールが届かない!
多くの方が困っているのはバイナリが処理中のまま長時間待たされる事ではないかと思います。
短い時は20分程度で処理が終わるのですが、6時間位かかる事もあります。流石に6時間は無いですよね(笑)
この処理時間が長い事に関しては待つしか無いのですが、以下の事に注意した方が良いかもしれません。
- アプリページのビルドの「+」ボタンを押しても更新されない
以前のアプリページでは、ビルドの「+」ボタンを押すとビルドの候補が表示され、ボタンを押す度に更新されました。しかし、新デザインは更新されない様です。
つまり、ページ自体を更新しない限り、ビルドの「+」ボタンを押し続けても一向に更新されない為、処理が終了してもずっと「処理中」表示のままという事です。これを知らないと更に無駄な時間を過ごす事になります!(笑)
ちなみに、バイナリの処理が終了したかどうかは、「アクティビティ」タブのページを再読込させた方が軽いかも知れません。
メモ: 何となく、バイナリの処理が大量に来て処理に時間がかかる様になるDeveloper PotalのTopページがメンテナンス画面になる事が多い気がしますが、その際でもiTunes ConnectのURLを直接たたけばiTunes Connectを見る事は出来るかと思います。
ちなみに、30日間「処理中」のバイナリは、自動的に削除される様なので、処理終了待ちも最高で30日間なので一安心ですね(苦)
iTunes Connectの癖には、長い処理時間の他に「バイナリ詰まり」もあります。
「えっ、何それ!」という感じですが、複数のアプリのバイナリを続けてアップロードしていると、先にアップロードしたはずのバイナリがビルド一覧に出て来ない時がありました。
後にアップロードした別アプリのバイナリの方が先に表示されたので、該当アプリのバイナリを作成し直してアップロードした所、後にアップロードしたバイナリが先に一覧に表示されました。
その後、後にアップロードしたバイナリを審査に提出した後、先にアップロードしたバイナリが「バイナリ詰まり」から解放された様で、ビルド一覧に現れ、そして他のバイナリがある的なエラーメールが届きました(苦)
上記の様に新しいiTunes Connectは、何かと処理詰まりが多く、しかも別のバイナリをアップロードする等、後から処理を入れると処理が終わる事があります。
そこで、この処理詰まり解消の事を「iSuppon (ラバーカップ)」と呼んでいます(笑)
ちなみに、バイナリの処理が16時間待っても終わらなかった事もあります。流石に16時間待った訳では無く、この「iSuppon (ラバーカップ)」を使用して後にアップロードしたバイナリを使いました。それでも4時間位は待ちましたけれどね(苦)
Ready for Saleメールが届かない問題は、現在Appleに問い合わせ中です。
しかし、「直ったら連絡する」の一点張りで既に約1ヶ月です。しばらく直らないのかも知れませんね(苦)
まとめ
なかなかマニアックな内容ばかりでしたが、iOS 9では細かい所が色々と仕様変更されているのがわかるかと思います。
しかも毎年この様な仕様変更ばかりなので、そろそろ「iOSのバージョンアップによる経済的損失」の計算が必要になるかも知れませんね(笑)
上記内容に限らず、iOSアプリ開発に関するご相談等を承っておりますので、メール等で気軽にご相談下さい。
超高機能テキストエディタアプリ「Wrix」と超高機能ファイル管理アプリ「NeoFiler」もよろしくお願いします!
両アプリ共に全機能無料で使えますので、別次元の超快適なテキスト編集環境を体験してみて下さい。
同時に複数の計算ができる多機能電卓アプリ「NeoCalcs」もよろしくお願いします! 無料版の「NeoCalcs Free」も用意してます!
多分、iOSアプリでは唯一「キー操作ができる電卓アプリ」です!(笑)