UIDevice uniqueIdentifier устарел. Что теперь делать?

Только что стало известно, что свойство UIDevice uniqueIdentifier устарело в iOS 5 и недоступно в iOS 7 и более поздних версиях. Никаких альтернативных методов или свойств, похоже, не существует или не ожидается.

Многие из наших существующих приложений сильно зависят от этого свойства для уникальной идентификации конкретного устройства. Как мы можем решить эту проблему в будущем?

Предложение от документация 2011-2012 гг. была следующей:

Особые соображения

Не используйте свойство uniqueIdentifier. Чтобы создать уникальный идентификатор, специфичный для вашего приложения, вы можете вызвать функцию CFUUIDCreate, чтобы создать UUID, и записать его в базу данных по умолчанию с помощью класса NSUserDefaults.

Однако это значение не будет таким же, если пользователь удалит и повторно установит приложение.


person Oliver Pearmain    schedule 09.08.2011    source источник
comment
Для приложений, все еще использующих uniqueIdentifier, iOS7 теперь возвращает FFFFFFFF + identifierForVendor, что нарушает работу многих плохо написанных приложений с невозобновляемой подпиской.   -  person Rhythmic Fistman    schedule 24.09.2013
comment
Если по счастливой случайности ваше приложение использует Push-уведомления, вы можете использовать токен, отправленный обратно из службы push-уведомлений Apple, он также уникален для каждого устройства.   -  person Calin Chitu    schedule 31.01.2014
comment
@CalinChitu. Если пользователь не принимает push-уведомления, вы все равно получаете pushID для этого пользователя?   -  person Chase Roberts    schedule 02.10.2014


Ответы (31)


UUID, созданный CFUUIDCreate , уникален, если пользователь удаляет и повторно устанавливает приложение: вы будете получать новый каждый раз.

Но вы можете захотеть, чтобы он был не уникальным, т.е. е. он должен оставаться неизменным, когда пользователь удаляет и повторно устанавливает приложение. Это требует немного усилий, поскольку наиболее надежным идентификатором устройства является MAC-адрес. Вы можете запросить MAC и используйте это как UUID.

Изменить. Конечно, всегда нужно запрашивать MAC одного и того же интерфейса. Думаю, лучше всего с en0. MAC присутствует всегда, даже если интерфейс не имеет IP / не работает.

Изменить 2: Как указывалось другими, предпочтительным решением с iOS 6 является - [UIDevice identifierForVendor]. В большинстве случаев вы сможете использовать его как замену старому -[UIDevice uniqueIdentifier] (но, похоже, Apple хочет, чтобы вы использовали UUID, который создается при первом запуске приложения).

Редактировать 3: Чтобы этот важный момент не терялся в шуме комментариев: не используйте MAC в качестве UUID, создайте хэш , используя MAC. Этот хеш всегда будет создавать один и тот же результат каждый раз, даже при переустановке и приложениях (если хеширование выполняется одинаково). В любом случае, в настоящее время (2013 г.) в этом больше нет необходимости, за исключением случаев, когда вам нужен «стабильный» идентификатор устройства на iOS ‹6.0.

Изменить 4: в iOS 7 Apple теперь всегда возвращает фиксированное значение при запросе MAC, чтобы специально помешать MAC в качестве основы для схемы идентификатора. Итак, теперь вам действительно следует использовать - [UIDevice identifierForVendor] или создать per-install UUID.

person DarkDust    schedule 09.08.2011
comment
Не меняется ли MAC-адрес в зависимости от того, подключен ли пользователь через Wi-Fi или нет? - person Oliver Pearmain; 09.08.2011
comment
Нет, IP есть, но не MAC. MAC уникален для интерфейса. - person DarkDust; 09.08.2011
comment
@DarkDust: но поскольку активный интерфейс изменяется при переключении с Wi-Fi на сотовый модем, MAC-адрес активного интерфейса также должен измениться; если вы всегда не выбираете конкретный интерфейс для получения MAC - person user102008; 27.08.2011
comment
@ user102008: Я предположил, что всегда следует запрашивать, скажем, en0, поскольку MAC присутствует, даже если интерфейс не работает. Но ты прав, наверное, это не очевидно. - person DarkDust; 27.08.2011
comment
Просто проверьте его в первый раз, а затем спрячьте в Связке ключей. Он будет сохраняться, даже если пользователь удалит / переустановит приложение. Кто-то упомянул об этом и в другом ответе. - person DougW; 26.03.2012
comment
Использование MAC-адреса больше не является решением. Apple собирается бороться с его использованием вместе с UDID. Apple говорит разработчикам, что MAC-адрес - не решение. - person xgalaxy; 29.03.2012
comment
Уникальный означает, что он единственный существующий. Уникальность не означает, что она должна меняться каждый раз. Таким образом, в любом случае, если UUID изменяется или не каждый раз, когда приложение переустанавливается или нет, он по-прежнему уникален, если не существует других экземпляров приложения с таким же идентификатором. - person jake_hetfield; 30.03.2012
comment
А теперь, пожалуйста, подскажите мне, как использовать идентификатор, я могу попросить клиента сказать мне, потому что у меня нет устройства и мне нужно зарегистрировать его устройство ... - person spankmaster79; 03.04.2012
comment
@Jay Imerman: Чтобы получить UDID, вы можете просто хешировать MAC en0, как и было предложено. Он определит устройство и останется неизменным для всех приложений и при переустановке приложения. Запросы UDID, как вы видите в iTunes, устарели и могут скоро исчезнуть (AFAIK Apple даже начала отклонять приложения, использующие uniqueIdentifier, но я не знаю наверняка). - person DarkDust; 24.08.2012
comment
Кто-нибудь исследовал законность использования Mac-адреса? Если UUID был проблемой с конфиденциальностью для Apple, то MacAddresses может быть еще большей проблемой. - person AlfeG; 23.10.2012
comment
@ Роджер Нолан: Пожалуйста, не редактируйте ответы других людей и не добавляйте вещи, которые выглядят так, как будто они исходят от первоначального автора. Спасибо. - person DarkDust; 27.03.2013
comment
@AlfeG: с предложенным хешированием MAC сам MAC никогда не будет передан. Но использование настоящего UUID, который вы создаете при первом запуске приложения, считается лучшим решением. - person DarkDust; 27.03.2013
comment
@DarkDust почему? Разве Stack OVerflow не является ресурсом сообщества? Я предполагаю, что, если бы SO захотелось такого поведения, они бы его принудили. Тем не менее, вы можете редактировать поверх других правок, чтобы отображать историю за счет удобочитаемости, если это важно для вас. - person Rog; 08.04.2013
comment
@RogerNolan Пока пост не является ответом сообщества, правки предназначены для исправления ошибок и тому подобного, а не для добавления нового материала. Есть причина, по которой вы заслужили эту привилегию. Представьте, что я редактирую ваш ответ и пишу какую-то чушь, люди подумают, что вы бы написали это. Сомневаюсь, что вам это понравится :-) Но вы не получите уведомление о изменении, я узнал об этом случайно. - person DarkDust; 08.04.2013
comment
@DarkDust Я думаю, что вы заслужили право не редактировать в BS (как я этого не делал), но добавляете разумные обновления, которые способствуют большему ресурсу. Я думаю, вы ошибаетесь: SO - это знание и как можно более качественные ответы, а не святость исходных сообщений. Тем не менее, я не думаю, что стоит продолжать обсуждение :-) - person Rog; 11.04.2013
comment
Apple теперь отклоняет приложения, использующие хешированный MAC. - person Idan; 20.05.2013
comment
@Idan Мало того, если вы проверите изменения API iOS 7, вы вообще не сможете получить MAC-адрес. - person Sulthan; 21.06.2013
comment
@DarkDust Итак, в новой iOS 7 и если я использую CFUUIDCReate, у меня не будет проблем? Поскольку, похоже, identifierForVendor не работает идеально, в некоторых случаях возвращает ноль или 0x0 - person CReaTuS; 10.07.2013
comment
@DarkDust Существовала не альтернатива старой функции UDID. Когда пользователь переустанавливает приложение, CFUUID меняется на другой, поэтому этот CFUUID является простой переменной. Спасибо за ответ - person CReaTuS; 30.07.2013
comment
Примечание: identifierForVendor стал доступен в iOS 6.0, поэтому для него не требуется iOS 7. Чтобы получить строку из identifierForVendor, вы можете использовать [[[UIDevice currentDevice] identifierForVendor] UUIDString] - person taber; 26.09.2013
comment
@DarkDust Если я создаю UUID с помощью CFUUIDCreate или использую identifierForVendor, то он изменяется при повторной установке приложения (удаление приложения и повторная установка). Можете ли вы посоветовать мне, что мне следует использовать как часть этого, чтобы получить идентификатор времени жизни на iOS6 и новее? - person βhargavḯ; 11.10.2013
comment
В SWIFT это синтаксис UIDevice.currentDevice().identifierForVendor или, если вам нужна строка UIDevice.currentDevice().identifierForVendor!.UUIDString через Как получить уникальный идентификатор устройства в Swift - person snibbe; 22.10.2015
comment
Я считаю, что identifierForVendor изменится после обновления приложения. - person CyberMew; 22.08.2017

