web-dev-qa-db-fra.com

WatchKit: impossible de trouver la classe du contrôleur d'interface

J'ai essayé d'ajouter un contrôleur d'interface à un storyboard, de définir sa classe personnalisée sur une sous-classe WKInterfaceController, de lancer l'application dans le simulateur et de naviguer vers le contrôleur d'interface spécifié.

Lorsque je le fais, j'obtiens l'erreur suivante:

Erreur WatchKit - impossible de trouver la classe de contrôleur d'interface 'TestController' à instancier

Si j'essaie d'interagir avec le contrôleur (par exemple, essayez de lancer l'action de son bouton), le message d'erreur suivant s'affiche:

  • *********** ERROR - [SPRemoteInterface _interfaceControllerClientIDForControllerID:] clientIdentifier pour interfaceControllerID: (null) introuvable. 
  • *********** ERROR - [SPRemoteInterface _interfaceControllerClientIDForControllerID:] clientIdentifier pour interfaceControllerID: 7120004 non trouvé

J'ai essayé en configurant le nom du module comme recommandé dans cette réponse , mais cela me donne quand même les erreurs suivantes:

  • Erreur WatchKit - impossible de trouver la classe de contrôleur d'interface '_TtC29myWatchApp_WatchKit_App19TestController' pour instancier 
  • *********** ERROR - [SPRemoteInterface _interfaceControllerClientIDForControllerID:] clientIdentifier pour interfaceControllerID: (null) introuvable.
  • *********** ERROR - [SPRemoteInterface _interfaceControllerClientIDForControllerID:] clientIdentifier pour interfaceControllerID: 6E20004 non trouvé
28
Senseful

J'ai eu cette erreur après avoir renommé la cible WatchKit, mais j'ai finalement réalisé: si vous renommez vos cibles WatchKit, vous devrez passer par les interfaces dans Interface Builder et vous assurer que les noms de module de chacune d'entre elles sont également renommés.

Pour ce faire, sélectionnez un contrôleur d'interface, cliquez sur l'inspecteur d'identité (ou sur commande-option-3), supprimez le nom du module, puis appuyez sur la touche. Il sera automatiquement renseigné avec le nouveau nom de la cible. Cela l'a fait pour moi!

34
canucklesandwich

Cette erreur est survenue car je ne gérais pas correctement le message didDeactivate. Mon contrôleur désactivé recevait toujours des messages via MMWormhole. Une fois que j'ai coupé cette connexion, l'erreur est partie. Il se trouve que dans le simulateur, tous les contrôleurs d'interface désactivés restent en mémoire, vous devez donc vous assurer qu'ils ne reçoivent plus aucun message. Je ne sais pas si cela se produit sur la montre elle-même, mais bien sûr, nous devrions le supposer.

16
phatmann

J'ai passé beaucoup trop de temps avec cette question, mais j'ai finalement compris ce que c'était . L'Apple Watch a essentiellement deux modèles de navigation:

Hiérarchique:

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

Basé sur la page:

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

Selon Apple:

Vous ne pouvez pas combiner des styles d'interface hiérarchiques et basés sur des pages. Au moment de la conception, vous devez choisir le style qui convient le mieux au contenu et au design de votre application.

Le problème est donc que je mélangeais les deux et que cela conduisait à un comportement indéfini comme:

*********** ERROR - [SPRemoteInterface _interfaceControllerClientIDForControllerID:] clientIdentifier pour interfaceControllerID: (null) introuvable.

J'espère que cela aide d'autres développeurs

MODIFIER:

Juste une suggestion qui a fonctionné pour moi comme solution de contournement, lorsque vous utilisez la navigation par page, vous pouvez toujours présenter des contrôleurs modaux (en disant simplement):

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

Ce bogue semble être étroitement lié à celui-ci: Impossible de voir les classes personnalisées dans la liste déroulante d’Interface Builder .

Lorsque j'avais initialement essayé de résoudre ce problème, je devais saisir manuellement le nom du module, car la liste déroulante était vide pour les classes personnalisées et les noms de modules.

L'examen du code source du storyboard révèle une solution de contournement.

Les contrôleurs d'interface qui fonctionnent ressemblent à ceci:

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

Les contrôleurs d'interface qui ne fonctionnent pas n'ont pas d'attribut customModule et/ou customModuleProvider.

Par conséquent, une solution de contournement consiste à ajouter manuellement ces attributs manquants au fichier de scénario en cliquant dessus avec le bouton droit de la souris et en choisissant Ouvrir en tant que> Code source.

Une solution à plus long terme peut être de réparer le storyboard de manière à ce que les classes personnalisées apparaissent dans les menus déroulants (voir question liée pour certaines corrections possibles).

Mettre à jour:

Les autres contrôleurs d'interface qui fonctionnent également utilisent customModule="myWatchApp_WatchKit_Extension" (remarquez la différence _Extension par rapport à _App) et n'ont pas besoin de l'attribut customModuleProvider.

6
Senseful

Pour moi, cela semble être un faux négatif. J'ai essayé toutes les solutions suggérées, mais j'ai ensuite prouvé qu'il s'agissait d'une erreur Apple en créant un tout nouveau projet Apple Kit, en apportant une modification à Glance (ajouter une image) et en obtenant l'erreur. J'ai enregistré l'erreur suivante avec Apple dans Bug Reporter.

Titre

Recevez clientIdentifier pour interfaceControllerID introuvable lorsque navigation vers Glance

La description

Je reçois l'erreur suivante qui semble être un faux négatif lors de la navigation vers un aperçu dans un projet watchOS 2.0. J'ai reproduit ceci en créant un tout nouveau projet Apple Kit, en apportant une modification à le regard (ajout d'une image) et obtenir l'erreur.

Étapes pour reproduire

  1. Effacer toutes les données des deux simulateurs de veille et iOS.
  2. Dans XCode, créez une nouvelle application WatchKit incluant la complication et l’apparence.
  3. Exécuter et ne voir aucun problème.
  4. Ajoutez un png à votre image.
  5. Ajoutez un UIImageView au survol dans Interface Builder.
  6. Exécutez l'extension dans le simulateur de surveillance.
  7. Activer le regard dans l'application compagnon iOS Watch.
  8. Accédez au Glance dans le simulateur de montre.
  9. Notez l'erreur suivante dans votre journal.

16/07/2015 08: 35: 10.663 rapports de restaurant WatchKit App Extension [78301: 2211560] *********** ERREUR - [SPRemoteInterface _interfaceControllerClientIDForControllerID:] clientIdentifier pour interfaceControllerID: 3118001E non trouvé

Résultat attendu

Aucun faux négatif ne devrait apparaître dans le journal

Résultat actuel

Faux négatif apparaît dans le journal

Regarder la version du système d'exploitation (build)

2,0 (13S5293f)

Ils m'ont donné le numéro d'identification de bogue 21853566.

3
Justin Domnitz

Je pense que vous avez oublié d'utiliser le storyboardID dans votre classe. C'est ce que je tire de votre erreur. 

enter image description here

2
Ashraf Tawfeeq

J'ai eu ce problème lorsque j'ai renommé la cible WatchKit. Quand je l'ai renommé, l'erreur est partie.

2
nh32rg

La meilleure façon de faire un contrôleur Push/pop est d’exécuter ce morceau de code dans le thread principal, ainsi:

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];
});

