Having Issue with store non property object

时间:2017-06-15 10:29:52

标签: ios arrays iphone swift xcode

I am trying to save store a custom file using UserDefaults, but my app crashesh due to :

fatal error: unexpectedly found nil while unwrapping an Optional value

Here is my code , in my custom class I declare an empty array

class AppDefualts: NSObject {

    var downloadedURLArray = [DownloadFile]() //Declare an empty array


    override init() {
        super.init()


        downloadedURLArray = loadStoredURL()
     }


//Store data
func addStored(file:DownloadFile) {

    //Add URL to array and save it
    downloadedURLArray.append(file)

    let data = NSKeyedArchiver.archivedData(withRootObject: downloadedURLArray)
    UserDefaults.standard.set(data, forKey: "storedURL")
}

 //Load:
    func loadStoredURL() -> Array<DownloadFile> {

        let data = UserDefaults.standard.data(forKey: "storedURL")
        downloadedURLArray = NSKeyedUnarchiver.unarchiveObject(with: data!) as? [DownloadFile] ?? [DownloadFile]()
        return downloadedURLArray

    }

Any help would be great

EDIT 1 : I added NSCoding protocols :

func encode(with aCoder: NSCoder) {
    aCoder.encode(downloadedURLArray, forKey: "storedURL")
}

required init?(coder aDecoder: NSCoder) {
    downloadedURLArray = aDecoder.decodeObject(forKey: "storedURL") as! [DownloadFile]
}

now app crashes due to this :

* Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '* -encodeObject:forKey: cannot be sent to an abstract object of class NSCoder: Create a concrete instance!'

1 个答案:

答案 0 :(得分:0)

如果要将自定义对象存储在UserDefault中,则必须执行编码/解码。您的自定义对象假设要确认NSCoding协议。

存储到UserDefault:您必须将对象转换为NSData并使用UserDefault将其存储到NSKeyedArchiver

从UserDefault获取:从USerDefault获取NSData并使用NSKeyedUnArchiver转换为自定义对象

请参阅convert custom object into NSData and vice versa

的链接

示例:确认NSCoding协议的自定义对象

class Book: NSObject, NSCoding {
    var title: String
    var author: String
    var pageCount: Int
    var categories: [String]
    var available: Bool

    // Memberwise initializer
    init(title: String, author: String, pageCount: Int, categories: [String], available: Bool) {
        self.title = title
        self.author = author
        self.pageCount = pageCount
        self.categories = categories
        self.available = available
    }

    // MARK: NSCoding

    required convenience init?(coder decoder: NSCoder) {
        guard let title = decoder.decodeObjectForKey("title") as? String,
            let author = decoder.decodeObjectForKey("author") as? String,
            let categories = decoder.decodeObjectForKey("categories") as? [String]
            else { return nil }

        self.init(
            title: title,
            author: author,
            pageCount: decoder.decodeIntegerForKey("pageCount"),
            categories: categories,
            available: decoder.decodeBoolForKey("available")
        )
    }

    func encodeWithCoder(coder: NSCoder) {
        coder.encodeObject(self.title, forKey: "title")
        coder.encodeObject(self.author, forKey: "author")
        coder.encodeInt(Int32(self.pageCount), forKey: "pageCount")
        coder.encodeObject(self.categories, forKey: "categories")
        coder.encodeBool(self.available, forKey: "available")
    }
}