Вы уже можете использовать альтернативу для Apple UDID. Добрый парень Гекиц написал категорию на UIDevice, которая будет генерировать своего рода UDID на основе MAC-адреса устройства и идентификатора пакета.

Вы можете найти код на github

person Serhii Mamontov    schedule 22.08.2011
comment
Эта реализация уникальна (MAC-адрес) для устройства при переустановках, например, уникальный идентификатор Apple, но также уважает конфиденциальность, будучи также уникальной для приложения (также используйте bundleId) ... Должно быть imho, которое Apple должна включать в свои API. .. вместо того, чтобы осуждать без каких-либо альтернатив. - person Vincent Guerci; 22.08.2011
comment
Хотя он использует лицензию bsd старого образца с пунктом о рекламе, фу. - person jbtule; 29.09.2011
comment
Для всех, кто теперь нашел этот пост, лицензия была изменена после вышеприведенного комментария jbtule. - person James; 04.03.2012
comment
Не думаю, что это слишком безопасно. (для вас это может не иметь значения) Возможно 10 ^ 14 MAC-адресов. Чтобы получить Mac-адрес с учетом хэша, на прохождение всех из них уйдет всего около часа на быстрой машине. whitepixel.zorinaq.com. Добавление идентификатора пакета не помогает, так как большинство знает идентификатор пакета, который нужно проверить. - person Tom Andersen; 16.05.2012
comment
@TomAndersen есть также некоторая формула о том, как вычислить UDID реального устройства, поэтому, если кто-то захочет что-то найти, он может это сделать. Этот код был предложен разработчикам для получения уникального идентификатора устройства, он не учитывает всех желающих обмануть бэкенды. - person Serhii Mamontov; 17.05.2012
comment
А когда телефон продан? Что насчет того, когда вы покупаете новый телефон и переносите все свои данные? - person Nicole; 20.07.2012
comment
Как обсуждалось в этом комментарии к фиксации, библиотека как есть создает серьезную проблему утечки конфиденциальности и не должна использоваться: - person Will; 13.02.2013
comment
Как уже упоминалось другими, эта библиотека вызывает серьезные утечки конфиденциальности: github.com/gekitz/UIDevice-with-UniqueIdentifier-for-iOS-5/ - person Eric; 18.02.2013
comment
Начиная с iOS 7, система всегда возвращает значение 02:00:00:00:00:00, когда вы запрашиваете MAC-адрес на любом устройстве. Проверьте здесь: developer.apple.com/library/prerelease/ios/releasenotes/General/ - person Hejazi; 12.06.2013

Основываясь на ссылке, предложенной @moonlight, я провел несколько тестов, и, похоже, это лучшее решение. Как сообщает @DarkDust, метод проверяет en0, который всегда доступен.
Есть 2 варианта:
uniqueDeviceIdentifier (MD5 MAC + CFBundleIdentifier) ​​
и uniqueGlobalDeviceIdentifier (MD5 MAC), они всегда возвращают те же значения.
Ниже приведены тесты, которые я провел (на реальном устройстве):

#import "UIDevice+IdentifierAddition.h"

NSLog(@"%@",[[UIDevice currentDevice] uniqueDeviceIdentifier]);
NSLog(@"%@",[[UIDevice currentDevice] uniqueGlobalDeviceIdentifier]);

XXXX21f1f19edff198e2a2356bf4XXXX - (WIFI) UDID
XXXX7dc3c577446a2bcbd77935bdXXXX - (WIFI) GlobalAppUDID

