NSUserDefaults-키가 있는지 확인하는 방법


208

작은 iPhone 앱을 만들고 있는데 NSUserDefaults데이터 지속성으로 사용 하고 있습니다. 이름과 숫자와 같은 몇 가지 사항 만 추적하면되므로 간단하게 유지할 수 있습니다.

이 페이지참조 하여 찾았 지만 내 질문에 대답 할 수는 없다고 생각합니다. 기본적으로 값 (또는 키)이 이미 존재하는지 확인한 NSUserDefaults다음 그에 따라 무언가를 수행 할 수 있기를 원합니다 .

몇 가지 예 : 앱이 시작됩니다. 앱이 처음 시작되면 시작을 알리는 경고를 출력합니다. 처음 열 었는지 UserDefaults확인 하려면를 읽고 확인하십시오.

예 2 : 이름이 입력 한 "Hello [Name]"입니다. 앱을 연 상태에서 이름이 없으면 "Hello World"라고 표시되어야합니다. 이미 이름을 입력했는지 확인하고 그에 따라 행동하십시오. 이름은에 저장됩니다 NSUserDefaults.

여기에 도움이 필요하십니까? 정말 고마워요!

답변:


382

objectForKey:nil존재하지 않으면 반환 됩니다.


1
NSUserDefaults에 기본 데이터 유형을 저장할 수 있다고 생각하지 않습니다.
kender

12
Apple의 문서에 따르면 사용자 기본값에서 부울 값이 defaultName과 연결되어 있으면 해당 값이 반환되고 그렇지 않으면 NO가 반환됩니다. 위의 대답이 BOOL에 대해 맞지 않다고 생각합니다. 아니오로 정의되어 있는지 또는 존재하지 않는지 확인할 수 없습니다. – dictionaryRepresentation열쇠 를 사용 하고 확인 해야한다고 생각합니다 .
zekel February

40
@zekel 추측하기보다는 (iOS 5.1.1에서) 이것을 테스트했으며 BOOL의 가치에 관계없이 BOOL이 있는지 여부를 확실히 감지했습니다. BOOL이 설정되지 않았기 때문에 BOOL이 없으면 "objectForKey"가 nil을 리턴했습니다.
DataGraham

8
BOOL을 가지고 있고 boolForKey로 테스트하면 @zekel이 맞습니다. 그렇습니다. objectForKey를 사용하여 테스트하면 (답이 암시하는 바와 같이) 키가 설정되어 있지 않으면 nil이됩니다.
주세페 가라 시노

2
더 이상 iOS 6.1 Simulator에서 작동하지 않습니다. objectForKey는 존재하지 않고 BOOL이 NO 인 경우 동일한 값을 리턴합니다. i.jameelkhan의 솔루션은 작동합니까
lschult2

98

위에서 언급했듯이 0 / NO가 유효한 값일 수있는 기본 유형에는 작동하지 않습니다. 이 코드를 사용하고 있습니다.

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

    NSLog(@"mykey found");
}

이것은 나를 구했다. 감사!
BalestraPatrick

이것은와 같은 프리미티브를 다룰 때 정답 BOOL입니다. NO달리 정확하게 구별 하고 설정하지 않습니다 objectForKey:.
devios1

@ devios1-키가 없으면 프로그래머가 결국 다른 데이터 형식을 저장하려는 의도와 상관없이 objectForKey:반환됩니다 . 프리미티브가 있으면 키가 프리미티브 값과 연결되어 있어도 반환하지 않습니다 . nilBoolobjectForKey:nil
테드 홉

이것은 정답입니다. 분명히 objectForKey가 0과 nil을 혼동하기 때문에 허용되는 대답이 잘못되었으므로 작동하지 않습니다. iOS 4.3에서 10.2.1까지 성공적으로 테스트
Chrysotribax

나는 이것이 오래되었다는 것을 알고 있지만 지금은이 정보 만 필요했기 때문에 'containsObject :'참조가 객체를 의미한다는 것을 지적해야합니다. 열쇠가 아닙니다. IOW, 헤더 파일에서 다음을 정의한 경우 : #define kMyKey @ "myKey" 'containsObject'는 'kMyKey'를 찾지 않고 'myKey'를 찾습니다. 'kMyKey'를 사용하면 항상 'NO'가 반환됩니다.
Bill Norman

55

objectForKey:방법은 반환 nil값이 존재하지 않는 경우. 다음은 값이 0인지 여부를 알려주는 간단한 IF / THEN 테스트입니다.

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

6

" 존재하지 않는 경우 objectForKey는 nil을 리턴합니다. " 존재하는 경우 nil도 리턴하며 값이 0 인 정수 또는 부울입니다 (예 : 부울의 경우 FALSE 또는 NO).

5.1 및 6.1 모두 시뮬레이터에서 이것을 테스트했습니다. 즉, "객체"를 요청하여 정수 또는 부울 값을 실제로 테스트 할 수 없습니다. "0으로 설정"된 것처럼 "설정되지 않음"을 처리하지 않으려면 정수를 사용하여이 문제를 해결할 수 있습니다.

이미 이것을 테스트 한 사람들은 잘못된 부정적 측면에 의해 바보 인 것처럼 보입니다. 즉, 키가 설정되지 않았다는 것을 알았을 때 objectForKey가 nil을 반환하는지, 키가 설정되어 있으면 nil을 반환한다는 것을 알지 못하는지 확인하여 테스트 설정되었지만 NO로 설정되었습니다.

내 자신의 문제로 나를 여기로 보냈기 때문에 원하는 부울의 의미를 변경하여 원하는 기본값이 NO로 설정된 값과 일치하도록했습니다. 옵션이 아닌 경우 부울 이외의 것으로 저장하고 YES, NO 및 "설정되지 않음"의 차이점을 알 수 있어야합니다.


나는 이것을 확인했지만 쉬운 해결책이 있습니다. 새 객체 리터럴 또는 상자 표현식을 사용하십시오. @0대신에 0, @NO대신에 NO, 또는 단순히 @(variable). 여기에 대해 읽어보십시오.
kaka

1
조금 늦었지만 초보자의 이익을 위해 : 이것은 잘못되었습니다. User의 object (forKey)는 0으로 설정되고 Bools가 false로 설정된 정수의 기본값은 0이 아닌 값을 올바르게 반환합니다. bool (forKey)를 사용하여 값이 설정되어 있는지 테스트하면 문제가 발생할 수 있습니다 (값이 False로 설정되어 있으면 bool (forKey)는 'true'를 예상하더라도 'false'를 반환 함)
thecloud_of_unknowing

5

스위프트 3/4 :

다음은 UserDefaults를 통해 액세스되는 다른 유형의 선택적 리턴 동작을 모방 한 Int / Double / Float / Bool 키-값 유형의 간단한 확장입니다.

( 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한 번만 값을 검색하기를 원합니다 .
Leo

3

방금이 과정을 거쳤 으며 귀하의 모든 답변이 저에게 좋은 해결책을 찾도록 도와주었습니다. 나는 읽고 이해하기가 어려워서 제안한 길을가는 것을 거부했다.

여기 내가 한 일이 있습니다. "_talkative"라는 변수에서 BOOL을 수행했습니다.

기본 (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 : @ "
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

스위프트 버전 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

Swift3에서는 이런 식으로 사용했습니다

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
                }
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.