我尝试将一个接口控制器添加到故事板,将其Custom Class设置为WKInterfaceController子类,在模拟器中启动应用程序并导航到指定的接口控制器。
当我这样做时,我收到以下错误:
WatchKit错误 - 无法找到接口控制器类'TestController'来实例化
如果我尝试与控制器交互(例如尝试启动其按钮的操作),我会收到以下错误:
- *********** ERROR - [SPRemoteInterface _interfaceControllerClientIDForControllerID:] interfaceControllerID的clientIdentifier :( null)未找到
- *********** ERROR - [SPRemoteInterface _interfaceControllerClientIDForControllerID:] clientControllerID的clientIdentifier:找不到7120004
我试过setting the module name as recommended on this answer,但这仍然给我以下错误:
- WatchKit错误 - 无法找到接口控制器类'_TtC29myWatchApp_WatchKit_App19TestController'来实例化
- *********** ERROR - [SPRemoteInterface _interfaceControllerClientIDForControllerID:] interfaceControllerID的clientIdentifier :( null)未找到
- *********** ERROR - [SPRemoteInterface _interfaceControllerClientIDForControllerID:] interfaceControllerID的clientIdentifier:找不到6E20004
重命名WatchKit目标后出现此错误,但最终意识到:如果重命名WatchKit目标,则必须通过Interface Builder中的接口并确保每个接口的模块名称也重命名。
您可以通过选择接口控制器,单击Identity Inspector(或command-option-3),删除模块名称,然后选项卡来完成此操作。它将自动填入新的目标名称。这样做对我来说!
您需要在此处验证视图控制器是否在您的编译源中:选择Project> Select Watchkit Extension Target> Build Phases> Compile Sources
这不是你做错的事。这已经是一个已知问题。看我的答案here。请在Apple的radar上填写以下Bug Reporting System以帮助提高优先级以解决此问题。
在最近的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.
}
这个错误出现了,因为我没有正确处理didDeactivate
消息。我的停用控制器仍然通过MMWormhole
接收消息。一旦我切断了那个连接,错误就消失了。事实证明,在模拟器中,所有已停用的接口控制器都会在内存中闲置,因此您必须仔细确保它们不会再收到任何类型的消息。我不知道手表本身是否会发生这种情况,但我们当然应该这样认为。
我花了太多时间处理这个问题,但终于想出了它是什么。 Apple Watch基本上有两种导航模式:
分级:
[self pushControllerWithName:@"controllerName" context:nil];
基于页面的:
[[self class] reloadRootControllersWithNames:@[@"controller1",@"controller2"] contexts:nil];
根据苹果:
您无法组合分层和基于页面的界面样式。在设计时,您必须选择最适合您应用内容和该风格设计的样式。
所以,问题是我混合了两者,这导致了未定义的行为,如:
*********** ERROR - [SPRemoteInterface _interfaceControllerClientIDForControllerID:] interfaceControllerID的clientIdentifier :( null)未找到
希望这有助于其他开发者
编辑:
只是一个对我有用的建议作为解决方法,当使用基于页面的导航时,你仍然可以呈现模态控制器(只是说):
[self presentControllerWithName:@"controllerName" context:nil];
这个错误似乎与这个错误密切相关:Unable to see custom classes in Interface Builder drop down。
当我最初尝试解决这个问题时,我不得不手动输入模块名称,因为自定义类和模块名称的下拉列表都是空的。
检查故事板的源代码揭示了一种解决方法。
工作的接口控制器如下所示:
<controller id="AgC-eL-Hgc" customClass="InterfaceController"
customModule="myWatchApp_WatchKit_App" customModuleProvider="target">
不工作的接口控制器缺少customModule
和/或customModuleProvider
属性。
因此,解决方法是通过右键单击并选择“打开方式”>“源代码”,将这些缺少的属性手动添加到情节提要文件中。
一个较长期的解决方案可能是修复故事板,以便自定义类出现在下拉列表中(有关一些可能的修复,请参阅linked question)。
更新:
其他接口控制器也使用customModule="myWatchApp_WatchKit_Extension"
(注意_Extension
与_App
差异)并且不需要customModuleProvider
属性。
对我来说,这似乎是一个假阴性。我尝试了所有建议的解决方案,但随后通过创建一个全新的Apple Kit项目证明了这是一个Apple错误,对Glance进行了一次更改(添加图像)并获得错误。我在他们的Bug Reporter中记录了Apple的以下错误。
标题
接收导航到Glance时未找到的interfaceControllerID的clientIdentifier
描述
我收到以下错误,当在watchOS 2.0项目中导航到一瞥时,这似乎是错误的否定。我通过创建一个全新的Apple Kit项目来重现这一点,对Glance进行一次更改(添加图像)并获得错误。
重现步骤
- 清除手表和iOS模拟器中的所有数据。
- 在XCode中,创建一个新的WatchKit应用程序,包括复杂性和一瞥。
- 运行,看不出任何问题。
- 将png添加到图像资源。
- 在Interface Builder中添加UIImageView到Glance。
- 在手表模拟器中运行扩展。
- 在iOS Watch配套应用中启用Glance。
- 导航到手表模拟器中的Glance。
- 请注意日志中的以下错误。
2015-07-16 08:35:10.663 restaurant-reports WatchKit App Extension [78301:2211560] *********** ERROR - [SPRemoteInterface _interfaceControllerClientIDForControllerID:] clientControllerID的clientIdentifier:3118001E未找到
预期结果
日志中不应出现任何漏报
实际结果
日志中出现假阴性
观看操作系统版本(构建)
A0(13)
他们给了我错误ID 21853566。
我想你忘了在课堂上使用storyboardID了。这就是我从你的错误中获得的。
当我重命名WatchKit目标时,我遇到了这个问题。当我重新命名它时,错误就消失了。
执行push / pop控制器的更好方法是将该段代码运行到主线程中,这样:
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文档说明了这三种方法:
始终从WatchKit扩展的主线程中调用此方法。
我能够通过从我的didSet
s中删除IBOutlet
观察员来解决这个问题。 tymac的故障排除代码很有帮助。似乎界面元素尚未可用,因为didSet
在awake(withContext:)
之前被调用。