XXXX21f1f19edff198e2a2356bf4XXXX - (3G) UDID
XXXX7dc3c577446a2bcbd77935bdXXXX - (3G) GlobalAppUDID

XXXX21f1f19edff198e2a2356bf4XXXX - (GPRS) UDID
XXXX7dc3c577446a2bcbd77935bdXXXX - (GPRS) GlobalAppUDID

XXXX21f1f19edff198e2a2356bf4XXXX - (режим AirPlane) UDID
XXXX7dc3c577446a2bcbd77935bdXXXX - (режим AirPlane) GlobalAppUDID

XXXX21f1f19edff198e2a2356bf4XXXX - (Wi-Fi) после удаления и переустановки приложения XXXX7dc3c577446a2bcbd77935bdXXXX (Wi-Fi) после удаления и установки приложения

Надеюсь, это будет полезно.

РЕДАКТИРОВАТЬ:
Как отмечали другие, это решение в iOS 7 больше не полезно, поскольку uniqueIdentifier больше не доступен, а запрос MAC-адреса теперь всегда возвращает 02: 00: 00: 00: 00: 00

person Mat    schedule 24.10.2011
comment
это не будет работать на iOS7, Apple исключает использование MAC-адреса. - person Sarim Sidd; 03.08.2013
comment
@SarimSidd На данный момент информация об iOS 7 находится под соглашением о неразглашении, мы не можем здесь обсуждать. - person Mat; 05.08.2013

Проверь это,

мы можем использовать Keychain вместо класса NSUserDefaults для хранения UUID, созданного CFUUIDCreate.

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

UUID будет воссоздан сразу после сброса устройства пользователем.

Я пробовал этот метод с помощью SFHFKeychainUtils, и он отлично работает.

person ytur    schedule 06.03.2012
comment
Этот метод - солидная замена UDID. Он также имеет дополнительное преимущество воссоздания идентификатора в зависимости от формата устройства (например, если устройство меняет владельца). Однако важно отметить, что связку ключей можно восстановить на других устройствах, если пользователь зашифрует свою резервную копию. Это может привести к ситуации, когда несколько устройств используют один и тот же UUID. Чтобы этого избежать, установите доступность элемента связки ключей на kSecAttrAccessibleAlwaysThisDeviceOnly. Это гарантирует, что ваш UUID не будет перенесен на любое другое устройство. Чтобы получить доступ к вашему UUID из других приложений, используйте ключ kSecAttrAccessGroup. - person Jeevan Takhar; 23.04.2012
comment
Где именно (какой ключ) вы должны использовать для хранения UUID в связке ключей? - person lostintranslation; 06.08.2014
comment
Оппс! ссылка не работает - person Hitesh Surani; 08.04.2020

Создайте свой собственный UUID, а затем сохраните его в Связке ключей. Таким образом, он сохраняется даже после удаления вашего приложения. Во многих случаях он также сохраняется, даже если пользователь перемещается между устройствами (например, полное резервное копирование и восстановление на другое устройство).

По сути, для вас он становится уникальным идентификатором пользователя. (даже лучше, чем идентификатор устройства).

Пример:

Я определяю собственный метод для создания UUID как:

- (NSString *)createNewUUID 
{
    CFUUIDRef theUUID = CFUUIDCreate(NULL);
    CFStringRef string = CFUUIDCreateString(NULL, theUUID);
    CFRelease(theUUID);
    return [(NSString *)string autorelease];
}

Затем вы можете сохранить его в KEYCHAIN при самом первом запуске вашего приложения. Так что после первого запуска мы можем просто использовать его из связки ключей, не нужно его восстанавливать. Основная причина использования Связки ключей для хранения: когда вы устанавливаете UUID в Связку ключей, она будет сохраняться, даже если пользователь полностью удалит Приложение, а затем установит его снова. . Таким образом, это постоянный способ хранения, а это значит, что ключ всегда будет уникальным.

     #import "SSKeychain.h"
     #import <Security/Security.h>

При запуске приложения добавьте следующий код:

 // getting the unique key (if present ) from keychain , assuming "your app identifier" as a key
       NSString *retrieveuuid = [SSKeychain passwordForService:@"your app identifier" account:@"user"];
      if (retrieveuuid == nil) { // if this is the first time app lunching , create key for device
        NSString *uuid  = [self createNewUUID];
// save newly created key to Keychain
        [SSKeychain setPassword:uuid forService:@"your app identifier" account:@"user"];
// this is the one time process
}

Загрузите файлы SSKeychain.m и .h из sskeychain и перетащите файлы SSKeychain.m и .h в свой проект и добавьте в свой проект "Security.framework". Чтобы впоследствии использовать UUID, просто используйте:

NSString *retrieveuuid = [SSKeychain passwordForService:@"your app identifier" account:@"user"];
person Samir Jwarchan    schedule 20.09.2012
comment
Потому что идентификаторForVendor работает не идеально. В некоторых случаях может возвращать ноль или 0x0. Кажется, этот метод отлично работает - person CReaTuS; 10.07.2013
comment
Кто-нибудь подтвердил, что это работает на iOS7 после цикла удаления / переустановки + подтвержденная отправка приложения Apple? - person mindbomb; 14.10.2013
comment
Я начал использовать это решение. Несколько тестов на 2 устройствах (перестройка, переустановка, выключение устройства) показали мне, что идентификатор одинаковый. iOS 10.3. - person deko; 28.04.2017

Возможно, вы можете использовать:

[UIDevice currentDevice].identifierForVendor.UUIDString

Документация Apple описывает identifierForVender следующим образом:

Значение этого свойства одинаково для приложений от одного поставщика, работающих на одном устройстве. Другое значение возвращается для приложений на одном устройстве, которые поставляются разными поставщиками, и для приложений на разных устройствах независимо от поставщика.

person diadyne    schedule 15.01.2013
comment
Любопытно, почему никто не поднял эту тему до недавнего времени ... А теперь я вижу, что это новинка в iOS 6. - person James Boutcher; 16.01.2013
comment
Если пользователь обновит ios и / или установит новый ios, то значение identifierForVendor изменится или останется прежним? - person Sunil Zalavadiya; 13.04.2013
comment
После удаления всех приложений от одного поставщика это значение будет изменено. - person Mitesh Khatri; 03.09.2013

