3

Does MonoTouch have a simple mechanism for retrieving the device serial number (not UDID) of an iOS device? Is there a third-party library which I can use to obtain this?

In case it matters, I'm looking to use this functionality in an in-house application and am not concerned with the App Store approval process.

OpenAway
  • 33
  • 1
  • 1
  • 4
  • possible duplicate of [How do you programmatically get the serial number of an iPhone?](http://stackoverflow.com/questions/756101/how-do-you-programmatically-get-the-serial-number-of-an-iphone) – tc. Feb 23 '13 at 02:52
  • Also http://stackoverflow.com/questions/7147416/if-i-access-the-iphone-serial-number-inside-an-app-is-it-allowed-in-the-app-sto – tc. Feb 23 '13 at 02:52
  • I'm specifically looking for a MonoTouch-based solution, and figure that there should be a simpler way to achieve this than writing and binding a native iOS library to gain a single function. – OpenAway Feb 23 '13 at 03:11
  • It's a private C API. It should be reasonably easy if you can link IOKit (possibly dynamically with `dlopen()`?) and make calls to C functions from MonoTouch (I had the impression that C# could do this without too much fuss), otherwise you'll need to write some native code or find someone else who has. Additionally, IME object file compatibility often breaks across major iOS SDK updates, so such a library would need to be provided as source or as a frequently-updated binary; the latter doesn't seem worth it for functionality that can't go on the app store. – tc. Feb 23 '13 at 04:14
  • Is it possible you can use a different ID? Or do you specifically need the UUID? There are a few (like advertising id http://developer.apple.com/library/ios/#documentation/AdSupport/Reference/ASIdentifierManager_Ref/ASIdentifierManager.html) that you could use instead, and are more supported by Xamarin and Apple. – jonathanpeppers Feb 25 '13 at 13:23
  • Specifically, I need the device serial number, or failing that, another value which users can easily look up on new iPads themselves without requiring the use of a downloaded app. – OpenAway Feb 26 '13 at 12:47

1 Answers1

8

UPDATE: from iOS 8, we cannot retrieve the serial number of our iDevice.

To retrieve iphone serial number from Monotouch, you can use this technic:

  1. Create a static library .a from XCode that have a function to get serial number
  2. In MonoDevelop, create a binding project to bind you .a library into C# classes/functions (http://docs.xamarin.com/guides/ios/advanced_topics/binding_objective-c_libraries)
  3. In your application, you call this binding library (in step 2).

For detail:

STEP 1. In my library.a, I have a class DeviceInfo, here is the implementation to get Serial number

#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

STEP 2. In ApiDefinition.cs of my Binding Library project in Monotouch, I add this binding:

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

STEP 3. In my application, I import Reference to Binding library project in step 2, then add

using 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);
            }

Hope that helps. Don't hesitate if you have any question.

Duyen-Hoa
  • 15,384
  • 5
  • 35
  • 44
  • I tried the code and works fine for iOS7_beta. Bt, I am not sure whether, it will deprecate or not in near future, or the accessibility of the DLL IOKit.Framework will be affected? Please reply with valid link if you could find. – Meet Aug 14 '13 at 06:49
  • 3
    Thanks, I tried this but it gives crash in iOS 8 beta 5....any other good approach for both iOS 7 and iOS 8?? Please advise – Meet Aug 13 '14 at 06:34
  • No, you can't get the serial number in iOS8. – Duyen-Hoa Jan 21 '15 at 10:16