La documentation Apple parle des trois méthodes:

Appelez toujours cette méthode à partir du thread principal de votre extension WatchKit.

2
mmcorrelo

Vous devez vérifier que le contrôleur de vue se trouve dans votre source de compilation ici: Sélectionnez Projet> Sélectionnez la cible d'extension Watchkit> Phases de construction> Sources de compilation.

1
zaolian

J'avais les mêmes problèmes après la récente version 8.2. Je devais aller sur chacun de mes InterfaceControllers et ajuster son module de classe personnalisé à tout ce qui était présenté comme une option ou "aucun". 

0
devone

J'ai eu ce problème lorsque j'ai défini par erreur l'identifiant du contrôleur d'interface racine. Lorsque je supprime l'identifiant, cet avertissement a disparu.

 enter image description here

0
morizotter

Le nom du module du contrôleur doit être identique à celui de la racine du projet (nom de l’icône du document Xcode bleu en haut à gauche).

 enter image description here

Le nom de module de votre interface dynamique doit être identique et celui de votre contrôleur de destination (c'est-à-dire celui que vous souhaitez pousser) doit également correspondre au même nom.

Au fait, au cas où vous seriez nouveau ou incertain, je pensais que je pourrais le dire parce que vous pensiez peut-être que votre classe a tort ou quelque chose du genre. Votre contrôleur d'interface dynamique ne doit pas nécessairement pointer vers la classe Xcode NotificationController.Swift par défaut. Bien entendu, vous pouvez créer une classe personnalisée, par exemple FriendRequestNotificationController.

Pour résoudre ce problème, vous pouvez ajouter ce code à la méthode awakeWithContext pour voir quels contrôleurs ont quels 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
tymac

J'ai pu résoudre ce problème en retirant les observateurs didSet de mes IBOutlets. Le code de dépannage de tymac était utile. Il semble que les éléments d’interface n’étaient pas encore disponibles, étant donné que didSet était appelé avant awake(withContext:).

0
Joshua C. Lerner
  • Si vous utilisez la navigation par page (à partir de l'endroit où vous manipulez Appuyez sur ou présentez un nouveau contrôleur de vue), veuillez alors présenter Le nouveau contrôleur au lieu de le pousser.
  • Depuis le premier écran qui est basé sur la page (comme le contrôleur de vue de page) Écrans, il utilise par défaut le fait d'appuyer sur la page suivante ou sur la page précédente. app. Dans ce cas, si Push un autre contrôleur est activécliquez depuis les commandes intérieures, il ne reconnaîtra pas le Push maisit reconnaîtra le nouveau contrôleur présent. Par conséquent, veuillez suivre les règles, si possible.
0
Vivek Gupta

Ce n'est pas quelque chose que vous faites mal. C'est déjà un problème connu. Voir ma réponse ici . Veuillez dupliquer le radar suivant sur le Bug Reporting System d’Apple pour aider à augmenter la priorité afin de résoudre ce problème.

0
cnoon