| /** |
| * Created by Weex. |
| * Copyright (c) 2016, Alibaba, Inc. All rights reserved. |
| * |
| * This source code is licensed under the Apache Licence 2.0. |
| * For the full copyright and license information,please view the LICENSE file in the root directory of this source tree. |
| */ |
| |
| #import "WXDeviceInfo.h" |
| #import <UIKit/UIKit.h> |
| #import <Security/Security.h> |
| |
| #define KEY_PASSWORD @"com.taobao.Weex.123456" |
| #define KEY_USERNAME_PASSWORD @"com.taobao.Weex.weex123456" |
| |
| @implementation WXDeviceInfo |
| |
| + (NSString *)getDeviceID { |
| NSMutableDictionary *usernamepasswordKVPairs = (NSMutableDictionary *)[self load:KEY_USERNAME_PASSWORD]; |
| NSString *deviceID = [usernamepasswordKVPairs objectForKey:KEY_PASSWORD]; |
| if (!deviceID) { |
| CFUUIDRef uuid = CFUUIDCreate(NULL); |
| deviceID = CFBridgingRelease(CFUUIDCreateString(NULL, uuid)); |
| assert(deviceID); |
| CFRelease(uuid); |
| NSMutableDictionary *usernamepasswordKVPairs = [NSMutableDictionary dictionary]; |
| [usernamepasswordKVPairs setObject:deviceID forKey:KEY_PASSWORD]; |
| [self save:KEY_USERNAME_PASSWORD data:usernamepasswordKVPairs]; |
| } |
| return deviceID; |
| } |
| |
| + (NSMutableDictionary *)getKeychainQuery:(NSString *)service { |
| return [NSMutableDictionary dictionaryWithObjectsAndKeys: |
| (id)kSecClassGenericPassword,(id)kSecClass, |
| service, (id)kSecAttrService, |
| service, (id)kSecAttrAccount, |
| (id)kSecAttrAccessibleAfterFirstUnlock,(id)kSecAttrAccessible, |
| nil]; |
| } |
| |
| + (void)save:(NSString *)service data:(id)data { |
| //Get search dictionary |
| NSMutableDictionary *keychainQuery = [self getKeychainQuery:service]; |
| //Delete old item before add new item |
| SecItemDelete((CFDictionaryRef)keychainQuery); |
| //Add new object to search dictionary(Attention:the data format) |
| [keychainQuery setObject:[NSKeyedArchiver archivedDataWithRootObject:data] forKey:(id)kSecValueData]; |
| //Add item to keychain with the search dictionary |
| SecItemAdd((CFDictionaryRef)keychainQuery, NULL); |
| } |
| |
| + (id)load:(NSString *)service { |
| id ret = nil; |
| NSMutableDictionary *keychainQuery = [self getKeychainQuery:service]; |
| //Configure the search setting |
| //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 |
| [keychainQuery setObject:(id)kCFBooleanTrue forKey:(id)kSecReturnData]; |
| [keychainQuery setObject:(id)kSecMatchLimitOne forKey:(id)kSecMatchLimit]; |
| CFDataRef keyData = NULL; |
| if (SecItemCopyMatching((CFDictionaryRef)keychainQuery, (CFTypeRef *)&keyData) == noErr) { |
| @try { |
| ret = [NSKeyedUnarchiver unarchiveObjectWithData:(__bridge NSData *)keyData]; |
| } @catch (NSException *e) { |
| NSLog(@"Unarchive of %@ failed: %@", service, e); |
| } @finally { |
| } |
| } |
| if (keyData) |
| CFRelease(keyData); |
| return ret; |
| } |
| |
| + (void)delete:(NSString *)service { |
| NSMutableDictionary *keychainQuery = [self getKeychainQuery:service]; |
| SecItemDelete((CFDictionaryRef)keychainQuery); |
| } |
| |
| + (NSString *)deviceName { |
| NSString *machine = [[UIDevice currentDevice] model]; |
| NSString *systemVer = [[UIDevice currentDevice] systemVersion] ? : @""; |
| NSString *model = [NSString stringWithFormat:@"%@:%@",machine,systemVer]; |
| return model; |
| } |
| |
| @end |