본문 바로가기

OBJECTIVE-C

UUID 키체인(Keychain)저장

iOS5부터 사용되던 UUID 값은 보통 서버와 연동하여 기기를 식별하는데 쓰인다. 

그런데 이 UUID값이 기기의 고유값은 맞지만 생성할때마다 값이 바뀌어 앱을 처음 실행할때 저장해 두고 불러오는 방식으로 쓰인다.

하지만 앱을 삭제할 경우 앱내 저장된 값도 같이 삭제되니 이를 방지하기 위해 기기내 저장소인 키체인(Keychain)을 이용한다.

(키체인에 저장된 값도 공장초기화할경우에는 사라진다.)


키체인 API의 경우 Security.framework에 정의되어 있다고는 하지만 사용하기가 까다로워 애플에서 KeychainItemWrapper 라는 클래스를 제공한다. (Download)

하지만 이 파일이 업데이트 안된지 좀 된 모양이라 ARC를 지원하지 않는다.

프로젝트에서 ARC를 지원하지 않도록 예외처리하거나 (방법)

ARC가 적용된 파일을 내려받자. (Download2)


파일을 내려받았다면 아래 두 파일을 프로젝트에 추가한다.

KeychainItemWrapper.h

KeychainItemWrapper.m


아래는 UUID를 불러오는 함수이다.

- (NSString *) getUUID {

    // initialize keychaing item for saving UUID.

    KeychainItemWrapper *wrapper = [[KeychainItemWrapper alloc] initWithIdentifier:@"UUID" accessGroup:nil];

    

    NSString *uuid = [wrapper objectForKey:(__bridge id)(kSecAttrAccount)];

    

    if( uuid == nil || uuid.length == 0)

    {

        // if there is not UUID in keychain, make UUID and save it.

        CFUUIDRef uuidRef = CFUUIDCreate(NULL);

        CFStringRef uuidStringRef = CFUUIDCreateString(NULL, uuidRef);

        CFRelease(uuidRef);

        uuid = [NSString stringWithString:(__bridge NSString *) uuidStringRef];

        CFRelease(uuidStringRef);

        

        // save UUID in keychain

        [wrapper setObject:uuid forKey:(__bridge id)(kSecAttrAccount)];

    }

    

    return uuid;

}


키체인 값에 "UUID"라고 정의된 값이 있다면 불러오고, 없다면 새로 생성해서 키체인에 저장하는 메소드이다.

CFUUIDRef uuidRef = CFUUIDCreate(NULL);

CFStringRef uuidStringRef = CFUUIDCreateString(NULL, uuidRef);

CFRelease(uuidRef);

uuid = [NSString stringWithString:(__bridge NSString *) uuidStringRef];


UUID를 새로 생성하는 코드는 아래 코드로 간단하게 표현이 가능하다.

uuid = [[NSUUID UUID] UUIDString];


만약 지금 만들고 있는 프로젝트가 iOS5이하를 지원하지 않는다면 iOS6부터 나온 identifierForVendor를 사용할 수 있다.

@property(nonatomic,readonly,retain) NSUUID      *identifierForVendor NS_AVAILABLE_IOS(6_0);      // a UUID that may be used to uniquely identify the device, same across apps from a single vendor.


사용법도 간단하다.

uuid = [[[UIDevice currentDevice] identifierForVendor] UUIDString];


한가지 주의할 점은 identifierForVendor는 프로젝트를 생성한 Company identifier를 기반으로 생성하는 값이기 때문에 같은 개발사 identifier를 가진 앱이 디바이스에 설치되어 있다면 같은 값을 리턴하게 된다. 이 점은 쓰이기에 따라 장점으로 작용할 수 있을 듯 하다.


아래 방법은 UUID생성을 간단하게 할 수 있는 방법들일 뿐 이 역시 키체인에 저장하지 않는다면 앱 삭제 후 재설치시 새로운 값을 리턴하게 된다.