Вы можете рассмотреть возможность использования OpenUDID, который является заменой устаревшего UDID.

В основном, чтобы соответствовать UDID, требуются следующие функции:

  1. уникальный или достаточно уникальный (коллизия с низкой вероятностью, вероятно, очень приемлема)
  2. постоянство при перезагрузке, восстановлении, удалении
  3. доступны в приложениях разных производителей (полезно для привлечения пользователей через сети CPI) -

OpenUDID выполняет вышеуказанное и даже имеет встроенный механизм отказа для дальнейшего рассмотрения.

Убедитесь, что http://OpenUDID.org указывает на соответствующий GitHub. Надеюсь это поможет!

В качестве примечания, я бы уклонился от любой альтернативы MAC-адреса. Хотя MAC-адрес кажется заманчивым и универсальным решением, убедитесь, что этот низко висящий плод отравлен. MAC-адрес очень чувствителен, и Apple вполне может отказаться от доступа к нему еще до того, как вы сможете сказать «ОТПРАВИТЬ ЭТО ПРИЛОЖЕНИЕ» ... сетевой MAC-адрес используется для аутентификации определенных устройств на частных LAN (WLAN) или других виртуальных частных сети (VPN). .. он даже более чувствительный, чем бывший UDID!

person ylechelle    schedule 28.03.2012
comment
Мне действительно любопытно, как это работает? Код написан на Objective-C, но нет другого хорошего решения, которое бы соответствовало вышеуказанным требованиям, так что же отличает этот фреймворк? Решение, которое использует эта структура, также должно быть возможно опубликовать в качестве предлагаемого ответа здесь ... - person jake_hetfield; 30.03.2012
comment
Я согласен - MAC-адрес также можно настроить вручную (клонировать), хотя по большей части это маловероятно. Я должен возразить против D в UDID. Это не идентификатор устройства, это UUID (универсальный уникальный идентификатор). Идентификатор устройства проштампован Apple на заводе-изготовителе на каждом устройстве в ПЗУ. - person Jay Imerman; 23.08.2012
comment
Лучшее решение для iOS7 также делает то, что действительно необходимо для уникальной идентификации устройства. - person vishal dharankar; 03.05.2014
comment
OpenUDID устарел и не рекомендуется использовать - person mkll; 07.12.2014

Я уверен, что Apple рассердила многих людей этим изменением. Я разрабатываю бухгалтерское приложение для iOS и имею онлайн-сервис для синхронизации изменений, внесенных на разных устройствах. Служба поддерживает базу данных всех устройств и изменений, которые необходимо распространить на них. Поэтому важно знать, какие устройства какие. Я отслеживаю устройства, использующие UIDevice uniqueIdentifier, и, чего бы это ни стоило, вот мои мысли.

  • Сгенерировать UUID и сохранить в пользовательских значениях по умолчанию? Бесполезно, потому что это не сохраняется, когда пользователь удаляет приложение. Если они установят снова позже, онлайн-сервис не должен создавать новую запись устройства, это приведет к потере ресурсов на сервере и выдаче списка устройств, содержащих одно и то же два или более раз. Пользователи увидят в списке более одного «iPhone Боба», если переустановят приложение.

  • Сгенерировать UUID и сохранить в связке ключей? Это был мой план, поскольку он сохраняется даже после удаления приложения. Но при восстановлении резервной копии iTunes на новое устройство iOS связка ключей передается, если резервная копия зашифрована. Это может привести к тому, что два устройства будут содержать один и тот же идентификатор устройства, если старые и новые устройства находятся в эксплуатации. Они должны быть указаны в онлайн-сервисе как два устройства, даже если имя устройства совпадает.

  • Сгенерировать хеш MAC-адрес и идентификатор пакета? Похоже, это лучшее решение для того, что мне нужно. Путем хеширования с идентификатором пакета сгенерированный идентификатор устройства не позволит отслеживать устройство в приложениях, и я получаю уникальный идентификатор для комбинации приложение + устройство.

Интересно отметить, что в собственной документации Apple говорится о проверке квитанций в Mac App Store путем вычисления хэша MAC-адреса системы, а также идентификатора пакета и версии. Так что это кажется допустимым политикой, проходит ли это через проверку приложения, я пока не знаю.

person Mathew Waters    schedule 13.04.2012
comment
Чтобы избежать ситуации, описанной во втором пункте, установите доступность элемента связки ключей на kSecAttrAccessibleAlwaysThisDeviceOnly. Это гарантирует, что ваш UUID не будет восстановлен на других устройствах, даже если резервная копия зашифрована. - person Jeevan Takhar; 23.04.2012
comment
Это действительно то поведение, которое я видел много раз. Например, я регистрирую свой iPhone для Google Sync. Затем я получил новый iPhone, зарегистрировал его и вуаля - теперь в моих настройках синхронизации указано 2 iPhone. - person Jay Imerman; 23.08.2012

Похоже, для iOS 6 Apple рекомендует использовать класс NSUUID.

Из сообщения теперь в UIDevice для свойства uniqueIdentifier:

Не рекомендуется в iOS 5.0. Вместо этого используйте свойство identifierForVendor этого класса или свойство AdvertisingIdentifier класса ASIdentifierManager, если это необходимо, или используйте метод UUID класса NSUUID для создания UUID и записи его в базу данных пользовательских значений по умолчанию.

person Nate    schedule 01.10.2012

Может помочь: используйте приведенный ниже код, он всегда будет уникальным, за исключением того, что вы сотрете (отформатируете) свое устройство.

Цель-C:

Вариант 1. Это будет меняться при каждой установке

UIDevice *uuid = [NSUUID UUID].UUIDString;

Вариант 2: он будет уникальным для каждой учетной записи Apple поставщика / разработчика.

UIDevice *myDevice = [UIDevice currentDevice];
NSString *uuid = [[myDevice identifierForVendor] UUIDString];

Swift 5.X:

Вариант 1. Это будет меняться при каждой установке

let uuid = UUID().uuidString

Вариант 2: он будет уникальным для каждой учетной записи Apple поставщика / разработчика.

