ios - How can get the unique id in iPhone -


need 1 unique id app. unique id should never change. when user uninstalls app or kills app should not changed. have searched something, don't need uuid. have decided device token using code:

- (bool)application:(uiapplication *)application didfinishlaunchingwithoptions:(nsdictionary *)launchoptions {     if ([[[uidevice currentdevice] systemversion] floatvalue] >= 8.0)     {         [[uiapplication sharedapplication] registerusernotificationsettings:[uiusernotificationsettings settingsfortypes:(uiusernotificationtypesound | uiusernotificationtypealert | uiusernotificationtypebadge) categories:nil]];         [[uiapplication sharedapplication] registerforremotenotifications];      }     else     {         [[uiapplication sharedapplication] registerforremotenotificationtypes: (uiremotenotificationtypenewsstandcontentavailability| uiremotenotificationtypebadge | uiremotenotificationtypesound | uiremotenotificationtypealert)];      }      return yes; } - (void)application:(uiapplication *)application didregisterusernotificationsettings:(uiusernotificationsettings *)notificationsettings // ns_available_ios(8_0); {     [application registerforremotenotifications]; }    - (void)application:(uiapplication*)application didregisterforremotenotificationswithdevicetoken:(nsdata*)devicetoken{       nsstring *token = [[devicetoken description] stringbytrimmingcharactersinset: [nscharacterset charactersetwithcharactersinstring:@"<>"]];     token = [token stringbyreplacingoccurrencesofstring:@" " withstring:@""];     nslog(@"content---%@", token);  } 

there 1 problem. in ios 7 got device token constant, uninstalled app , killed app, , got device token constant. in ios 8 , above device token not constant. when user kills app, device token changes. need 1 unique device token app, or other way unique id. how can fix issue? me. advance.

you have store value in keychain this. import "keychainitemwrapper.h" in appdelegate.m file

add these code in

- (bool)application:(uiapplication *)application didfinishlaunchingwithoptions:(nsdictionary *)launchoptions;

//+++++++++++++++for unique identifier of app++++++++++++++++ [[nsuserdefaults standarduserdefaults] setobject:@"" forkey:@"uniqueidentifier"];  keychainitemwrapper *keychainitem = [[keychainitemwrapper alloc] initwithidentifier:@"myuniqueid" accessgroup:nil];  nsstring *strident;  if ([[keychainitem objectforkey:(id)ksecattraccount] isequaltostring:@""]) {     nsstring *uniqueidentifier = [[[uidevice currentdevice] identifierforvendor] uuidstring];     nslog(@"uniqueidentifier=%@",uniqueidentifier);     [keychainitem setobject:uniqueidentifier forkey:(id)ksecattraccount];     strident = [keychainitem objectforkey:(id)ksecattraccount];     [[nsuserdefaults standarduserdefaults] setobject:strident forkey:@"uniqueidentifier"];    }else{     strident=[keychainitem objectforkey:(id)ksecattraccount];     [[nsuserdefaults standarduserdefaults] setobject:strident forkey:@"uniqueidentifier"]; }  nslog(@"strident=%@",strident); [[nsuserdefaults standarduserdefaults] synchronize];  //[keychainitem resetkeychainitem]; // reset keychain 

//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

keychainitemwrapper.h

+++++++++++++++++++

#import <uikit/uikit.h> @interface keychainitemwrapper : nsobject  // designated initializer. - (id)initwithidentifier: (nsstring *)identifier accessgroup:(nsstring *)accessgroup; - (void)setobject:(id)inobject forkey:(id)key; - (id)objectforkey:(id)key;  // initializes , resets default generic keychain item data. - (void)resetkeychainitem;  @end 

+++++++++++++++++++++++++++++++

keychainitemwrapper.m

+++++++++++++++++++++++++++++++

