2016-03-27 9 views
-1

Ich habe eine Komplikation, dass funktioniert auf Simulator, funktioniert aber nicht auf einem tatsächlichen Gerät, wenn ich TestFlight es auf einem tatsächlichen Gerät zu testen (und der Klarheit halber, wenn es ist jede Verwirrung, ich spreche nicht über das Debugging über das Gerät, sondern nur testen, ob es auf einem Gerät funktioniert).Komplikation funktioniert auf Simulator, aber nicht auf Gerät

Speziell auf die Watch-Gerät:

  • ich wählen Sie die Komplikationsrate auf der Uhr durch das Zifferblatt Customizing, die mir den Platzhalter Text gibt (so weit so gut, weil getPlaceholderTemplateForComplication Arbeiten auf Simulator auch). ..
  • aber dann immer die Complication als Platzhalter-Text bleibt (nicht korrekt, weil getCurrentTimelineEntryForComnplication Arbeiten auf Simulator) ...
  • auch wenn durch Time Travel der Platzhalter-Text Scrollen nicht chan ge aber nur abgeblendet (nicht richtig, weil getTimelineEntriesForComplication:afterDate Werke Simulator) ...

Info auf dem iPhone:

game.duel = playoffs[“Duel”] as! String 
    game.tv = playoffs[“TV”] as! String 
    game.td = playoffs[“TD”] as! AnyObject 
    let dictionary = [“Duel” : game.duel, “TV” : game.tv, “TD” : game.td] 
    let transferComplication = WCSession.defaultSession().transferCurrentComplicationUserInfo(dictionary) 

ExtensionDelegate in WatchKit Erweiterung:

