WatchKit:无法找到接口控制器类

问题描述 投票:28回答:15

我尝试将一个接口控制器添加到故事板,将其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
ios storyboard watchkit
15个回答
34
投票

重命名WatchKit目标后出现此错误,但最终意识到:如果重命名WatchKit目标,则必须通过Interface Builder中的接口并确保每个接口的模块名称也重命名。

您可以通过选择接口控制器,单击Identity Inspector(或command-option-3),删除模块名称,然后选项卡来完成此操作。它将自动填入新的目标名称。这样做对我来说!


1
投票

您需要在此处验证视图控制器是否在您的编译源中:选择Project> Select Watchkit Extension Target> Build Phases> Compile Sources


0
投票

这不是你做错的事。这已经是一个已知问题。看我的答案here。请在Apple的radar上填写以下Bug Reporting System以帮助提高优先级以解决此问题。


0
投票

在最近的8.2发布之后,我遇到了同样的问题。我不得不去我的每个InterfaceControllers并将其自定义类模块调整为显示为选项或“无”的任何内容。


0
投票

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

enter image description here


0
投票

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

enter image description here

您的动态接口的模块名称应该是相同的名称,并且目标控制器的模块名称(即您要推送的模块名称)也应该是相同的名称。

顺便说一句,如果你是新手或不确定我以为我会把它扔进去,因为你可能认为你的班级错了什么的。您的动态接口控制器不必指向默认的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.
}

0
投票
  • 如果您正在使用基于页面的导航(从您处理推送或呈现新视图控制器的位置),请提供新控制器而不是推送它。
  • 由于第一个屏幕如果基于页面(如页面视图控制器)屏幕,那么它默认使用左/右刷的下一页或上一页的推送,它成为您的WatchKit应用程序的根窗口视图。在这种情况下,如果您从内部控件上单击另一个控制器,则它将无法识别推送,但它将识别当前的新控制器。因此,请尽可能遵守规则。

16
投票

这个错误出现了,因为我没有正确处理didDeactivate消息。我的停用控制器仍然通过MMWormhole接收消息。一旦我切断了那个连接,错误就消失了。事实证明,在模拟器中,所有已停用的接口控制器都会在内存中闲置,因此您必须仔细确保它们不会再收到任何类型的消息。我不知道手表本身是否会发生这种情况,但我们当然应该这样认为。


10
投票

我花了太多时间处理这个问题,但终于想出了它是什么。 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];

7
投票

这个错误似乎与这个错误密切相关: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属性。


3
投票

对我来说,这似乎是一个假阴性。我尝试了所有建议的解决方案,但随后通过创建一个全新的Apple Kit项目证明了这是一个Apple错误,对Glance进行了一次更改(添加图像)并获得错误。我在他们的Bug Reporter中记录了Apple的以下错误。

标题

接收导航到Glance时未找到的interfaceControllerID的clientIdentifier

描述

我收到以下错误,当在watchOS 2.0项目中导航到一瞥时,这似乎是错误的否定。我通过创建一个全新的Apple Kit项目来重现这一点,对Glance进行一次更改(添加图像)并获得错误。

重现步骤

  1. 清除手表和iOS模拟器中的所有数据。
  2. 在XCode中,创建一个新的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:] clientControllerID的clientIdentifier:3118001E未找到

预期结果

日志中不应出现任何漏报

实际结果

日志中出现假阴性

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

A0(13)

他们给了我错误ID 21853566。


2
投票

我想你忘了在课堂上使用storyboardID了。这就是我从你的错误中获得的。


2
投票

当我重命名WatchKit目标时,我遇到了这个问题。当我重新命名它时,错误就消失了。


2
投票

执行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扩展的主线程中调用此方法。


2
投票

我能够通过从我的didSets中删除IBOutlet观察员来解决这个问题。 tymac的故障排除代码很有帮助。似乎界面元素尚未可用,因为didSetawake(withContext:)之前被调用。

© www.soinside.com 2019 - 2024. All rights reserved.