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

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,因此添加这对我来说听起来很合理。

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

【讨论】:

以上是关于无法取消归档手表发送的文件的主要内容,如果未能解决你的问题,请参考以下文章

添加了一个自定义框架,现在 Swift 无法取消归档数据

如何存档手表套件应用程序?

苹果手表的企业版

Swift:从手表取消本地通知(安排在手机上)

WCSession 无法发送消息

将对象归档到只读文件