WatchKit:无法find接口控制器类

我尝试添加一个界面控制器到故事板,将其自定义类设置为WKInterfaceController子类,在模拟器中启动应用程序并导航到指定的界面控制器。

当我这样做,我得到以下错误:

WatchKit错误 – 无法find接口控制器类“TestController”来实例化

如果我尝试与控制器交互(例如,尝试启动其button的操作),我得到以下错误:

  • ***********错误 – [SPRemoteInterface _interfaceControllerClientIDForControllerID:] clientIdentifier for interfaceControllerID:(null)not found
  • ***********错误 – [SPRemoteInterface _interfaceControllerClientIDForControllerID:] clientIdentifier for interfaceControllerID:7120004 not found

我试着按照这个答案的build议设置模块名称 ,但仍然给我以下错误:

  • WatchKit错误 – 无法find接口控制器类“_TtC29myWatchApp_WatchKit_App19TestController”来实例化
  • ***********错误 – [SPRemoteInterface _interfaceControllerClientIDForControllerID:] clientIdentifier for interfaceControllerID:(null)not found
  • ***********错误 – [SPRemoteInterface _interfaceControllerClientIDForControllerID:] clientIdentifier interfaceControllerID:6E20004未find

重命名WatchKit目标后,我得到了这个错误,但终于实现了:如果你重命名你的WatchKit目标,你将不得不通过界面生成器中的接口,并确保它们每个的模块名称也被重命名。

您可以通过select一个界面控制器,单击Identity Inspector(或命令选项-3),删除模块名称,然后将其移开。 它将自动填入新的目标名称。 那是为我做的!

这个错误对我来说是因为我没有正确处理didDeactivate消息。 我停用的控制器仍然通过MMWormhole接收消息。 一旦我断开连接,错误就消失了。 事实certificate,在模拟器中,所有被禁用的接口控制器都在内存中,所以你必须小心地确保它们不会有任何types的消息。 我不知道这是否发生在手表本身,但我们当然应该这样做。

我在这个问题上花了太多的时间,但最后还是算了一下。 Apple Watch基本上有两种导航模式:

分级:

 [self pushControllerWithName:@"controllerName" context:nil]; 

基于页面的:

 [[self class] reloadRootControllersWithNames:@[@"controller1",@"controller2"] contexts:nil]; 

据苹果介绍:

您不能组合分层和基于页面的界面样式。 在devise时,您必须select最适合您应用内容的风格,并根据该风格进行devise。

所以,问题是我在混合这两个,并导致未定义的行为,如:

***********错误 – [SPRemoteInterface _interfaceControllerClientIDForControllerID:] clientIdentifier for interfaceControllerID:(null)not found

希望这有助于其他开发者

编辑:

只是一个build议,这对我来说是一个解决方法,当使用基于页面的导航时,你仍然可以呈现模态控制器(只是说):

 [self presentControllerWithName:@"controllerName" context:nil]; 

这个bug似乎与这个bug密切相关: 无法在Interface Builder下拉菜单中看到自定义的类 。

当我最初尝试解决这个问题时,我不得不手动input模块名称,因为自定义类和模块名称的下拉列表都是空的。

检查故事板的源代码揭示了一种解决方法。

接口控制器的工作是这样的:

 <controller id="AgC-eL-Hgc" customClass="InterfaceController" customModule="myWatchApp_WatchKit_App" customModuleProvider="target"> 

不工作的接口控制器缺lesscustomModule和/或customModuleProvider属性。

因此,解决方法是通过右键单击故事板文件并select“ 打开方式”>“源代码”手动将这些缺less的属性添加到故事板文件。

较长期的解决scheme可能是修复故事板,以便自定义类出现在下拉列表中(请参阅链接的问题了解一些可能的修复方法)。

更新:

其他接口控制器也可以使用customModule="myWatchApp_WatchKit_Extension" (注意_Extension_App区别),不需要customModuleProvider属性。

对我而言,这似乎是一个错误的否定。 我尝试了所有build议的解决scheme,但后来通过创build一个全新的Apple Kit项目certificate了这是一个苹果错误,对Glance进行了一次更改(添加图像)并获取错误。 我在他们的Bug Reporter中logging了以下错误。

标题

在导航到Glance时,无法findinterfaceControllerID的clientIdentifier

描述

我收到下面的错误,当在一个watchOS 2.0项目中导航时,看起来是一个错误的否定。 我通过创build一个全新的Apple Kit项目来再现这一点,对Glance进行一次更改(添加图像)并获取错误。

重现步骤

  1. 清除手表和iOS模拟器中的所有数据。
  2. 在XCode中,创build一个新的WatchKit应用程序,包括复杂和一目了然。
  3. 运行,看看没有问题。
  4. 添加一个PNG到您的图像资产。
  5. 在Interface Builder中将UIImageView添加到Glance中。
  6. 在手表模拟器中运行扩展。
  7. 在iOS Watch伴侣应用程序中启用Glance。
  8. 在手表模拟器中导航到Glance。
  9. 请注意您的日志中的跟踪错误。

2015-07-16 08:35:10.663 restaurant-reports WatchKit App Extension [78301:2211560] *********** ERROR – [SPRemoteInterface _interfaceControllerClientIDForControllerID:] clientIdentifier for interfaceControllerID:3118001E not found

预期结果

日志中不应该出现假阴性

实际结果

日志中出现假阴性

观看操作系统版本(版本)

2.0(13S5293f)

他们给了我bug编号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]; }); 

苹果的文档说了三种方法:

始终从WatchKit扩展的主线程调用此方法。

您需要validation视图控制器在您的编译源中:selectProject>selectWatchkit扩展目标>构build阶段>编译源

这不是你做错了什么。 这已经是一个已知的问题。 在这里看到我的答案。 请在苹果的Bug报告系统中join以下雷达 ,以帮助提高固定的优先级。

在最近的8.2版本之后,我遇到了同样的问题。 我不得不去每一个我的InterfaceControllers和调整自定义类模块,无论是显示为一个选项或“无”。

当我错误地设置了根接口控制器的标识符时,我遇到了这个问题。 当我删除标识符时,此警告消失。

在这里输入图像说明

控制器的模块名称应该与项目的根名称(左上angular的蓝色Xcode文档图标名称)相同。

在这里输入图像说明

你的dynamic接口的模块名称应该是相同的名称,你的目的地控制器的模块名称(即你推送的)也应该是相同的名称。

顺便说一句,如果你是新的或不知道我以为我会把这个,因为你可能认为你的课是错误的或什么的。 您的dynamic界面控制器不必指向默认的Xcode NotificationController.swift类。 当然,你可以创build一个自定义类,即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. }