0

我正在阅读其他一些帖子,但我似乎无法弄清楚为什么在下面使用 NSKeyedUnarchiver 保存到磁盘的对象总是将空行打印到控制台。我的最终目标是使用 NSKeyedArchiver 将单个用户对象存储到磁盘。

我目前正在学习如何使用 Firebase 来存储一些数据。我有一个代表用户的自定义类,如下所示:

class User: NSObject, NSCoding {
let key: String
let email: String
let familyKey: String
let username: String
let provider: String
let role: String



// Initialize from arbitrary data
init(key: String, email: String, fKey: String, uName:String, provider:String, role: String) {
    self.key = key
    self.email = email
    self.familyKey = fKey
    self.username = uName
    self.provider = provider
    self.role = role
    super.init()
}

required init?(coder aDecoder: NSCoder) {
    self.key = aDecoder.valueForKey("key") as! String
    self.email = aDecoder.valueForKey("email") as! String
    self.familyKey = aDecoder.valueForKey("familyKey") as! String
    self.username = aDecoder.valueForKey("username") as! String
    self.provider = aDecoder.valueForKey("provider") as! String
    self.role = aDecoder.valueForKey("role") as! String
}
func encodeWithCoder(aCoder: NSCoder) {
    aCoder.encodeObject(self.key, forKey: "key")
    aCoder.encodeObject(self.email, forKey: "email")
    aCoder.encodeObject(self.familyKey, forKey: "familyKey")
    aCoder.encodeObject(self.username, forKey: "username")
    aCoder.encodeObject(self.provider, forKey: "provider")
    aCoder.encodeObject(self.role, forKey: "role")
}

在我的注册视图控制器中,我创建用户并使用 Firebase 对用户进行身份验证,没有任何问题。在身份验证块中,我使用上面的第一个自定义初始化程序初始化用户对象。我已经尝试了以下方法来保存它,所以我相信我的问题在于我上面的代码与数据的编码/解码,因为这些都不起作用。

根据来自HackingWithSwift的此链接在本地存档文件。FBPath.shared.docDir 只是一个指向我的文档目录的 NSString 链接。

let userPath = FBPath.shared.docDir.stringByAppendingPathComponent("currentUser")
                    let userData = NSKeyedArchiver.archivedDataWithRootObject(newUser)
                    userData.writeToFile(userPath, atomically: true)

尝试使用

let userPath = FBPath.shared.docDir.stringByAppendingPathComponent("currentUser")
    if let user = NSKeyedUnarchiver.unarchiveObjectWithFile(userPath) as? User {
        print(user.username)
    }

这没有用,所以我尝试使用来自 Whasssaaahhh 的帖子将其存储到磁盘,这里是 Whasssaaahhh 的帖子。这是实际工作的代码,但存储了一个 emtpy 文件。

required convenience init?(coder aDecoder: NSCoder) {

    guard let aKey = aDecoder.decodeObjectForKey("userKey") as? String else {return nil}
    guard let anEmail = aDecoder.decodeObjectForKey("userEmail") as? String else {return nil}
    guard let aFamilyKey = aDecoder.decodeObjectForKey("usersFamilyKey") as? String else {return nil}
    guard let userName = aDecoder.decodeObjectForKey("username") as? String else {return nil}
    guard let aProvider = aDecoder.decodeObjectForKey("userProvider") as? String else {return nil}
    guard let aRole = aDecoder.decodeObjectForKey("userRole") as? String else {return nil}

    self.init(key: aKey, email: anEmail, fKey: aFamilyKey, uName:userName, provider:aProvider, role: aRole)
}

private class func getCurrentUserURL() -> NSURL {
    let documentsDirectory = NSFileManager().URLsForDirectory((.DocumentDirectory), inDomains: .UserDomainMask).first!
    let userPath = documentsDirectory.URLByAppendingPathComponent("currentUser")
    return userPath
}

class func saveCurrentUserToDisk(user:User){
    let success = NSKeyedArchiver.archiveRootObject(user, toFile: User.getCurrentUserURL().path!)
    if !success {
        print("failed to save user to disk")
    }
}
class func loadCurrentUserFromDisk() -> User?{
    return NSKeyedUnarchiver.unarchiveObjectWithFile(User.getCurrentUserURL().path!) as? User
}

在我注册的 VC 中将用户存储到磁盘:

let newUser = User(key: authData.uid, email: self.emailField.text!, fKey: newFamily.key, uName: self.usernameField.text!, provider: authData.provider, role: "parent")
                    newUser.createUserRecords()
                    User.saveCurrentUserToDisk(newUser)

然后尝试访问数据:

if let user = User.loadCurrentUserFromDisk() {
        print(user)
    }

见下文编辑这将打印一个空行。我不知道该怎么做才能将此用户保存到磁盘。基于此尝试,尝试将其保存在用户默认值中似乎不是一个好主意,并且它作为单个用户的数据集如此之小,无论如何将数据对象存储在磁盘上都不会受到伤害。只需要弄清楚为什么我不能让它工作。我还尝试将所有实例变量从 let 更新为 var 并将 "" 分配为字符串值。我希望第二双眼睛可以帮助我看到我在这里缺少的东西。提前致谢!

编辑:当我将实例变量更改为 vars 并将它们的值设置为空字符串时,现在该对象没有被返回,并且没有任何内容打印到控制台。如果我将它们改回来,那么即使我没有覆盖描述,用户也会向控制台打印一个空白行。如果我尝试打印实例变量,它也会再次打印一个空字符串。

所以我也决定检查位置。价值观都在那里。只是没有使用 NSKeyedUnarchiver 恢复它们。我打印了文件位置以验证它尝试访问正确的位置并且一切都很好。文档的 XML 在这里没有很好地显示。我是该网站的新手,我不相信我可以上传文件。但我查看了生成的 plist 及其所有内容。我离放弃这一点不远了,只是手动将数据存储到 plist 中。不确定与 NSKeyedArchiver 的好处和使用 NSCoding 相比会导致什么问题

4

1 回答 1

0

问题在于保护声明停止了未归档对象的初始化。如果无法按照迈克尔在上面的评论中建议的那样解码值,我从 guard 语句更改为 let 分配空字符串的语句。这帮助我找到了具有不正确键的值,因此我可以更新代码。现在一切都很好。

于 2016-02-15T18:42:02.870 回答