2014-12-22 114 views
2

我想知道如何获得iOS8上使用IOKit设备的序列号的设备的序列号?我使用UIDevice+serialNumber,我可以在iOS6和7中获得序列号。在iOS8上的platformSerialNumber值来nil下面一行:如何获得在iOS8上的使用由于IOKit作为IOPlatformSerialNumber给予零值

CFTypeRef platformSerialNumber = IORegistryEntryCreateCFProperty(platformExpertDevice,CFSTR("IOPlatformSerialNumber"), kCFAllocatorDefault, 0); 

我使用:https://gist.github.com/0xced/566994

注:我的应用程序不会去应用程序商店,其点播服务。所以我要寻找更具体的东西是永远不会改变,无论是字符串或整数

+0

我添加了越狱标签,因为这是一个不适用于应用商店的问题,不确定这是否是正确的标签,他可以通过企业帐户进行分发。 –

回答

1

我不知道怎么去iOS8上的下序列号。我很确定它不再被允许。苹果现在要你使用ASIdentifierManager的

@property(nonatomic, readonly) NSUUID *advertisingIdentifier 

更多细节见https://developer.apple.com/library/prerelease/ios/documentation/AdSupport/Reference/ASIdentifierManager_Ref/index.html

注:如果您使用此,要么不投放广告或响应改变应用程序的行为与先前提供的广告你会被拒绝。我们做了以后,得到了拒绝依旧,但后来在我们提交解释指出正是我们使用它(我们被接受。)

+0

一旦删除并重新安装应用程序,它会改变吗? – Inder

+0

不,但会在用户进入设置>隐私等等时更改,并重置广告索引。对不起,这就是苹果想要的方式。 –

+0

我同意你的保罗,但我的应用程序不会去应用程序商店,它的内部。所以我正在寻找更具体的东西,永远不会改变。 – Inder

3

iOS中8,硬件信息,启动如序列号,是受保护的。如果您想要检索此值,则必须使用私有权利对您的应用程序进行签名。我不确定是否可以在企业应用程序中使用私有权利,并且它们当然不能用于App Store应用程序,但是此问题标有越狱,因此我将为此提供解决方案。

如果你想要的序列号来跟踪你的公司拥有的设备,我建议采取像苹果的移动设备管理(MDM)服务的优势。这使您可以访问大量有关设备的信息,并允许您远程管理它们。

如果您只是在寻找一个永远不会为其他目的而改变的标识符,我建议您改用设备的UDID。我可以在没有权利的情况下在我的设备上获得此信息,但这可能是由于我的手机遭到越狱。其他人告诉我,实际上需要权利。有关这方面的更多信息可以在iPhoneDevWiki找到。

代码:

- (NSString *)udid 
{ 
    void *gestalt = dlopen("/usr/lib/libMobileGestalt.dylib", RTLD_GLOBAL | RTLD_LAZY); 
    CFStringRef (*MGCopyAnswer)(CFStringRef) = (CFStringRef (*)(CFStringRef))(dlsym(gestalt, "MGCopyAnswer")); 
    return CFBridgingRelease(MGCopyAnswer(CFSTR("UniqueDeviceID"))); 
} 

享权利:

<key>com.apple.private.MobileGestalt.AllowedProtectedKeys</key> 
<array> 
    <string>UniqueDeviceID</string> 
</array> 
+0

iOS版本7.1.1中返回null – Inder

+0

我对此感兴趣,你能告诉我更多如何处理权利?我为了获得序列号而添加到这个文件中? –

+0

@ tyt_g207您必须开发越狱应用才能使用私有权利。如果你是,我已经更新了我的答案,但如果不是的话,恐怕你的运气可能不好。我无法找到任何方式来检索iOS 8上没有授权的硬件信息。 –

2

提醒:这是仅适用于非应用商店的应用程序(如那些用于在内部的分布,或用于破解的设备)。如果您将此代码提交给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