Today, Bo Master has a unique identification of the needs of equipment, encountered some difficulties, here and we share, hope to progress together.
Before iOS7.0, the only way to get the device's unique identity was to get the Udid or MAC address, but after iOS7.0, to protect the user's privacy, Apple banned them, making the device's data tracking more and more difficult.
After iOS7.0, there are two main ways to obtain a device's unique identity:
1. AD identifier IDFA
In order to improve its own ecosystem, Apple launched the IAD ad network around 2010. Then the relationship between this idfa and the IAD is self-explanatory. It doesn't matter if you don't know the ads, simply put, now the accurate delivery of Internet ads need to understand user data, based on this information to make the ads more efficient, unique identification is very important, the use of IDFA.
Advertisingidentifier in the Asidentifiermanager class of Adsupport.framework, is one of two of these properties.
It can be said that using this IDFA to identify the device should still be very accurate (otherwise iad will not play at all), many developers are still in use.
2.idfv+key Chain
Since IDFV removed the app and then reinstalled, the identifier changed, to solve this problem, you can save the first generation of the ID to the key chain, delete the app after the key chain in the data is OK.
#define KEY_UDID @ "Key_udid"
#define Key_in_keychain @ "Key_in_keychain"
#import <Security/Security.h>
#import "APPIdentificationManage.h"
@implementation Appidentificationmanage
Singleton_implementation (Appidentificationmanage)
#pragma mark gets the UUID
/**
* This UUID is within the same program-the same vindor-is not changed under the same device
* This UUID is unique, but will change after the app is removed and reinstalled, taking steps to save it once in the keychain and then get it from the keychain
**/
-(NSString *) Openudid
{
NSString *identifierforvendor = [[Uidevice Currentdevice]. Identifierforvendor uuidstring];
return Identifierforvendor;
}
#pragma mark saves the UUID to the keychain
-(void) Saveudid: (nsstring *) Udid
{
Nsmutabledictionary *udidkvpairs = [nsmutabledictionary dictionary];
[Udidkvpairs setobject:udid Forkey:key_udid];
[[Appidentificationmanage sharedappidentificationmanage] save:key_in_keychain Data:udidkvpairs];
}
#pragma mark Read UUID
/**
* First obtain the UUID from memory, if not taken from the keychain, if not yet generate a new UUID, and saved to the keychain for later use
**/
-(ID) readudid
{
if (_uuid = = Nil | | _uuid. length = = 0) {
Nsmutabledictionary *udidkvpairs = (nsmutabledictionary *) [[Appidentificationmanage Sharedappidentificationmanage] Load:key_in_keychain];
NSString *uuid = [udidkvpairs objectforkey:key_udid];
if (uuid = = Nil | | uuid. length = = 0) {
UUID = [self openudid];
[self saveudid:UUID];
}
_uuid = uuid;
}
return _uuid;
}
#pragma mark removes the UUID
-(void) Deleteuuid
{
[Appidentificationmanage Delete:key_in_keychain];
}
#pragma mark Check Keychain
-(nsmutabledictionary *) Getkeychainquery: (NSString *) Service {
return [nsmutabledictionary Dictionarywithobjectsandkeys: (__bridge_transfer ID) Ksecclassgenericpassword, (__bridge_transfer ID) ksecclass, service, (__bridge_transfer ID) Ksecattrservice, service, (__bridge_transfer ID) ksecattraccount, (__bridge_transfer ID) Ksecattraccessibleafterfirstunlock, (__bridge_transfer ID) ksecattraccessible, nil Nil];
}
#pragma mark saves the data to the keychain
-(void) Save: (NSString *) Service data: (ID) data {
Nsmutabledictionary *keychainquery = [self getkeychainquery:service];
Secitemdelete ((__bridge_retained cfdictionaryref) keychainquery);
[Keychainquery setobject:[nskeyedarchiver archiveddatawithrootobject:data] forkey: (__bridge_transfer ID) Ksecvaluedata];
Secitemadd ((__bridge_retained cfdictionaryref) keychainquery, NULL);
}
#pragma mark loads data in keychain
-(ID) Load: (NSString *) Service {
ID ret = nil;
Nsmutabledictionary *keychainquery = [self getkeychainquery:service];
[Keychainquery setobject: (ID) kcfbooleantrue forkey: (__bridge_transfer ID) ksecreturndata];
[Keychainquery setobject: (__bridge_transfer ID) ksecmatchlimitone forkey: (__bridge_transfer ID) Ksecmatchlimit];
Cfdataref keyData = NULL;
if (secitemcopymatching (__bridge_retained cfdictionaryref) keychainquery, (cftyperef *) &keydata) = = NOERR) {
@try {
ret = [Nskeyedunarchiver unarchiveobjectwithdata: (__bridge_transfer NSData *) KeyData];
} @catch (nsexception *e) {
NSLog (@ "Unarchive of%@ failed:%@", service, E);
} @finally {
}
}
return ret;
}
#pragma mark deletes data from the keychain
-(void)Delete: (NSString *) Service {
Nsmutabledictionary *keychainquery = [self getkeychainquery:service];
Secitemdelete ((__bridge_retained cfdictionaryref) keychainquery);
}
@end
iOS Development journal 20-7.0 after acquiring device unique identity