NSUserDefaults - यदि कोई कुंजी मौजूद है तो कैसे बताएं


208

मैं एक छोटे iPhone ऐप पर काम कर रहा हूं, और मैं NSUserDefaultsअपने डेटा दृढ़ता के रूप में उपयोग कर रहा हूं । इसमें केवल कुछ चीजों का ध्यान रखना होता है, जैसे कि कुछ नाम और कुछ संख्या ताकि मुझे लगता है कि मैं इसे सरल रख सकूं।

मुझे यह पृष्ठ कुछ संदर्भ के लिए मिला , लेकिन मुझे नहीं लगता कि यह मेरे प्रश्न का उत्तर दे सकता है। मूल रूप से, मैं यह जांचने में सक्षम होना चाहता हूं कि क्या कोई मान (या कुंजी) पहले से मौजूद है NSUserDefaultsऔर फिर उसके अनुसार कुछ किया जाए।

कुछ उदाहरण: एप्लिकेशन शुरू होता है, अगर यह पहली बार शुरू होता है तो यह एक चेतावनी का स्वागत करते हुए आउटपुट करता है। यह बताने के लिए कि क्या यह पहली बार खुला है, यह पढ़ता है UserDefaultsऔर जाँच करता है।

उदाहरण 2: यह कहता है, "नमस्ते [नाम]", जहां नाम कुछ ऐसा है जिसे आपने दर्ज किया है। यदि आपने ऐप खोला है और कोई नाम नहीं है, तो इसे "हैलो वर्ल्ड" कहना चाहिए। मुझे यह जांचने की आवश्यकता है कि क्या आपने पहले से ही एक नाम दर्ज किया है और उसके अनुसार कार्य करें। नाम में संग्रहीत किया जाएगा NSUserDefaults

कुछ यहाँ मदद? मैं वास्तव में इसकी सराहना करता हूँ!

जवाबों:


382

objectForKey:nilयदि यह मौजूद नहीं है तो वापस आ जाएगा ।


1
मुझे नहीं लगता कि आप NSUserDefaults में एक आदिम डेटा प्रकार संग्रहीत कर सकते हैं।
kender

12
Apple के डॉक्स का कहना है कि "यदि उपयोगकर्ता के डिफॉल्ट में बूलियन मान डिफ़ॉल्ट नाम से जुड़ा होता है, तो वह मान वापस कर दिया जाता है। अन्यथा, NO लौटाया नहीं जाता है।" मुझे नहीं लगता कि उपरोक्त उत्तर BOOLs के लिए सही है, आप यह निर्धारित नहीं कर सकते कि यह कोई परिभाषित नहीं है या मौजूद नहीं है। मुझे लगता है कि आपको – dictionaryRepresentationकुंजी का उपयोग और जांच करनी होगी ।
zekel

40
@ ज़ेकेल अनुमान लगाने के बजाय, मैंने इसे (आईओएस 5.1.1 पर) परीक्षण किया, और यह निश्चित रूप से पता चला कि एक बीओएल मौजूद था या नहीं, स्वतंत्र था कि बोओल का मूल्य क्या हो सकता है। "ऑब्जेक्टफ़ोरके" शून्य वापस आ गया जब BOOL मौजूद नहीं था क्योंकि यह कभी भी सेट नहीं किया गया था।
दाताग्राम

8
यदि आपके पास BOOL है और इसे boolForKey के साथ परीक्षण करते हैं, तो @zekel सही है, आपको YES या NOT मिल जाएगा। यदि आप इसे objectForKey (जैसे कि उत्तर का सुझाव देते हैं) के साथ परीक्षण करते हैं, तो आपको कुंजी सेट नहीं होने पर शून्य मिलता है।
Giuseppe Garassino

2
यह अब कम से कम iOS 6.1 सिम्युलेटर के रूप में काम नहीं करता है। यदि यह मौजूद नहीं है और यदि यह NO के BOOL के साथ मौजूद है, तो objectForKey समान मान लौटाता है। i.jameelkhan का समाधान काम करता है
lschult2

98

जैसा कि ऊपर उल्लेख किया गया है कि यह आदिम प्रकारों के लिए काम करेगा जहां 0 / NO एक वैध मूल्य हो सकता है। मैं इस कोड का उपयोग कर रहा हूं।

NSUserDefaults *defaults= [NSUserDefaults standardUserDefaults];
if([[[defaults dictionaryRepresentation] allKeys] containsObject:@"mykey"]){

    NSLog(@"mykey found");
}

इससे मैं बच गया। धन्यवाद!
बैलेस्ट्रापैट्रिक

आदिम लोगों के साथ व्यवहार करते समय यह सही उत्तर है BOOL। यह ठीक NOइसके विपरीत और सेट नहीं के बीच अंतर करेगा objectForKey:
देवियो 1

@ devios1 - यदि कुंजी गायब है, तो प्रोग्रामर के इरादे की परवाह किए बिना objectForKey:वापस लौट आएगा या किसी अन्य डेटा प्रकार को nilसंग्रहीत करेगा Bool। जब एक आदिम मौजूद होता है, तो कुंजी एक आदिम मान के साथ जुड़ी होने objectForKey:पर nilभी वापस नहीं आती है।
टेड हॉप

