UIDevice uniqueIdentifier 더 이상 사용되지 않음-지금 무엇을해야합니까?
UIDevice uniqueIdentifier 속성은 iOS 5 에서 더 이상 사용되지 않으며 iOS 7 이상 에서는 사용할 수 없다는 사실 이 밝혀 졌습니다. 다른 방법이나 속성을 사용할 수 없거나 앞으로 나올 것으로 보이지 않습니다.
기존의 많은 앱은 특정 기기를 고유하게 식별하기 위해이 속성에 밀접하게 의존합니다. 앞으로이 문제를 어떻게 처리 할 수 있습니까?
2011-2012 년 문서에서 제안한 내용 은 다음과 같습니다.
특별 고려 사항
uniqueIdentifier 속성을 사용하지 마십시오. 앱에 고유 한 식별자
CFUUIDCreate
를 만들려면 함수를 호출하여 를 만들고 클래스를UUID
사용하여 기본 데이터베이스에 쓸 수NSUserDefaults
있습니다.
그러나 사용자가 앱을 제거했다가 다시 설치하는 경우이 값은 동일하지 않습니다.
사용자가 앱을 제거했다가 다시 설치하는 경우에 의해 생성 된 UUID CFUUIDCreate
는 고유합니다. 매번 새 UI를 얻게됩니다.
그러나 고유 하지 않을 수도 있습니다
. 즉, 사용자가 앱을 제거했다가 다시 설치할 때 동일하게 유지되어야합니다. 가장 안정적인 장치 별 식별자는 MAC 주소 인 것으로 보이므로 약간의 노력이 필요합니다. MAC을 쿼리하여 UUID로 사용할 수
있습니다 .
편집 : 물론 항상 동일한 인터페이스의 MAC을 쿼리해야합니다. 가장 좋은 방법은입니다
en0
. 인터페이스에 IP가 없거나 작동 중지 된 경우에도 MAC은 항상 존재합니다.
편집 2 : 다른 사람들이 지적했듯이 iOS 6 이후 선호되는 솔루션은 -[UIDevice identifierForVendor] 입니다. 대부분의 경우 이전 버전의 드롭 인 대체품으로 사용할 수 있습니다 -[UIDevice uniqueIdentifier]
(그러나 앱을 처음 시작할 때 생성되는 UUID는 Apple이 사용하기를 원하는 것입니다).
편집 3 : 이 주요 요점은 주석 잡음에서 길을 잃지 않습니다. MAC 을 UUID로 사용하지 말고
MAC 을 사용하여 해시를 만드십시오
. 해시가 동일한 방식으로 수행되는 경우 다시 설치 및 앱에서도 해시가 항상 동일한 결과를 생성합니다. 어쨌든 요즘 (2013) iOS <6.0에서 "안정된"장치 식별자가 필요한 경우를 제외하고는 더 이상 필요하지 않습니다.
편집 4 : iOS 7에서 Apple은 MAC을 쿼리 할 때 항상 고정 값을 반환하여 MAC을 ID 체계의 기초 로 구체적으로 방해합니다 . 따라서 실제로 -[UIDevice identifierForVendor]를 사용 하거나 설치마다 UUID를 작성해야합니다.
UDID
이미 Apple의 대안을 사용할 수 있습니다 . Kind guy gekitz는 장치 mac-address 및 번들 식별자 UIDevice
를 UDID
기반으로 일종의 카테고리를 생성하는 카테고리를 작성했습니다 .
github에서 코드를 찾을 수 있습니다
@moonlight가 제안한 링크를 기반으로 여러 테스트를 수행했으며 최상의 솔루션 인 것 같습니다. @DarkDust가 말했듯이 메소드 en0
는 항상 사용 가능한 것을 확인 합니다. (MAC + CFBundleIdentifier의 MD5 ) 및 ( MAC의 MD5)의
두 가지 옵션이 있으며 항상 같은 값을 반환합니다. 내가 한 테스트 아래 (실제 장치로) :
uniqueDeviceIdentifier
uniqueGlobalDeviceIdentifier
#import "UIDevice+IdentifierAddition.h"
NSLog(@"%@",[[UIDevice currentDevice] uniqueDeviceIdentifier]);
NSLog(@"%@",[[UIDevice currentDevice] uniqueGlobalDeviceIdentifier]);
XXXX21f1f19edff198e2a2356bf4XXXX-(WIFI) UDID
XXXX7dc3c577446a2bcbd77935bdXXXX-(WIFI) GlobalAppUDIDXXXX21f1f19edff198e2a2356bf4XXXX-(3G) UDID
XXXX7dc3c577446a2bcbd77935bdXXXX-(3G) GlobalAppUDIDXXXX21f1f19edff198e2a2356bf4XXXX-(GPRS) UDID
XXXX7dc3c577446a2bcbd77935bdXXXX-(GPRS) GlobalAppUDIDXXXX21f1f19edff198e2a2356bf4XXXX-(AirPlane 모드) UDID
XXXX7dc3c577446a2bcbd77935bdXXXX-(AirPlane 모드) GlobalAppUDIDXXXX21f1f19edff198e2a2356bf4XXXX-앱 제거 및 설치 후 앱 XXXX7dc3c577446a2bcbd77935bdXXXX (Wi-Fi) 제거 및 재설치 후 (Wi-Fi)
유용하기를 바랍니다.
편집 :
다른 사람들이 지적했듯이 iOS 7 의이 솔루션 uniqueIdentifier
은 더 이상 사용할 수 없으므로 MAC 주소를 쿼리하면 항상 02 : 00 : 00 : 00 : 00 : 00을 반환합니다.
이것 좀 봐,
NSUserDefaults
클래스 대신 키 체인을 사용하여에 UUID
의해 생성 된 것을 저장할 수 있습니다 CFUUIDCreate
.
이런 식으로 우리는 UUID
재설치 로 인한 레크리에이션을 피할 수 UUID
있으며 동일한 응용 프로그램에서 사용자 제거 및 다시 설치조차도 항상 동일하게 얻을 수 있습니다.
UUID
사용자가 기기를 재설정 할 때만 다시 생성됩니다.
SFHFKeychainUtils 로이 방법을 시도 했으며 매력처럼 작동합니다.
자신 만의 UUID를 만든 다음 키 체인에 저장하십시오. 따라서 앱이 제거 되어도 지속됩니다. 대부분의 경우 사용자가 장치간에 마이그레이션하더라도 (예 : 전체 백업 및 다른 장치로 복원) 지속됩니다.
실제로는 사용자 가 관심을 갖는 한 고유 한 사용자 식별자가 됩니다. ( 기기 식별자 보다 낫습니다 ).
예:
UUID
as 를 만들기위한 사용자 정의 방법을 정의하고 있습니다.
- (NSString *)createNewUUID
{
CFUUIDRef theUUID = CFUUIDCreate(NULL);
CFStringRef string = CFUUIDCreateString(NULL, theUUID);
CFRelease(theUUID);
return [(NSString *)string autorelease];
}
그런 다음 KEYCHAIN
앱을 처음 시작할 때 저장할 수 있습니다 . 따라서 처음 시작한 후에는 키 체인에서 간단히 사용할 수 있으므로 다시 생성 할 필요가 없습니다. 키 체인을 사용하여 저장하는 주된 이유는 다음과 같습니다. 키 체인을 설정 UUID
하면 사용자가 앱을 완전히 제거한 후 다시 설치하더라도 키 체인이 유지됩니다. . 따라서 이것은 영구적으로 저장하는 방식이므로 키가 완전히 고유합니다.
#import "SSKeychain.h"
#import <Security/Security.h>
응용 프로그램을 시작할 때 다음 코드를 포함하십시오.
// getting the unique key (if present ) from keychain , assuming "your app identifier" as a key
NSString *retrieveuuid = [SSKeychain passwordForService:@"your app identifier" account:@"user"];
if (retrieveuuid == nil) { // if this is the first time app lunching , create key for device
NSString *uuid = [self createNewUUID];
// save newly created key to Keychain
[SSKeychain setPassword:uuid forService:@"your app identifier" account:@"user"];
// this is the one time process
}
sskeychain에서 SSKeychain.m 및 .h 파일을 다운로드 하고 SSKeychain.m 및 .h 파일을 프로젝트로 끌어 프로젝트에 "Security.framework"를 추가하십시오. 나중에 UUID를 사용하려면 다음을 사용하십시오.
NSString *retrieveuuid = [SSKeychain passwordForService:@"your app identifier" account:@"user"];
아마도 당신은 사용할 수 있습니다 :
[UIDevice currentDevice].identifierForVendor.UUIDString
Apple의 설명서는 identifierForVender를 다음과 같이 설명합니다.
이 속성의 값은 동일한 장치에서 실행되는 동일한 공급 업체에서 온 앱의 경우와 동일합니다. 다른 공급 업체에서 제공하는 동일한 장치의 앱과 공급 업체에 관계없이 다른 장치의 앱에 대해 다른 값이 반환됩니다.
OpenUDID
더 이상 사용되지 않는에 대한 드롭 인 대체를 사용 하는 것이 UDID
좋습니다.
기본적으로와 일치하려면 UDID
다음 기능이 필요합니다.
- 독특하거나 충분히 독특함 (낮은 확률의 충돌이 허용 될 수 있음)
- 재부팅, 복원, 제거를 통한 지속성
- 여러 공급 업체의 앱에서 사용 가능 (CPI 네트워크를 통해 사용자를 확보하는 데 유용)-
OpenUDID
위의 사항을 충족하며 나중에 고려할 수 있도록 기본 제공 거부 메커니즘이 있습니다.
해당 GitHub를 가리키는 http://OpenUDID.org를 확인 하십시오 . 도움이 되었기를 바랍니다!
부수적으로, 나는 MAC 주소 대안에서 멀어 질 것입니다. MAC 주소는 유혹적이고 보편적 인 해결책처럼 보이지만이 낮은 매달린 과일은 중독되어 있어야합니다. MAC 주소는 매우 중요하며, "이 응용 프로그램 제출"이라고 말하기 전에 Apple은이 응용 프로그램에 대한 액세스를 매우 사용하지 않을 수 있습니다. MAC 네트워크 주소는 개인 LAN (WLAN) 또는 기타 가상 개인의 특정 장치를 인증하는 데 사용됩니다. 네트워크 (VPN). .. 그것은 이전 UDID보다 훨씬 더 민감합니다!
나는 애플이이 변화로 많은 사람들을 괴롭 혔을 것이라고 확신한다. iOS 용 부기 앱 을 개발하고 다른 기기에서 변경 한 내용을 동기화하는 온라인 서비스가 있습니다. 이 서비스는 모든 장치의 데이터베이스와 해당 장치에 전파해야하는 변경 사항을 유지 관리합니다. 따라서 어떤 장치가 어떤 장치인지 알아야합니다. UIDevice uniqueIdentifier를 사용하여 장치를 추적하고 있으며 그 가치가있는 것은 다음과 같습니다.
UUID를 생성하고 사용자 기본값으로 저장 하시겠습니까? 사용자가 앱을 삭제할 때 지속되지 않기 때문에 좋지 않습니다. 나중에 다시 설치하면 온라인 서비스가 새 장치 레코드를 작성하지 않아야합니다. 그러면 서버의 자원이 낭비되고 동일한 장치를 두 번 이상 포함하는 장치 목록이 제공됩니다. 사용자가 앱을 다시 설치하면 "Bob 's iPhone"이 둘 이상 표시됩니다.
UUID를 생성하고 키 체인에 저장 하시겠습니까? 앱을 제거해도 지속되기 때문에 이것은 나의 계획이었습니다. 그러나 iTunes 백업을 새로운 iOS 장비로 복원 할 때 백업이 암호화되면 키 체인이 전송됩니다. 이전 장치와 새 장치가 모두 서비스중인 경우 동일한 장치 ID를 포함하는 두 개의 장치로 이어질 수 있습니다. 장치 이름이 동일하더라도 온라인 서비스에서 두 장치로 나열되어야합니다.
해시 MAC 주소와 번들 ID를 생성 하시겠습니까? 이것은 내가 필요한 것에 가장 적합한 솔루션처럼 보입니다. 번들 ID로 해싱하면 생성 된 장치 ID가 장치간에 장치를 추적 할 수 없으며 앱 + 장치 조합에 대한 고유 ID를 얻습니다.
Apple 자체 문서는 시스템 MAC 주소의 해시와 번들 ID 및 버전의 해시를 계산하여 Mac App Store 영수증의 유효성을 검사 하는 것에 관한 것입니다. 따라서 아직 알지 못하는 앱 검토를 통과하는지 여부는 정책에 따라 허용되는 것 같습니다.
iOS 6의 경우 Apple 에서 NSUUID 클래스 를 사용 하는 것이 좋습니다 .
속성 에 대한 UIDevice 문서 의 메시지에서 다음을 수행하십시오 uniqueIdentifier
.
iOS 5.0에서 사용되지 않습니다. 이 클래스의 identifierForVendor 특성 또는 ASIdentifierManager 클래스의 AdvertisingIdentifier 특성을 대신 사용하거나 NSUUID 클래스의 UUID 메소드를 사용하여 UUID를 작성하고이를 사용자 기본값 데이터베이스에 쓰십시오.
도움이 될 수 있습니다 : 아래 코드를 사용하면 장치를 지우는 것을 제외하고 항상 고유합니다.
UIDevice *myDevice=[UIDevice currentDevice];
NSString *UUID = [[myDevice identifierForVendor] UUIDString];
또한부터 변경 제안 uniqueIdentifier
에 이 오픈 소스 라이브러리 UDID 교체로 사용할 수있는 응용 프로그램에 고유 ID를 생성하는 응용 프로그램 번들 식별자와 함께 장치의 MAC 주소를 사용 (정말이 개 간단한 분류).
UDID와 달리이 숫자는 모든 앱마다 다릅니다.
포함 NSString
및 UIDevice
카테고리 를 가져 와서 다음과 [[UIDevice currentDevice] uniqueDeviceIdentifier]
같이 호출 하면됩니다.
#import "UIDevice+IdentifierAddition.h"
#import "NSString+MD5Addition.h"
NSString *iosFiveUDID = [[UIDevice currentDevice] uniqueDeviceIdentifier]
Github에서 찾을 수 있습니다 :
iOS 5 용 UniqueIdentifier가있는 UIDevice
범주는 다음과 같습니다 (.m 파일 만-헤더의 github 프로젝트 확인).
UIDevice + IdentifierAddition.m
#import "UIDevice+IdentifierAddition.h"
#import "NSString+MD5Addition.h"
#include <sys/socket.h> // Per msqr
#include <sys/sysctl.h>
#include <net/if.h>
#include <net/if_dl.h>
@interface UIDevice(Private)
- (NSString *) macaddress;
@end
@implementation UIDevice (IdentifierAddition)
////////////////////////////////////////////////////////////////////////////////
#pragma mark -
#pragma mark Private Methods
// Return the local MAC addy
// Courtesy of FreeBSD hackers email list
// Accidentally munged during previous update. Fixed thanks to erica sadun & mlamb.
- (NSString *) macaddress{
int mib[6];
size_t len;
char *buf;
unsigned char *ptr;
struct if_msghdr *ifm;
struct sockaddr_dl *sdl;
mib[0] = CTL_NET;
mib[1] = AF_ROUTE;
mib[2] = 0;
mib[3] = AF_LINK;
mib[4] = NET_RT_IFLIST;
if ((mib[5] = if_nametoindex("en0")) == 0) {
printf("Error: if_nametoindex error\n");
return NULL;
}
if (sysctl(mib, 6, NULL, &len, NULL, 0) < 0) {
printf("Error: sysctl, take 1\n");
return NULL;
}
if ((buf = malloc(len)) == NULL) {
printf("Could not allocate memory. error!\n");
return NULL;
}
if (sysctl(mib, 6, buf, &len, NULL, 0) < 0) {
printf("Error: sysctl, take 2");
return NULL;
}
ifm = (struct if_msghdr *)buf;
sdl = (struct sockaddr_dl *)(ifm + 1);
ptr = (unsigned char *)LLADDR(sdl);
NSString *outstring = [NSString stringWithFormat:@"%02X:%02X:%02X:%02X:%02X:%02X",
*ptr, *(ptr+1), *(ptr+2), *(ptr+3), *(ptr+4), *(ptr+5)];
free(buf);
return outstring;
}
////////////////////////////////////////////////////////////////////////////////
#pragma mark -
#pragma mark Public Methods
- (NSString *) uniqueDeviceIdentifier{
NSString *macaddress = [[UIDevice currentDevice] macaddress];
NSString *bundleIdentifier = [[NSBundle mainBundle] bundleIdentifier];
NSString *stringToHash = [NSString stringWithFormat:@"%@%@",macaddress,bundleIdentifier];
NSString *uniqueIdentifier = [stringToHash stringFromMD5];
return uniqueIdentifier;
}
- (NSString *) uniqueGlobalDeviceIdentifier{
NSString *macaddress = [[UIDevice currentDevice] macaddress];
NSString *uniqueIdentifier = [macaddress stringFromMD5];
return uniqueIdentifier;
}
@end
NSString + MD5Addition.m :
#import "NSString+MD5Addition.h"
#import <CommonCrypto/CommonDigest.h>
@implementation NSString(MD5Addition)
- (NSString *) stringFromMD5{
if(self == nil || [self length] == 0)
return nil;
const char *value = [self UTF8String];
unsigned char outputBuffer[CC_MD5_DIGEST_LENGTH];
CC_MD5(value, strlen(value), outputBuffer);
NSMutableString *outputString = [[NSMutableString alloc] initWithCapacity:CC_MD5_DIGEST_LENGTH * 2];
for(NSInteger count = 0; count < CC_MD5_DIGEST_LENGTH; count++){
[outputString appendFormat:@"%02x",outputBuffer[count]];
}
return [outputString autorelease];
}
@end
이 코드에서 얻을 수 있습니다 : UIDevice-with-UniqueIdentifier-for-iOS-5
MAC 주소를 스푸핑하면 이러한 접근 방식을 사용하여 특정 사용자에게 콘텐츠를 연결하거나 블랙리스트와 같은 보안 기능을 구현할 수 없습니다.
몇 가지 추가 연구를 한 결과, 현재로서는 적절한 대안이없는 것으로 보입니다. 나는 애플이 그들의 결정을 재고하기를 진심으로 바란다.
어쩌면 개발자에게 완전한 결과를 알지 못하기 때문에이 주제에 대해 Apple에 전자 메일을 보내거나 버그 / 기능 요청을 제출하는 것이 좋습니다.
UIDevice identifierForVendor
iOS 6에 도입 된 것은 귀하의 목적에 적합합니다.
identifierForVendor
앱 공급 업체에서 기기를 고유하게 식별하는 영숫자 문자열입니다. (읽기 전용)
@property(nonatomic, readonly, retain) NSUUID *identifierForVendor
이 속성의 값은 동일한 장치에서 실행되는 동일한 공급 업체에서 온 앱의 경우와 동일합니다. 다른 공급 업체에서 제공하는 동일한 장치의 앱과 공급 업체와 관련된 다른 장치의 앱에 대해 다른 값이 반환됩니다.
iOS 6.0 이상에서 사용 가능하며 UIDevice.h
iOS 5의 경우이 링크를 참조하십시오. UIDevice-with-UniqueIdentifier-for-iOS-5
위에서 언급 한 SSKeychain 및 코드 사용 복사 / 붙여 넣기 (SSKeychain 모듈 추가) 코드는 다음과 같습니다.
+(NSString *) getUUID {
//Use the bundle name as the App identifier. No need to get the localized version.
NSString *Appname = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleName"];
//Check if we have UUID already
NSString *retrieveuuid = [SSKeychain passwordForService:Appname account:@"user"];
if (retrieveuuid == NULL)
{
//Create new key for this app/device
CFUUIDRef newUniqueId = CFUUIDCreate(kCFAllocatorDefault);
retrieveuuid = (__bridge_transfer NSString*)CFUUIDCreateString(kCFAllocatorDefault, newUniqueId);
CFRelease(newUniqueId);
//Save key to Keychain
[SSKeychain setPassword:retrieveuuid forService:Appname account:@"user"];
}
return retrieveuuid;
}
다음 코드는 UDID를 얻는 데 도움이됩니다.
udid = [[[UIDevice currentDevice] identifierForVendor] UUIDString];
NSLog(@"UDID : %@", udid);
이것은 iOS 5와 iOS 6, 7 모두의 ID를 얻는 데 사용하는 코드입니다.
- (NSString *) advertisingIdentifier
{
if (!NSClassFromString(@"ASIdentifierManager")) {
SEL selector = NSSelectorFromString(@"uniqueIdentifier");
if ([[UIDevice currentDevice] respondsToSelector:selector]) {
return [[UIDevice currentDevice] performSelector:selector];
}
}
return [[[ASIdentifierManager sharedManager] advertisingIdentifier] UUIDString];
}
iOS 6부터는 RFC4122NSUUID
를 준수하는 클래스 가 있습니다.
Apple Link : NSUUID에 대한 apple_ref
iOS 11은 DeviceCheck 프레임 워크를 도입했습니다. 장치를 고유하게 식별하기위한 완벽한 솔루션이 있습니다.
UDID를 얻는 효과적인 방법 :
- 두 페이지로 앱 내에서 웹 서버를 시작하십시오. 하나는 특수하게 조작 된 MobileConfiguration 프로파일을 리턴하고 다른 하나는 UDID를 수집해야합니다. 더 많은 정보는 여기 , 여기 그리고 여기 .
- 앱 내부에서 Mobile Safari의 첫 페이지를 열면 설정 프로파일 설치를 요청하는 Settings.app로 리디렉션됩니다. 프로파일을 설치하면 UDID가 두 번째 웹 페이지로 전송되며 앱 내부에서 액세스 할 수 있습니다. (Settings.app에는 필요한 모든 권한과 다른 샌드 박스 규칙이 있습니다).
RoutingHTTPServer 를 사용하는 예 :
import UIKit
import RoutingHTTPServer
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var bgTask = UIBackgroundTaskInvalid
let server = HTTPServer()
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
application.openURL(NSURL(string: "http://localhost:55555")!)
return true
}
func applicationDidEnterBackground(application: UIApplication) {
bgTask = application.beginBackgroundTaskWithExpirationHandler() {
dispatch_async(dispatch_get_main_queue()) {[unowned self] in
application.endBackgroundTask(self.bgTask)
self.bgTask = UIBackgroundTaskInvalid
}
}
}
}
class HTTPServer: RoutingHTTPServer {
override init() {
super.init()
setPort(55555)
handleMethod("GET", withPath: "/") {
$1.setHeader("Content-Type", value: "application/x-apple-aspen-config")
$1.respondWithData(NSData(contentsOfFile: NSBundle.mainBundle().pathForResource("udid", ofType: "mobileconfig")!)!)
}
handleMethod("POST", withPath: "/") {
let raw = NSString(data:$0.body(), encoding:NSISOLatin1StringEncoding) as! String
let plistString = raw.substringWithRange(Range(start: raw.rangeOfString("<?xml")!.startIndex,end: raw.rangeOfString("</plist>")!.endIndex))
let plist = NSPropertyListSerialization.propertyListWithData(plistString.dataUsingEncoding(NSISOLatin1StringEncoding)!, options: .allZeros, format: nil, error: nil) as! [String:String]
let udid = plist["UDID"]!
println(udid) // Here is your UDID!
$1.statusCode = 200
$1.respondWithString("see https://developer.apple.com/library/ios/documentation/NetworkingInternet/Conceptual/iPhoneOTAConfiguration/ConfigurationProfileExamples/ConfigurationProfileExamples.html")
}
start(nil)
}
}
내용은 다음과 같습니다 udid.mobileconfig
.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>PayloadContent</key>
<dict>
<key>URL</key>
<string>http://localhost:55555</string>
<key>DeviceAttributes</key>
<array>
<string>IMEI</string>
<string>UDID</string>
<string>PRODUCT</string>
<string>VERSION</string>
<string>SERIAL</string>
</array>
</dict>
<key>PayloadOrganization</key>
<string>udid</string>
<key>PayloadDisplayName</key>
<string>Get Your UDID</string>
<key>PayloadVersion</key>
<integer>1</integer>
<key>PayloadUUID</key>
<string>9CF421B3-9853-9999-BC8A-982CBD3C907C</string>
<key>PayloadIdentifier</key>
<string>udid</string>
<key>PayloadDescription</key>
<string>Install this temporary profile to find and display your current device's UDID. It is automatically removed from device right after you get your UDID.</string>
<key>PayloadType</key>
<string>Profile Service</string>
</dict>
</plist>
프로파일 설치가 실패하지만 (예상 응답을 구현하지 않아도 설명서를 참조하십시오 ) 앱에 올바른 UDID가 표시됩니다. 또한 mobileconfig에 서명 해야합니다 .
당신이 사용할 수있는
NSString *sID = [[[ASIdentifierManager sharedManager] advertisingIdentifier] UUIDString];
모든 응용 프로그램에서 장치에 고유합니다.
Apple은 iOS 11에 DeviceCheck라는 새로운 프레임 워크를 추가하여 고유 식별자를 매우 쉽게 얻을 수 있도록 도와줍니다. 자세한 내용은이 양식을 읽으십시오. https://medium.com/@santoshbotre01/unique-identifier-for-the-ios-devices-590bb778290d
대안을 찾을 때 누군가 가이 질문에 걸려 넘어지면. 나는이 접근법을 IDManager
수업 에서 따랐습니다. 이것은 다른 솔루션의 모음입니다. KeyChainUtil은 키 체인에서 읽을 수있는 래퍼입니다. 또한 hashed MAC address
일종의 고유 ID로 사용할 수 있습니다 .
/* Apple confirmed this bug in their system in response to a Technical Support Incident
request. They said that identifierForVendor and advertisingIdentifier sometimes
returning all zeros can be seen both in development builds and apps downloaded over the
air from the App Store. They have no work around and can't say when the problem will be fixed. */
#define kBuggyASIID @"00000000-0000-0000-0000-000000000000"
+ (NSString *) getUniqueID {
if (NSClassFromString(@"ASIdentifierManager")) {
NSString * asiID = [[[ASIdentifierManager sharedManager] advertisingIdentifier] UUIDString];
if ([asiID compare:kBuggyASIID] == NSOrderedSame) {
NSLog(@"Error: This device return buggy advertisingIdentifier.");
return [IDManager getUniqueUUID];
} else {
return asiID;
}
} else {
return [IDManager getUniqueUUID];
}
}
+ (NSString *) getUniqueUUID {
NSError * error;
NSString * uuid = [KeychainUtils getPasswordForUsername:kBuyassUser andServiceName:kIdOgBetilngService error:&error];
if (error) {
NSLog(@"Error geting unique UUID for this device! %@", [error localizedDescription]);
return nil;
}
if (!uuid) {
DLog(@"No UUID found. Creating a new one.");
uuid = [IDManager GetUUID];
uuid = [Util md5String:uuid];
[KeychainUtils storeUsername:USER_NAME andPassword:uuid forServiceName:SERVICE_NAME updateExisting:YES error:&error];
if (error) {
NSLog(@"Error getting unique UUID for this device! %@", [error localizedDescription]);
return nil;
}
}
return uuid;
}
/* NSUUID is after iOS 6. */
+ (NSString *)GetUUID
{
CFUUIDRef theUUID = CFUUIDCreate(NULL);
CFStringRef string = CFUUIDCreateString(NULL, theUUID);
CFRelease(theUUID);
return [(NSString *)string autorelease];
}
#pragma mark - MAC address
// Return the local MAC addy
// Courtesy of FreeBSD hackers email list
// Last fallback for unique identifier
+ (NSString *) getMACAddress
{
int mib[6];
size_t len;
char *buf;
unsigned char *ptr;
struct if_msghdr *ifm;
struct sockaddr_dl *sdl;
mib[0] = CTL_NET;
mib[1] = AF_ROUTE;
mib[2] = 0;
mib[3] = AF_LINK;
mib[4] = NET_RT_IFLIST;
if ((mib[5] = if_nametoindex("en0")) == 0) {
printf("Error: if_nametoindex error\n");
return NULL;
}
if (sysctl(mib, 6, NULL, &len, NULL, 0) < 0) {
printf("Error: sysctl, take 1\n");
return NULL;
}
if ((buf = malloc(len)) == NULL) {
printf("Error: Memory allocation error\n");
return NULL;
}
if (sysctl(mib, 6, buf, &len, NULL, 0) < 0) {
printf("Error: sysctl, take 2\n");
free(buf); // Thanks, Remy "Psy" Demerest
return NULL;
}
ifm = (struct if_msghdr *)buf;
sdl = (struct sockaddr_dl *)(ifm + 1);
ptr = (unsigned char *)LLADDR(sdl);
NSString *outstring = [NSString stringWithFormat:@"%02X:%02X:%02X:%02X:%02X:%02X", *ptr, *(ptr+1), *(ptr+2), *(ptr+3), *(ptr+4), *(ptr+5)];
free(buf);
return outstring;
}
+ (NSString *) getHashedMACAddress
{
NSString * mac = [IDManager getMACAddress];
return [Util md5String:mac];
}
+ (NSString *)md5String:(NSString *)plainText
{
if(plainText == nil || [plainText length] == 0)
return nil;
const char *value = [plainText UTF8String];
unsigned char outputBuffer[CC_MD5_DIGEST_LENGTH];
CC_MD5(value, strlen(value), outputBuffer);
NSMutableString *outputString = [[NSMutableString alloc] initWithCapacity:CC_MD5_DIGEST_LENGTH * 2];
for(NSInteger count = 0; count < CC_MD5_DIGEST_LENGTH; count++){
[outputString appendFormat:@"%02x",outputBuffer[count]];
}
NSString * retString = [NSString stringWithString:outputString];
[outputString release];
return retString;
}
+ (NSString *) getUniqueUUID {
NSError * error;
NSString * uuid = [KeychainUtils getPasswordForUsername:kBuyassUser andServiceName:kIdOgBetilngService error:&error];
if (error) {
NSLog(@"Error geting unique UUID for this device! %@", [error localizedDescription]);
return nil;
}
if (!uuid) {
DLog(@"No UUID found. Creating a new one.");
uuid = [IDManager GetUUID];
uuid = [Util md5String:uuid];
[KeychainUtils storeUsername:USER_NAME andPassword:uuid forServiceName:SERVICE_NAME updateExisting:YES error:&error];
if (error) {
NSLog(@"Error getting unique UUID for this device! %@", [error localizedDescription]);
return nil;
}
}
return uuid;
}
ios7에 identifierForVendor 를 사용할 수 있습니다 .
-(NSString*)uniqueIDForDevice
{
NSString* uniqueIdentifier = nil;
if( [UIDevice instancesRespondToSelector:@selector(identifierForVendor)] ) { // >=iOS 7
uniqueIdentifier = [[[UIDevice currentDevice] identifierForVendor] UUIDString];
} else { //<=iOS6, Use UDID of Device
CFUUIDRef uuid = CFUUIDCreate(NULL);
//uniqueIdentifier = ( NSString*)CFUUIDCreateString(NULL, uuid);- for non- ARC
uniqueIdentifier = ( NSString*)CFBridgingRelease(CFUUIDCreateString(NULL, uuid));// for ARC
CFRelease(uuid);
}
}
return uniqueIdentifier;
}
--중요 사항 ---
UDID와 identifierForVendor가 다릅니다 : ---
1.) On uninstalling and reinstalling the app identifierForVendor will change.
2.) The value of identifierForVendor remains the same for all the apps installed from the same vendor on the device.
3.) The value of identifierForVendor also changes for all the apps if any of the app (from same vendor) is reinstalled.
Apple은 iOS 7부터 모든 공개 API에서 UDID를 숨겼습니다. FFFF로 시작하는 모든 UDID는 가짜 ID입니다. 이전에 작동 한 "UDID 보내기"앱을 더 이상 테스트 장치의 UDID를 수집하는 데 사용할 수 없습니다. (한숨!)
UDID는 기기가 XCode (주최자)에 연결되어있을 때와 기기가 iTunes에 연결되어있을 때 표시됩니다 (단, 일련 번호)를 클릭하여 식별자를 표시해야합니다.
장비가 프로비저닝 프로파일에 추가하기 위해 UDID를 가져와야하고 XCode에서 직접 수행 할 수없는 경우 iTunes에서 복사 / 붙여 넣기 단계를 수행해야합니다.
PC / Mac에서 iTunes를 사용하지 않고 UDID를 얻는 방법이 있습니까 (iOS 7 릴리스)?
나도 문제가 있었고 해결책은 간단합니다.
// Get Bundle Info for Remote Registration (handy if you have more than one app)
NSString *appName = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleDisplayName"];
NSString *appVersion = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleVersion"];
// Get the users Device Model, Display Name, Unique ID, Token & Version Number
UIDevice *dev = [UIDevice currentDevice];
NSString *deviceUuid=[dev.identifierForVendor UUIDString];
NSString *deviceName = dev.name;
완벽하지는 않지만 UDID에 대한 가장 좋고 가장 가까운 대안 중 하나입니다 (iOS 8.1 및 Xcode 6.1을 사용하는 Swift에서).
임의의 UUID 생성
let strUUID: String = NSUUID().UUIDString
그리고 KeychainWrapper 라이브러리를 사용하십시오 :
키 체인에 문자열 값을 추가하십시오.
let saveSuccessful: Bool = KeychainWrapper.setString("Some String", forKey: "myKey")
키 체인에서 문자열 값을 검색하십시오.
let retrievedString: String? = KeychainWrapper.stringForKey("myKey")
키 체인에서 문자열 값을 제거하십시오.
let removeSuccessful: Bool = KeychainWrapper.removeObjectForKey("myKey")
이 솔루션은 키 체인을 사용하므로 앱을 제거한 후 다시 설치 한 후에도 키 체인에 저장된 레코드가 유지됩니다. 이 레코드를 삭제하는 유일한 방법은 장치의 모든 내용과 설정을 재설정하는 것입니다. 그렇기 때문에이 대체 솔루션이 완벽하지는 않지만 Swift를 사용하는 iOS 8.1에서 UDID를 대체하는 최상의 솔루션 중 하나를 유지합니다.
NSLog (@ "% @", [[UIDevice currentDevice] identifierForVendor]);
Swift 3.0의 경우 아래 코드를 사용하십시오.
let deviceIdentifier: String = (UIDevice.current.identifierForVendor?.uuidString)!
NSLog("output is : %@", deviceIdentifier)
참고 URL : https://stackoverflow.com/questions/6993325/uidevice-uniqueidentifier-deprecated-what-to-do-now
'Programming' 카테고리의 다른 글
Swift에서 문자열에 다른 문자열이 포함되어 있는지 어떻게 확인합니까? (0) | 2020.02.12 |
---|---|
Java에서 바이트 크기를 사람이 읽을 수있는 형식으로 변환하는 방법은 무엇입니까? (0) | 2020.02.12 |
비표준 글꼴을 웹 사이트에 추가하는 방법은 무엇입니까? (0) | 2020.02.12 |
존재하지 않음 vs 존재하지 않음 (0) | 2020.02.12 |
앵커 안에 div를 넣는 것이 올바른가요? (0) | 2020.02.12 |