IOS 编辑器错误。归档数据重命名

Posted

技术标签:

【中文标题】IOS 编辑器错误。归档数据重命名【英文标题】:IOS editor bug. archivedData renamed 【发布时间】:2019-04-20 04:58:00 【问题描述】:

请帮帮我!我陷入了一个循环,找不到我的出路。我正在尝试学习 ios 编程以供工作,所以我想我会从他们的教程应用程序 Meal list 应用程序开始。我在你应该开始保存持久数据的部分,现在编辑器让我陷入了一个永无止境的循环。我有一行代码...

let isSuccessfulSave = NSKeyedArchiver.archiveRootObject(meals, toFile: Meal.ArchiveURL.path)

这给了我一个警告,上面写着......

'archiveRootObject(_:toFile:)' 在 iOS 12.0 中已弃用:使用 +archivedDataWithRootObject:requiringSecureCoding:error: 代替

好的,所以我将代码行更改为...

let isSuccessfulSave = NSKeyedArchiver.archivedDataWithRootObject(meals)

然后给我警告......

'archivedDataWithRootObject' 已重命名为 'archivedData(withRootObject:)'

好的,所以我将代码行更改为...

let isSuccessfulSave = NSKeyedArchiver.archivedData(withRootObject: meals)

这告诉我...

'archivedData(withRootObject:)' 在 iOS 12.0 中已弃用:使用 +archivedDataWithRootObject:requiringSecureCoding:error: 代替

好的...所以...archivedData 已被弃用,我必须使用archivedDataWithRootObject,但使用archivedDataWithRootObject 已重命名为archivedData,但archivedData 已弃用,因此请使用已重命名为archivedData 的archivedDataWithRootObject 已弃用......无限期.

我尝试查看开发人员文档,但他们只是告诉我同样的事情,一个已被弃用,没有链接或任何内容,搜索谷歌只会给我一堆页面,向我展示使用其中任何一个的语法。我对 IOS 编程还是很陌生,不知道如何摆脱这个无休止的循环,将 deprecated 重命名为 deprecated to...

请帮忙,我迷路了,不知道如何继续。谢谢。

【问题讨论】:

另一个要问的问题是为什么在 Swift 中使用 NSKeyedArchiver?为什么不使用基于 Codable 的现代 Swift API? 上面的 2 个 cmets 确实是垃圾,首先应该避免在代码中弃用,其次答案与问题的区域非常相关 @matt 所以你对一个全新的程序员的建议是忽略警告并且不提问?谢谢,这很有帮助。我不懂IOS编程。 我的意思是不要称它为错误,不要发泄。随便问问。 我理解并道歉,我只是不知道如何描述它。编辑器没有任何帮助,因为它只是循环发送给我,而且这些文档对一个全新的 IOS 开发人员非常没有帮助。我不太了解整个 :requireingSecureCoding:error: 整个事情的一部分,所以对于一个完整的新手来说,它就像一个错误,你会陷入循环。 【参考方案1】:

我正在关注the same example you are trying to do,我想出了如何在 iOS 12 中更新存储和检索值的方法,这应该对您有所帮助:

//MARK: Private Methods
private func saveMeals() 

    let fullPath = getDocumentsDirectory().appendingPathComponent("meals")

    do 
        let data = try NSKeyedArchiver.archivedData(withRootObject: meals, requiringSecureCoding: false)
        try data.write(to: fullPath)
        os_log("Meals successfully saved.", log: OSLog.default, type: .debug)
     catch 
        os_log("Failed to save meals...", log: OSLog.default, type: .error)
    


func getDocumentsDirectory() -> URL 
    let paths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
    return paths[0]


private func loadMeals() -> [Meal]? 
    let fullPath = getDocumentsDirectory().appendingPathComponent("meals")
    if let nsData = NSData(contentsOf: fullPath) 
        do 

            let data = Data(referencing:nsData)

            if let loadedMeals = try NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(data) as? Array<Meal> 
                return loadedMeals
            
         catch 
            print("Couldn't read file.")
            return nil
        
    
    return nil

另外你会发现你需要像这样更新 ViewDidLoad:

override func viewDidLoad() 
    super.viewDidLoad()

    // Use the edit button item provided by the table view controller.
    navigationItem.leftBarButtonItem = editButtonItem

    let savedMeals = loadMeals()

    if savedMeals?.count ?? 0 > 0 
        meals = savedMeals ?? [Meal]()
     else 
        loadSampleMeals()
    


我希望这会有所帮助,对我来说,该应用程序现在正在运行、存储和检索数据。

仅供参考:这不适用于 Xcode 11 测试版,而 iOS 13 应该适用于这些版本之前的任何东西。

【讨论】:

【参考方案2】:

iOS 12 的一般解决方案是:

class SettingsArchiver 
    static func setData(_ value: Any, key: String) 
        let ud = UserDefaults.standard
        let archivedPool = try? NSKeyedArchiver.archivedData(withRootObject: value, requiringSecureCoding: true)
        ud.set(archivedPool, forKey: key)
    

    static func getData<T>(key: String) -> T? 
        let ud = UserDefaults.standard
        if let val = ud.value(forKey: key) as? Data,
            let obj = try? NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(val) as? T 
            return obj
        
        return nil
    

【讨论】:

【参考方案3】:

你需要

try 
   let data = try NSKeyedArchiver.archivedData(withRootObject:meals,requiringSecureCoding:true)
   try data.write(to:fullPath)

catch 
   print(error)

这里是Docs IOS 11+

【讨论】:

教程应用程序中原始调用的“toFile”部分怎么样?现在都去同一个地方了吗?我必须将静态成员添加到我的 Meal 类... static let DocumentsDirectory = FileManager().urls(for: .documentDirecory, in: .userDomainMask).first! static let ArchiveURL = DocumentsDirectory.appendingPathComponent("meals") 是的,但它已被弃用 developer.apple.com/documentation/foundation/nskeyedarchiver/… ,您需要使用安全的答案并将返回的数据写入文件 所以我运行archivedData函数后还需要将数据写入文件吗?我不知道该怎么做。他们的教程显然已经过时,并告诉您使用应该自动写入文件的已弃用方法 检查我的答案好友。【参考方案4】:

我想说,直接解决您的问题的答案是使用在 Meal.swift 数据模型中定义的 ArchiveURL(想想 MVC 模式),并使用推荐的替换方法在 MealTableViewController.swift 控制器中重新实现 saveMeals() 函数以这种方式弃用 archiveRootObject 方法:

private func saveMeals()
    do 
        let data = try NSKeyedArchiver.archivedData(withRootObject: meals, requiringSecureCoding: true)
        try data.write(to: Meal.ArchiveURL)
    
    catch 
        print("Couldn't save to file")
    

虽然这个答案有点晚了 :-) 我希望它对遇到这个问题的人有所帮助。

【讨论】:

此外,您必须将“NSSecureCoding”添加到您的 Meal 类声明以及以下变量声明中:“static var supportsSecureCoding: Bool = true”

以上是关于IOS 编辑器错误。归档数据重命名的主要内容,如果未能解决你的问题,请参考以下文章

重命名存档工件的容器

删除分支后在 Github 中重命名/编辑标签?

iOS/iPadOS 中的 SwiftUI + DocumentGroup:如何重命名当前打开的文档

重命名 XCode 5.1 项目后出现编译器错误

数据库不能重命名报,5030的错误.

SpriteKit NSTimeInterval 重命名