gpt4 book ai didi

ios - 尝试归档符合 NSCoder 的类的实例

转载 作者:行者123 更新时间:2023-11-30 13:25:21 26 4
gpt4 key购买 nike

我正在开发我的第一个 Swift iOS 应用程序,在序列化和保存从服务器获取 JSON 的对象时遇到问题。我正在使用Gloss ,一个轻量级 JSON 解析库,它定义了一个 Decodable 协议(protocol),通过该协议(protocol)可以从 JSON 实例化实例。我的目的是从 JSON ([String : AnyObject] 的类型别名)加载一个东西,首先提取它的 id,然后检查我是否已经有本地存档复制。如果这样做,请取消存档并获取图像。如果没有,则对图像文件发出异步请求。

问题在于 Thing.localArchiveExists(id) 始终返回 false。事物已成功实例化,但它们总是重新获取图像。我检查了文件系统并确认没有写入存档文件。但是,我没有看到“错误。无法存档”,这表明保存成功。我是否缺少有关如何存档和保存 NSCoder 对象的信息?谢谢!

这是我对 Decodable 协议(protocol)的实现:

// MARK: Decodable protocol
// When a thing is loaded from JSON, we load its image from archive if possible.
required init?(json: JSON) {
guard let id: Int = "id" <~~ json else { return nil}

if Thing.localArchiveExists(id) {
guard let savedThing = NSKeyedUnarchiver.unarchiveObjectWithFile(Thing.archiveFilePath(id)) as? Thing else { return nil }
self.id = savedThing.id
self.name = savedThing.name
self.image = savedThing.image
self.imageUrl = savedThing.imageUrl
super.init()
print("Loaded Thing \(self.name) from archive")
}
else {
guard let name: String = "name" <~~ json else { return nil}
guard let imageUrl: NSURL = "url" <~~ json else { return nil}
self.id = id
self.name = name
self.imageUrl = imageUrl
super.init()
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)) {
let data = NSData(contentsOfURL: imageUrl)
dispatch_async(dispatch_get_main_queue(), {
self.image = UIImage(data: data!)
guard self.save() else {
print("ERROR. Could not archive")
return
}
print("Loaded Thing \(self.name) from server")
})
}
}
}

以下是 Thing 类的相关部分:

// MARK: Properties
var id: Int?
var name: String
var imageUrl: NSURL?
var image: UIImage?

// MARK: Archiving Paths
static let DocumentsDirectory = NSFileManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask).first!
static let ArchiveURL = DocumentsDirectory.URLByAppendingPathComponent("things")

// MARK: Types
struct PropertyKey {
static let nameKey = "name"
static let imageKey = "image"
static let imageUrlKey = "imageUrl"
static let idKey = "id"
}

// Returns the file URL at which a Thing with the given ID should be saved.
class func archiveFilePath(id: Int) -> String {
return Thing.ArchiveURL.URLByAppendingPathComponent("thing\(id)").absoluteString
}

// Checks whether an archived copy of a Thing with the given ID exists.
class func localArchiveExists(id: Int) -> Bool {
let fileManager = NSFileManager.defaultManager()
return fileManager.fileExistsAtPath(Thing.archiveFilePath(id))
}

// MARK: NSCoding
func encodeWithCoder(coder: NSCoder) {
coder.encodeObject(name, forKey: PropertyKey.nameKey)
if image != nil {
coder.encodeObject(image!, forKey: PropertyKey.imageKey)
}
if imageUrl != nil {
coder.encodeObject(imageUrl!, forKey: PropertyKey.imageUrlKey)
}
coder.encodeInteger(id!, forKey: PropertyKey.idKey)
}

required convenience init?(coder aDecoder: NSCoder) {
let name = aDecoder.decodeObjectForKey(PropertyKey.nameKey) as! String
let image = aDecoder.decodeObjectForKey(PropertyKey.imageKey) as? UIImage
let imageUrl = aDecoder.decodeObjectForKey(PropertyKey.imageUrlKey) as? NSURL
let id = aDecoder.decodeIntegerForKey(PropertyKey.idKey)

// Must call designated initializer.
self.init(name: name, image: image, imageUrl: imageUrl, id: id)
}

func save() -> Bool {
// For some reason I can't archive to file.
return NSKeyedArchiver.archiveRootObject(self, toFile: Thing.archiveFilePath(self.id!))
}

最佳答案

我发现了我的问题:保存失败,因为我还没有创建我试图保存我的东西的目录。

func save() -> Bool {        
let archivedData = NSKeyedArchiver.archivedDataWithRootObject(self)
do {
try NSFileManager.defaultManager().createDirectoryAtURL(Thing.ArchiveURL, withIntermediateDirectories: true, attributes: [:])
try archivedData.writeToFile(Thing.archiveFilePath(self.id!), options: [])
return true
} catch {
print(error)
return false
}
}

关于ios - 尝试归档符合 NSCoder 的类的实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37283046/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com