let myDevice = UIDevice.current
let uuid = myDevice.identifierForVendor?.uuidString
person Ashvin A    schedule 12.03.2013
comment
Я использовал этот код. Но когда я удалил приложение и снова установил, у меня появился новый идентификатор - person Durgaprasad; 30.05.2013
comment
это простое решение, если вам не нужен надежный метод. Сейчас я использую его в своем приложении. - person Reuben L.; 16.06.2013
comment
@Durgaprasad: он всегда будет меняться, потому что зависит от поставщика. Например: 1. Если вы установили приложение с помощью bundleidenedifier: com.abcd.com = ›, оно изменится. 2. Если вы установили два приложения с помощью bundleidenedifier: com.abcd.com = ›Тогда они не будут заменяться (оставьте любое приложение во время) - person Ashvin A; 25.04.2014

Я также предлагаю перейти с uniqueIdentifier на эту библиотеку с открытым исходным кодом (На самом деле две простые категории), которые используют MAC-адрес устройства вместе с идентификатором пакета приложений для создания уникального идентификатора в ваших приложениях, который может использоваться в качестве замены UDID.

Имейте в виду, что в отличие от UDID этот номер будет отличаться для каждого приложения.

Вам просто нужно импортировать включенные категории NSString и UIDevice и вызвать [[UIDevice currentDevice] uniqueDeviceIdentifier] следующим образом:

#import "UIDevice+IdentifierAddition.h"
#import "NSString+MD5Addition.h"
NSString *iosFiveUDID = [[UIDevice currentDevice] uniqueDeviceIdentifier]

Вы можете найти его на Github здесь:

UIDevice с UniqueIdentifier для iOS 5


Вот категории (только файлы .m - проверьте заголовки в проекте github):

UIDevice + IdentifierAddition.m

#import "UIDevice+IdentifierAddition.h"
#import "NSString+MD5Addition.h"

#include <sys/socket.h> // Per msqr
#include <sys/sysctl.h>
#include <net/if.h>
#include <net/if_dl.h>

@interface UIDevice(Private)

- (NSString *) macaddress;

@end

@implementation UIDevice (IdentifierAddition)

////////////////////////////////////////////////////////////////////////////////
#pragma mark -
#pragma mark Private Methods

// Return the local MAC addy
// Courtesy of FreeBSD hackers email list
// Accidentally munged during previous update. Fixed thanks to erica sadun & mlamb.
- (NSString *) macaddress{
    
    int                 mib[6];
    size_t              len;
    char                *buf;
    unsigned char       *ptr;
    struct if_msghdr    *ifm;
    struct sockaddr_dl  *sdl;
    
    mib[0] = CTL_NET;
    mib[1] = AF_ROUTE;
    mib[2] = 0;
    mib[3] = AF_LINK;
    mib[4] = NET_RT_IFLIST;
    
    if ((mib[5] = if_nametoindex("en0")) == 0) {
        printf("Error: if_nametoindex error\n");
        return NULL;
    }
    
    if (sysctl(mib, 6, NULL, &len, NULL, 0) < 0) {
        printf("Error: sysctl, take 1\n");
        return NULL;
    }
    
    if ((buf = malloc(len)) == NULL) {
        printf("Could not allocate memory. error!\n");
        return NULL;
    }
    
    if (sysctl(mib, 6, buf, &len, NULL, 0) < 0) {
        printf("Error: sysctl, take 2");
        return NULL;
    }
    
    ifm = (struct if_msghdr *)buf;
    sdl = (struct sockaddr_dl *)(ifm + 1);
    ptr = (unsigned char *)LLADDR(sdl);
    NSString *outstring = [NSString stringWithFormat:@"%02X:%02X:%02X:%02X:%02X:%02X", 
                           *ptr, *(ptr+1), *(ptr+2), *(ptr+3), *(ptr+4), *(ptr+5)];
    free(buf);
    
    return outstring;
}

////////////////////////////////////////////////////////////////////////////////
#pragma mark -
#pragma mark Public Methods

- (NSString *) uniqueDeviceIdentifier{
    NSString *macaddress = [[UIDevice currentDevice] macaddress];
    NSString *bundleIdentifier = [[NSBundle mainBundle] bundleIdentifier];  
    NSString *stringToHash = [NSString stringWithFormat:@"%@%@",macaddress,bundleIdentifier];
    NSString *uniqueIdentifier = [stringToHash stringFromMD5];  
    return uniqueIdentifier;
}

- (NSString *) uniqueGlobalDeviceIdentifier{
    NSString *macaddress = [[UIDevice currentDevice] macaddress];
    NSString *uniqueIdentifier = [macaddress stringFromMD5];    
    return uniqueIdentifier;
}

@end

NSString + MD5Addition.m:

#import "NSString+MD5Addition.h"
#import <CommonCrypto/CommonDigest.h>

@implementation NSString(MD5Addition)

- (NSString *) stringFromMD5{
    
    if(self == nil || [self length] == 0)
        return nil;
    
    const char *value = [self UTF8String];
    
    unsigned char outputBuffer[CC_MD5_DIGEST_LENGTH];
    CC_MD5(value, strlen(value), outputBuffer);
    
    NSMutableString *outputString = [[NSMutableString alloc] initWithCapacity:CC_MD5_DIGEST_LENGTH * 2];
    for(NSInteger count = 0; count < CC_MD5_DIGEST_LENGTH; count++){
        [outputString appendFormat:@"%02x",outputBuffer[count]];
    }
    return [outputString autorelease];
}

@end
person chown    schedule 30.10.2011
comment
Начиная с iOS 7, Apple будет возвращать постоянное значение для MAC-адреса. В этом есть смысл. MAC-адрес чувствителен. - person Roberto; 27.08.2013

Вы можете получить с помощью этого кода: UIDevice-with-UniqueIdentifier-for-iOS-5

person SachinVsSachin    schedule 31.10.2012

MAC-адрес может быть подделан, что делает такой подход бесполезным для привязки контента к конкретным пользователям или реализации функций безопасности, таких как черные списки.

После некоторых дальнейших исследований мне кажется, что на данный момент у нас нет подходящей альтернативы. Я очень надеюсь, что Apple пересмотрит свое решение.

Возможно, было бы неплохо написать Apple по электронной почте по этой теме и / или отправить запрос об ошибке / функции по этому поводу, поскольку, возможно, они даже не знают о всех последствиях для разработчиков.

