复杂功能适用于模拟器,但不适用于设备

时间:2016-03-27 18:07:29

标签: ios swift watchkit watch-os-2 apple-watch-complication

我有一个复杂的问题,适用于模拟器,但是当我试用它来测试实际设备时,它不适用于实际设备(为清楚起见,如果有任何混淆,我我不是在谈论通过设备进行调试,而只是测试它是否适用于设备。

具体来说,在Watch设备上:

  • 我通过自定义钟面来选择手表上的复杂功能,它给了我占位符文本(到目前为止很好,因为 getPlaceholderTemplateForComplication也适用于模拟器...)
  • 但随后Complication始终保留为占位符文本(不是 正确,因为getCurrentTimelineEntryForComnplication正在处理 模拟器)...
  • 即使滚动浏览Time Travel,占位符文本也不会改变,只是变暗(不正确,因为getTimelineEntriesForComplication:afterDate适用于模拟器)...
iPhone上的

Info

    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)
WatchKit Extension中的

ExtensionDelegate

    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”)
}
WatchKit Extension中的

ComplicationController

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

这是数据流:

transferCurrentComplicationUserInfo将数据传递给观看ExtensionDelegate,其中数据保存在NSUserDefaults中。 ComplicationController然后从NSUserDefaults

中提取其初始数据

1 个答案:

答案 0 :(得分:1)

乍一看:

  • 这似乎不是正常工作的代码,因为你会看到很多关于“找到Unicode卷曲引号的Xcode修复错误”......

  • 请避免使用as!强制转发,因为它可能会失败并且您的代码会崩溃。你有很多不必要的类型铸造发生。 As I mentioned before,您应该键入变量以允许编译器捕获任何程序员错误。

    例如,如果字典的键和值都是字符串,则安全地将其键入:

    var playoffs: [String: String]
    
  • 如果无法进行as?向下转播,您的扩展委托代码可能会有条件地失败(因为您传递了与预期接收的内容不同的内容)。确保传递了您期望的值类型,或者整个块不会运行。您可以通过设置断点并单步执行该代码来轻松地在调试器中检查它。

    收到信息后,您还需要明确更新并发症。

    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)
            }
        }
    }
    
  • 您对阵列和NSUserDefaults所做的事情确实令人费解。虽然在启动之间保留数据非常合适,但 NSUserDefaults绝不是将代码的一部分“细节”传递给另一部分的方法。

    您的并发症数据源应该从模型或数据管理器获取数据,而不是从NSUserDefaults获取数据。

  • getCurrentTimelineEntryForComplication if let ... { } else {代码毫无意义。如果你没有得到一个字符串数组,你期望在else块中做什么?

    您还可以在switch语句之前准备数据,以使代码更具可读性和紧凑性,如下所示:

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

可能的问题是ClockKit要求提供并发症数据,扩展程序之前就已收到它,因此您的并发症数据源没有数据可供提供,也没有条目出现。< / p>

即使某些事情恰好在模拟器上运行,但这并不意味着您的代码在实际设备上也可以运行。有各种各样的差异可以解释为什么它不能在真实硬件上运行,这就是为什么你绝对需要在设备上交互式调试的原因。它将帮助您了解代码无法按预期工作的原因。

理想情况下,在进入此处之前,您应该进行此类交互式调试并解决其他问题,因此您可以使用最小的工作代码块来提出非常具体的问题。需要某人广泛调试代码的问题确实对其他人没用。