ストーリーボードにインターフェイスコントローラーを追加し、カスタムクラスをWKInterfaceControllerサブクラスに設定して、シミュレーターでアプリを起動し、指定されたインターフェイスコントローラーに移動しました。
そうすると、次のエラーが表示されます。
WatchKitエラー-インスタンス化するインターフェイスコントローラークラス 'TestController'が見つかりません
コントローラとやり取りしようとすると(たとえば、ボタンのアクションを起動しようとすると)、次のエラーが表示されます。
- ***********エラー-[SPRemoteInterface _interfaceControllerClientIDForControllerID:] interfaceControllerID:(null)のclientIdentifierが見つかりません
- ***********エラー-[SPRemoteInterface _interfaceControllerClientIDForControllerID:] clientController for interfaceControllerID:7120004が見つかりません
この回答で推奨されているようにモジュール名を設定する を試しましたが、それでも次のエラーが発生します:
- WatchKitエラー-インスタンス化するインターフェイスコントローラークラス '_TtC29myWatchApp_WatchKit_App19TestController'が見つかりません
- ***********エラー-[SPRemoteInterface _interfaceControllerClientIDForControllerID:] interfaceControllerID:(null)のclientIdentifierが見つかりません
- ***********エラー-[SPRemoteInterface _interfaceControllerClientIDForControllerID:] interfaceControllerID:6E20004のclientIdentifierが見つかりません
WatchKitターゲットの名前を変更した後にこのエラーが発生しましたが、ようやく気付きました:WatchKitターゲットの名前を変更する場合、Interface Builderでインターフェイスを調べて、それぞれのモジュール名も必ず名前を変更する必要があります。
これを行うには、インターフェイスコントローラーを選択し、Identity Inspector(またはcommand-option-3)をクリックし、モジュール名を削除してからTabキーを押します。新しいターゲット名が自動的に入力されます。それは私のためにそれをしました!
didDeactivate
メッセージを適切に処理していなかったため、このエラーが発生しました。非アクティブ化したコントローラーは、MMWormhole
を介してメッセージを受信し続けていました。その接続を切断すると、エラーはなくなりました。シミュレーターでは、非アクティブ化されたすべてのインターフェイスコントローラーがメモリ内に存在するため、どのような種類のメッセージも受信しないように注意する必要があります。これがWatch自体で起こるかどうかはわかりませんが、もちろんそうするべきです。
私はこの問題にあまりにも多くの時間を費やしましたが、最終的にそれが何であるかを理解しました。 Apple Watchには、基本的に2つのナビゲーションパターンがあります。
階層的:
[self pushControllerWithName:@"controllerName" context:nil];
ページベース:
[[self class] reloadRootControllersWithNames:@[@"controller1",@"controller2"] contexts:nil];
Appleによると:
階層的なインターフェイススタイルとページベースのインターフェイススタイルを組み合わせることはできません。設計時には、アプリのコンテンツに最適なスタイルを選択し、そのスタイルに合わせて設計する必要があります。
だから、問題は私が両方を混ぜていて、それが次のような未定義の動作につながることです:
***********エラー-[SPRemoteInterface _interfaceControllerClientIDForControllerID:] interfaceControllerID:(null)のclientIdentifierが見つかりません
これが他の開発者に役立つことを願っています
編集:
回避策として私のために働いた提案だけですが、ページベースのナビゲーションを使用する場合、モーダルコントローラを提示することができます(ちょうど言って):
[self presentControllerWithName:@"controllerName" context:nil];
このバグは、これと密接に関連しているようです。 Interface Builderドロップダウンでカスタムクラスを表示できません 。
最初にこれを解決しようとしたとき、カスタムクラスとモジュール名の両方のドロップダウンが空だったため、モジュール名を手動で入力する必要がありました。
ストーリーボードのソースコードを調べると、1つの回避策が明らかになります。
動作するインターフェイスコントローラーは次のようになります。
<controller id="AgC-eL-Hgc" customClass="InterfaceController"
customModule="myWatchApp_WatchKit_App" customModuleProvider="target">
動作しないインターフェイスコントローラーには、customModule
および/またはcustomModuleProvider
属性がありません。
したがって、回避策として、ストーリーボードファイルを右クリックして[名前を付けて開く]> [ソースコード]を選択して、不足している属性をストーリーボードファイルに手動で追加します。
長期的な解決策は、ストーリーボードを修正して、ドロップダウンにカスタムクラスが表示されるようにすることです(修正の可能性については リンクされた質問 を参照してください)。
更新:
動作する他のインターフェイスコントローラーはcustomModule="myWatchApp_WatchKit_Extension"
(_Extension
と_App
の違いに注意)を使用し、customModuleProvider
属性を必要としません。
私にとって、これは偽陰性のようです。提案された解決策をすべて試しましたが、Appleキットプロジェクトを新規作成し、Glanceに1つの変更(画像の追加)を加えてエラーを取得することで、Appleエラーであることを証明しました。 Bug ReporterでAppleを使用して次のエラーを記録しました。
題名
Glanceへの移動時に、interfaceControllerIDのclientIdentifierが見つかりません
説明
WatchOS 2.0プロジェクトでGlanceに移動すると、偽陰性と思われる次のエラーが表示されます。これを再現するには、新しいApple Kitプロジェクトを作成し、Glanceに1つの変更(画像の追加)を加えてエラーを取得しました。
再現する手順
- 時計とiOSシミュレータの両方のすべてのデータを消去します。
- XCodeで、合併症や視線を含む新しいWatchKitアプリケーションを作成します。
- 実行して問題を確認します。
- 画像アセットにpngを追加します。
- Interface BuilderのGlanceにUIImageViewを追加します。
- ウォッチシミュレータで拡張機能を実行します。
- IOS WatchコンパニオンアプリでGlanceを有効にします。
- 時計シミュレーターの一覧に移動します。
- ログのフォローエラーに注意してください。
2015-07-16 08:35:10.663 restaurant-reports WatchKit App Extension [78301:2211560] ***********エラー-[SPRemoteInterface _interfaceControllerClientIDForControllerID:] clientController for interfaceControllerID:3118001Eが見つかりません
期待される結果
偽陰性はログに表示されません
実結果
ログに偽陰性が表示される
OSバージョン(ビルド)を見る
2.0(13S5293f)
彼らは私にバグID 21853566を与えました。
クラスでstoryboardIDを使用するのを忘れたと思います。それは私があなたのエラーから得るものです。
WatchKitターゲットの名前を変更すると、この問題が発生しました。名前を変更すると、エラーはなくなりました。
didSet
sからIBOutlet
オブザーバーを削除することで、これを修正できました。 tymacのトラブルシューティングコードは役に立ちました。 didSet
はawake(withContext:)
の前に呼び出されていたため、インターフェース要素はまだ利用できなかったようです。
プッシュ/ポップコントローラーを実行するより良い方法は、そのコードをメインスレッドで実行することです。
dispatch_async(dispatch_get_main_queue(), ^{
[self pushControllerWithName:@"controllerIdentifier" context:data];
});
dispatch_async(dispatch_get_main_queue(), ^{
[self popToRootController];
});
dispatch_async(dispatch_get_main_queue(), ^{
[self popController];
});
Appleのドキュメントには、3つの方法が記載されています。
このメソッドは、常にWatchKit拡張機能のメインスレッドから呼び出します。
View Controllerがコンパイルソースにあることをここで確認する必要があります:プロジェクトを選択> Watchkit拡張ターゲットを選択>ビルドフェーズ>ソースをコンパイル
最近の8.2リリース以降も同じ問題が発生していました。 InterfaceControllersのそれぞれに移動し、そのカスタムクラスモジュールをオプションまたは「なし」として表示されるものに調整する必要がありました。
コントローラのモジュール名は、プロジェクトのルート名と同じ名前にする必要があります(左上の青いXcodeドキュメントアイコン名)。
動的インターフェースのモジュール名は同じ名前であり、宛先コントローラーのモジュール名(つまり、プッシュ先のモジュール名)も同じ名前である必要があります。
ちなみに、クラスが間違っているか何かを考えているかもしれないので、あなたが新しいか、私がこれを投げると思ったのかわからない場合。ダイナミックインターフェイスコントローラーは、デフォルトのXcode NotificationController.Swiftクラスを指す必要はありません。もちろん、FriendRequestNotificationControllerなどのカスタムクラスを作成できます。
トラブルシューティングを行うには、このコードをawakeWithContextメソッドに追加して、どのコントローラーがどのIDを持っているかを確認します。
override func awakeWithContext(context: AnyObject?) {
super.awakeWithContext(context)
if let vcID = self.valueForKey("_viewControllerID") as? NSString {
print("Controller: \(vcID)")
}
// Configure interface objects here.
}
それはあなたが間違っていることではありません。これはすでに既知の問題です。私の答えをご覧ください こちら 。次の radar をAppleの Bug Reporting System にコピーして、この問題を修正する優先度を上げてください。