Właśnie wyszło na jaw, że właściwość unikalnego identyfikatora UIDevice jest przestarzała w iOS 5 i niedostępna w iOS 7 i nowszych. Wydaje się, że żadna alternatywna metoda lub właściwość nie jest dostępna ani nie będzie dostępna.
Wiele naszych istniejących aplikacji jest ściśle zależnych od tej właściwości w celu jednoznacznego identyfikowania konkretnego urządzenia. Jak poradzimy sobie z tym problemem w przyszłości?
Sugestia z dokumentacji w latach 2011-2012 była następująca:
Uwagi specjalne
Nie używaj właściwości uniqueIdentifier. Aby utworzyć unikalny identyfikator specyficzny dla aplikacji, możesz wywołać
CFUUIDCreate
funkcję w celu utworzeniaUUID
i zapisać ją w domyślnej bazie danych za pomocąNSUserDefaults
klasy.
Jednak ta wartość nie będzie taka sama, jeśli użytkownik odinstaluje i ponownie zainstaluje aplikację.
źródło
Odpowiedzi:
UUID utworzony przez
CFUUIDCreate
jest unikalny, jeśli użytkownik odinstaluje i ponownie zainstaluje aplikację: za każdym razem otrzymasz nowy.Ale możesz chcieć, aby nie był unikalny, tzn. Powinien pozostać niezmieniony, gdy użytkownik odinstaluje i ponownie zainstaluje aplikację. Wymaga to trochę wysiłku, ponieważ najbardziej wiarygodnym identyfikatorem na urządzenie wydaje się być adres MAC. Możesz zapytać o MAC i użyć go jako UUID.Edycja: Oczywiście należy zawsze zapytać o MAC tego samego interfejsu. Chyba najlepszy jest zakładen0
. MAC jest zawsze obecny, nawet jeśli interfejs nie ma adresu IP / jest wyłączony.Edycja 2: Jak zauważyli inni, preferowanym rozwiązaniem od iOS 6 jest - [identyfikator UIDeviceForVendor] . W większości przypadków powinieneś być w stanie użyć go jako zamiennika starego
-[UIDevice uniqueIdentifier]
(ale identyfikator UUID, który jest tworzony podczas pierwszego uruchomienia aplikacji, wydaje się, że Apple chce, abyś używał).Edycja 3: Aby ten główny punkt nie zagubił się w szumie komentarza: nie używaj MAC jako UUID, utwórz skrót używając MAC . Ten skrót zawsze da ten sam wynik za każdym razem, nawet w przypadku ponownej instalacji i aplikacji (jeśli skrót jest wykonywany w ten sam sposób). W każdym razie, obecnie (2013) nie jest to już konieczne, chyba że potrzebujesz „stabilnego” identyfikatora urządzenia w iOS <6.0.Edycja 4: W iOS 7 Apple zawsze zwraca teraz stałą wartość podczas wysyłania zapytania do MAC, aby udaremnić MAC jako podstawę dla schematu ID . Dlatego naprawdę powinieneś teraz użyć - [UIDevice identifierForVendor] lub utworzyć identyfikator UUID dla instalacji.
źródło
Możesz już użyć swojej alternatywy dla Apple
UDID
. Gekitz, miły człowiek, napisał kategorię, na podstawieUIDevice
której wygeneruje coś wUDID
oparciu o adres MAC urządzenia i identyfikator pakietu.Możesz znaleźć kod na github
źródło
02:00:00:00:00:00
gdy poprosisz o adres MAC na dowolnym urządzeniu. Sprawdź tutaj: developer.apple.com/library/prerelease/ios/releasenotes/General/…Na podstawie linku zaproponowanego przez @moonlight wykonałem kilka testów i wydaje się to najlepszym rozwiązaniem. Jak mówi @DarkDust, metoda sprawdza,
en0
która jest zawsze dostępna.Istnieją 2 opcje:
uniqueDeviceIdentifier
(MD5 MAC + CFBundleIdentifier)i
uniqueGlobalDeviceIdentifier
(MD5 MAC), zawsze zwracają te same wartości.Poniżej testy, które przeprowadziłem (z prawdziwym urządzeniem):
Mam nadzieję, że to się przyda.
EDYCJA:
Jak zauważyli inni, to rozwiązanie w iOS 7 nie jest już przydatne, ponieważ
uniqueIdentifier
nie jest już dostępne, a zapytania o adres MAC zwracają teraz zawsze 02: 00: 00: 00: 00: 00źródło
Spójrz na to,
możemy użyć pęku kluczy zamiast
NSUserDefaults
klasy, do przechowywaniaUUID
utworzonego przezCFUUIDCreate
.w ten sposób możemy uniknąć
UUID
rekreacji z ponowną instalacją i uzyskać zawsze to samoUUID
dla tej samej aplikacji, nawet odinstalowanie użytkownika i ponowna instalacja.UUID
zostaną odtworzone właśnie po zresetowaniu urządzenia przez użytkownika.Wypróbowałem tę metodę z SFHFKeychainUtils i działa jak urok.
źródło
kSecAttrAccessibleAlwaysThisDeviceOnly
. Zapewni to, że Twój UUID nie migruje na żadne inne urządzenie. Aby uzyskać dostęp do UUID z innych aplikacji, użyjkSecAttrAccessGroup
klucza.Utwórz własny identyfikator UUID, a następnie zapisz go w pęku kluczy. W ten sposób utrzymuje się nawet po odinstalowaniu aplikacji. W wielu przypadkach utrzymuje się również, nawet jeśli użytkownik migruje między urządzeniami (np. Pełna kopia zapasowa i przywracanie na inne urządzenie).
W efekcie staje się unikalnym identyfikatorem użytkownika . (nawet lepszy niż identyfikator urządzenia ).
Przykład:
Definiuję niestandardową metodę tworzenia
UUID
jako:Następnie możesz zapisać go
KEYCHAIN
przy pierwszym uruchomieniu aplikacji. Dzięki temu po pierwszym uruchomieniu możemy po prostu użyć go z pęku kluczy, bez potrzeby jego ponownego generowania. Głównym powodem korzystania z pęku kluczy do przechowywania jest: Po ustawieniuUUID
pęku kluczy będzie on trwał, nawet jeśli użytkownik całkowicie odinstaluje aplikację, a następnie zainstaluje ją ponownie. . Jest to więc stały sposób przechowywania, co oznacza, że klucz będzie wyjątkowy przez cały czas.Podczas uruchamiania aplikacji dołącz następujący kod:
Pobierz plik SSKeychain.m i .h z sskeychain i przeciągnij plik SSKeychain.m i .h do swojego projektu i dodaj „Security.framework” do swojego projektu. Aby później użyć UUID, po prostu użyj:
źródło
Być może możesz użyć:
Dokumentacja Apple opisuje identyfikator FVVender w następujący sposób:
Wartość tej właściwości jest taka sama dla aplikacji pochodzących od tego samego dostawcy działającego na tym samym urządzeniu. Inna wartość jest zwracana dla aplikacji na tym samym urządzeniu pochodzących od różnych dostawców oraz dla aplikacji na różnych urządzeniach, niezależnie od dostawcy.
źródło
Możesz zastanowić się nad użyciem tego,
OpenUDID
który zastępuje przestarzałeUDID
.Zasadniczo, aby dopasować
UDID
, wymagane są następujące funkcje:OpenUDID
spełnia powyższe wymagania, a nawet ma wbudowany mechanizm rezygnacji do późniejszego rozpatrzenia.Sprawdź http://OpenUDID.org, który wskazuje odpowiedni GitHub. Mam nadzieję że to pomoże!
Na marginesie, unikałbym wszelkich alternatywnych adresów MAC. Chociaż adres MAC wydaje się kuszącym i uniwersalnym rozwiązaniem, upewnij się, że ten nisko wiszący owoc jest zatruty. Adres MAC jest bardzo wrażliwy i Apple może bardzo przestać mieć do niego dostęp, zanim jeszcze powiesz „ZGŁOŚ TĄ APLIKACJĘ” ... adres sieciowy MAC służy do uwierzytelniania niektórych urządzeń na prywatnych liniach (WLAN) lub innych wirtualnych prywatnych sieci (VPN). .. jest jeszcze bardziej czuły niż poprzedni UDID!
źródło
Jestem pewien, że Apple zirytowało wiele osób tą zmianą. I opracować aplikację księgowości dla iOS i posiada usługa online do synchronizacji zmian dokonanych na różnych urządzeniach. Usługa utrzymuje bazę danych wszystkich urządzeń i zmiany, które należy im przekazać. Dlatego ważne jest, aby wiedzieć, które urządzenia są które. Śledzę urządzenia korzystające z unikalnego identyfikatora UIDevice i za ile są warte, oto moje przemyślenia.
Wygenerować identyfikator UUID i zapisać w ustawieniach domyślnych użytkownika? Nic dobrego, ponieważ nie utrzymuje się, gdy użytkownik usuwa aplikację. Jeśli zainstalują się ponownie później, usługa online nie powinna utworzyć nowego rekordu urządzenia, co zmarnowałoby zasoby na serwerze i dałoby listę urządzeń zawierających ten sam dwa lub więcej razy. Użytkownicy zobaczyliby więcej niż jednego „iPhone'a Boba” na liście, gdyby ponownie zainstalowali aplikację.
Wygenerować UUID i przechowywać w pęku kluczy? To był mój plan, ponieważ utrzymuje się nawet po odinstalowaniu aplikacji. Ale podczas przywracania kopii zapasowej iTunes na nowym urządzeniu z systemem iOS, brelok jest przesyłany, jeśli kopia zapasowa jest zaszyfrowana. Może to prowadzić do dwóch urządzeń zawierających ten sam identyfikator urządzenia, jeśli oba stare i nowe urządzenia są w użyciu. Powinny być wymienione jako dwa urządzenia w usłudze online, nawet jeśli nazwa urządzenia jest taka sama.
Wygenerować hash adres MAC i identyfikator pakietu? To wygląda na najlepsze rozwiązanie tego, czego potrzebuję. Przez mieszanie z identyfikatorem pakietu wygenerowany identyfikator urządzenia nie pozwoli na śledzenie urządzenia w aplikacjach i otrzymam unikalny identyfikator dla kombinacji aplikacja + urządzenie.
Warto zauważyć, że własna dokumentacja Apple odnosi się do sprawdzania wpływów z Mac App Store poprzez obliczenie skrótu systemowego adresu MAC oraz identyfikatora i wersji pakietu. Wydaje się, że jest to dozwolone przez zasady, niezależnie od tego, czy przechodzi przez przegląd aplikacji, którego jeszcze nie znam.
źródło
kSecAttrAccessibleAlwaysThisDeviceOnly
. Zapewni to, że Twój identyfikator UUID nie zostanie przywrócony na inne urządzenia, nawet jeśli kopia zapasowa jest zaszyfrowana.Wygląda na to, że w iOS 6 Apple zaleca korzystanie z klasy NSUUID .
Z wiadomości teraz w dokumentach UIDevice dla
uniqueIdentifier
właściwości:źródło
Może pomóc: użyj poniższego kodu, zawsze będzie Unikatowy, z wyjątkiem tego, że usuniesz (sformatujesz) urządzenie.
źródło
Chciałbym również zasugerować zmianie ze
uniqueIdentifier
do tej otwartej biblioteki źródłowej (2 proste kategorie naprawdę), które wykorzystują urządzenia adres MAC wraz z App Bundle identyfikatora do wygenerowania unikalnego identyfikatora w aplikacjach, które mogą być używane jako UDID wymiany.Pamiętaj, że w przeciwieństwie do UDID, liczba ta będzie inna dla każdej aplikacji.
Musisz po prostu zaimportować dołączone
NSString
iUIDevice
kategorie i zadzwonić w ten[[UIDevice currentDevice] uniqueDeviceIdentifier]
sposób:Możesz go znaleźć na Github tutaj:
UIDevice z UniqueIdentifier dla iOS 5
Oto kategorie (tylko pliki .m - sprawdź nagłówki w projekcie github):
źródło
Możesz osiągnąć dzięki temu kodowi: UIDevice-with-UniqueIdentifier-for-iOS-5
źródło
Adres MAC może być sfałszowany, co czyni takie podejście bezużytecznym do wiązania treści z konkretnymi użytkownikami lub wdrażania funkcji bezpieczeństwa, takich jak czarne listy.
Po kilku dalszych badaniach wydaje mi się, że na razie nie mamy odpowiedniej alternatywy. Mam poważną nadzieję, że Apple ponownie rozważy swoją decyzję.
Być może dobrym pomysłem byłoby wysłanie wiadomości e-mail do Apple na ten temat i / lub zgłoszenie prośby o błąd / funkcję w tym temacie, ponieważ może nawet nie są świadomi pełnych konsekwencji dla programistów.
źródło
UIDevice identifierForVendor
wprowadzone w iOS 6 będzie działać na twoje potrzeby.identifierForVendor
to ciąg alfanumeryczny, który jednoznacznie identyfikuje urządzenie od dostawcy aplikacji. (tylko czytać)Wartość tej właściwości jest taka sama dla aplikacji pochodzących od tego samego dostawcy działającego na tym samym urządzeniu. Inna wartość jest zwracana dla aplikacji na tym samym urządzeniu, które pochodzą od różnych dostawców, oraz dla aplikacji na różnych urządzeniach, niezależnie od dostawcy.
Dostępne w iOS 6.0 i nowszych oraz zadeklarowane w
UIDevice.h
W przypadku systemu iOS 5 skorzystaj z tego linku UIDevice-with-UniqueIdentifier-for-iOS-5
źródło
Korzystanie z SSKeychain i kodu wspomnianego powyżej. Oto kod do skopiowania / wklejenia (dodaj moduł SSKeychain):
}
źródło
Poniższy kod pomaga uzyskać UDID:
źródło
To jest kod, którego używam, aby uzyskać identyfikator dla iOS 5 i iOS 6, 7:
źródło
PerformSelector may cause a leak because its selector is unknown
?Począwszy od iOS 6, mamy
NSUUID
klasę zgodną z RFC4122Apple Link: apple_ref dla NSUUID
źródło
iOS 11 wprowadził platformę DeviceCheck. Posiada w pełni odporne rozwiązanie do jednoznacznej identyfikacji urządzenia.
źródło
Działający sposób na uzyskanie UDID:
Przykład użycia RoutingHTTPServer :
Oto zawartość
udid.mobileconfig
:Instalacja profilu zakończy się niepowodzeniem (nie zadałem sobie trudu, aby zaimplementować oczekiwaną odpowiedź, zobacz dokumentację ), ale aplikacja otrzyma poprawny identyfikator UDID. I powinieneś także podpisać mobileconfig .
źródło
W przypadku Swift 3.0 użyj poniższego kodu.
źródło
Możesz użyć
Który jest unikalny dla urządzenia we wszystkich aplikacjach.
źródło
Apple dodał nową platformę w iOS 11 o nazwie DeviceCheck, która pomoże ci bardzo łatwo uzyskać unikalny identyfikator. Przeczytaj ten formularz, aby uzyskać więcej informacji. https://medium.com/@santoshbotre01/unique-identifier-for-the-ios-devices-590bb778290d
źródło
Jeśli ktoś natknie się na to pytanie, szukając alternatywy. Stosowałem to podejście w
IDManager
klasie. Jest to zbiór różnych rozwiązań. KeyChainUtil to opakowanie do odczytu z pęku kluczy. Możesz także użyć tegohashed MAC address
rodzaju jako unikalnego identyfikatora.źródło
źródło
Możemy użyć identyfikatora ForVendor dla ios7,
--Ważna uwaga ---
UDID i identyfikator ForVendor są różne: ---
źródło
Apple ukrył identyfikator UDID przed wszystkimi publicznymi interfejsami API, zaczynając od iOS 7. Każdy identyfikator UDID rozpoczynający się od FFFF jest fałszywym identyfikatorem. Aplikacje „Wyślij UDID”, które wcześniej działały, nie mogą już być używane do gromadzenia UDID dla urządzeń testowych. (westchnienie!)
Identyfikator UDID jest wyświetlany, gdy urządzenie jest podłączone do XCode (w organizatorze) i gdy urządzenie jest podłączone do iTunes (chociaż trzeba kliknąć „Numer seryjny”, aby wyświetlić identyfikator.
Jeśli chcesz uzyskać identyfikator UDID dla urządzenia, aby dodać je do profilu administracyjnego, a nie możesz zrobić tego samodzielnie w XCode, musisz przeprowadzić je przez kroki, aby skopiować / wkleić go z iTunes.
Czy istnieje sposób (od wydania iOS 7), aby uzyskać identyfikator UDID bez używania iTunes na PC / Mac?
źródło
Miałem też problem, a rozwiązanie jest proste:
źródło
Niezbyt doskonała, ale jedna z najlepszych i najbliższych alternatyw dla UDID (w Swift z iOS 8.1 i Xcode 6.1):
Generowanie losowego UUID
I użyj biblioteki KeychainWrapper :
Dodaj wartość ciągu do pęku kluczy:
Pobierz wartość ciągu z pęku kluczy:
Usuń wartość ciągu z pęku kluczy:
To rozwiązanie korzysta z pęku kluczy, dlatego zapis przechowywany w pęku kluczy zostanie zachowany, nawet po odinstalowaniu i ponownej instalacji aplikacji. Jedynym sposobem usunięcia tego rekordu jest zresetowanie całej zawartości i ustawień urządzenia. Dlatego wspomniałem, że to rozwiązanie zastępowania nie jest idealne, ale pozostaje jednym z najlepszych rozwiązań zastępujących UDID na iOS 8.1 za pomocą Swift.
źródło
NSLog (@ "% @", [[UIDevice currentDevice] identyfikatorForVendor]);
źródło