[iOS] [KeychainItemWrapper getUUID]: unrecognized selector sent to instance 0x2829369c0

[iOS] [KeychainItemWrapper getUUID]: unrecognized selector sent to instance 0x2829369c0

도대체가 이유를 알 수 없지만 Xcode 콘솔에 아래와 같은 오류가 발생하는 경우.

*** Terminating app due to uncaught exception ‘NSInvalidArgumentException’, reason: ‘-[KeychainItemWrapper getUUID]: unrecognized selector sent to instance 0x2829369c0’

*** First throw call stack:

(0x18b8ed27c 0x18aac79f8 0x18b809ab8 0x18b8f2ac4 0x18b8f475c 0x104c08168 0x104bef108 0x104beed0c 0x104beec70 0x1b80b1040 0x1b7b5a1c8 0x1b7b5a4e8 0x1b7b59554 0x1b80e8304 0x1b80e952c 0x1b80c959c 0x1b818f714 0x1b8191e40 0x1b818b070 0x18b87f018 0x18b87ef98 0x18b87e880 0x18b8797bc 0x18b8790b0 0x18da7979c 0x1b80af978 0x104be9c10 0x18b33e8e0)

libc++abi.dylib: terminating with uncaught exception of type NSException

문자 그대로 해석해보면 KeychainItemWrapper 파일의 getUUID 메서드가 없다는 오류이다.

필자의 상황은 외부 업체의 라이브러리를 사용했는데 위 오류가 발생하였다. 해당 라이브러리는 C로 구현된 것으로, 뜯어서 내부를 보고 싶었지만 그럴 수가 없어서 어쩔 수 없이 getUUID 메서드를 구현해주었다.

아마도 KeychainItemWrapper.h 파일과 KeychainItemWrapper.m 파일이 프로젝트 내에 구현되어 있을 것이다.

해당 파일을 찾아서 수정한다.

1. KeychainItemWrapper.h 파일에 내용 추가

– (NSString*) getUUID;

2. KeychainItemWrapper.m 파일에 내용 추가

// 처음에 UUID를 KeyChain에서 불러오는데 nil이라면 UUID를 생성해서 KeyChain에 저장한다.
// 저장 후에 다시 함수를 호출 하면 저장된 값을 리턴한다.
– (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;
}

메서드의 내용의 출처는 다음 주소에서 가져왔다. 이 자리를 빌어 감사드린다.