person Toastor    schedule 10.08.2011
comment
Верный момент, однако я считаю, что UUID также можно подделать / использовать на взломанном телефоне, поэтому технически существующий [UIDevice uniqueIdentifier] так же ошибочен. - person Oliver Pearmain; 11.08.2011
comment
Вы всегда можете создать идентификатор на сервере и сохранить его на устройстве. Вот как это делает большинство приложений. Я не понимаю, зачем программистам iOS что-то особенное. - person Sulthan; 05.01.2012
comment
@Sulthan не работает на iOS, потому что если вы удалите приложение, все его данные исчезнут, поэтому нет возможности гарантировать уникальный идентификатор устройства таким образом. - person lkraider; 15.02.2012
comment
Нет, если вы сохраните его на связку ключей. Во всяком случае, я никогда не видел приложения, в котором это было бы проблемой. Если приложение и данные были удалены, вам не нужен один и тот же идентификатор устройства. Если вы хотите идентифицировать пользователя, попросите его адрес электронной почты. - person Sulthan; 16.02.2012
comment
Доступ к MAC-адресам также был запрещен Apple в новом выпуске iOS; - person Ans; 08.07.2013

UIDevice identifierForVendor, представленный в iOS 6, подойдет для ваших целей.

identifierForVendor - это буквенно-цифровая строка, которая однозначно идентифицирует устройство для поставщика приложения. (только для чтения)

@property(nonatomic, readonly, retain) NSUUID *identifierForVendor

Значение этого свойства одинаково для приложений от одного поставщика, работающих на одном устройстве. Другое значение возвращается для приложений на одном устройстве, которые поставляются разными поставщиками, и для приложений на разных устройствах, независимо от поставщика.

Доступно в iOS 6.0 и новее и заявлено в UIDevice.h

Для iOS 5 перейдите по этой ссылке UIDevice-with-UniqueIdentifier-for-iOS-5

person Mahendra Liya    schedule 08.04.2013

Использование SSKeychain и кода, упомянутого выше. Вот код для копирования / вставки (добавить модуль SSKeychain):

+(NSString *) getUUID {

//Use the bundle name as the App identifier. No need to get the localized version.

NSString *Appname = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleName"];    

//Check if we have UUID already

NSString *retrieveuuid = [SSKeychain passwordForService:Appname account:@"user"];

if (retrieveuuid == NULL)
{

    //Create new key for this app/device

    CFUUIDRef newUniqueId = CFUUIDCreate(kCFAllocatorDefault);

    retrieveuuid = (__bridge_transfer NSString*)CFUUIDCreateString(kCFAllocatorDefault, newUniqueId);

    CFRelease(newUniqueId);

    //Save key to Keychain
    [SSKeychain setPassword:retrieveuuid forService:Appname account:@"user"];
}

return retrieveuuid;

}

person Komposr    schedule 04.09.2013

Следующий код помогает получить UDID:

        udid = [[[UIDevice currentDevice] identifierForVendor] UUIDString];
        NSLog(@"UDID : %@", udid);
person santify    schedule 09.08.2013

Это код, который я использую для получения идентификатора как для iOS 5, так и для iOS 6, 7:

- (NSString *) advertisingIdentifier
{
    if (!NSClassFromString(@"ASIdentifierManager")) {
        SEL selector = NSSelectorFromString(@"uniqueIdentifier");
        if ([[UIDevice currentDevice] respondsToSelector:selector]) {
            return [[UIDevice currentDevice] performSelector:selector];
        }
    }
    return [[[ASIdentifierManager sharedManager] advertisingIdentifier] UUIDString];
}
person Grzegorz Krukowski    schedule 17.09.2013
comment
Что делать с предупреждением компилятора PerformSelector may cause a leak because its selector is unknown? - person Basil Bourque; 22.02.2014
comment
Вы больше не можете использовать AdvertisingIdentifier для этой цели, так как Apple отклонит его. Дополнительная информация: techcrunch.com/2014/02/03/ - person codeplasma; 09.04.2014

Начиная с iOS 6, у нас есть NSUUID класс, который соответствует RFC4122.

Ссылка Apple: apple_ref для NSUUID

person DShah    schedule 17.10.2012

iOS 11 представила фреймворк DeviceCheck. У него есть полностью защищенное решение для однозначной идентификации устройства.

person Santosh Botre    schedule 21.06.2017

Рабочий способ получения UDID:

  1. Запустите веб-сервер внутри приложения с двумя страницами: одна должна возвращать специально созданный профиль MobileConfiguration, а другая должна собирать UDID. Дополнительная информация здесь, здесь и здесь.
  2. Вы открываете первую страницу в Mobile Safari из приложения, и оно перенаправляет вас на Settings.app с просьбой установить профиль конфигурации. После установки профиля UDID отправляется на вторую веб-страницу, и вы можете получить к нему доступ из приложения. (В Settings.app есть все необходимые права и разные правила песочницы).

Пример использования RoutingHTTPServer:

import UIKit
import RoutingHTTPServer

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
    var bgTask = UIBackgroundTaskInvalid
    let server = HTTPServer()

    func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
        application.openURL(NSURL(string: "http://localhost:55555")!)
        return true
    }

    func applicationDidEnterBackground(application: UIApplication) {
        bgTask = application.beginBackgroundTaskWithExpirationHandler() {
            dispatch_async(dispatch_get_main_queue()) {[unowned self] in
                application.endBackgroundTask(self.bgTask)
                self.bgTask = UIBackgroundTaskInvalid
            }
        }
    }
}

class HTTPServer: RoutingHTTPServer {
    override init() {
        super.init()
        setPort(55555)
        handleMethod("GET", withPath: "/") {
            $1.setHeader("Content-Type", value: "application/x-apple-aspen-config")
            $1.respondWithData(NSData(contentsOfFile: NSBundle.mainBundle().pathForResource("udid", ofType: "mobileconfig")!)!)
        }
        handleMethod("POST", withPath: "/") {
            let raw = NSString(data:$0.body(), encoding:NSISOLatin1StringEncoding) as! String
            let plistString = raw.substringWithRange(Range(start: raw.rangeOfString("<?xml")!.startIndex,end: raw.rangeOfString("</plist>")!.endIndex))
            let plist = NSPropertyListSerialization.propertyListWithData(plistString.dataUsingEncoding(NSISOLatin1StringEncoding)!, options: .allZeros, format: nil, error: nil) as! [String:String]

            let udid = plist["UDID"]! 
            println(udid) // Here is your UDID!

            $1.statusCode = 200
            $1.respondWithString("see https://developer.apple.com/library/ios/documentation/NetworkingInternet/Conceptual/iPhoneOTAConfiguration/ConfigurationProfileExamples/ConfigurationProfileExamples.html")
        }
        start(nil)
    }
}