यह सही उत्तर है: जाहिर है, स्वीकृत उत्तर गलत है क्योंकि ऑब्जेक्टफॉरके 0 के साथ शून्य है, इसलिए यह काम नहीं कर सकता है। आईओएस 4.3 से 10.2.1 तक सफलतापूर्वक परीक्षण किया गया
क्राइसोट्रिबैक्स

मुझे पता है कि यह पुराना है, लेकिन केवल अब इस जानकारी की आवश्यकता होने पर, मुझे यह इंगित करने की आवश्यकता है कि ''OOOject:' 'संदर्भ का अर्थ बस यही है: वस्तु। चाबी नहीं है। IOW, आपकी हेडर फ़ाइल में यदि आपने परिभाषित किया है: #define kMyKey @ "myKey" में ''OOOject' 'kMyKey' की तलाश नहीं है, यह 'myKey' की तलाश में है। 'KMyKey' के प्रयोग से हमेशा 'NO' वापस आएगा।
बिल नॉर्मन

55

objectForKey:विधि वापस आ जाएगी nilअगर मूल्य मौजूद नहीं है। यहाँ एक सरल IF / THEN परीक्षण है जो आपको बताएगा कि मान शून्य है:

if([[NSUserDefaults standardUserDefaults] objectForKey:@"YOUR_KEY"] != nil) {
    ...
}

6

" ObjectForKey शून्य में वापस आ जाएगी यदि यह मौजूद नहीं है। " यह शून्य भी वापस आ जाएगा यदि यह मौजूद है और यह या तो एक पूर्णांक या बूलियन है जिसका मूल्य शून्य है (यानी बूलियन के लिए FALSE या NO)।

मैंने इसे 5.1 और 6.1 दोनों के लिए सिम्युलेटर में परीक्षण किया है। इसका मतलब है कि आप वास्तव में पूर्णांक या बूलियन के लिए परीक्षण नहीं कर सकते हैं जो "ऑब्जेक्ट" के लिए पूछकर सेट किया गया है। आप इसे पूर्णांक के लिए निकाल सकते हैं यदि आपको "सेट नहीं" मानने में कोई आपत्ति नहीं है जैसे कि यह "शून्य पर सेट" था।

जिन लोगों ने पहले से ही यह परीक्षण किया है, वे झूठे नकारात्मक पहलू से मूर्ख दिखाई देते हैं, अर्थात यह देखकर कि यदि ऑब्जेक्ट कुंजी सेट नहीं है, तो ऑब्जेक्ट को लौटाता है या नहीं, लेकिन यह नोटिस करने में असफल रहा कि यह शून्य हो गया है। सेट किया गया है लेकिन NO पर सेट किया गया है।

अपनी समस्या के लिए, जिसने मुझे यहां भेजा, मैंने बस अपने बूलियन के शब्दार्थ को बदलना समाप्त कर दिया, ताकि मेरा वांछित डिफ़ॉल्ट मूल्य के अनुरूप न हो। यदि यह विकल्प नहीं है, तो आपको बूलियन के अलावा किसी अन्य चीज़ के रूप में स्टोर करना होगा और यह सुनिश्चित करना होगा कि आप YES, NO, और "सेट नहीं" के बीच अंतर बता सकते हैं।


मैंने इसकी पुष्टि की है, लेकिन एक आसान उपाय है; बस नई वस्तु शाब्दिक या एक बॉक्सिंग अभिव्यक्ति का उपयोग करें। @0के बजाय 0, के @NOबजाय NO, या बस @(variable)उनके बारे में यहां पढ़ें।
काका

1
थोड़ा देर से, लेकिन न्यूबीक के लाभ के लिए: यह गलत है। ऑब्जेक्ट के लिए (forKey) 0 पर सेट पूर्णांकों के UserDefault मानों पर, और Bools को गलत पर सेट किया गया, सही ढंग से गैर-शून्य वापस आ जाएगा। यदि आप मान सेट करने के लिए बूल (forKey) का उपयोग करते हैं, तो आप समस्याओं में चल सकते हैं (क्योंकि यदि मान गलत पर सेट है, तो bool (forKey) 'गलत' वापस आएगा, भले ही आप 'सही' की उम्मीद कर रहे हों)
thecloud_of_unknowing

5

स्विफ्ट 3/4:

यहाँ Int / Double / Float / Bool key-value प्रकारों के लिए एक सरल एक्सटेंशन है जो UserDefaults के माध्यम से एक्सेस किए गए अन्य प्रकारों के वैकल्पिक-रिटर्न व्यवहार की नकल करता है।

( 30 अगस्त 2018 को संपादित करें: लियो के सुझाव से अधिक कुशल वाक्यविन्यास के साथ अद्यतन।)

