IOS7开发~UDID解决方法

来源:互联网 发布:淘宝活动倒计时生成 编辑:程序博客网 时间:2024/05/22 17:10

原文链接: http://blog.csdn.net/lizhongfu2013/article/details/11982851


前言:IOS7中,UDID和MAC地址等设备唯一标识方法都被淘汰,但开发中,业务往往需要这个唯一标识,经过研究,还没找到可以完全替代UDID和MAC地址的方法,但退而求其次,找到了将UUID作为UDID使用的办法,UUID保证了序列号的唯一性,所以剩下问题就是解决如何保存UUID的问题了,经过调研,利用KeyChain可以保存数据,并且APP删除,重启机器情况下仍然不影响保存的数据,但如果用户刷系统,这种办法就不行了。下面奉上代码:

项目要引入:Security.framework

[cpp] view plaincopyprint?
  1. #import <UIKit/UIKit.h>  
  2. #import "KeychainHelper.h"  
  3.   
  4. @interface ViewController : UIViewController  
  5.   
  6. @end  

[cpp] view plaincopyprint?
  1. #import "ViewController.h"  
  2.   
  3. NSString * const KEY_DIC = @"com.company.app.dic";  
  4. NSString * const KEY_UDID = @"com.company.app.kUdidTest";  
  5.   
  6. @interface ViewController ()  
  7.   
  8. @end  
  9.   
  10. @implementation ViewController  
  11.   
  12. - (void)viewDidLoad  
  13. {  
  14.     [super viewDidLoad];  
  15. }  
  16.   
  17. - (NSString*) uuid  
  18. {  
  19.     CFUUIDRef puuid = CFUUIDCreate(nil);  
  20.     CFStringRef uuidString = CFUUIDCreateString(nil, puuid);  
  21.     NSString *result = (NSString *)CFStringCreateCopy(NULL, uuidString);  
  22.     CFRelease(puuid);  
  23.     CFRelease(uuidString);  
  24.     return [result autorelease];  
  25. }  
  26.   
  27. - (void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event  
  28. {  
  29.     NSMutableDictionary *dic = (NSMutableDictionary *)[KeychainHelper load:KEY_DIC];  
  30.     NSString *udid = [dic objectForKey:KEY_UDID];  
  31.       
  32.     if (udid)  
  33.     {  
  34.         NSLog(@"udid:%@", udid);  
  35.     }  
  36.       
  37.     if (!udid)  
  38.     {  
  39.         NSLog(@"save");  
  40.         NSMutableDictionary *dic = [NSMutableDictionary dictionary];  
  41.         [dic setObject:[self uuid] forKey:KEY_UDID];  
  42.           
  43.         [KeychainHelper save:KEY_DIC data:dic];  
  44.     }  
  45. }  
  46.   
  47. @end  


-------------------分割线---------------------


[cpp] view plaincopyprint?
  1. #import <Foundation/Foundation.h>  
  2. #import <Security/Security.h>  
  3.   
  4.   
  5. @interface KeychainHelper : NSObject  
  6.   
  7. + (void) save:(NSString *)service data:(id)data;  
  8. + (id)   load:(NSString *)service;  
  9. + (void) deleteData:(NSString *)service;  
  10.   
  11.   
  12. @end  

[cpp] view plaincopyprint?
  1. #import "KeychainHelper.h"  
  2.   
  3. @implementation KeychainHelper  
  4.   
  5. + (NSMutableDictionary *)getKeychainQuery:(NSString *)service  
  6. {  
  7.     return [NSMutableDictionary dictionaryWithObjectsAndKeys:  
  8.             (id)kSecClassGenericPassword,(id)kSecClass,  
  9.             service, (id)kSecAttrService,  
  10.             service, (id)kSecAttrAccount,  
  11.             (id)kSecAttrAccessibleAfterFirstUnlock,(id)kSecAttrAccessible,  
  12.             nil];  
  13. }  
  14.   
  15. + (void)save:(NSString *)service data:(id)data  
  16. {  
  17.     //Get search dictionary  
  18.     NSMutableDictionary *keychainQuery = [self getKeychainQuery:service];  
  19.     //Delete old item before add new item  
  20.     SecItemDelete((CFDictionaryRef)keychainQuery);  
  21.     //Add new object to search dictionary(Attention:the data format)  
  22.     [keychainQuery setObject:[NSKeyedArchiver archivedDataWithRootObject:data] forKey:(id)kSecValueData];  
  23.     //Add item to keychain with the search dictionary  
  24.     SecItemAdd((CFDictionaryRef)keychainQuery, NULL);  
  25. }  
  26.   
  27. + (id)load:(NSString *)service  
  28. {  
  29.     id ret = nil;  
  30.     NSMutableDictionary *keychainQuery = [self getKeychainQuery:service];  
  31.     //Configure the search setting  
  32.     //Since in our simple case we are expecting only a single attribute to be returned (the password) we can set the attribute kSecReturnData to kCFBooleanTrue  
  33.     [keychainQuery setObject:(id)kCFBooleanTrue forKey:(id)kSecReturnData];  
  34.     [keychainQuery setObject:(id)kSecMatchLimitOne forKey:(id)kSecMatchLimit];  
  35.     CFDataRef keyData = NULL;  
  36.     if (SecItemCopyMatching((CFDictionaryRef)keychainQuery, (CFTypeRef *)&keyData) == noErr) {  
  37.         @try {  
  38.             ret = [NSKeyedUnarchiver unarchiveObjectWithData:(NSData *)keyData];  
  39.         } @catch (NSException *e) {  
  40.             NSLog(@"Unarchive of %@ failed: %@", service, e);  
  41.         } @finally {  
  42.         }  
  43.     }  
  44.     if (keyData)  
  45.         CFRelease(keyData);  
  46.     return ret;  
  47. }  
  48.   
  49. + (void)deleteData:(NSString *)service  
  50. {  
  51.     NSMutableDictionary *keychainQuery = [self getKeychainQuery:service];  
  52.     SecItemDelete((CFDictionaryRef)keychainQuery);  
  53. }  
  54.   
  55.   
  56. @end 

0 0