提醒:这是仅适用于非应用商店的应用程序(如那些用于在内部的分布,或用于破解的设备)。如果您将此代码提交给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
我添加了越狱标签,因为这是一个不适用于应用商店的问题,不确定这是否是正确的标签,他可以通过企业帐户进行分发。 –