Udid is deprecated and is used as a unique identifier for the device. After obtaining the UUID, if you use Nsuserdefaults storage, and then reload after the program is unloaded, the UUID obtained is different from the previous. Use keychain storage to guarantee that the UUID will not change when the program unloads load. But when the machine is brushed or upgraded, the UUID will change. But this is still the best solution so far, and if there is a better solution, please leave a message.
To all two categories:
Code in UUID.H:
#import angle bracket (foundation/foundation.h)
@interface Uuid:nsobject
+ (NSString *) Getuuid;
@end
Code in UUID.M:
#import "UUID.h"
#import angle bracket (foundation/foundation.h)
#import "KeychainItemWrapper.h"
@implementation UUID
+ (NSString *) getuuid
{
Keychainitemwrapper *keychainitem = [[Keychainitemwrapper alloc]
initwithidentifier:@ "UUID"
accessgroup:@ "YOUR_BUNDLE_SEED.com.yourcompany.userinfo"];
NSString *struuid = [Keychainitem objectforkey: (ID) cfbridgingrelease (ksecvaluedata)];
When the method is first executed, the UUID is empty
if ([Struuid isequaltostring:@ ""])
{
Cfuuidref uuidref = cfuuidcreate (Kcfallocatordefault);
Struuid = (NSString *) cfbridgingrelease (cfuuidcreatestring (kcfallocatordefault,uuidref));
[Keychainitem setobject:struuid Forkey: (ID) Cfbridgingrelease (Ksecvaluedata)];
}
return struuid;
}
@end
The second class is Apple's official demo package, demo download address: http://developer.apple.com/library/ios/#samplecode/generickeychain/listings/ Classes_keychainitemwrapper_h.html#//apple_ref/doc/uid/dts40007797-classes_keychainitemwrapper_ H-dontlinkelementid_9
Code in KeychainItemWrapper.h:
#import angle bracket (uikit/uikit.h)
@interface Keychainitemwrapper:nsobject
{
Nsmutabledictionary *keychainitemdata;
Nsmutabledictionary *genericpasswordquery;
}
@property (nonatomic, retain) nsmutabledictionary *keychainitemdata;
@property (nonatomic, retain) nsmutabledictionary *genericpasswordquery;
-(ID) Initwithidentifier: (NSString *) identifier Accessgroup: (NSString *) Accessgroup;
-(void) SetObject: (ID) inobject Forkey: (ID) key;
-(ID) Objectforkey: (ID) key;
-(void) Resetkeychainitem;
@end
Code in KEYCHAINITEMWRAPPER.M:
#import "KeychainItemWrapper.h"
#import angle bracket (security/security.h)
@interface Keychainitemwrapper (Privatemethods)
-(Nsmutabledictionary *) Secitemformattodictionary: (Nsdictionary *) Dictionarytoconvert;
-(Nsmutabledictionary *) Dictionarytosecitemformat: (Nsdictionary *) Dictionarytoconvert;
-(void) Writetokeychain;
@end
@implementation Keychainitemwrapper
@synthesize Keychainitemdata, Genericpasswordquery;
-(ID) Initwithidentifier: (NSString *) identifier Accessgroup: (NSString *) Accessgroup;
{
if (self = [super init])
{
Genericpasswordquery = [[Nsmutabledictionary alloc] init];
[Genericpasswordquery setobject: (ID) Cfbridgingrelease (Ksecclassgenericpassword) Forkey: (ID) ksecclass];
[Genericpasswordquery setobject:identifier Forkey: (ID) Cfbridgingrelease (Ksecattrgeneric)];
if (Accessgroup!= nil)
{
#if Target_iphone_simulator
#else
[Genericpasswordquery setobject:accessgroup Forkey: (ID) ksecattraccessgroup];
#endif
}
[Genericpasswordquery setobject: (ID) Cfbridgingrelease (Ksecmatchlimitone) Forkey: (ID) ksecmatchlimit];
[Genericpasswordquery setobject: (ID) kcfbooleantrue Forkey: (ID) ksecreturnattributes];
Nsdictionary *tempquery = [Nsdictionary dictionarywithdictionary:genericpasswordquery];
Nsmutabledictionary *outdictionary = nil;
if (! Secitemcopymatching ((Cfdictionaryref) tempquery, (Cftyperef *) &outdictionary) = = NOERR)
{
[Self resetkeychainitem];
[Keychainitemdata setobject:identifier Forkey: (ID) ksecattrgeneric];
if (Accessgroup!= nil)
{
#if Target_iphone_simulator
#else
[Keychainitemdata setobject:accessgroup Forkey: (ID) ksecattraccessgroup];
#endif
}
}
Else
{
Self.keychainitemdata = [self secitemformattodictionary:outdictionary];
}
[Outdictionary release];
}
return self;
}
-(void) dealloc
{
[Keychainitemdata release];
[Genericpasswordquery release];
[Super Dealloc];
}
-(void) SetObject: (ID) inobject Forkey: (ID) key
{
if (Inobject = = nil) return;
ID currentobject = [keychainitemdata Objectforkey:key];
if (![ Currentobject Isequal:inobject])
{
[Keychainitemdata Setobject:inobject Forkey:key];
[Self writetokeychain];
}
}
-(ID) Objectforkey: (ID) key
{
return [Keychainitemdata Objectforkey:key];
}
-(void) Resetkeychainitem
{
Osstatus junk = NOERR;
if (!keychainitemdata)
{
Self.keychainitemdata = [[Nsmutabledictionary alloc] init];
}
else if (keychainitemdata)
{
Nsmutabledictionary *tempdictionary = [self dictionarytosecitemformat:keychainitemdata];
Junk = Secitemdelete ((cfdictionaryref) tempdictionary);
Nsassert (junk = = NOERR | | junk = = Errsecitemnotfound, @ "Problem deleting current dictionary.");
}
[Keychainitemdata setobject:@ "" Forkey: (ID) ksecattraccount];
[Keychainitemdata setobject:@ "" Forkey: (ID) Ksecattrlabel];
[Keychainitemdata setobject:@ "" Forkey: (ID) ksecattrdescription];
[Keychainitemdata setobject:@ "" Forkey: (ID) ksecvaluedata];
}
-(Nsmutabledictionary *) Dictionarytosecitemformat: (Nsdictionary *) Dictionarytoconvert
{
Nsmutabledictionary *returndictionary = [Nsmutabledictionary Dictionarywithdictionary:dictionarytoconvert];
[Returndictionary setobject: (ID) Ksecclassgenericpassword Forkey: (ID) ksecclass];
NSString *passwordstring = [Dictionarytoconvert objectforkey: (ID) ksecvaluedata];
[Returndictionary setobject:[passwordstring datausingencoding:nsutf8stringencoding] ForKey: (ID) kSecValueData];
return returndictionary;
}
-(Nsmutabledictionary *) Secitemformattodictionary: (Nsdictionary *) Dictionarytoconvert
{
Nsmutabledictionary *returndictionary = [Nsmutabledictionary Dictionarywithdictionary:dictionarytoconvert];
[Returndictionary setobject: (ID) kcfbooleantrue Forkey: (ID) ksecreturndata];
[Returndictionary setobject: (ID) Ksecclassgenericpassword Forkey: (ID) ksecclass];
NSData *passworddata = NULL;
if (secitemcopymatching (Cfdictionaryref) returndictionary, (Cftyperef *) &passworddata) = = NOERR)
{
[Returndictionary Removeobjectforkey: (ID) ksecreturndata];
NSString *password = [[[NSString Alloc] initwithbytes:[passworddata bytes] Length:[passworddata length]
Encoding:nsutf8stringencoding] autorelease];
[Returndictionary Setobject:password Forkey: (ID) ksecvaluedata];
}
Else
{
Nsassert (No, @ "serious error, no matching item found in the keychain.\n");
}
[Passworddata release];
return returndictionary;
}
-(void) Writetokeychain
{
Nsdictionary *attributes = NULL;
Nsmutabledictionary *updateitem = NULL;
Osstatus result;
if (secitemcopymatching (Cfdictionaryref) genericpasswordquery, (Cftyperef *) &attributes) = = NOERR)
{
UpdateItem = [Nsmutabledictionary dictionarywithdictionary:attributes];
[UpdateItem setobject:[genericpasswordquery Objectforkey: (ID) ksecclass] forkey: (ID) ksecclass];
Nsmutabledictionary *tempcheck = [self dictionarytosecitemformat:keychainitemdata];
[Tempcheck Removeobjectforkey: (ID) ksecclass];
#if Target_iphone_simulator
[Tempcheck Removeobjectforkey: (ID) ksecattraccessgroup];
#endif
result = Secitemupdate ((cfdictionaryref) UpdateItem, (cfdictionaryref) tempcheck);
Nsassert (Result = = NOERR, @ "couldn ' t update the keychain Item.");
}
Else
{
result = Secitemadd ((cfdictionaryref) [self dictionarytosecitemformat:keychainitemdata], NULL);
Nsassert (Result = = NOERR, @ "couldn ' t add the keychain Item.");
}
}
@end
Ps:1. Keychainitemwrapper class in the official demo inside also have, if I copy error, you can download the official demo on the link above.
2. Add security.framework when using
3. It is particularly important to note that the set method of group in the code below the UUID class.
Keychainitemwrapper *keychainitem = [[Keychainitemwrapper alloc]
initwithidentifier:@ "UUID"
accessgroup:@ "YOUR_BUNDLE_SEED.com.yourcompany.userinfo"];
(1) Create the Keychainaccessgroups.plist file in the same directory as the project.
(Absolutely useful) iOS acquires UUID and uses keychain storage
The topmost node in the structure of the file must be an array named "Keychain-access-groups", and each item in the array is a nsstring that describes the grouping. YOUR_BUNDLE_SEED.com.yourcompany.userinfo is the name of the group you want to set.
(2) Create the Keychainaccessgroups.plist file in the same directory as the project. Add entitlements to the right of the Code signing keychainaccessgroups.plist under the Target-build settings-code signing column, as shown in the following figure.
(Absolutely useful) iOS acquires UUID and uses keychain storage
By this, the work is done.
When you first install the program, print out a UUID, and when you uninstall the program, use Getuuid to obtain
UUID, the printed result is the same as before. Prove to achieve the purpose.
Test code:
NSString * uuid= [uuid getuuid];
NSLog (@ "uuid=%@", uuid);
Test results:
uuid=19aab430-9cb8-4325-acc5-d7d386b68960