2013-02-23 76 views
3

MonoTouch有一个简单的机制来检索iOS设备的设备序列号(非UDID)吗?有没有我可以用来获得这个的第三方库?使用MonoTouch检索iOS设备的设备序列号的最简单方法是什么?

万一它很重要,我打算在内部应用程序中使用此功能,而不关心App Store审批流程。

+0

[你如何以编程方式获取iPhone的序列号?](http://stackoverflow.com/questions/756101/how-do-you-programmatically-get-the-serial-number-of -an-iphone) – 2013-02-23 02:52:41

+0

同时http://stackoverflow.com/questions/7147416/if-i-access-the-iphone-serial-number-inside-an-app-is-it-allowed-in-the-app -sto – 2013-02-23 02:52:55

+0

我正在寻找一种基于MonoTouch的解决方案,并认为应该有一种更简单的方法来实现这一点,而不是编写和绑定本地iOS库以获得单一功能。 – OpenAway 2013-02-23 03:11:19

回答

8

更新:从iOS 8,我们无法检索我们的iDevice的序列号。

从MonoTouch的检索iPhone序列号,您可以使用此工艺:

  1. 创建在Xcode静态库。一个有一个函数来获取序列号
  2. 在MonoDevelop中,创建绑定项目将您的.a库绑定到C#类/函数(http://docs.xamarin.com/guides/ios/advanced_topics/binding_objective-c_libraries
  3. 在您的应用程序中,您可以调用该绑定库(在步骤2中)。

对于细节:

STEP 1.我library.a,我有一个类DeviceInfo,这里是实现获得序列号

#import "DeviceInfo.h" 

#import <dlfcn.h> 
#import <mach/port.h> 
#import <mach/kern_return.h> 
@implementation DeviceInfo 

- (NSString *) serialNumber 
{ 
    NSString *serialNumber = nil; 

    void *IOKit = dlopen("/System/Library/Frameworks/IOKit.framework/IOKit", RTLD_NOW); 
    if (IOKit) 
    { 
     mach_port_t *kIOMasterPortDefault = dlsym(IOKit, "kIOMasterPortDefault"); 
     CFMutableDictionaryRef (*IOServiceMatching)(const char *name) = dlsym(IOKit, "IOServiceMatching"); 
     mach_port_t (*IOServiceGetMatchingService)(mach_port_t masterPort, CFDictionaryRef matching) = dlsym(IOKit, "IOServiceGetMatchingService"); 
     CFTypeRef (*IORegistryEntryCreateCFProperty)(mach_port_t entry, CFStringRef key, CFAllocatorRef allocator, uint32_t options) = dlsym(IOKit, "IORegistryEntryCreateCFProperty"); 
     kern_return_t (*IOObjectRelease)(mach_port_t object) = dlsym(IOKit, "IOObjectRelease"); 

     if (kIOMasterPortDefault && IOServiceGetMatchingService && IORegistryEntryCreateCFProperty && IOObjectRelease) 
     { 
      mach_port_t platformExpertDevice = IOServiceGetMatchingService(*kIOMasterPortDefault, IOServiceMatching("IOPlatformExpertDevice")); 
      if (platformExpertDevice) 
      { 
       CFTypeRef platformSerialNumber = IORegistryEntryCreateCFProperty(platformExpertDevice, CFSTR("IOPlatformSerialNumber"), kCFAllocatorDefault, 0); 
       if (CFGetTypeID(platformSerialNumber) == CFStringGetTypeID()) 
       { 
        serialNumber = [NSString stringWithString:(__bridge NSString*)platformSerialNumber]; 
        CFRelease(platformSerialNumber); 
       } 
       IOObjectRelease(platformExpertDevice); 
      } 
     } 
     dlclose(IOKit); 
    } 

    return serialNumber; 
} 

@end 

第2步。在Monotouch中我的Binding Library项目的ApiDefinition.cs中添加了以下绑定:

[BaseType (typeof (NSObject))] 
    public interface DeviceInfo { 
     [Export ("serialNumber")] 
     NSString GetSerialNumber(); 
    } 

步骤3.在我的应用程序中,我在步骤2中导入参考到绑定库项目,然后使用MyBindingProject添加

;

...

string serialNumber = ""; 
      try { 
       DeviceInfo nativeDeviceInfo = new DeviceInfo(); 
       NSString temp = nativeDeviceInfo.GetSerialNumber(); 
       serialNumber = temp.ToString(); 
      } catch (Exception ex) { 
       Console.WriteLine("Cannot get serial number {0} - {1}",ex.Message, ex.StackTrace); 
      } 

希望有所帮助。如果您有任何问题,请不要犹豫。

+0

我试了一下代码,并且适用于iOS7_beta。 Bt,我不确定是否会在不久的将来弃用它,或者IOKit.Framework的可访问性会受到影响? 如果您能找到,请回复有效的链接。 – Meet 2013-08-14 06:49:32

+0

作为更新,这似乎仍然在IOS7中工作。 – OpenAway 2013-10-26 22:21:47

+3

谢谢,我试过,但它在iOS 8 beta 5崩溃....任何其他好的方法,为iOS 7和iOS 8?请告知 – Meet 2014-08-13 06:34:02

相关问题