この記事では、iOS 9 で Xamarin.iOS アプリを使用する際に生じる問題を解決するためのヒントをいくつかご紹介します。
iOS 8 シミュレーターはどこにありますか?
Xcode 7 (またはそれ以上) をインストールした場合、既定では、すべての iOS 8 シミュレーターが iOS 9 シミュレーターに自動的に置き換えられます。 iOS 8 でテストする必要がある場合は、Xcode を起動してから、iOS 8 シミュレーターをダウンロードしてインストールできます。
Xcode で、[Xcode] メニューを選択し、[Preferences...]>[Downloads] を選択します。
[Check and Install Now] ボタンを選択して、iOS 8 シミュレーターを再インストールします。
左/右属性のエラーを含むレイアウト制約
iOS 8 (およびそれ以前) では、ストーリーボードの UI 要素は、同じレイアウトで右と左の属性 (NSLayoutAttributeRight
と NSLayoutAttributeLeft
) と先頭と末尾の属性 (NSLayoutAttributeLeading
と NSLayoutAttributeTrailing
) の両方を組み合わせて使用できます。
iOS 9 で同じストーリーボードが実行されると、次の形式で例外が発生します。
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** +[NSLayoutConstraint constraintWithItem:attribute:relatedBy:toItem:attribute:multiplier:constant:]: A constraint cannot be made between a leading/trailing attribute and a right/left attribute. Use leading/trailing for both or neither.'
iOS 9 では、レイアウトで Right & Left or Leading & Trailing 属性を使用しますが、両方 使用することはできません 。 この問題を解決するには、ストーリーボード ファイル内で同じ属性セットを使用するようにすべてのレイアウト制約を変更します。
詳細については、Stack Overflow の iOS 9 制約エラーに関する説明を参照してください。
ERROR ITMS-90535: Unexpected CFBundleExecutable Key
iOS 9 に切り替えた後、アプリから iOS 8 (またはそれ以前) でコンパイルおよび実行したサードパーティ製コンポーネント (具体的には既存の Google マップ コンポーネント) を使用し、iTunes Connect に新しいビルドを送信しようとすると、次の形式でエラーが発生することがあります。
ERROR ITMS-90535: Unexpected CFBundleExecutable Key. The bundle at 'Payload/app-name.app/component.bundle' does not contain a bundle executable...
この問題は通常、プロジェクトで名前付きバンドルを見つけることで解決できます。エラー メッセージが示すように、CFBundleExecutable
キーを削除してバンドル内にある Info.plist
を編集します。 CFBundlePackageType
キーも同様に BNDL
に設定する必要があります。
これらの変更を行った後、クリーニングを実行し、プロジェクト全体をリビルドします。 これらの変更を行った後、問題なく iTunes Connect に送信できます。
詳細については、こちらの Stack Overflow の説明を参照してください。
CFNetwork SSLHandshake failed (-9824) エラー
iOS 9 で直接または Web ビューからインターネットに接続しようとすると、次の形式のエラーが発生するおそれがあります。
2015-09-04 14:38:05.757 FormsWebViewiOS[2553:30362] CFNetwork SSLHandshake failed (-9824)
2015-09-04 14:38:05.758 FormsWebViewiOS[2553:30363] NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9824)
または、次の形式の場合もあります。
2015-09-04 14:39:17.881 FormsWebViewiOS[2568:30974] App Transport Security has blocked a cleartext HTTP (http://) resource load since it is insecure.
Temporary exceptions can be configured via your app's Info.plist file.
iOS 9 では、アプリ トランスポート セキュリティ (ATS) が、インターネット リソース (アプリのバックエンド サーバーなど) とアプリ間にセキュリティで保護された接続を強制します。 さらに、ATS では、HTTPS
プロトコルを使用した通信と、TLS バージョン 1.2 を使用した高度な API 通信を前方秘匿性で暗号化する必要があります。
iOS 9 と OS X 10.11 (El Capitan) 用に構築されたアプリでは ATS が既定で有効になっているため、NSURLConnection
、CFURL
、または NSURLSession
を使用するすべての接続は ATS セキュリティ要件の対象となります。 接続がこれらの要件を満たしていない場合、例外が発生して失敗します。
この問題を解決する方法については、アプリ トランスポート セキュリティ ガイドの ATS のオプトアウトに関するセクションを参照してください。
iOS 9 で既存のアプリが実行されない
iOS 9 で実行する既存のアプリのリビルドと再デプロイの手順については、iOS 9 の互換性情報を参照してください。
UICollectionViewCell.ContentView がコンストラクターで Null である
理由: iOS 9 では、UICollectionView ドキュメントの状態として iOS 9 の動作が変更されたため、initWithFrame:
コンストラクターが必要になりました。 指定した識別子のクラスを登録し、新しいセルを作成する必要がある場合は、その initWithFrame:
メソッドを呼び出すことによってセルが初期化されます。
修正: 次のように initWithFrame:
コンストラクターを追加します。
[Export ("initWithFrame:")]
public YourCellClassName (CGRect frame) : base (frame)
{
Initialize (); // refactor initialize code into a method
}
関連サンプル: MotionGraph、TextKitDemo
Xib/Nib からビューを読み込むと UIView がコーダーで初期化に失敗する
理由: initWithCoder:
コンストラクターは、Interface Builder Xib ファイルからビューを読み込むときに呼び出されます。 このコンストラクターがエクスポートされていない場合、アンマネージ コードはマネージド バージョンを呼び出すことはできません。 以前は (iOS 8) ビューを初期化するために IntPtr
コンストラクターが呼び出されていました。
修正: 次のように initWithCoder:
コンストラクターを作成してエクスポートします。
[Export ("initWithCoder:")]
public YourClassName (NSCoder coder) : base (coder)
{
Initialize (); // refactor initialize code into a method
}
関連サンプル: チャット
Dyld Message: No Cache Image with Name...
ログに次の情報が記録されてクラッシュすることがあります。
Dyld Error Message:
Dyld Message: no cach image with name (/System/Library/PrivateFrameworks/JavaScriptCore.framework/JavaScriptCore)
理由: これは、Apple のネイティブ リンカーのバグです。この問題は、プライベート フレームワークをパブリックにすると発生します (JavaScriptCore はプライベート フレームワークとなる前に iOS 7 でパブリックにされました)。フレームワークがプライベートだったとき、アプリのデプロイ ターゲットは iOS バージョンでした。 この場合、Apple のリンカーは、パブリック バージョンではなく、プライベート バージョンのフレームワークとリンクします。
修正: これは iOS 9 で対処されますが、それまでの間、適用できる簡単な回避策があります。プロジェクトの新しい iOS バージョンをターゲットにするだけです (この場合は iOS 7 を試すことができます)。 他のフレームワークでも同様の問題が発生する可能性があります。たとえば、WebKit フレームワークが iOS 8 でパブリックにされました (そのため、iOS 7 をターゲットにすると、このエラーが発生します。アプリで WebKit を使用するには iOS 8 をターゲットにする必要があります)。
信頼されていないエンタープライズ開発者
実際の iOS ハードウェアで iOS 9 バージョンの Xamarin.iOS アプリを実行しようとすると、開発者アカウントがデバイスで信頼されていないことを示すメッセージが表示される場合があります。 次に例を示します。
この問題を解決するには、次の手順を実行します。
開発用 Mac で Xcode (最新のベータ版) を起動します。
ウィンドウ メニューから [Devices] を選択し、[Devices] ウィンドウを開きます。
[DEVICES] サイド パネルで、デバイスを選択し、右クリックして [Show Provisioning Profiles...] を選択します。
デバイス上の現在の各プロビジョニング プロファイルを選択し、- ボタンを選択して削除します。
Xcode メニューから、[Preferences...]、[Accounts] の順に選択します。
[View Details...] ボタンをクリックし、[Download all] ボタンを選択します。
リストの更新が完了したら、[Done] ボタンを選択し、[Preferences] ウィンドウを閉じます。
iOS デバイスからテストしようとしていた Xamarin.iOS アプリの既存のバージョンを削除します。
Visual Studio for Mac に戻り、クリーン ビルドを実行し、デバイスでアプリの再実行を試みます。
Xcode によって読み込まれた新しいプロビジョニング プロファイルが表示される前に、Visual Studio for Mac を停止して再起動しなければならない場合があります。 新しいプロビジョニング プロファイルを選択して、Xamarin.iOS アプリの iOS バンドル署名オプションを調整する必要がある場合もあります。
起動画面の問題
iOS 9 では、異なるインターフェイスの向きをサポートするために同じ起動イメージを再利用できないように、起動画面の要件が適用されるようになりました。 詳細については、Apple の UILanchImage リファレンスを参照してください。
必要に応じて、アプリの起動画面を表示するために、一連の .png イメージ ファイルを使用するのではなく、ストーリーボード ファイルを使用できます。 これは、起動画面を表示するための Apple が推奨する方法です。 詳細については、統合ストーリーボードの概要ガイドを参照してください。
最後に、アプリは起動画面にストーリーボード ファイルを使用し、スライド オーバー パネルまたは分割ビュー モードで実行する場合に考慮される 4 つのインターフェイスの向き (縦向き、逆さまの縦向き、左横向き、右横向き) をすべてサポートする必要があります。 iOS 9 の新しいマルチタスク機能の詳細については、iPad のマルチタスクに関するガイドを参照してください。
NSInternalInconsistencyException 例外
iOS 9 用の既存の Xamarin.iOS アプリをコンパイルして実行すると、次の形式でエラーが発生することがあります。
Objective-C exception thrown. Name: NSInternalInconsistencyException Reason: Application windows are expected to have a root view controller at the end of application launch
このエラーは、アプリケーション起動の最後に、アプリ ウィンドウにルート ビュー コントローラーがあることが想定されているのに、既存のアプリに存在しないため、発生します。
この問題を回避する方法は 2 つあります。
xib
ファイルの代わりにストーリーボード ファイルを使用するように、ユーザー インターフェイスを定義してアプリを更新します。 アプリのサイズと Xcode の Interface Builder を使用してストーリーボードをレイアウトする方法に関する知識に応じて、この修正に多くの時間がかかる可能性があります。 詳細については、統合ストーリーボードの概要ガイドを参照してください。- アプリの UI でビュー コントローラーを指すように、
AppDelegate
クラスのFinishedLaunching
メソッドでアプリ ウィンドウのRootViewController
プロパティを設定します。
ビューとビュー コントローラーを初期化するタイミング
Xamarin.iOS では、マネージド コードで何かが公開されたときに呼び出されるコンストラクター内でビューまたはビュー コントローラーを初期化できますが、iOS の設計が中断されます。
通常、コンストラクターから Objective-C コードを呼び出すことができるものは、初期化しないでください。これは呼び出されるタイミングがわからないためです。 またこれは、この初期化を行う適切な場所 (.ctor) またはオーバーライドする呼び出し (Objective-C にイベントがない場合) があることを意味します。