var duelArray = [String]() 
    var tvArray = [String]() 
    var tdArray = [NSDate]() 
    let defaults = NSUserDefaults.standardUserDefaults() 

     if let duel = userInfo[“Duel”] as? String, let tv = userInfo[“TV”] as? String, let td = userInfo[“TD”] as? String { 
      duelArray.append(duel) 
      tvArray.append(tv) 
      tdArray.append(td as! NSDate) 
      defaults.setObject(duelArray, forKey: “DuelSaved”) 
      defaults.setObject(tvArray, forKey: "TVSaved”) 
      defaults.setObject(tdArray, forKey: "TDSaved”) 
} 

ComplicationController in WatchKit extension:

func getCurrentTimelineEntryForComplication(complication: CLKComplication, withHandler handler: ((CLKComplicationTimelineEntry?) -> Void)) { 
switch complication.family { 
     case .ModularLarge: 
      let mlTemplate = CLKComplicationTemplateModularLargeStandardBody() 
       if let currentDuel = defaults.arrayForKey(“DuelSaved”) as? [String] { 
         let firstDuel = currentDuel[0] 
         let headerTextProvider = CLKSimpleTextProvider(text: firstDuel) 
         mlTemplate.headerTextProvider = headerTextProvider 
       } else { 
        // … 

       } 
       if let currentTV = defaults.arrayForKey(“TVSaved”) as? [String] { 
        let firstTV = currentTV[0] 
        let body1TextProvider = CLKSimpleTextProvider(text: firstTV) 
        mlTemplate.body1TextProvider = body1TextProvider 
       } else { 
        // … 
       } 
       if let currentTD = defaults.arrayForKey("TDSaved"){ 
         let firstTD = currentTD[0] 
         let body2TextProvider = CLKTimeTextProvider(date: firstTD as! NSDate) 
         mlTemplate.body2TextProvider = body2TextProvider 
       } else { 
        // … 
       } 
       let timelineEntry = CLKComplicationTimelineEntry(date: NSDate(), complicationTemplate: mlTemplate) 
       handler(timelineEntry) 
    // … 
} 


    func getTimelineEntriesForComplication(complication: CLKComplication, afterDate date: NSDate, limit: Int, withHandler handler: (([CLKComplicationTimelineEntry]?) -> Void)) { 
     let headerArray = defaults.arrayForKey(“DuelSaved”) 
     let body1Array = defaults.arrayForKey("TVSaved") 
     let body2Array = defaults.arrayForKey("TDSaved") 

     guard let headers = headerArray, texts = body1Array, dates = body2Array else { return } 
     var entries = [CLKComplicationTimelineEntry]() 
for (index, header) in headers.enumerate() { 
      let text = texts[index] 
      let date1 = dates[index] 
      let headerTextProvider = CLKSimpleTextProvider(text: header as! String, shortText: headerShort as? String) 
      let body1TextProvider = CLKSimpleTextProvider(text: text as! String) 
      let timeTextProvider = CLKTimeTextProvider(date: date1 as! NSDate) 
      let template = CLKComplicationTemplateModularLargeStandardBody() 

      template.headerTextProvider = headerTextProvider 
      template.body1TextProvider = body1TextProvider 
      template.body2TextProvider = timeTextProvider 

      switch complication.family { 
      case .ModularLarge: 
       let timelineEntry = CLKComplicationTimelineEntry(date: date1 as! NSDate, complicationTemplate: template) 
       entries.append(timelineEntry) 
      // … 
} 

    func requestedUpdateDidBegin() {   
     let server=CLKComplicationServer.sharedInstance() 
     for comp in (server.activeComplications) { 
      server.reloadTimelineForComplication(comp) 
     } 
    } 

Dies ist der Fluss der Daten:

transferCurrentComplicationUserInfo leitet Daten an die Uhr ExtensionDelegate wobei die Daten in NSUserDefaults gespeichert wird. ComplicationController zieht dann seine ursprünglichen Daten von NSUserDefaults.

+0

Nicht genug Info. Woher kommt Ihre Komplikation beim ersten Start? Wenn keine Einträge vorhanden sind, ist es wahrscheinlich, dass ein leeres (oder kein) Array ausgeführt wird. Was macht 'createData()' nach dem Update? ist es synchron? Wenn nicht, wird die Komplikation ohne Daten aktualisiert, und die Daten werden nach dem Update eintreffen. –

+0

@PetahChristian Klingt gut, wollte nicht zu viele Infos posten, also danke, dass du mir Bescheid gegeben hast, ich muss noch etwas hinzufügen. Die anfänglichen Daten der Komplikationen stammen von 'NSUserDefaults', das innerhalb der 'extensionDelegate'' didReceiveUserInfo' erstellt wurde, die von der' transferCurrentComplicationUserInfo' übergeben wurde. – victorpulak

+0

ClockKit hat bereits die ersten Daten * angefordert, bevor * Informationen empfangen werden, also wird es nicht geben alle anfänglichen Einträge zur Anzeige. Sobald Sie die ersten Daten erhalten haben, müssen Sie die Komplikation manuell aktualisieren (indem Sie die Zeitleiste neu laden). –

Antwort

1

Auf den ersten Blick:

  • Dies scheint nicht Code zu arbeiten, wie Sie eine Menge von Xcode Fix-it-Fehler über „Unicode geschweiften Zitat fand sehen würde ... ".

  • Bitte vermeiden Sie Force Downcasting mit as!, da es fehlschlagen kann und Ihr Code abstürzt. Sie haben viele unnötige Typ Casting statt. As I mentioned before sollten Sie Ihre Variablen eingeben, damit der Compiler alle Programmierfehler abfangen kann.

    Zum Beispiel, wenn Ihr Wörterbuch des Schlüssel und Werte beider Strings sind, dann geben Sie ihm sicher als:

    var playoffs: [String: String] 
    
  • Ihre Erweiterung Delegaten Code bedingt fehlschlagen kann, wenn die as? gesenkten nicht möglich ist (weil Sie bestehen etwas anderes als das, was Sie erwartet haben). Stellen Sie sicher, dass Sie die Typen von Werten übergeben, die Sie erwarten, oder dass der gesamte Block nicht ausgeführt wird. Sie können dies im Debugger leicht überprüfen, indem Sie einen Haltepunkt setzen und diesen Code durchlaufen.

    Sie müssen auch Ihre Komplikation explizit aktualisieren, sobald die Informationen empfangen werden.

    func session(session: WCSession, didReceiveUserInfo userInfo: [String : AnyObject]) { 
        if let ... { // Retrieve values from dictionary 
    
         // Update complication 
         let complicationServer = CLKComplicationServer.sharedInstance() 
         guard let activeComplications = complicationServer.activeComplications else { // watchOS 2.2 
          return 
         } 
    
         for complication in activeComplications { 
          complicationServer.reloadTimelineForComplication(complication) 
         } 
        } 
    } 
    
  • Es ist wirklich gewunden, was Sie mit der Arrays und NSUserDefaults tun. Obwohl es ideal ist, die Daten zwischen den Starts zu persistieren, istNSUserDefaults nie dazu gedacht, eine Möglichkeit zu sein, um Details von einem Teil Ihres Codes an einen anderen zu "weitergeben".

    Ihre Komplikationsdatenquelle sollte ihre Daten von einem Modell oder Datenmanager erhalten, anstatt von NSUserDefaults.

  • Der getCurrentTimelineEntryForComplicationif let ... { } else { Code macht keinen Sinn. Wenn Sie kein Array mit Strings erhalten, was erwarten Sie im Block else?

    Sie können Ihre Daten vor der Switch-Anweisung, bereiten Sie Ihren Code besser lesbar und kompakt zu machen, etwa so:

    func getCurrentTimelineEntryForComplication(complication: CLKComplication, withHandler handler: ((CLKComplicationTimelineEntry?) -> Void)) { 
        // Call the handler with the current timeline entry 
    
        let recentData = DataManager.sharedManager.complicationData ?? "???" 
    
        let template: CLKComplicationTemplate? 
        let simpleTextProvider = CLKSimpleTextProvider(text: recentData) 
    
        switch complication.family { 
        case .ModularLarge: 
         let modularLargeTemplate = CLKComplicationTemplateModularLargeStandardBody() 
         modularLargeTemplate.headerTextProvider = CLKSimpleTextProvider(text: "Update Complication", shortText: "Update") 
         modularLargeTemplate.body1TextProvider = simpleTextProvider 
         template = modularLargeTemplate 
        case .UtilitarianLarge: 
         let utilitarianLargeTemplate = CLKComplicationTemplateUtilitarianLargeFlat() 
         utilitarianLargeTemplate.textProvider = simpleTextProvider 
         template = utilitarianLargeTemplate 
        case .CircularSmall: 
         let circularSmallTemplate = CLKComplicationTemplateCircularSmallSimpleText() 
         circularSmallTemplate.textProvider = simpleTextProvider 
         template = circularSmallTemplate 
        case .ModularSmall: 
         let modularSmallTemplate = CLKComplicationTemplateModularSmallSimpleText() 
         modularSmallTemplate.textProvider = simpleTextProvider 
         template = modularSmallTemplate 
        case .UtilitarianSmall: 
         let utilitarianSmallTemplate = CLKComplicationTemplateUtilitarianSmallFlat() 
         utilitarianSmallTemplate.textProvider = simpleTextProvider 
         template = utilitarianSmallTemplate 
        } 
        let timelineEntry = CLKComplicationTimelineEntry(date: NSDate(), complicationTemplate: template!) 
        handler(timelineEntry) 
    } 
    

Das wahrscheinliche Problem ist, dass ClockKit für Komplikation Daten gefragt, gut vor Ihre Erweiterung hat es sogar erhalten, so dass Ihre Komplikationsdatenquelle keine Daten zur Verfügung gestellt hat und keine Einträge erscheinen.

Obwohl etwas passiert, um am Simulator zu arbeiten, bedeutet das nicht, dass Ihr Code robust ist, um auch auf dem tatsächlichen Gerät zu funktionieren. Es gibt alle möglichen Unterschiede, die erklären können, warum es auf der realen Hardware nicht funktioniert, weshalb Sie unbedingt interaktiv auf dem Gerät debuggen müssen. Es wird Ihnen helfen zu verstehen, warum Ihr Code nicht wie vorgesehen funktioniert.

Im Idealfall sollten Sie diese Art von interaktivem Debuggen und die Lösung dieser anderen Probleme, bevor Sie hierher kommen, so können Sie eine sehr spezifische Frage mit einem minimalen Arbeitsblock Code. Fragen, die erfordern, dass jemand Ihren Code grob debuggt, sind für andere im Allgemeinen nicht nützlich.