NSUserDefaults-キーが存在するかどうかを確認する方法


208

私は小さなiPhoneアプリで作業してNSUserDefaultsおり、データの永続化として使用しています。名前や番号など、いくつかのことを追跡するだけでよいので、単純にしておくとよいでしょう。

参照用にこのページを見つけましたが、私の質問には答えられないと思います。基本的に、値(またはキー)が既にに存在するかどうかを確認しNSUserDefaults、それに応じて何かを実行できるようにしたいと考えています。

いくつかの例:アプリが起動します。初めて起動する場合は、「ようこそ」という警告が出力されます。これが初めて開いたかどうかを知るために、UserDefaultsを読み取ってチェックします。

例2:「Hello [Name]」と表示されます。ここで、Nameは入力したものです。アプリを開いたときに名前がない場合は、「Hello World」と表示されます。名前をすでに入力しているかどうかを確認し、それに応じて行動する必要があります。名前はに保存されNSUserDefaultsます。

ここで助けますか?本当にありがたいです!

回答:


381

objectForKey:nil存在しない場合は戻ります。


1
NSUserDefaultsにプリミティブデータタイプを格納できないと思います。
ケンダー、2011年

12
Appleのドキュメントによれば、「ブール値がユーザーデフォルトのdefaultNameに関連付けられている場合、その値が返されます。それ以外の場合は、NOが返されます。」上記の答えがBOOLに対して正しいとは思いません。NOと定義されているか、存在しないかを判断できません。– dictionaryRepresentationキーを使用して確認する必要があると思います。
ゼケル

40
@zekel推測するのではなく、これをテストし(iOS 5.1.1で)、BOOLが存在するかどうかを、そのBOOLの値に関係なく確実に検出しました。「objectForKey」は、BOOLが設定されたことがないためにBOOLが存在しない場合、nilを返しました。
DataGraham 2012

8
BOOLがあり、それをboolForKeyでテストすると、@ zekelが正しいので、YESまたはNOTになります。(答えが示すように)objectForKeyでテストすると、キーが設定されていない場合はnilになります。
Giuseppe Garassino 2013

2
これは、少なくともiOS 6.1シミュレータでは機能しません。objectForKeyは、存在しない場合、およびBOOLがNOで存在する場合、同じ値を返します。i.jameelkhanのソリューションは機能します
lschult2 2013

98

上記のように、0 / NOが有効な値である可能性があるプリミティブ型では機能しません。このコードを使用しています。

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

    NSLog(@"mykey found");
}

これは私を救った。ありがとう!
BalestraPatrick 2014

のようなプリミティブを扱う場合、これが正しい答えBOOLです。とはNO異なり、設定と設定なしを正確に区別しobjectForKey:ます。
devios1

@ devios1-キーが欠落している場合は、プログラマーの意図に関係なくobjectForKey:返さnilれ、最終的にBoolまたはその他のデータ型を格納します。プリミティブが存在する場合、キーがプリミティブ値に関連付けられてobjectForKey:いても戻りませんnil
テッドホップ2017

これは正しい答えです。明らかに、objectForKeyは0とnilを混同するため、受け入れられた答えは間違っているため、機能しません。iOS 4.3から10.2.1まで正常にテスト
Chrysotribax

私はこれが古いことを知っていますが、この情報が必要になったのは今だけなので、 'containsObject:'参照がまさにそれを意味することを指摘する必要があります:オブジェクトです。キーではありません。IOW、ヘッダーファイルで次のように定義した場合:#define kMyKey @ "myKey" 'containsObject'は 'kMyKey'を探していません。'myKey 'を探しています。「kMyKey」を使用すると、常に「NO」が返されます。
ビルノーマン

55

objectForKey:この方法は、返されnilた値が存在しない場合。次に、値がnilかどうかを示す簡単なIF / THENテストを示します。

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

6

objectForKeyは、存在しない場合はnilを返します。存在する場合もnilを返し、整数またはブール値がゼロの値(つまり、ブール値の場合はFALSEまたはNO)のいずれかです。

5.1と6.1の両方のシミュレータでこれをテストしました。これは、「オブジェクト」を要求して設定された整数またはブール値を実際にテストできないことを意味します。「設定されていない」ことを「ゼロに設定されている」ように扱うことを気にしない場合、整数についてはこれで回避できます。

これをすでにテストした人は、偽陰性の側面に騙されたようです。つまり、キーが設定されていないことがわかっているときにobjectForKeyがnilを返すかどうかを確認することによってテストしましたが、キーが設定されている場合もnilを返すことに気付かない設定されていますが、NOに設定されています。

ここで私を送った私自身の問題については、ブールのセマンティクスを変更して、希望のデフォルトがNOに設定された値に一致するようにしました。それがオプションではない場合は、ブール値以外のものとして保存し、YES、NO、および「未設定」の違いを識別できることを確認する必要があります。


私はこれを確認しましたが、簡単な解決策があります。新しいオブジェクトリテラルまたはボックス化された式を使用するだけです。@0の代わりに0@NO代わりにNO、または単に@(variable)それらについてはこちらをお読みください。
カカ2013

1
少し遅いですが、初心者のために:これは正しくありません。0に設定された整数のUserDefault値およびfalseに設定されたBoolsのobject(forKey)は、nil以外を正しく返します。値が設定されているかどうかをテストするためにbool(forKey)を使用すると、問題が発生する可能性があります(値がFalseに設定されている場合、bool(forKey)は「true」を期待しているにもかかわらず、「false」を返します。)
thecloud_of_unknowing

5

Swift 3/4:

これは、UserDefaultsを介してアクセスされる他のタイプのオプションの戻り動作を模倣するInt / Double / Float / Bool Key-Valueタイプの単純な拡張です。

2018年8月30日編集: Leoの提案からより効率的な構文で更新されました。)

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

これらは、他の組み込みgetメソッド(文字列、データなど)と並んでより一貫性があります。古いメソッドの代わりにgetメソッドを使用してください。

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

私はこれを経験しました、そしてあなたのすべての答えは私にとって良い解決に向けて私を助けました。私が読んだり理解したりするのが難しいと思ったからといって、提案されたルートをたどることに抵抗した。

これが私がしたことです。「_talkative」という変数でBOOLが実行されていました。

デフォルト(NSUserDefaults)オブジェクトを設定するときは、それをオブジェクトとして設定します。これで、nilであるかどうかをテストできます

//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"]) {
 ...

これは私の場合うまくいくようです。視覚的に理解しやすくなりました。


これでうまくいきました([defaults boolForKey:@ "
talkative

3

この小さなクランペットを試してください:

-(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

取得するSwiftバージョン Bool?

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

1
なぜ使用しないのboolForKeyですか? NSUserDefaults.standardUserDefaults().boolForKey(DefaultsIsGiver)
JAL

1
boolForKeyは返されBool、は返されませんBool?。したがって、キーがそこにない場合、取得されfalse、返されませんnil
Ben

3

UserDefaultsこのソリューションをコピーアンドペーストしないように1回拡張します。

extension UserDefaults {

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

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

0

Swift3では、私はこのように使用しました

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

答えは、あなたがそれを複数回使用するようにしている場合は素晴らしいです。

それが役に立てば幸いです:)


-1

Swift 3.0

if NSUserDefaults.standardUserDefaults().dictionaryRepresentation().contains({ $0.0 == "Your_Comparison_Key" }){
                    result = NSUserDefaults.standardUserDefaults().objectForKey(self.ticketDetail.ticket_id) as! String
                }
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.