2014-12-22 1 views
2

Мне было интересно узнать, как получить серийный номер устройства, используя IOKit в iOS8? Я использовал UIDevice+serialNumber, и я могу получить серийный номер в iOS6 и7. В iOS8 значение platformSerialNumber приходит nil в следующей строке:Как получить серийный номер устройства с использованием IOKit в iOS8 как IOPlatformSerialNumber, задающий значение nil

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

Я использую: https://gist.github.com/0xced/566994

Примечание: Мое приложение не будет идти в магазин приложений, его за просмотр. Поэтому я ищу что-то более конкретное, которое никогда не изменится, ни String, ни целое

+0

Я добавил тэг джейлбрейка, так как это вопрос не для магазина приложений, не уверен, что это правильный тег, он может распространяться через учетную запись Enterprise. –

ответ

1

Я не знаю, как получить серийный номер под iOS8. Я почти уверен, что это больше не разрешено. Apple, теперь хочет, чтобы вы использовать ASIdentifierManager-х

@property(nonatomic, readonly) NSUUID *advertisingIdentifier 

См https://developer.apple.com/library/prerelease/ios/documentation/AdSupport/Reference/ASIdentifierManager_Ref/index.html более подробно.

Примечание. Если вы используете это, вы отклоните его и не будете показывать рекламу или изменять поведение приложений в ответ на ранее загруженное объявление. Мы делаем это позже, но все же отказались, но затем пояснили в наших сообщениях о том, что мы используем для этого (и мы были приняты.)

+0

Будет ли он изменяться после удаления и установки приложения снова? – Inder

+0

Нет, но он изменится, когда пользователь перейдет в настройку> Конфиденциальность и т. Д. ... и сбрасывает рекламный индекс. Извините, так хочет Apple. –

+0

Я согласен с вами, Пол, но мое приложение не пойдет в магазин приложений, его для дома. Поэтому я ищу что-то более конкретное, которое никогда не изменится. – Inder

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

Entitlements:

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

Возврат null в версии iOS 7.1.1 – Inder

+0

Меня интересует это, можете ли вы рассказать мне больше о том, как делать с правами? Что я добавил в этот файл, чтобы получить серийный номер? –

+0

@ tyt_g207 Вы должны разрабатывать приложение для взлома, чтобы использовать частные права. Я обновил свой ответ, если вы есть, но если нет, я боюсь, что вам может быть не повезло. Я не смог найти способ получить аппаратную информацию на iOS 8 без прав. –

2

Напоминание: Это применимо только к не-App магазин приложений (например, те, которые предназначены для распространения в доме, или для взломанных устройств). Если вы отправите этот код в Apple, он будет отклонен.

Ниже приведен подход, основанный на IOKit, который извлекает серийный номер аккумулятора, который является хорошим статическим уникальным идентификатором для устройства, которое будет одинаковым для всех приложений на данном устройстве. Следующий код работает для 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

Смежные вопросы