मैं प्रोग्रामिंग में नया हूँ। मैंने पहले से ही एक Codable प्रकार बनाया है, लेकिन मुझे नहीं पता कि मुझे viewWillDisappear फ़ंक्शन में क्या रखना है जहां संरचना को UserDefaults में सहेजा जाना चाहिए और मुझे इसमें क्या डालना है फ़ंक्शन viewDidAppear जहां सहेजी गई संरचना को फिर से प्रस्तुत किया जाना चाहिए।

यह मेरा अब तक का कोड है:

import UIKit



class QuotesViewController: UIViewController {

var randomItems: RandomItems?


var quotes: RandomItems! = RandomItems([

   "Andre",
   "James",
   "Max",
   "Stephen",
   "Sarah",
   "Jeff",
   "Paul",
   "Mary",
                          ])




}

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 viewDidLoad() {
    let defaults = UserDefaults.standard
    defaults.set(codable: quotes, forKey: "quotes")
}

override func viewDidAppear(_ animated: Bool) {
    // Code to load the struct again after the view appears.
    let defaults = UserDefaults.standard
    quotes = defaults.codable(RandomItems.self, forKey: "quotes") ?? 
RandomItems([])
}

override func viewWillDisappear(_ animated: Bool) {
    // Code to save struct before the view disappears.
    let defaults = UserDefaults.standard
    if let quotes = quotes {
        defaults.set(codable: quotes, forKey: "quotes")
    }
}
}

extension UserDefaults {

func set<T: Encodable>(codable: T, forKey key: String) {
    let encoder = JSONEncoder()
    do {
        let data = try encoder.encode(codable)
        let jsonString = String(data: data, encoding: .utf8)!
        print("Saving \"\(key)\": \(jsonString)")
        self.set(jsonString, forKey: key)
    } catch {
        print("Saving \"\(key)\" failed: \(error)")
    }
}

func codable<T: Decodable>(_ codable: T.Type, forKey key: String) -> T? {
    guard let jsonString = self.string(forKey: key) else { return nil }
    guard let data = jsonString.data(using: .utf8) else { return nil }
    let decoder = JSONDecoder()
    print("Loading \"\(key)\": \(jsonString)")
    return try? decoder.decode(codable, from: data)
}
}
1
Joy Lucas 22 अक्टूबर 2017, 13:51

2 जवाब

सबसे बढ़िया उत्तर

इसे डिज़ाइन करने का एक अच्छा तरीका सहायक विधियों की एक जोड़ी के साथ विस्तार UserDefaults करना है:

extension UserDefaults {

    func set<T: Encodable>(codable: T, forKey key: String) {
        let encoder = JSONEncoder()
        do {
            let data = try encoder.encode(codable)
            let jsonString = String(data: data, encoding: .utf8)!
            print("Saving \"\(key)\": \(jsonString)")
            self.set(jsonString, forKey: key)
        } catch {
            print("Saving \"\(key)\" failed: \(error)")
        }
    }

    func codable<T: Decodable>(_ codable: T.Type, forKey key: String) -> T? {
        guard let jsonString = self.string(forKey: key) else { return nil }
        guard let data = jsonString.data(using: .utf8) else { return nil }
        let decoder = JSONDecoder()
        print("Loading \"\(key)\": \(jsonString)")
        return try? decoder.decode(codable, from: data)
    }
}

फिर इसे QuotesViewController में इस तरह इस्तेमाल करें:

class QuotesViewController: UIViewController {

    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)
        }
    }

    var quotes: RandomItems! = RandomItems([
        "James",
        "John",
        "William",
    ])

    override func viewDidAppear(_ animated: Bool) {
        // Code to load the struct again after the view appears.
        let defaults = UserDefaults.standard
        quotes = defaults.codable(RandomItems.self, forKey: "quotes")
    }

    override func viewWillDisappear(_ animated: Bool) {
        // Code to save struct before the view disappears.
        let defaults = UserDefaults.standard
        if let quotes = quotes {
            defaults.set(codable: quotes, forKey: "quotes")
        }
    }
}

उपरोक्त दृश्य नियंत्रक प्रिंट दर्ज करना (और बाहर निकलना):

"उद्धरण" सहेजा जा रहा है: {"आइटम": ["जेम्स", "जॉन", "विलियम"], "देखा": 0}
लोड हो रहा है "उद्धरण": {"आइटम": ["जेम्स", "जॉन", "विलियम"], "देखा": 0}


अपडेट करें। इसके लायक क्या है, नीचे पूर्ण कोड है जिसका उपयोग मैंने Xcode 9 खेल के मैदान में इसका परीक्षण करने के लिए किया था:

import Foundation

extension UserDefaults {

    func set<T: Encodable>(codable: T, forKey key: String) {
        let encoder = JSONEncoder()
        do {
            let data = try encoder.encode(codable)
            let jsonString = String(data: data, encoding: .utf8)!
            print("Saving \"\(key)\": \(jsonString)")
            self.set(jsonString, forKey: key)
        } catch {
            print("Saving \"\(key)\" failed: \(error)")
        }
    }

    func codable<T: Decodable>(_ codable: T.Type, forKey key: String) -> T? {
        guard let jsonString = self.string(forKey: key) else { return nil }
        guard let data = jsonString.data(using: .utf8) else { return nil }
        let decoder = JSONDecoder()
        print("Loading \"\(key)\": \(jsonString)")
        return try? decoder.decode(codable, from: data)
    }
}

class UIViewController: NSObject {
    func viewDidAppear(_ animated: Bool) { }
    func viewWillDisappear(_ animated: Bool) { }
}

class QuotesViewController: UIViewController {

    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)
        }
    }

    var quotes: RandomItems! = RandomItems([
        "James",
        "John",
        "William",
        "Mary",
        "Sarah",
        "Michael",
        "Steve",
        "Lisa",
        "Jeff",
        "Chris",
        ])

    override func viewDidAppear(_ animated: Bool) {
        // Code to load the struct again after the view appears.
        let defaults = UserDefaults.standard
        quotes = defaults.codable(RandomItems.self, forKey: "quotes")
    }

    override func viewWillDisappear(_ animated: Bool) {
        // Code to save struct before the view disappears.
        let defaults = UserDefaults.standard
        if let quotes = quotes {
            defaults.set(codable: quotes, forKey: "quotes")
        }
    }
}

let vc = QuotesViewController()

vc.viewWillDisappear(false)
vc.quotes = nil

vc.viewDidAppear(true)
print(vc.quotes)
1
Paulo Mattos 23 अक्टूबर 2017, 21:15

RandomItems के लिए अपने मान रखने के लिए अपने ViewController में एक संपत्ति/चर बनाएं

var randomItems: RandomItems?

ViewWillDisappear विधि में, डेटा को अपनी कुंजी के साथ UserDefaults में सहेजें।

if let propertyList = self.randomItems?.toPropertyList() {
   UserDefaults.standard.setValue(propertyList, forKey: "MyItems")
}

ViewWillAppear विधि में, UserDefaults से डेटा प्राप्त करें और इसे अपने वेरिएबल को असाइन करें

if let propertyList = UserDefaults.standard.dictionary(forKey: "MyItems") {
   self.randomItems = RandomItems(propertyList: propertyList)
} 
0
Rikesh Subedi 22 अक्टूबर 2017, 14:49