提醒:這是僅適用於非應用商店的應用程序(如那些用於在內部的分佈,或用於破解的設備)。如果您將此代碼提交給Apple,它將被拒絕。
以下是一種基於IOKit的方法,用於檢索電池的序列號,這是設備的一個很好的靜態唯一ID,它將在給定設備上的所有應用程序中保持一致。以下代碼適用於iOS 8和9,但不適用於舊版本。
- (NSString *) deviceUniqueID
{
mach_port_t iokitPort = 0;
CFMutableDictionaryRef properties;
IOMasterPort(0, &iokitPort);
CFDictionaryRef serviceName = IOServiceNameMatching("charger");
io_service_t service = IOServiceGetMatchingService(iokitPort, serviceName);
if (service == 0)
return nil;
kern_return_t status = IORegistryEntryCreateCFProperties(service,
&properties,
kCFAllocatorDefault,
kNilOptions);
IOObjectRelease(service);
if (status == KERN_SUCCESS)
{
NSDictionary *dict = (__bridge NSDictionary *)(properties);
NSData *batteryIDData = dict[@"battery-id"];
CFRelease(properties);
if ([batteryIDData isKindOfClass: [NSData class]])
return [NSString stringWithUTF8String:[batteryIDData bytes]];
}
return nil;
}
此代碼需要一堆IOKit符號。你可以包含必要的IOKit頭文件,但這可能有點痛苦。假如你不使用由於IOKit別處,剛纔添加以下的聲明,它應該罰款編譯:現在
typedef mach_port_t io_object_t;
typedef io_object_t io_registry_entry_t;
typedef io_object_t io_iterator_t;
typedef io_object_t io_connect_t;
typedef io_object_t io_service_t;
typedef UInt32 IOOptionBits;
kern_return_t IOMasterPort(mach_port_t bootstrapPort, mach_port_t *masterPort);
CFMutableDictionaryRef IOServiceNameMatching(const char *name);
io_service_t IOServiceGetMatchingService (mach_port_t masterPort, CFDictionaryRef matching);
kern_return_t IORegistryEntryCreateCFProperties(io_registry_entry_t entry,
CFMutableDictionaryRef *properties,
CFAllocatorRef allocator,
IOOptionBits options);
kern_return_t IOObjectRelease (io_object_t object);
,爲得到它的鏈接,你將需要IOKit.framework添加到您的應用程序。在大多數系統上,它應該可以在/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk/System/Library/Frameworks/IOKit.framework
我添加了越獄標籤,因爲這是一個不適用於應用商店的問題,不確定這是否是正確的標籤,他可以通過企業帳戶進行分發。 –