#define password_uses_data  #import "keychainitemwrapper.h" #import <security/security.h>    @interface keychainitemwrapper (privatemethods)  - (nsmutabledictionary *)secitemformattodictionary:(nsdictionary *)dictionarytoconvert; - (nsmutabledictionary *)dictionarytosecitemformat:(nsdictionary *)dictionarytoconvert;  - (void)writetokeychain;  @end  @implementation keychainitemwrapper { nsmutabledictionary *keychainitemdata;      // actual keychain item data backing store. nsmutabledictionary *genericpasswordquery;  // placeholder generic keychain item query used locate item. }  - (id)initwithidentifier: (nsstring *)identifier accessgroup:(nsstring *) accessgroup; { if (self = [super init]) {      genericpasswordquery = [[nsmutabledictionary alloc] init];      [genericpasswordquery setobject:(__bridge id)ksecclassgenericpassword forkey:(__bridge id)ksecclass];     [genericpasswordquery setobject:identifier forkey:(__bridge id)ksecattrgeneric];        if (accessgroup != nil)     { #if target_iphone_simulator         // ignore access group if running on iphone simulator.         //          // apps built simulator aren't signed, there's no keychain access group         // simulator check. means apps can see keychain items when run         // on simulator.         //         // if secitem contains access group attribute, secitemadd , secitemupdate on         // simulator return -25243 (errsecnoaccessforitem). #else                    [genericpasswordquery setobject:accessgroup forkey:(__bridge id)ksecattraccessgroup]; #endif     }      // use proper search constants, return attributes of first match.     [genericpasswordquery setobject:(__bridge id)ksecmatchlimitone forkey:(__bridge id)ksecmatchlimit];     [genericpasswordquery setobject:(__bridge id)kcfbooleantrue forkey:(__bridge id)ksecreturnattributes];      nsdictionary *tempquery = [nsdictionary dictionarywithdictionary:genericpasswordquery];      cfmutabledictionaryref outdictionary = null;      if (!(secitemcopymatching((__bridge cfdictionaryref)tempquery, (cftyperef *)&outdictionary) == noerr))     {         // stick these default values keychain item if nothing found.         [self resetkeychainitem];          // add generic attribute , keychain access group.         [keychainitemdata setobject:identifier forkey:(__bridge id)ksecattrgeneric];         if (accessgroup != nil)         { #if target_iphone_simulator             // ignore access group if running on iphone simulator.             //              // apps built simulator aren't signed, there's no keychain access group             // simulator check. means apps can see keychain items when run             // on simulator.             //             // if secitem contains access group attribute, secitemadd , secitemupdate on             // simulator return -25243 (errsecnoaccessforitem). #else                        [keychainitemdata setobject:accessgroup forkey:(__bridge id)ksecattraccessgroup]; #endif         }     }     else     {         // load saved data keychain.         keychainitemdata = [self secitemformattodictionary:(__bridge nsdictionary *)outdictionary];     }     if(outdictionary) cfrelease(outdictionary); }  return self; }  - (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 { if (!keychainitemdata)  {     keychainitemdata = [[nsmutabledictionary alloc] init]; } else if (keychainitemdata) {     nsmutabledictionary *tempdictionary = [self dictionarytosecitemformat:keychainitemdata]; #ifndef ns_block_assertions     osstatus junk =  #endif         secitemdelete((__bridge cfdictionaryref)tempdictionary);     nsassert( junk == noerr || junk == errsecitemnotfound, @"problem deleting current dictionary." ); }  // default attributes keychain item. [keychainitemdata setobject:@"" forkey:(__bridge id)ksecattraccount]; [keychainitemdata setobject:@"" forkey:(__bridge id)ksecattrlabel]; [keychainitemdata setobject:@"" forkey:(__bridge id)ksecattrdescription];  // default data keychain item. #ifndef password_uses_data [keychainitemdata setobject:@"" forkey:(__bridge id)ksecvaluedata]; #else [keychainitemdata setobject:[nsdata data] forkey:(__bridge id)ksecvaluedata]; #endif }  - (nsmutabledictionary *)dictionarytosecitemformat:(nsdictionary *)dictionarytoconvert { // assumption method called populated dictionary // containing right key/value pairs secitem.  // create dictionary return populated attributes , data. nsmutabledictionary *returndictionary = [nsmutabledictionary dictionarywithdictionary:dictionarytoconvert];  // add generic password keychain item class attribute. [returndictionary setobject:(__bridge id)ksecclassgenericpassword forkey:(__bridge id)ksecclass];  // convert nsstring nsdata meet requirements value type ksecvaluedata. // store sensitive data should encrypted. #ifndef password_uses_data // orig nsstring *passwordstring = [dictionarytoconvert objectforkey:(__bridge id)ksecvaluedata]; [returndictionary setobject:[passwordstring datausingencoding:nsutf8stringencoding] forkey:(__bridge id)ksecvaluedata]; #else // dfh id val = [dictionarytoconvert objectforkey:(__bridge id)ksecvaluedata]; if([val iskindofclass:[nsstring class]]) {     val = [(nsstring *)val datausingencoding:nsutf8stringencoding]; } [returndictionary setobject:val forkey:(__bridge id)ksecvaluedata]; #endif   return returndictionary; }  - (nsmutabledictionary *)secitemformattodictionary:(nsdictionary *)dictionarytoconvert { // assumption method called populated dictionary // containing right key/value pairs ui element.  // create dictionary return populated attributes , data. nsmutabledictionary *returndictionary = [nsmutabledictionary dictionarywithdictionary:dictionarytoconvert];  // add proper search key , class attribute. [returndictionary setobject:(__bridge id)kcfbooleantrue forkey:(__bridge id)ksecreturndata]; [returndictionary setobject:(__bridge id)ksecclassgenericpassword forkey:(__bridge id)ksecclass];  // acquire password data attributes. cfdataref passworddata = null; if (secitemcopymatching((__bridge cfdictionaryref)returndictionary, (cftyperef *)&passworddata) == noerr) {     // remove search, class, , identifier key/value, don't need them anymore.     [returndictionary removeobjectforkey:(__bridge id)ksecreturndata];  #ifndef password_uses_data     // add password dictionary, converting nsdata nsstring.     nsstring *password = [[nsstring alloc] initwithbytes:[(__bridge nsdata *)passworddata bytes] length:[(__bridge nsdata *)passworddata length]                                                   encoding:nsutf8stringencoding]; #else     nsdata *password = (__bridge_transfer nsdata *)passworddata;     passworddata = null; #endif     [returndictionary setobject:password forkey:(__bridge id)ksecvaluedata]; } else {     // don't if nothing found.     nsassert(no, @"serious error, no matching item found in keychain.\n"); } if(passworddata) cfrelease(passworddata);  return returndictionary; }  - (void)writetokeychain { cfdictionaryref attributes = null; nsmutabledictionary *updateitem = nil; osstatus result;  if (secitemcopymatching((__bridge cfdictionaryref)genericpasswordquery, (cftyperef *)&attributes) == noerr) {     // first need attributes keychain.     updateitem = [nsmutabledictionary dictionarywithdictionary:(__bridge nsdictionary *)attributes];     // second need add appropriate search key/values.     [updateitem setobject:[genericpasswordquery objectforkey:(__bridge id)ksecclass] forkey:(__bridge id)ksecclass];      // lastly, need set updated attribute list being careful remove class.     nsmutabledictionary *tempcheck = [self dictionarytosecitemformat:keychainitemdata];     [tempcheck removeobjectforkey:(__bridge id)ksecclass];  #if target_iphone_simulator     // remove access group if running on iphone simulator.     //      // apps built simulator aren't signed, there's no keychain access group     // simulator check. means apps can see keychain items when run     // on simulator.     //     // if secitem contains access group attribute, secitemadd , secitemupdate on     // simulator return -25243 (errsecnoaccessforitem).     //     // access group attribute included in items returned secitemcopymatching,     // why need remove before updating item.     [tempcheck removeobjectforkey:(__bridge id)ksecattraccessgroup]; #endif      // implicit assumption can update single item @ time. #ifndef ndebug           result =  #endif         secitemupdate((__bridge cfdictionaryref)updateitem, (__bridge cfdictionaryref)tempcheck);      nsassert( result == noerr, @"couldn't update keychain item." ); } else {     // no previous item found; add new one.     result = secitemadd((__bridge cfdictionaryref)[self dictionarytosecitemformat:keychainitemdata], null);     nsassert( result == noerr, @"couldn't add keychain item." ); }  if(attributes) cfrelease(attributes); }  @end 

Comments

Popular posts from this blog

scala - 'wrong top statement declaration' when using slick in IntelliJ -

c# - DevExpress.Wpf.Grid.InfiniteGridSizeException was unhandled -

PySide and Qt Properties: Connecting signals from Python to QML -