(Absolutely useful) iOS gets UUID and uses keychain storage

Source: Internet
Author: User
Tags uikit

Udid is deprecated and uses the UUID as a unique identifier for the device. Once the UUID is acquired, if it is stored with Nsuserdefaults, when the program is unloaded and then re-loaded, the UUID obtained is different from the previous. Using the keychain storage ensures that the UUID does not change when the program unloads load. However, the UUID will still change when the machine is being brushed or the system is upgraded. But this is still the best solution so far, if there is a better solution, please leave a message.

(The source of the solution I've collated: http://blog.k-res.net/archives/1081.html) gives you two classes: code in UUID.H:

#import angle brackets (foundation/foundation.h)

@interface Uuid:nsobject

+ (NSString *) Getuuid;

@end

Code in UUID.M:

#import "UUID.h"

#import angle brackets (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: 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 brackets (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 brackets (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 = [Nsmutabledictionarydictionarywithdictionary: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 also has, if I copy error, you can download the official demo on the link above. 2.to add when usingsecurity.framework3. In particular, the set method of group in the following code of the UUID class is noted. 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.


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 to be set.        (2)Create the Keychainaccessgroups.plist file under the same directory as the project. Add entitlements to the right of Code Signing keychainaccessgroups.plist under the Target-build Settings-code Signing Bar, as.           
At this, the work is done. When the program is first installed, a UUID is printed, and when the program is unloaded, the UUID is obtained with getuuid, and the results are printed the same as before.     Prove to be achieved. Test code:

NSString * uuid= [uuid getuuid];

NSLog (@ "uuid=%@", uuid);

Test results: uuid=19aab430-9cb8-4325-acc5-d7d386b68960

(Absolutely useful) iOS gets UUID and uses keychain storage

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.