2017-06-15 57 views
0

我想保存存儲使用UserDefaults一個自定義的文件,但我的應用crashesh由於有問題:與存儲非財產對象

fatal error: unexpectedly found nil while unwrapping an Optional value

這裏是我的代碼,在我的自定義類,我宣佈一個空數組

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 

    } 

任何幫助將是巨大的

編輯1: 我加NSCoding協議:

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

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

現在應用程序崩潰是由於這樣的:

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

+0

讀取數據存儲準則自定義對象。你試圖做的只是錯誤的。 – Desdenova

回答

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") 
    } 
} 
+0

我做了同樣的事情,使用'NSKeyedArchiver'存儲數據,並用'NSKeyedUnarchiver'加載它,你讀了我的代碼嗎? –

+0

@ Mc.Lover但是你的自定義對象沒有確認NSCoding協議 – Subramanian

+0

@ Mc.Lover我已經更新了我的答案,它是確認NSCoding協議的示例類 – Subramanian