无法取消归档手表发送的文件
Posted
技术标签:
【中文标题】无法取消归档手表发送的文件【英文标题】:Can't unarchive a file sent by watch 【发布时间】:2021-10-21 21:43:35 【问题描述】:我有一个类,其中包含正在 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 上取消归档数据是可行的,所以这不是问题。也许文件发送有另一种格式,但我无法获得任何信息。
【问题讨论】:
【参考方案1】:我将问题作为 DTS 的票打开并得到以下答案:
罪魁祸首是您的 Model 类在不同的目标中具有不同的(完整)类名。 Swift 类有一个模块名称,默认情况下它与目标名称相关联。当你的 Model 类为你的 WatchKit 扩展编译时,它的全名是“TgetName_watchkit_extension.Model”;当它为您的 ios 应用程序编译时,它变为“TargetName.Model”。
当您的 WatchKit 扩展归档对象模型时,它使用“Target_watchkit_extension.Model”作为类名,您的 iOS 应用无法识别该类名,并触发失败。
您可以使用
@objc
为您的模型类指定一个全名,这样可以防止编译器添加模块名称,如下所示:@objc(Model) class Model: NSObject, NSCoding, ObservableObject
我实施了这个建议,它奏效了。但是,在我的 MacBook 上,我从预览中收到一条错误消息,指出我需要更改我的模型的一些方法,前缀为“@objc dynamic”。但是,这可能会发生,因为 Apple 的 DTS 没有收到此错误。
对这个问题的回应是:
KVO(键值观察)支持需要“@objc 动态”。由于“@Published”变量也依赖于 KVO,因此添加这对我来说听起来很合理。
这解决了我的问题,我很高兴。
【讨论】:
以上是关于无法取消归档手表发送的文件的主要内容,如果未能解决你的问题,请参考以下文章