我有一个复杂的问题,适用于模拟器,但是当我试用它来测试实际设备时,它不适用于实际设备(为清楚起见,如果有任何混淆,我我不是在谈论通过设备进行调试,而只是测试它是否适用于设备。
具体来说,在Watch设备上:
getPlaceholderTemplateForComplication
也适用于模拟器...)getCurrentTimelineEntryForComnplication
正在处理
模拟器)... getTimelineEntriesForComplication:afterDate
适用于模拟器)... 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
。
答案 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>
即使某些事情恰好在模拟器上运行,但这并不意味着您的代码在实际设备上也可以运行。有各种各样的差异可以解释为什么它不能在真实硬件上运行,这就是为什么你绝对需要在设备上交互式调试的原因。它将帮助您了解代码无法按预期工作的原因。
理想情况下,在进入此处之前,您应该进行此类交互式调试并解决其他问题,因此您可以使用最小的工作代码块来提出非常具体的问题。需要某人广泛调试代码的问题确实对其他人没用。