Вот содержимое udid.mobileconfig:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
    <dict>
        <key>PayloadContent</key>
        <dict>
            <key>URL</key>
            <string>http://localhost:55555</string>
            <key>DeviceAttributes</key>
            <array>
                <string>IMEI</string>
                <string>UDID</string>
                <string>PRODUCT</string>
                <string>VERSION</string>
                <string>SERIAL</string>
            </array>
        </dict>
        <key>PayloadOrganization</key>
        <string>udid</string>
        <key>PayloadDisplayName</key>
        <string>Get Your UDID</string>
        <key>PayloadVersion</key>
        <integer>1</integer>
        <key>PayloadUUID</key>
        <string>9CF421B3-9853-9999-BC8A-982CBD3C907C</string>
        <key>PayloadIdentifier</key>
        <string>udid</string>
        <key>PayloadDescription</key>
        <string>Install this temporary profile to find and display your current device's UDID. It is automatically removed from device right after you get your UDID.</string>
        <key>PayloadType</key>
        <string>Profile Service</string>
    </dict>
</plist>

Установка профиля завершится неудачно (я не стал реализовывать ожидаемый ответ, см. документация), но приложение получит правильный UDID. И вам также следует подписать файл mobileconfig .

person bzz    schedule 04.06.2015

Для Swift 3.0 используйте приведенный ниже код.

let deviceIdentifier: String = (UIDevice.current.identifierForVendor?.uuidString)!
NSLog("output is : %@", deviceIdentifier)
person Ganesh    schedule 17.09.2016
comment
iOS 11 представила фреймворк DeviceCheck. У него есть полностью защищенное решение для однозначной идентификации устройства. - person Santosh Botre; 21.06.2017

Вы можете использовать

NSString *sID = [[[ASIdentifierManager sharedManager] advertisingIdentifier] UUIDString];

Что уникально для устройства во всех приложениях.

person Dhaval    schedule 25.02.2014

Apple добавила в iOS 11 новую платформу под названием DeviceCheck, которая поможет вам очень легко получить уникальный идентификатор. Прочтите эту форму для получения дополнительной информации. https://medium.com/@santoshbotre01/unique-identifier-for-the-ios-devices-590bb778290d

person Santosh Botre    schedule 24.08.2017
comment
Но для этого нужно подключение к Интернету, не так ли? - person Nik Kov; 05.12.2019
comment
Да, требуется подключение к Интернету. - person Santosh Botre; 05.12.2019

Если кто-то наткнется на этот вопрос при поиске альтернативы. Я следовал этому подходу в классе IDManager. Это коллекция из разных решений. KeyChainUtil - это оболочка для чтения из связки ключей. Вы также можете использовать hashed MAC address как своего рода уникальный идентификатор.

/*  Apple confirmed this bug in their system in response to a Technical Support Incident 
    request. They said that identifierForVendor and advertisingIdentifier sometimes 
    returning all zeros can be seen both in development builds and apps downloaded over the 
    air from the App Store. They have no work around and can't say when the problem will be fixed. */
#define kBuggyASIID             @"00000000-0000-0000-0000-000000000000"

+ (NSString *) getUniqueID {
    if (NSClassFromString(@"ASIdentifierManager")) {
        NSString * asiID = [[[ASIdentifierManager sharedManager] advertisingIdentifier] UUIDString];
        if ([asiID compare:kBuggyASIID] == NSOrderedSame) {
            NSLog(@"Error: This device return buggy advertisingIdentifier.");
            return [IDManager getUniqueUUID];
        } else {
            return asiID;
        }

    } else {
        return [IDManager getUniqueUUID];
    }
}


+ (NSString *) getUniqueUUID {
    NSError * error;
    NSString * uuid = [KeychainUtils getPasswordForUsername:kBuyassUser andServiceName:kIdOgBetilngService error:&error];
    if (error) {
        NSLog(@"Error geting unique UUID for this device! %@", [error localizedDescription]);
        return nil;
    }
    if (!uuid) {
        DLog(@"No UUID found. Creating a new one.");
        uuid = [IDManager GetUUID];
        uuid = [Util md5String:uuid];
        [KeychainUtils storeUsername:USER_NAME andPassword:uuid forServiceName:SERVICE_NAME updateExisting:YES error:&error];
        if (error) {
            NSLog(@"Error getting unique UUID for this device! %@", [error localizedDescription]);
            return nil;
        }
    }
    return uuid;
}

/* NSUUID is after iOS 6. */
+ (NSString *)GetUUID
{
    CFUUIDRef theUUID = CFUUIDCreate(NULL);
    CFStringRef string = CFUUIDCreateString(NULL, theUUID);
    CFRelease(theUUID);
    return [(NSString *)string autorelease];
}

#pragma mark - MAC address
// Return the local MAC addy
// Courtesy of FreeBSD hackers email list
// Last fallback for unique identifier
+ (NSString *) getMACAddress
{
    int                 mib[6];
    size_t              len;
    char                *buf;
    unsigned char       *ptr;
    struct if_msghdr    *ifm;
    struct sockaddr_dl  *sdl;

    mib[0] = CTL_NET;
    mib[1] = AF_ROUTE;
    mib[2] = 0;
    mib[3] = AF_LINK;
    mib[4] = NET_RT_IFLIST;

    if ((mib[5] = if_nametoindex("en0")) == 0) {
        printf("Error: if_nametoindex error\n");
        return NULL;
    }

    if (sysctl(mib, 6, NULL, &len, NULL, 0) < 0) {
        printf("Error: sysctl, take 1\n");
        return NULL;
    }

    if ((buf = malloc(len)) == NULL) {
        printf("Error: Memory allocation error\n");
        return NULL;
    }

    if (sysctl(mib, 6, buf, &len, NULL, 0) < 0) {
        printf("Error: sysctl, take 2\n");
        free(buf); // Thanks, Remy "Psy" Demerest
        return NULL;
    }

    ifm = (struct if_msghdr *)buf;
    sdl = (struct sockaddr_dl *)(ifm + 1);
    ptr = (unsigned char *)LLADDR(sdl);
    NSString *outstring = [NSString stringWithFormat:@"%02X:%02X:%02X:%02X:%02X:%02X", *ptr, *(ptr+1), *(ptr+2), *(ptr+3), *(ptr+4), *(ptr+5)];

    free(buf);
    return outstring;
}

