IOS 编辑器错误。 archivedData 重命名

IOS editor bug. archivedData renamed

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

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

这给了我一个警告说...

'archiveRootObject(_:toFile:)' was deprecated in iOS 12.0: Use +archivedDataWithRootObject:requiringSecureCoding:error: instead

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

let isSuccessfulSave = NSKeyedArchiver.archivedDataWithRootObject(meals)

然后给我警告...

'archivedDataWithRootObject' has been renamed to 'archivedData(withRootObject:)'

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

let isSuccessfulSave = NSKeyedArchiver.archivedData(withRootObject: meals)

这告诉我...

'archivedData(withRootObject:)' was deprecated in iOS 12.0: Use +archivedDataWithRootObject:requiringSecureCoding:error: instead

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

我试过查看开发人员文档,但他们只是告诉我同样的事情,一个已被弃用,没有链接或任何东西,搜索 google 只是给了我一堆页面,向我展示了语法使用其中任何一个。我仍然是 IOS 编程的新手,不知道如何摆脱 deprecated to renamed to deprecated to...

这个无休止的循环

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

你需要

try {
   let data = try NSKeyedArchiver.archivedData(withRootObject:meals,requiringSecureCoding:true)
   try data.write(to:fullPath)
}
catch {
   print(error)
}

Docs这里是IOS11+

我正在关注 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 beta,而 iOS 13 应该适用于这些版本之前的任何版本。

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
    }
}

我会说,直接解决您的问题的答案是使用您的 Meal.swift 数据模型(想想 MVC 模式)中定义的 ArchiveURL 并在您的 [=18= 中重新实现 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")
    }
}

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