无法取消归档手表发送的文件



我有一个包含在Apple Watch上生成的数据的类。我使用以下方法对类进行归档,将数据存储在一个文件中,然后将文件发送到iPhone。

func send(file counter: CounterModel) {
let session = WCSession.default
let fm = FileManager.default
let documentsDirectory = fm.urls(for: .documentDirectory, in: .userDomainMask).first!
let transferStore = documentsDirectory.appendingPathComponent("transferfile").appendingPathExtension("cnt")
do {
let counterData = try NSKeyedArchiver.archivedData(
withRootObject: counter,
requiringSecureCoding: false
)
try counterData.write(to: transferStore)
if session.activationState == .activated {
session.transferFile(transferStore, metadata: nil)
}
} catch {
print("Oops")
}
}

将文件发送到iPhone工作正常,委托方法正在被调用并且文件被接收。但是,我无法对数据进行解归档,并得到错误消息"无法读取数据,因为它不是正确的格式"。委托很简单:

func session(_ session: WCSession, didReceive file: WCSessionFile) {
do {
let contents = try Data(contentsOf: file.fileURL)

if let newValue = try NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(contents) as? CounterModel {
listOfCounters.append(newValue)
} else {
print("The content could not be decoded.")
}
} catch {
print("Failed to retrieve the file with error (error.localizedDescription).")
}
}

显然,我做错了什么。iPhone上的数据可以解除存档,所以这不是问题。也许发送的文件有另一种格式,但我无法得到任何有关的信息。

我将这个问题作为DTS的票证打开,得到以下答案:

罪魁祸首是您的Model类在不同的目标中具有不同的(完整的)类名。Swift类有一个模块名,默认情况下与目标名称绑定。当你的模型类为你的WatchKit扩展编译,它的全名是"TagetName_watchkit_extension.Model";当它被编译到你的iOS应用程序时,它变成了"TargetName.Model"。

当你的WatchKit扩展存档一个对象模型时,它使用"Target_watchkit_extension"。Model"作为类名,你的iOS应用无法识别它,从而触发失败。

你可以使用@objc给你的Model类一个全名,这样可以防止编译器添加模块名,如下所示:

@objc(Model)
class Model: NSObject, NSCoding, ObservableObject {

我执行了这个建议,它起作用了。然而,在我的MacBook上,我从预览中得到了一条错误信息,上面说我需要用"@objc dynamic"前缀更改我的模型的一些方法。然而,这可能会发生,因为苹果的DTS没有得到这个错误。

对这个问题的回应是:

对于KVO(键值观察)支持需要"@objc dynamic"。自从"@ publishhed"变量也依赖于KVO,并补充说这对我来说听起来很合理。

这解决了我的问题,我很高兴。

最新更新