使用NSKeyedArchiver archivedData将数据写入路径为的文件会引发Swift 4.2的无法识别选择



我正试图使用NSKeyedArchiver将Codable写入磁盘。

我能找到的关于这个主题的所有问题都使用了不推荐的方法。我找不到任何使用Swift 4语法的SO问题或教程。

我得到错误

-[_SwiftValue encodeWithCoder:]: unrecognized selector sent to instance 

我猜是UsersSession类中的try writeData.write(to: fullPath)行。

在Swift 4.2中,向文件写入数据的正确方法是什么

struct UserObject {
var name : String?
}
extension UserObject  : Codable {
enum CodingKeys : String, CodingKey {
case name
}
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
name = try container.decode(String.self, forKey: .name)
}
func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(name, forKey: .name)
}
}

UserSession.swift

class UserSession {
static let shared = UserSession()
let fileName = "userdata.dat"
var user : UserObject?
lazy var fullPath : URL =  {
return getDocumentsDirectory().appendingPathComponent(fileName)
}()
private init(){
print("FullPath: (fullPath)")
user = UserObject()
load()
}
func save(){
guard let u = user else { print("invalid user data to save"); return}
do {
let writeData = try NSKeyedArchiver.archivedData(withRootObject: u, requiringSecureCoding: false)
try writeData.write(to: fullPath)
} catch {
print("Couldn't write user data file")
}
}
func load() {
guard  let data = try? Data(contentsOf: fullPath, options: []) else {
print("No data found at location")
save()
return
}
guard  let loadedUser = try? NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(data) as? UserObject else {
print("Couldn't read user data file.");
return
}
user = loadedUser
}
func getDocumentsDirectory() -> URL {
return FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
}
}

由于您使用的是Codable,因此应该首先对Data进行编码,然后对Data进行归档。这是代码:

func save(){
guard let u = user else { print("invalid user data to save"); return}
do {
// Encode to Data
let jsonData = try JSONEncoder().encode(u)
let writeData = try NSKeyedArchiver.archivedData(withRootObject: jsonData, requiringSecureCoding: false)
try writeData.write(to: fullPath)
} catch {
print("Couldn't write user data file")
}
}
func load() {
guard  let data = try? Data(contentsOf: fullPath, options: []) else {
print("No data found at location")
save()
return
}
guard  let loadedUserData = try? NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(data) as? Data else {
print("Couldn't read user data file.");
return
}
// Decode Data
user = try? JSONDecoder().decode(UserObject.self, from: loadedUserData)
}

最新更新