+ (NSString *) getHashedMACAddress
{
    NSString * mac = [IDManager getMACAddress];
    return [Util md5String:mac];
}

+ (NSString *)md5String:(NSString *)plainText
{
    if(plainText == nil || [plainText length] == 0)
        return nil;

    const char *value = [plainText UTF8String];
    unsigned char outputBuffer[CC_MD5_DIGEST_LENGTH];
    CC_MD5(value, strlen(value), outputBuffer);

    NSMutableString *outputString = [[NSMutableString alloc] initWithCapacity:CC_MD5_DIGEST_LENGTH * 2];
    for(NSInteger count = 0; count < CC_MD5_DIGEST_LENGTH; count++){
        [outputString appendFormat:@"%02x",outputBuffer[count]];
    }
    NSString * retString = [NSString stringWithString:outputString];
    [outputString release];
    return retString;
}
person karim    schedule 13.05.2013

Мы можем использовать identifierForVendor для ios7,

-(NSString*)uniqueIDForDevice
{
    NSString* uniqueIdentifier = nil;
    if( [UIDevice instancesRespondToSelector:@selector(identifierForVendor)] ) { // >=iOS 7
        uniqueIdentifier = [[[UIDevice currentDevice] identifierForVendor] UUIDString];
    } else { //<=iOS6, Use UDID of Device       
            CFUUIDRef uuid = CFUUIDCreate(NULL);
            //uniqueIdentifier = ( NSString*)CFUUIDCreateString(NULL, uuid);- for non- ARC
            uniqueIdentifier = ( NSString*)CFBridgingRelease(CFUUIDCreateString(NULL, uuid));// for ARC
            CFRelease(uuid);
         }
    }
return uniqueIdentifier;
}

--Важное примечание ---

UDID и identifierForVendor разные: ---

1.) On uninstalling  and reinstalling the app identifierForVendor will change.

2.) The value of identifierForVendor remains the same for all the apps installed from the same vendor on the device.

3.) The value of identifierForVendor also changes for all the apps if any of the app (from same vendor) is reinstalled.
person HDdeveloper    schedule 03.12.2013
comment
вы уверены ? можем ли мы использовать identifierForVendor для ios7 ,? - person Avis; 23.09.2014

Apple скрыла UDID от всех общедоступных API, начиная с iOS 7. Любой UDID, начинающийся с FFFF, является поддельным идентификатором. Приложения «Отправить UDID», которые ранее работали, больше не могут использоваться для сбора UDID для тестовых устройств. (вздох!)

UDID отображается, когда устройство подключено к XCode (в органайзере) и когда устройство подключено к iTunes (хотя вам нужно щелкнуть «Серийный номер», чтобы отобразить идентификатор.

Если вам нужно получить UDID для устройства, которое нужно добавить в профиль обеспечения, и вы не можете сделать это самостоятельно в XCode, вам придется пройти через все шаги, чтобы скопировать / вставить его из iTunes.

Есть ли способ с тех пор (выпуск iOS 7) получить UDID без использования iTunes на ПК / Mac?

person Preet    schedule 23.01.2014

У меня тоже была проблема, и решение простое:

    // Get Bundle Info for Remote Registration (handy if you have more than one app)
    NSString *appName = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleDisplayName"];
    NSString *appVersion = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleVersion"];


    // Get the users Device Model, Display Name, Unique ID, Token & Version Number
    UIDevice *dev = [UIDevice currentDevice];
    NSString *deviceUuid=[dev.identifierForVendor  UUIDString];

    NSString *deviceName = dev.name;
person Ahmet Kazim Günay    schedule 18.04.2014

Не идеальная, но одна из лучших и ближайших альтернатив UDID (в Swift с использованием iOS 8.1 и Xcode 6.1):

Генерация случайного UUID

let strUUID: String = NSUUID().UUIDString

И используйте библиотеку KeychainWrapper:

Добавьте строковое значение в цепочку для ключей:

let saveSuccessful: Bool = KeychainWrapper.setString("Some String", forKey: "myKey")

Получить строковое значение из связки ключей:

let retrievedString: String? = KeychainWrapper.stringForKey("myKey")

Удалите строковое значение из связки ключей:

let removeSuccessful: Bool = KeychainWrapper.removeObjectForKey("myKey")

В этом решении используется связка для ключей, поэтому запись, хранящаяся в связке для ключей, будет сохраняться даже после удаления и повторной установки приложения. Единственный способ удалить эту запись - Сбросить все содержимое и настройки устройства. Вот почему я упомянул, что это решение замены не является идеальным, но остается одним из лучших решений замены UDID в iOS 8.1 с использованием Swift.

person King-Wizard    schedule 01.12.2014

NSLog (@ "% @", [[UIDevice currentDevice] identifierForVendor]);

person garg    schedule 30.12.2016

Не используйте эти библиотеки - libOmnitureAppMeasurement, он использует uniqueIdentifier, который Apple больше не поддерживает

person Nagarjuna    schedule 05.06.2013

Маленький хак для вас:

/**
 @method uniqueDeviceIdentifier
 @abstract A unique device identifier is a hash value composed from various hardware identifiers such
 as the device’s serial number. It is guaranteed to be unique for every device but cannot 
 be tied to a user account. [UIDevice Class Reference]
 @return An 1-way hashed identifier unique to this device.
 */
+ (NSString *)uniqueDeviceIdentifier {      
    NSString *systemId = nil;
    // We collect it as long as it is available along with a randomly generated ID.
    // This way, when this becomes unavailable we can map existing users so the
    // new vs returning counts do not break.
    if (([[[UIDevice currentDevice] systemVersion] floatValue] < 6.0f)) {
        SEL udidSelector = NSSelectorFromString(@"uniqueIdentifier");
        if ([[UIDevice currentDevice] respondsToSelector:udidSelector]) {
            systemId = [[UIDevice currentDevice] performSelector:udidSelector];
        }
    }
    else {
        systemId = [NSUUID UUID];
    }
    return systemId;
}
person digipeople    schedule 17.05.2013