如何在iOS8中使用IOKit获取设备的序列号,因为IOPlatformSerialNumber给出nil值

时间:2014-12-22 12:02:39

标签: ios ios8 jailbreak ipod iokit

我想知道如何在iOS8中使用IOKit获取设备的序列号?我使用了UIDevice+serialNumber,我可以在iOS6和7中获得序列号。在iOS8中,platformSerialNumber的值在以下行中显示为nil

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

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

注意:我的应用程序不会进入应用程序商店,它用于内部。所以我正在寻找一些永远不会改变的具体事物,无论是String还是整数

3 个答案:

答案 0 :(得分:3)

从iOS 8开始,硬件信息(例如序列号)受到保护。如果要检索此值,则必须使用私有权利对应用进行签名。我不确定是否可以在企业应用中使用私有权利,而且它们当然不能用于App Store应用,但这个问题会被越狱标记,所以我会这样做为此提供解决方案。

如果您希望序列号跟踪公司拥有的设备,我建议您使用Apple的移动设备管理(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>

答案 1 :(得分:2)

提醒:这仅适用于非App Store应用程序(例如用于内部分发或越狱设备的应用程序)。如果您将此代码提交给Apple,它将被拒绝。

以下是一种基于IOKit的方法,用于检索电池的序列号,该序列号是设备的良好静态唯一ID,在给定设备上的所有应用程序中都是相同的。以下代码适用于iOS 8和9,但不适用于旧版本。

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符号。您可以包含必要的IOKit标头,但这可能有点痛苦。假设您没有在其他地方使用IOKit,只需添加以下声明即可编译:

/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk/System/Library/Frameworks/IOKit.framework

现在,至于要进行链接,您需要将IOKit.framework添加到您的应用中。在大多数系统上,它应该在public static void main(String[] args) throws InvalidFormatException, IOException { String filePath = "Sample.docx"; File outputfile = new File("SampleProcessed.docx"); XWPFDocument doc = new XWPFDocument(OPCPackage.open(filePath)); for (XWPFParagraph p : doc.getParagraphs()) { List<XWPFRun> runs = p.getRuns(); if (runs != null) { for (XWPFRun r : runs) { String text = r.getText(0); if (text != null && text.contains("$VAR")) { text = text.replace("$VAR", "JohnDoe"); r.setText(text, 0); } } } } doc.write(new FileOutputStream(outputfile)); doc.close(); System.out.println("Done"); Desktop.getDesktop().open(outputfile); }

处可用

答案 2 :(得分:1)

我不知道如何在iOS8下获取序列号。我很确定不再允许这样做。 Apple现在希望您使用ASIdentifierManager的

@property(nonatomic, readonly) NSUUID *advertisingIdentifier

有关详细信息,请参阅https://developer.apple.com/library/prerelease/ios/documentation/AdSupport/Reference/ASIdentifierManager_Ref/index.html

注意:如果您使用此功能,您将被拒绝,或者不提供广告或更改应用行为以响应以前投放的广告。我们做了以后,仍被拒绝,但后来在我们的提交说明中解释了我们使用它的确切内容(我们被接受了。)