मैं प्रोग्रामिंग में नया हूँ। मैंने पहले से ही एक 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)
}
}
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)
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)
}