2015-01-12 6 views
6

में एक tuple सहेजें मैं इस तरह कुछ स्टोर करने के लिए एक tuple का उपयोग कर रहा हूँ।NSUserDefaults

var accessLavels: (hasInventoryAccess: Bool, hasPayrolAccess: Bool) 
accessLavels = (hasInventoryAccess: true, hasPayrolAccess: false) 

अब मैं इसे NSUserDefaults में सहेजना चाहता हूं।

NSUserDefaults.standardUserDefaults().setValue(accessLavels, forKey: "AccessLevelKey") 
NSUserDefaults.standardUserDefaults().synchronize() 

लेकिन मुझे निम्न त्रुटि मिलती है।

प्रकार '(hasInventoryAccess: बूल, hasPayrolAccess: बूल)' प्रोटोकॉल के अनुरूप नहीं है 'AnyObject'

मैं कैसे इस समस्या को हल कर सकते हैं? यदि यह असंभव है, तो टुपल को बचाने के लिए कोई अन्य सुझाव स्वागत है।

धन्यवाद।

+0

होगा (मैं स्विफ्ट और प्रोग्रामिंग पूरी तरह करने के लिए काफी नई हूँ) , 'NSUserDefaults' पर 'सिंक्रनाइज़' को कॉल करना लगभग कभी जरूरी नहीं है और इसे" बस मामले में "ऐप्पल द्वारा अनुशंसित नहीं किया जाता है। –

+0

NSUserDefaults केवल संपत्ति सूची प्रकारों का समर्थन करता है: एनएसडीटा, एनएसएसटींग, एनएसएनंबर, एनएसडीएटी, एनएसएआरआरई, या एनएस डिक्शनरी। यदि आप किसी अन्य प्रकार की ऑब्जेक्ट को स्टोर करना चाहते हैं, तो आप NSData का उदाहरण बनाने के लिए इसे संग्रहीत कर सकते हैं। – Bobby

उत्तर

7

मैं एक ऐसी ही सामना करना पड़ा परिदृश्य NSCoder के साथ एक tuple एन्कोड करने की कोशिश कर रहा है। जिस तरह से मैं इसे हल कर रहा हूं वह मैन्युअल रूप से ट्यूपल को Dictionary में परिवर्तित कर रहा है। यह एक अच्छा समाधान नहीं है क्योंकि कई जगहों पर कुंजियों को बदलने की जरूरत है यदि टुपल कभी बदलता है।

मेरे पास मेरे ट्यूपल में घोंसला वाला enum था और इसे एक मूल प्रकार (स्ट्रिंग) दिया जिससे मैंने कच्चे मूल्य को परिवर्तित किया। यह थोड़ा अतिरिक्त काम था लेकिन शुक्र है कि आपका केवल प्राइमेटिव है।

# SerializeableTuple.swift 

typealias AccessTuple = (hasInventoryAccess: Bool, hasPayrolAccess: Bool) 
typealias AccessDictionary = [String: Bool] 

let InventoryKey = "hasInventoryAccess" 
let PayrollKey = "hasPayrollAccess" 

func serializeTuple(tuple: AccessTuple) -> AccessDictionary { 
    return [ 
     InventoryKey : tuple.hasInventoryAccess, 
     PayrollKey : tuple.hasPayrolAccess 
    ] 
} 

func deserializeDictionary(dictionary: AccessDictionary) -> AccessTuple { 
    return AccessTuple(
     dictionary[InventoryKey] as Bool!, 
     dictionary[PayrollKey] as Bool! 
    ) 
} 

# Encoding/Decoding 

var accessLavels: AccessTuple = (hasInventoryAccess: true, hasPayrolAccess: false) 

// Writing to defaults 
let accessLevelDictionary = serializeTuple(accessLavels) 
NSUserDefaults.standardUserDefaults().setObject(accessLevelDictionary, forKey: "AccessLevelKey") 

// Reading from defaults 
let accessDic = NSUserDefaults.standardUserDefaults().dictionaryForKey("AccessLevelKey") as AccessDictionary 
let accessLev = deserializeDictionary(accessDic) 
+1

साफ चाल! यह अच्छा काम करता है। हालांकि मुझे कास्टिंग जैसे कुछ मामूली बदलाव करना पड़ा और मुझे लगता है कि आपको 'accessDictionary' में' deserializeDictionary() 'विधि में पास करना होगा। मैंने परिवर्तनों को दर्शाने के लिए अपना कोड अपडेट किया। उम्मीद है कि ठीक है। वैसे भी अजीब समाधान के लिए धन्यवाद। मुझे आशा है कि ऐप्पल स्विफ्ट के आने वाले संस्करणों में इसके लिए समर्थन लाएगा। – Isuru

+0

वैसे, क्या 'NSVserDefaults' से मूल्यों को सहेजने और पुनर्प्राप्त करने में 'objectForKey' के बजाय' setValue' और 'dictionaryForKey'' के बजाय 'setObject' का उपयोग करने का कोई विशिष्ट कारण है? – Isuru

+1

