2017-10-18 109 views
-2

如何保存我的結構與NSCoding,以便它不會改變,即使用戶 關閉應用程序?我將不勝感激,如果你也可以告訴我如何正確實施缺少的代碼。如何用NSCoding保存結構

更新與以下兩個新的功能: 這裏是我的代碼:

struct RandomItems: Codable 
{ 
    var items : [String] 
    var seen = 0 

    init(items:[String], seen: Int) 
    { 
     self.items = items 
     self.seen = seen 
    } 

    init(_ items:[String]) 
    { self.init(items: items, seen: 0) } 


    mutating func next() -> String 
    { 
     let index = Int(arc4random_uniform(UInt32(items.count - seen))) 
     let item = items.remove(at:index) 
     items.append(item) 
     seen = (seen + 1) % items.count 
     return item 
    } 
    func toPropertyList() -> [String: Any] { 
     return [ 
      "items": items, 
      "seen": seen 
     ] 
    } 


    } 





override func viewWillDisappear(_ animated: Bool) { 
    UserDefaults.standard.set(try? PropertyListEncoder().encode(quotes), forKey:"quote2") 
} 

override func viewDidAppear(_ animated: Bool) { 
    if let data = UserDefaults.standard.value(forKey:"quote2") as? Data { 
     let quote3 = try? PropertyListDecoder().decode(Array<RandomItems>.self, from: data) 
    } 

} 




    } 


extension QuotesViewController.RandomItems { 
init?(propertyList: [String: Any]) { 
    return nil 
} 

} 

我怎樣才能確保整個陣列在此範圍內?

+0

你需要把它變成一個類。您還需要子類化NSObject並使其符合NSCoding –

+2

可能的重複[使用Swift將類中的結構保存到NSUserDefaults中](https://stackoverflow.com/questions/25546716/save-struct-in-class-to- nsuserdefaults-using-swift) – TNguyen

回答

2

對於結構體,您應該使用新的Codable協議。從swift 4開始可用,並且強烈推薦。

struct RandomItems: Codable 
{ 
    var items: [String] 
    var seen = 0 
} 

extension RandomItems { 
    init?(propertyList: [String: Any]) { 
      ... 
    } 
} 

// Example usage 
let a = RandomItems(items: ["hello"], seen: 2) 
let data: Data = try! JSONEncoder().encode(a) 
UserDefaults.standard.set(data, forKey: "MyKey") // Save data to disk 
// some time passes 
let data2: Data = UserDefaults.standard.data(forKey: "MyKey")! // fetch data from disk 
let b = try! JSONDecoder().decode(RandomItems.self, from: data2) 

更新

它看起來像原來的海報被嵌套另一個類的內部結構。這裏是結構嵌套的另一個例子。

class QuotesViewController: UIViewController { 

    struct RandomItems: Codable 
    { 
     var items: [String] 
     var seen = 0 
    } 
} 

extension QuotesViewController.RandomItems { 
    init(_ items:[String]) 
     { self.items = items } 

    init?(propertyList: [String: Any]) { 
     guard let items = propertyList["items"] as? [String] else { return nil } 
     guard let seen = propertyList["seen"] as? Int else { return nil } 
     self.items = items 
     self.seen = seen 
    } 
} 

// example usage 
let a = QuotesViewController.RandomItems(items: ["hello"], seen: 2) 
let data: Data = try! JSONEncoder().encode(a) 
UserDefaults.standard.set(data, forKey: "MyKey") // Save data to disk 
// some time passes 
let data2: Data = UserDefaults.standard.data(forKey: "MyKey")! // fetch data from disk 
let b = try! JSONDecoder().decode(QuotesViewController.RandomItems.self, from: data2) 
+0

我到底需要在變量聲明中插入三行? @ Calimari328 –

+0

@JoyLucas我不知道我理解你的問題。你能改述一下嗎? – DerrickHo328

+0

let a = .... //錯誤:無法使用類型'(items:[String],看到:Int)的參數列表類型'QuotesViewController.RandomItems'調用初始化程序'@ Calimari328我該如何解決這個問題? –