2014-12-22 115 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