@LucasHuang नोट्स 'setValue' 'NSKeyValueCoding' से है। 'setValue'' id'/'AnyObject' को इसके प्रकार के रूप में उपयोग करता है और इसलिए उपलब्ध संकलन समय पर अधिक प्रकार की सुरक्षा प्रदान नहीं करता है। शब्दकोश एक वर्ग है (और शब्दकोश का एक उदाहरण एक वस्तु है) और यह सबसे उपयुक्त प्रकार-विधियों है। आप * डेटाफोरकी विधियों का उपयोग कर सकते हैं और शब्दकोश को एनएसडीटा से/में कनवर्ट कर सकते हैं लेकिन यह केवल अतिरिक्त काम है। – JoePasq

0

प्रलेखन में, मुझे कोई विधि -setValue दिखाई नहीं दे रही है। दस्तावेज़ों के आधार पर, NSUserDefaults केवल एनएसएसटींग, एनएसएनंबर, एनएसडीटा, एनएस डिक्शनरी, एनएसएआरएआरई, एनएसडीटा और एनएसडीएट को बचाने में सक्षम है। यहां लिंक है: NSUserDefaults Class Reference.

तो, आप यहां ट्यूपल को सहेजने में सक्षम नहीं हैं। और -setValueNSKeyValueCoding प्रोटोकॉल से है।

0

आप बूल, फ्लोट, इंट, ऑब्जेक्ट, डबल या यूआरएल स्टोर कर सकते हैं लेकिन टुपल नहीं। तो तुम दो विकल्प, दो केवल hasPayrolAccess और hasPayrolAccess बूल मूल्यों सहेजना:

NSUserDefaults.standardUserDefaults().setBool(true, forKey: "hasInventoryAccess") 
NSUserDefaults.standardUserDefaults().setBool(false, forKey: "hasPayrolAccess") 
let hasInventoryAccess = NSUserDefaults.standardUserDefaults().boolForKey("hasInventoryAccess") 
println(hasInventoryAccess) 

let hasPayrolAccess = NSUserDefaults.standardUserDefaults().boolForKey("hasPayrolAccess") 
println(hasPayrolAccess) 

या बूल के एक सरणी का उपयोग कर सहेजें:

var accessLavels = [true,false] 
println(accessLavels) 
NSUserDefaults.standardUserDefaults().setValue(accessLavels, forKey: "accessLavels") 
if let loadAccessLavels = NSUserDefaults.standardUserDefaults().arrayForKey("accessLavels") as? [Bool] { 
    if let hasInventoryAccess = loadAccessLavels.first { 
     println(hasInventoryAccess) 
    } 
    if let hasPayrolAccess = loadAccessLavels.last { 
     println(hasPayrolAccess) 
    } 
} 
+0

दो अलग-अलग बूल के रूप में संग्रहित करता है लेकिन ट्यूपल्स की शक्ति का लाभ नहीं उठाता है और डेटा को अलग करता है। सरणी के रूप में संग्रह करना थोड़ा बेहतर होता है क्योंकि केवल एक ही वस्तु संग्रहित होती है, लेकिन चाबियों के कारण शब्दकोश अधिक स्पष्ट होते हैं (विशेष रूप से मनमानी tuples के लिए)। – JoePasq

1

मैं 3 मूल्यों के साथ एक टपल था।

निम्नलिखित कोड का उपयोग टुपल को बचाने के लिए किया गया था। असल में, मैंने tuple से एक स्ट्रिंग बनाई (घटक को अल्पविराम से अलग किया गया)।

let defaultsLoad = NSUserDefaults.standardUserDefaults() 
if appSingleton.runwayDestShared != nil 
{ 
    // Creating a String from the tuple 
    let runwayDestString = appSingleton.runwayDestShared!.0 + "," + appSingleton.runwayDestShared!.1 + "," + appSingleton.runwayDestShared!.2 
    defaultsLoad.setObject(runwayDestString, forKey: "RunwayDest") 
} 

टपल को पुनः प्राप्त करने के लिए, मैं स्ट्रिंग लिया गया, सरणी में इसे तोड़ दिया और सारणी का प्रयोग किया एक टपल फिर से बनाने के लिए।

let accesLvl : [String:AnyObject] = ["hasInventoryAcces":true, "hasPayrolAccess":false] 
NSUserDefaults.standardUserDefaults().setObject(accesLvl, forKey: "accesLevel") 

मामले में आप केवल bools बचाने के लिए, let accesLvl : [String:Bool] एक बेहतर विकल्प है:

let runwayDestString = defaultsLoad.stringForKey("RunwayDest") 
if let runwayDestString = runwayDestString 
{ 
    let runwayDestArray = runwayDestString.componentsSeparatedByString(",") 
    appSingleton.runwayDestShared = (runwayDestArray[0],runwayDestArray[1],runwayDestArray[2]) 
} 
0
एक साल का सवाल है लेकिन अभी भी I'ts

मामले में मैं कुछ भी नहीं मिलता है, ठीक वैसे ही शब्दकोश में एक "टपल" का उपयोग कर के लाभ के लिए, या एक अलग रूप में के रूप में भी एक struct

+0

टुपल बनाना और उपयोग करना आसान है। कोई और चाबियाँ नहीं – Glenn

संबंधित मुद्दे