extension UserDefaults {
    /// Convenience method to wrap the built-in .integer(forKey:) method in an optional returning nil if the key doesn't exist.
    func integerOptional(forKey: String) -> Int? {
        return self.object(forKey: forKey) as? Int
    }
    /// Convenience method to wrap the built-in .double(forKey:) method in an optional returning nil if the key doesn't exist.
    func doubleOptional(forKey: String) -> Double? {
        return self.object(forKey: forKey) as? Double
    }
    /// Convenience method to wrap the built-in .float(forKey:) method in an optional returning nil if the key doesn't exist.
    func floatOptional(forKey: String) -> Float? {
        return self.object(forKey: forKey) as? Float
    }
    /// Convenience method to wrap the built-in .bool(forKey:) method in an optional returning nil if the key doesn't exist.
    func boolOptional(forKey: String) -> Bool? {
        return self.object(forKey: forKey) as? Bool
    }
}

वे अब अन्य अंतर्निहित तरीकों (स्ट्रिंग, डेटा, आदि) के साथ अधिक सुसंगत हैं। पुराने के स्थान पर बस प्राप्त तरीकों का उपयोग करें।

let AppDefaults = UserDefaults.standard

// assuming the key "Test" does not exist...

// old:
print(AppDefaults.integer(forKey: "Test")) // == 0
// new:
print(AppDefaults.integerOptional(forKey: "Test")) // == nil

2
मैं return self.object(forKey: key) as? Intकेवल एक बार मूल्य खोजने के लिए प्राथमिकता दूंगा।
सिंह

3

मैं बस इसके माध्यम से चला गया, और आपके सभी जवाबों ने मेरे लिए, एक अच्छे समाधान की ओर मदद की। मैंने उसके द्वारा सुझाए मार्ग पर जाने का विरोध किया, सिर्फ इसलिए कि मुझे पढ़ना और समझना कठिन लगा।

यहाँ मैंने क्या किया है। मेरे पास एक BOOL था जिसे "_talkative" नामक एक चर में चारों ओर ले जाया जा रहा था।

जब मैंने अपना डिफ़ॉल्ट (NSUserDefaults) ऑब्जेक्ट सेट किया, तो मैंने इसे ऑब्जेक्ट के रूप में सेट किया , जैसा कि मैं यह देखने के लिए परीक्षण कर सकता था कि क्या यह शून्य था :

//converting BOOL to an object so we can check on nil
[defaults setObject:@(_talkative) forKey:@"talkative"];

फिर जब मैं यह देखने गया कि क्या यह अस्तित्व में है, तो मैंने उपयोग किया:

if ([defaults objectForKey:@"talkative"]!=nil )
  {

तब मैंने ऑब्जेक्ट को BOOL के रूप में उपयोग किया:

if ([defaults boolForKey:@"talkative"]) {
 ...

यह मेरे मामले में काम करता है। यह सिर्फ मेरे लिए अधिक दृश्य अर्थ बनाता है।


यह मेरे लिए काम किया ([चूक boolForKey: @ "बातूनी"]
Vineesh TP

3

इस छोटे crumpet का प्रयास करें:

-(void)saveUserSettings{
NSNumber*   value;

value = [NSNumber numberWithFloat:self.sensativity];
[[NSUserDefaults standardUserDefaults] setObject:value forKey:@"sensativity"];
}
-(void)loadUserSettings{
    NSNumber*   value;
    value = [[NSUserDefaults standardUserDefaults] objectForKey:@"sensativity"];
    if(value == nil){
        self.sensativity = 4.0;
    }else{
        self.sensativity = [value floatValue];
    }
}

एक वस्तु के रूप में सब कुछ समझो। लगता है मेरे लिए काम करता है।


3

पाने के लिए स्विफ्ट संस्करण Bool?

NSUserDefaults.standardUserDefaults().objectForKey(DefaultsIsGiver) as? Bool

1
उपयोग क्यों नहीं boolForKey? NSUserDefaults.standardUserDefaults().boolForKey(DefaultsIsGiver)
JAL

1
boolForKeyवापस आएँगे Boolऔर नहीं Bool?, तो अगर चाबी वहाँ नहीं है तो आपको मिलेगा falseऔर नहींnil
बेन

3

UserDefaultsइस समाधान को कॉपी-पेस्ट न करने के लिए एक बार बढ़ाएँ :

extension UserDefaults {

    func hasValue(forKey key: String) -> Bool {
        return nil != object(forKey: key)
    }
}

// Example
UserDefaults.standard.hasValue(forKey: "username")

0

स्विफ्ट 3 में, मैंने इस तरह से उपयोग किया है

var hasAddedGeofencesAtleastOnce: Bool {
    get {
        return UserDefaults.standard.object(forKey: "hasAddedGeofencesAtleastOnce") != nil
    }
}

जवाब महान आपको लगता है कि कई बार उपयोग करने के लिए कर रहे हैं है।

मुझे उम्मीद है यह मदद करेगा :)


-1

स्विफ्ट 3.0

if NSUserDefaults.standardUserDefaults().dictionaryRepresentation().contains({ $0.0 == "Your_Comparison_Key" }){
                    result = NSUserDefaults.standardUserDefaults().objectForKey(self.ticketDetail.ticket_id) as! String
                }
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.