iOS 고유 사용자 식별자
저는 REST를 이용하여 제 서버와 통신하는 아이폰 앱을 작성하고 있습니다.가장 큰 문제는 어떻게든 사용자를 식별해야 한다는 것입니다.얼마 전까지만 해도 UDID를 사용할 수 있었지만, 지금은 사용할 수 없습니다.그럼 무엇을 대신 사용해야 할까요?나는 아이폰에 어떤 종류의 식별자가 필요해서 사용자가 애플리케이션을 삭제하고 다시 설치하면 그는 동일한 ID를 얻을 것입니다.
저는 용한사를 요.CFUUIDCreate()
UUID 생성하기
+ (NSString *)GetUUID {
CFUUIDRef theUUID = CFUUIDCreate(NULL);
CFStringRef string = CFUUIDCreateString(NULL, theUUID);
CFRelease(theUUID);
return [(NSString *)string autorelease];
}
그런 다음 위의 UUID를 내 NSString으로 설정합니다.
NSString *UUID = [nameofclasswhereGetUUIDclassmethodresides UUID];
그런 다음 SSKeyChain을 사용하여 UUID를 KeyChain에 저장했습니다.
SSKeyChain을 사용하여 UUID를 설정하는 방법
[SSKeychain setPassword:UUID forService:@"com.yourapp.yourcompany" account:@"user"];
검색 방법:
NSString *retrieveuuid = [SSKeychain passwordForService:@"com.yourapp.yourcompany" account:@"user"];
UUID를 Keychain으로 설정하면 사용자가 앱을 완전히 제거한 후 다시 설치하더라도 UUID가 유지됩니다.
모든 장치가 키 체인에서 동일한 UUID를 가지고 있는지 확인합니다.
- iCloud를 사용하도록 앱을 설정합니다.
- Keychain에 있는 UUID도 NSUserDefaults에 저장합니다.
- Key-Value Data Store를 사용하여 NSUserDefaults의 UUID를 클라우드에 전달합니다.
- App을 처음 실행할 때 클라우드 데이터를 사용할 수 있는지 확인하고 새 디바이스의 Keychain에서 UUID를 설정합니다.
이제 모든 장치와 영구적이고 공유/동기화된 고유 식별자를 갖게 되었습니다.
우선, UDID는 iOS 5에서만 사용되지 않습니다.그렇다고 해서 그것이 사라진 것은 아닙니다.
두 번째로, 여러분은 여러분이 정말로 그런 것이 필요한지 스스로에게 물어봐야 합니다.사용자가 새 장치를 얻고 거기에 앱을 설치하면 어떻게 됩니까?동일한 사용자이지만 UDID가 변경되었습니다.한편, 원래 사용자는 이전 기기를 팔았을 수 있으므로 이제 완전히 새로운 사용자가 앱을 설치하고 UDID에 기반한 다른 사용자라고 생각합니다.
UDID를 합니다.CFUUIDCreate()
실행 시 합니다(" "ID" 사용).CFUUIDCreateString()
먼저 UUID를 문자열로 변환합니다.백업 및 복원 과정에서 살아남고 원래 사용자가 새 장치로 전환할 때도 함께 제공됩니다.그것은 여러 면에서 UDID보다 더 나은 선택입니다.
고유한 장치 식별자가 정말로 필요한 경우(사용자처럼 들리지 않음) Suhail의 답변에 나와 있는 대로 MAC 주소로 이동합니다.
iOS 4.3 이상을 지원하는 Unique Identifier만을 기반으로 작동하는 애플리케이션을 업데이트하고 있었습니다.
는 사할수없다니습었을 사용할 수 .[UIDevice currentDevice].uniqueIdentifier;
더 이상 구할 수 없었기 때문에
는 사할수없다니습을 할 수 없었습니다.[UIDevice currentDevice].identifierForVendor.UUIDString
할 수 있고 이 낮은 할 수 입니다.OS 6.0 이상에서만 사용할 수 있었고 iOS 버전이 낮은 경우에는 사용할 수 없었기 때문입니다.
mac 주소는 iOS-7에서 허용되지 않았기 때문에 옵션이 아니었습니다.
OpenUDID는 얼마 전에 더 이상 사용되지 않았으며 iOS-6에도 문제가 있었습니다.
iOS-5 이하에서는 광고 식별자를 사용할 수 없습니다.
마침내 이것이 제가 한 일이었습니다.
프로젝트에 SFHFKeychain Utils 추가
생성된 CFUUID 키 문자열
CFUUIDRef cfuuid = CFUUIDCreate(kCFAllocatorDefault);
udidString = (NSString*)CFBridgingRelease(CFUUIDCreateString(kCFAllocatorDefault, cfuuid));
키 체인 유틸리티에 저장하지 않으면 매번 새 고유 항목이 생성됩니다.
최종 코드
+ (NSString *)GetDeviceID {
NSString *udidString;
udidString = [self objectForKey:@"deviceID"];
if(!udidString)
{
CFUUIDRef cfuuid = CFUUIDCreate(kCFAllocatorDefault);
udidString = (NSString*)CFBridgingRelease(CFUUIDCreateString(kCFAllocatorDefault, cfuuid));
CFRelease(cfuuid);
[self setObject:udidString forKey:@"deviceID"];
}
return udidString;
}
+(void) setObject:(NSString*) object forKey:(NSString*) key
{
NSString *objectString = object;
NSError *error = nil;
[SFHFKeychainUtils storeUsername:key
andPassword:objectString
forServiceName:@"LIB"
updateExisting:YES
error:&error];
if(error)
NSLog(@"%@", [error localizedDescription]);
}
+(NSString*) objectForKey:(NSString*) key
{
NSError *error = nil;
NSString *object = [SFHFKeychainUtils getPasswordForUsername:key
andServiceName:@"LIB"
error:&error];
if(error)
NSLog(@"%@", [error localizedDescription]);
return object;
}
사용 가능한 여러 옵션에 대해 자세히 알고 싶어하는 사람도 있으며, 알고 있다면 @NSQuamber.java의 답변을 살펴보십시오.NSUUID를 사용하고 iCloud와 동기화하는 방법을 알고 싶다면 계속해서 읽으십시오.이 게시물은 제가 원래 원했던 것보다 더 장황한 결과를 낳았지만, 저는 이것이 이러한 단계를 밟는 모든 사람들에게 분명하게 해주기를 바랍니다!
NSUUID 사용
NSUUID 클래스를 사용하여 UUID를 생성합니다.
NSUUID *uuid = [NSUUID UUID];
그런 다음 문자열을 만들려면 다음을 호출하기만 하면 됩니다.UUIDString
방법:
NSString *uuidString = [uuid UUIDString];
또는 한 줄로 수행합니다.
NSString *uuidString = [[NSUUID UUID] UUIDString];
IMHO, 이것은 CFUUID Create를 사용하고 유지해야 하는 방법을 사용하는 것보다 훨씬 쉽습니다.
편집: 지금은 UIKeyChainStore를 사용합니다.
UIKeyChainStore를 사용하여 UUID를 설정하는 방법
UICKeyChainStore *keychain = [UICKeyChainStore keyChainStoreWithService:@"com.sample.MyApp"];
keychain[@"com.sample.MyApp.user"] = userID;
검색 방법:
UICKeyChainStore *keychain = [UICKeyChainStore keyChainStoreWithService:@"com.sample.MyApp"];
NSString *userID = keychain[@"com.sample.MyApp.user"];
그런 다음 SSKeyChain을 사용하여 UUID를 KeyChain에 저장했습니다.
SSKeyChain을 사용하여 UUID를 설정하는 방법
[SSKeychain setPassword:userID forService:@"com.sample.MyApp.user" account:@"com.sample.MyApp"];
검색 방법:
NSString *userID = [SSKeychain passwordForService:@"com.sample.MyApp.user" account:@"com.sample.MyApp"];
UUID를 Keychain으로 설정하면 사용자가 앱을 완전히 제거한 후 다시 설치하더라도 UUID가 유지됩니다.
iCloud와 동기화
따라서 모든 사용자의 장치가 동일한 UUID를 사용하는지 확인하는 것이 유용합니다.이는 각 장치가 고유한 사용자라고 생각하지 않고 모든 장치에서 데이터가 동기화되도록 하기 위한 것입니다.
동기화가 어떻게 작동하는지에 대한 제 답변에 대한 몇 가지 질문이 댓글에 있었습니다. 이제 모두 작동했으므로 더 자세한 내용을 제공하겠습니다.
iCloud/NSUbiquitous 키 값 저장소 사용 구성
- Xcode의 Project Navigator 상단에서 프로젝트를 클릭합니다.
- Capabilities를 선택합니다.
- iCloud를 켭니다.
는 이렇게: 이제다같표시됩니다이음과다니▁it표됩.
NSUbiquitous KeyValueStore 사용
iCloud를 사용하는 것은 매우 간단합니다.쓰기:
// create the UUID
NSUUID *userUUID = [[NSUUID UUID];
// convert to string
NSString *userID = [userUUID UUIDString];
// create the key to store the ID
NSString *userKey = @"com.sample.MyApp.user";
// Save to iCloud
[[NSUbiquitousKeyValueStore defaultStore] setString:userID forKey:userKey];
읽기:
// create the key to store the ID
NSString *userKey = @"com.sample.MyApp.user";
// read from iCloud
NSString *userID = [[NSUbiquitousKeyValueStore defaultStore] stringForKey:userKey];
NSUbiquitousKeyValueStore 설명서를 작성하려면 먼저 iCloud에서 읽어야 합니다.강제로 읽으려면 다음 메서드를 호출합니다.
[[NSUbiquitousKeyValueStore defaultStore] synchronize];
앱이 iCloud 변경 알림을 받도록 하려면 다음 알림을 추가합니다.
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(iCloudStoreDidChange:)
name:NSUbiquitousKeyValueStoreDidChangeExternallyNotification
object:[NSUbiquitousKeyValueStore defaultStore]];
iCloud를 사용하여 UUID 생성
NSUUID, SSKeychain 및 NSUbiquityKeyValueStore를 결합하여 사용자 ID를 생성하는 방법은 다음과 같습니다.
- (NSUUID *)createUserID {
NSString *userKey = @"com.sample.MyApp.user";
NSString *KEYCHAIN_ACCOUNT_IDENTIFIER = @"com.sample.MyApp";
NSString *userID = [SSKeychain passwordForService:userKey account:KEYCHAIN_ACCOUNT_IDENTIFIER];
if (userID) {
return [[NSUUID UUID] initWithUUIDString:userID];
}
// check iCloud
userID = [[NSUbiquitousKeyValueStore defaultStore] stringForKey:userKey];
if (!userID) {
// none in iCloud, create one
NSUUID *newUUID = [NSUUID UUID];
userID = [newUUID UUIDString];
// save to iCloud
[[NSUbiquitousKeyValueStore defaultStore] setString:userID forKey:userKey];
}
// store the user ID locally
[SSKeychain setPassword:userID forService:userKey account:KEYCHAIN_ACCOUNT_IDENTIFIER];
return [[NSUUID UUID] initWithUUIDString:userID];
}
사용자 ID가 동기화되었는지 확인하는 방법
위해서는 을 iCloud의 맨 .(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
ㅠㅠ. 했습니다.저는 거기에 알림 등록도 추가했습니다.이를 통해 iCloud의 변경 사항을 감지하고 적절하게 처리할 수 있습니다.
여기 샘플이 있습니다.
NSString *const USER_KEY = @"com.sample.MyApp.user";
NSString *const KEYCHAIN_ACCOUNT_IDENTIFIER = @"com.sample.MyApp";
- (void)iCloudStoreDidChange:(NSNotification *)notification {
NSDictionary *userInfo = notification.userInfo;
NSNumber *changeReason = userInfo[NSUbiquitousKeyValueStoreChangeReasonKey];
NSArray *keysChanged = userInfo[NSUbiquitousKeyValueStoreChangedKeysKey];
if (changeReason) {
switch ([changeReason intValue]) {
default:
case NSUbiquitousKeyValueStoreServerChange:
case NSUbiquitousKeyValueStoreInitialSyncChange:
// check changed keys
for (NSString *keyChanged in keysChanged) {
NSString *iCloudID = [[NSUbiquitousKeyValueStore defaultStore] stringForKey:keyChanged];
if (![keyChanged isEqualToString:USER_KEY]) {
NSLog(@"Unknown key changed [%@:%@]", keyChanged, iCloudID);
continue;
}
// get the local key
NSString *localID = [SSKeychain passwordForService:keyChanged account:KEYCHAIN_ACCOUNT_IDENTIFIER];
if (!iCloudID) {
// no value from iCloud
continue;
}
// local ID not created yet
if (!localID) {
// save the iCloud value locally
[SSKeychain setPassword:iCloudID forService:keyChanged account:KEYCHAIN_ACCOUNT_IDENTIFIER];
continue; // continue because there is no user information on the server, so no migration
}
if ([iCloudID isEqualToString:localID]) {
// IDs match, so continue
continue;
}
[self handleMigration:keyChanged from:localID to:iCloudID];
}
break;
case NSUbiquitousKeyValueStoreAccountChange:
// need to delete all data and download new data from server
break;
}
}
}
애플리케이션이 시작되거나 애플리케이션이 처음 시작될 때 iCloud와 강제로 동기화하고 UUID의 무결성을 확인합니다.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[self configureSecKeyWrapper];
// synchronize data from iCloud first. If the User ID already exists, then we can initialize with it
[[NSUbiquitousKeyValueStore defaultStore] synchronize];
[self checkUseriCloudSync];
}
- (void)applicationWillEnterForeground:(UIApplication *)application {
// synchronize changes from iCloud
[[NSUbiquitousKeyValueStore defaultStore] synchronize];
[self checkUseriCloudSync];
}
- (BOOL)checkUseriCloudSync {
NSString *userKey = @"com.sample.MyApp.user";
NSString *KEYCHAIN_ACCOUNT_IDENTIFIER = @"com.sample.MyApp";
NSString *localID = [SSKeychain passwordForService:userKey account:KEYCHAIN_ACCOUNT_IDENTIFIER];
NSString *iCloudID = [[NSUbiquitousKeyValueStore defaultStore] stringForKey:userKey];
if (!iCloudID) {
// iCloud does not have the key saved, so we write the key to iCloud
[[NSUbiquitousKeyValueStore defaultStore] setString:localID forKey:userKey];
return YES;
}
if (!localID || [iCloudID isEqualToString:localID]) {
return YES;
}
// both IDs exist, so we keep the one from iCloud since the functionality requires synchronization
// before setting, so that means that it was the earliest one
[self handleMigration:userKey from:localID to:iCloudID];
return NO;
}
어떤 UUID가 먼저냐가 중요한지 여부
UUID를 먼저 생성한 장치에 관계없이 iCloud에 푸시된 첫 번째 UUID이므로 사용자 ID의 사용 사례에서는 iCloud의 값을 유지해야 한다고 가정했습니다.대부분의 사용자는 동일한 경로를 사용할 것입니다. 단일 UUID로 해결되는 경우 어떤 UUID로 해결되는지는 중요하지 않기 때문입니다. 생성("Timestampgeneration")을 것이 .[[NSDate date] timeIntervalSince1970]
어떤 것이 더 오래되었는지 확인할 수:
// using dates
NSDate *uuid1Timestamp = [NSDate dateWithTimeIntervalSince1970:timestamp1];
NSDate *uuid2Timestamp = [NSDate dateWithTimeIntervalSince1970:timestamp2];
NSTimeInterval timeDifference = [uuid1 timeIntervalSinceDate:uuid2Timestamp];
// or just subtract
double timeDifference = timestamp1 - timestamp2;
Github에는 Mac 주소와 번들 식별자의 조합을 기반으로 고유 식별자를 생성하는 좋은 대안이 있습니다: UIDevice-with-UniqueIdentifier-for-iOS-5.
iOS7에서 Apple은 UID 장치 클래스에 "identifierForVendor"라는 읽기 전용 속성을 도입했습니다.만약 당신이 그것을 사용하기로 결정한다면, 당신은 다음을 기록해야 합니다.
- 사용자가 장치의 잠금을 해제하기 전에 액세스하는 경우 이 값은 0일 수 있습니다.
- 사용자가 장치에서 해당 공급업체의 앱을 모두 삭제한 후 하나 이상을 다시 설치하면 값이 변경됩니다.
- Xcode를 사용하여 테스트 빌드를 설치하거나 애드혹 배포를 사용하여 장치에 앱을 설치할 때도 값이 변경될 수 있습니다.
광고 목적으로 식별자가 필요한 경우 ASIdentifierManager의 advertisingIdentifier 속성을 사용합니다.그러나 위에서 논의한 사항 1은 이에 대해서도 여전히 사실이라는 점에 유의해야 합니다.
출처: https://developer.apple.com/library/ios/documentation/uikit/reference/UIDevice_Class/Reference/UIDevice.html #//apple_ref/occ/instp/UIDevice/identifierForVendor
이것은 정말로 뜨거운 주제입니다.UDID를 사용하여 서버에 저장할 XML 파일의 이름을 지정했기 때문에 마이그레이션해야 하는 앱이 있습니다.그런 다음 앱이 있는 장치는 서버에 연결하여 특정 udid.xml을 다운로드하고 구문 분석하여 작동합니다.
저는 정말로 사용자가 새로운 기기로 이동하면 앱이 깨질 것이라고 생각해왔습니다.그래서 저는 정말 다른 것을 사용해야 합니다.중요한 것은, 저는 데이터를 위해 데이터베이스를 사용하지 않는다는 것입니다.데이터는 클라우드에 저장된 장치당 하나의 xml 파일인 xml 형식으로 저장됩니다.
저는 사용자가 웹에서 데이터를 작성하고, php가 데이터베이스에 저장되지 않고 사용자에게 전송되는 토큰을 즉시 생성하도록 하는 것이 가장 좋은 방법이라고 생각합니다.그런 다음 사용자는 대상 장치에 토큰을 입력하고 문제의 xml을 검색할 수 있습니다.
그것이 그 문제에 대한 저의 해결책이 될 것입니다.하지만 '독특한 토큰 생성'이라는 모든 것을 구현하는 방법은 확실하지 않습니다.
언급URL : https://stackoverflow.com/questions/7273014/ios-unique-user-identifier
'programing' 카테고리의 다른 글
Supervisor에서 실행 중인 Flask/uWSGI/MariaDB가 거의 매일 작동을 멈춤 (0) | 2023.09.03 |
---|---|
인라인 블록 목록 항목 사이의 공백 (0) | 2023.09.03 |
유연한 항목에 상위 컨테이너의 너비가 아닌 내용 너비를 사용하도록 설정 (0) | 2023.09.03 |
jQuery에서 AJAX를 통해 양식 제출 (0) | 2023.09.03 |
앵커(a) 태그에서 로컬 href 값 가져오기 (0) | 2023.09.03 |