diff --git a/Classes_cocos/DataManager.h b/Classes_cocos/DataManager.h new file mode 100644 index 0000000..5df7f2f --- /dev/null +++ b/Classes_cocos/DataManager.h @@ -0,0 +1,21 @@ +// +// DataManager.h +// Unity-iPhone +// +// Created by zhl on 2022/11/23. +// + +#import + +typedef NS_ENUM(NSUInteger, InitType) { + SynLock, + GCD, +}; + +@interface DataManager : NSObject + ++ (instancetype)sharedInstanceWith:(InitType)type; +-(void)saveKey:(NSString *) account key:(NSString *) key; +-(NSString *)loadKey:(NSString *) account; + +@end diff --git a/Classes_cocos/DataManager.m b/Classes_cocos/DataManager.m new file mode 100644 index 0000000..4c84480 --- /dev/null +++ b/Classes_cocos/DataManager.m @@ -0,0 +1,87 @@ +// +// DataManager.m +// Unity-iPhone +// +// Created by zhl on 2022/11/23. +// + +#import "DataManager.h" +#import "UICKeyChainStore.h" + + +@interface DataManager () + +@end + +static NSString * const cebgWalletService = @"com.cebg.wallet"; +//global var +static id _instance; + +UICKeyChainStore *keychain; + +InitType _instanceInitType; + +@implementation DataManager + ++ (instancetype)sharedInstanceWith:(InitType)type { + _instanceInitType = type; + if (type == SynLock) { + @synchronized (self) { + if (_instance == nil) { + _instance = [[self alloc] init]; + } + } + } + + else { + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + _instance = [[self alloc] init]; + }); + } + return _instance; +} + ++ (instancetype)allocWithZone:(struct _NSZone *)zone { + if (_instanceInitType == SynLock) { + @synchronized (self) { + if (_instance == nil) { + _instance = [super allocWithZone:zone]; + } + } + } + else { + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + _instance = [super allocWithZone:zone]; + }); + } + return _instance; +} + +- (id)copyWithZone:(nullable NSZone *)zone { + return _instance; +} + +-(void)saveKey:(NSString *) account key:(NSString *) key { + if (keychain == nil ){ + keychain = [UICKeyChainStore keyChainStoreWithService:cebgWalletService]; + keychain.synchronizable = YES; + } + keychain[account] = key; +} + +-(NSString *)loadKey:(NSString *) account { + if (keychain == nil ){ + keychain = [UICKeyChainStore keyChainStoreWithService:cebgWalletService]; + keychain.synchronizable = YES; + } + NSError *error; + NSString * result = [keychain stringForKey:account error:&error]; + if (error) { + NSLog(@"%@", error.localizedDescription); + } + return result; +} + +@end diff --git a/Classes_cocos/SSKeychain.h b/Classes_cocos/SSKeychain.h deleted file mode 100644 index 3f70404..0000000 --- a/Classes_cocos/SSKeychain.h +++ /dev/null @@ -1,357 +0,0 @@ -// -// SSKeychain.h -// SSToolkit -// -// Created by Sam Soffes on 5/19/10. -// Copyright (c) 2009-2011 Sam Soffes. All rights reserved. -// - -#import -#import - -/** Error codes that can be returned in NSError objects. */ -typedef enum { - /** No error. */ - SSKeychainErrorNone = noErr, - - /** Some of the arguments were invalid. */ - SSKeychainErrorBadArguments = -1001, - - /** There was no password. */ - SSKeychainErrorNoPassword = -1002, - - /** One or more parameters passed internally were not valid. */ - SSKeychainErrorInvalidParameter = errSecParam, - - /** Failed to allocate memory. */ - SSKeychainErrorFailedToAllocated = errSecAllocate, - - /** No trust results are available. */ - SSKeychainErrorNotAvailable = errSecNotAvailable, - - /** Authorization/Authentication failed. */ - SSKeychainErrorAuthorizationFailed = errSecAuthFailed, - - /** The item already exists. */ - SSKeychainErrorDuplicatedItem = errSecDuplicateItem, - - /** The item cannot be found.*/ - SSKeychainErrorNotFound = errSecItemNotFound, - - /** Interaction with the Security Server is not allowed. */ - SSKeychainErrorInteractionNotAllowed = errSecInteractionNotAllowed, - - /** Unable to decode the provided data. */ - SSKeychainErrorFailedToDecode = errSecDecode -} SSKeychainErrorCode; - -extern NSString *const kSSKeychainErrorDomain; - -/** Account name. */ -extern NSString *const kSSKeychainAccountKey; - -/** - Time the item was created. - - The value will be a string. - */ -extern NSString *const kSSKeychainCreatedAtKey; - -/** Item class. */ -extern NSString *const kSSKeychainClassKey; - -/** Item description. */ -extern NSString *const kSSKeychainDescriptionKey; - -/** Item label. */ -extern NSString *const kSSKeychainLabelKey; - -/** Time the item was last modified. - - The value will be a string. - */ -extern NSString *const kSSKeychainLastModifiedKey; - -/** Where the item was created. */ -extern NSString *const kSSKeychainWhereKey; - -/** - Simple wrapper for accessing accounts, getting passwords, setting passwords, and deleting passwords using the system - Keychain on Mac OS X and iOS. - - This was originally inspired by EMKeychain and SDKeychain (both of which are now gone). Thanks to the authors. - SSKeychain has since switched to a simpler implementation that was abstracted from [SSToolkit](http://sstoolk.it). - */ -@interface SSKeychain : NSObject - -///----------------------- -/// @name Getting Accounts -///----------------------- - -/** - Returns an array containing the Keychain's accounts, or `nil` if the Keychain has no accounts. - - See the `NSString` constants declared in SSKeychain.h for a list of keys that can be used when accessing the - dictionaries returned by this method. - - @return An array of dictionaries containing the Keychain's accounts, or `nil` if the Keychain doesn't have any - accounts. The order of the objects in the array isn't defined. - - @see allAccounts: - */ -+ (NSArray *)allAccounts; - -/** - Returns an array containing the Keychain's accounts, or `nil` if the Keychain doesn't have any - accounts. - - See the `NSString` constants declared in SSKeychain.h for a list of keys that can be used when accessing the - dictionaries returned by this method. - - @param error If accessing the accounts fails, upon return contains an error that describes the problem. - - @return An array of dictionaries containing the Keychain's accounts, or `nil` if the Keychain doesn't have any - accounts. The order of the objects in the array isn't defined. - - @see allAccounts - */ -+ (NSArray *)allAccounts:(NSError **)error; - -/** - Returns an array containing the Keychain's accounts for a given service, or `nil` if the Keychain doesn't have any - accounts for the given service. - - See the `NSString` constants declared in SSKeychain.h for a list of keys that can be used when accessing the - dictionaries returned by this method. - - @param serviceName The service for which to return the corresponding accounts. - - @return An array of dictionaries containing the Keychain's accountsfor a given `serviceName`, or `nil` if the Keychain - doesn't have any accounts for the given `serviceName`. The order of the objects in the array isn't defined. - - @see accountsForService:error: - */ -+ (NSArray *)accountsForService:(NSString *)serviceName; - -/** - Returns an array containing the Keychain's accounts for a given service, or `nil` if the Keychain doesn't have any - accounts for the given service. - - @param serviceName The service for which to return the corresponding accounts. - - @param error If accessing the accounts fails, upon return contains an error that describes the problem. - - @return An array of dictionaries containing the Keychain's accountsfor a given `serviceName`, or `nil` if the Keychain - doesn't have any accounts for the given `serviceName`. The order of the objects in the array isn't defined. - - @see accountsForService: - */ -+ (NSArray *)accountsForService:(NSString *)serviceName error:(NSError **)error; - - -///------------------------ -/// @name Getting Passwords -///------------------------ - -/** - Returns a string containing the password for a given account and service, or `nil` if the Keychain doesn't have a - password for the given parameters. - - @param serviceName The service for which to return the corresponding password. - - @param account The account for which to return the corresponding password. - - @return Returns a string containing the password for a given account and service, or `nil` if the Keychain doesn't - have a password for the given parameters. - - @see passwordForService:account:error: - */ -+ (NSString *)passwordForService:(NSString *)serviceName account:(NSString *)account; - -/** - Returns a string containing the password for a given account and service, or `nil` if the Keychain doesn't have a - password for the given parameters. - - @param serviceName The service for which to return the corresponding password. - - @param account The account for which to return the corresponding password. - - @param error If accessing the password fails, upon return contains an error that describes the problem. - - @return Returns a string containing the password for a given account and service, or `nil` if the Keychain doesn't - have a password for the given parameters. - - @see passwordForService:account: - */ -+ (NSString *)passwordForService:(NSString *)serviceName account:(NSString *)account error:(NSError **)error; - -/** - Returns the password data for a given account and service, or `nil` if the Keychain doesn't have data - for the given parameters. - - @param serviceName The service for which to return the corresponding password. - - @param account The account for which to return the corresponding password. - - @param error If accessing the password fails, upon return contains an error that describes the problem. - - @return Returns a the password data for the given account and service, or `nil` if the Keychain doesn't - have data for the given parameters. - - @see passwordDataForService:account:error: - */ -+ (NSData *)passwordDataForService:(NSString *)serviceName account:(NSString *)account; - -/** - Returns the password data for a given account and service, or `nil` if the Keychain doesn't have data - for the given parameters. - - @param serviceName The service for which to return the corresponding password. - - @param account The account for which to return the corresponding password. - - @param error If accessing the password fails, upon return contains an error that describes the problem. - - @return Returns a the password data for the given account and service, or `nil` if the Keychain doesn't - have a password for the given parameters. - - @see passwordDataForService:account: - */ -+ (NSData *)passwordDataForService:(NSString *)serviceName account:(NSString *)account error:(NSError **)error; - - -///------------------------- -/// @name Deleting Passwords -///------------------------- - -/** - Deletes a password from the Keychain. - - @param serviceName The service for which to delete the corresponding password. - - @param account The account for which to delete the corresponding password. - - @return Returns `YES` on success, or `NO` on failure. - - @see deletePasswordForService:account:error: - */ -+ (BOOL)deletePasswordForService:(NSString *)serviceName account:(NSString *)account; - -/** - Deletes a password from the Keychain. - - @param serviceName The service for which to delete the corresponding password. - - @param account The account for which to delete the corresponding password. - - @param error If deleting the password fails, upon return contains an error that describes the problem. - - @return Returns `YES` on success, or `NO` on failure. - - @see deletePasswordForService:account: - */ -+ (BOOL)deletePasswordForService:(NSString *)serviceName account:(NSString *)account error:(NSError **)error; - - -///------------------------ -/// @name Setting Passwords -///------------------------ - -/** - Sets a password in the Keychain. - - @param password The password to store in the Keychain. - - @param serviceName The service for which to set the corresponding password. - - @param account The account for which to set the corresponding password. - - @return Returns `YES` on success, or `NO` on failure. - - @see setPassword:forService:account:error: - */ -+ (BOOL)setPassword:(NSString *)password forService:(NSString *)serviceName account:(NSString *)account; - -/** - Sets a password in the Keychain. - - @param password The password to store in the Keychain. - - @param serviceName The service for which to set the corresponding password. - - @param account The account for which to set the corresponding password. - - @param error If setting the password fails, upon return contains an error that describes the problem. - - @return Returns `YES` on success, or `NO` on failure. - - @see setPassword:forService:account: - */ -+ (BOOL)setPassword:(NSString *)password forService:(NSString *)serviceName account:(NSString *)account error:(NSError **)error; - -/** - Sets arbirary data in the Keychain. - - @param password The data to store in the Keychain. - - @param serviceName The service for which to set the corresponding password. - - @param account The account for which to set the corresponding password. - - @param error If setting the password fails, upon return contains an error that describes the problem. - - @return Returns `YES` on success, or `NO` on failure. - - @see setPasswordData:forService:account:error: - */ -+ (BOOL)setPasswordData:(NSData *)password forService:(NSString *)serviceName account:(NSString *)account; - -/** - Sets arbirary data in the Keychain. - - @param password The data to store in the Keychain. - - @param serviceName The service for which to set the corresponding password. - - @param account The account for which to set the corresponding password. - - @param error If setting the password fails, upon return contains an error that describes the problem. - - @return Returns `YES` on success, or `NO` on failure. - - @see setPasswordData:forService:account: - */ -+ (BOOL)setPasswordData:(NSData *)password forService:(NSString *)serviceName account:(NSString *)account error:(NSError **)error; - - -///-------------------- -/// @name Configuration -///-------------------- - -#if __IPHONE_4_0 && TARGET_OS_IPHONE -/** - Returns the accessibility type for all future passwords saved to the Keychain. - - @return Returns the accessibility type. - - The return value will be `NULL` or one of the "Keychain Item Accessibility Constants" used for determining when a - keychain item should be readable. - - @see accessibilityType - */ -+ (CFTypeRef)accessibilityType; - -/** - Sets the accessibility type for all future passwords saved to the Keychain. - - @param accessibilityType One of the "Keychain Item Accessibility Constants" used for determining when a keychain item - should be readable. - - If the value is `NULL` (the default), the Keychain default will be used. - - @see accessibilityType - */ -+ (void)setAccessibilityType:(CFTypeRef)accessibilityType; -#endif - -@end diff --git a/Classes_cocos/SSKeychain.m b/Classes_cocos/SSKeychain.m deleted file mode 100644 index e0b0111..0000000 --- a/Classes_cocos/SSKeychain.m +++ /dev/null @@ -1,262 +0,0 @@ -// -// SSKeychain.m -// SSToolkit -// -// Created by Sam Soffes on 5/19/10. -// Copyright (c) 2009-2011 Sam Soffes. All rights reserved. -// - -#import "SSKeychain.h" - -NSString *const kSSKeychainErrorDomain = @"com.samsoffes.sskeychain"; - -NSString *const kSSKeychainAccountKey = @"acct"; -NSString *const kSSKeychainCreatedAtKey = @"cdat"; -NSString *const kSSKeychainClassKey = @"labl"; -NSString *const kSSKeychainDescriptionKey = @"desc"; -NSString *const kSSKeychainLabelKey = @"labl"; -NSString *const kSSKeychainLastModifiedKey = @"mdat"; -NSString *const kSSKeychainWhereKey = @"svce"; - -#if __IPHONE_4_0 && TARGET_OS_IPHONE -CFTypeRef SSKeychainAccessibilityType = NULL; -#endif - -@interface SSKeychain () -+ (NSMutableDictionary *)_queryForService:(NSString *)service account:(NSString *)account; -@end - -@implementation SSKeychain - -#pragma mark - Getting Accounts - -+ (NSArray *)allAccounts { - return [self accountsForService:nil error:nil]; -} - - -+ (NSArray *)allAccounts:(NSError **)error { - return [self accountsForService:nil error:error]; -} - - -+ (NSArray *)accountsForService:(NSString *)service { - return [self accountsForService:service error:nil]; -} - - -+ (NSArray *)accountsForService:(NSString *)service error:(NSError **)error { - OSStatus status = SSKeychainErrorBadArguments; - NSMutableDictionary *query = [self _queryForService:service account:nil]; -#if __has_feature(objc_arc) - [query setObject:(__bridge id)kCFBooleanTrue forKey:(__bridge id)kSecReturnAttributes]; - [query setObject:(__bridge id)kSecMatchLimitAll forKey:(__bridge id)kSecMatchLimit]; -#else - [query setObject:(id)kCFBooleanTrue forKey:(id)kSecReturnAttributes]; - [query setObject:(id)kSecMatchLimitAll forKey:(id)kSecMatchLimit]; -#endif - - CFTypeRef result = NULL; -#if __has_feature(objc_arc) - status = SecItemCopyMatching((__bridge CFDictionaryRef)query, &result); -#else - status = SecItemCopyMatching((CFDictionaryRef)query, &result); -#endif - if (status != noErr && error != NULL) { - *error = [NSError errorWithDomain:kSSKeychainErrorDomain code:status userInfo:nil]; - return nil; - } - -#if __has_feature(objc_arc) - return (__bridge_transfer NSArray *)result; -#else - return [(NSArray *)result autorelease]; -#endif -} - - -#pragma mark - Getting Passwords - -+ (NSString *)passwordForService:(NSString *)service account:(NSString *)account { - return [self passwordForService:service account:account error:nil]; -} - - -+ (NSString *)passwordForService:(NSString *)service account:(NSString *)account error:(NSError **)error { - NSData *data = [self passwordDataForService:service account:account error:error]; - if (data.length > 0) { - NSString *string = [[NSString alloc] initWithData:(NSData *)data encoding:NSUTF8StringEncoding]; -#if !__has_feature(objc_arc) - [string autorelease]; -#endif - return string; - } - - return nil; -} - - -+ (NSData *)passwordDataForService:(NSString *)service account:(NSString *)account { - return [self passwordDataForService:service account:account error:nil]; -} - - -+ (NSData *)passwordDataForService:(NSString *)service account:(NSString *)account error:(NSError **)error { - OSStatus status = SSKeychainErrorBadArguments; - if (!service || !account) { - if (error) { - *error = [NSError errorWithDomain:kSSKeychainErrorDomain code:status userInfo:nil]; - } - return nil; - } - - CFTypeRef result = NULL; - NSMutableDictionary *query = [self _queryForService:service account:account]; -#if __has_feature(objc_arc) - [query setObject:(__bridge id)kCFBooleanTrue forKey:(__bridge id)kSecReturnData]; - [query setObject:(__bridge id)kSecMatchLimitOne forKey:(__bridge id)kSecMatchLimit]; - status = SecItemCopyMatching((__bridge CFDictionaryRef)query, &result); -#else - [query setObject:(id)kCFBooleanTrue forKey:(id)kSecReturnData]; - [query setObject:(id)kSecMatchLimitOne forKey:(id)kSecMatchLimit]; - status = SecItemCopyMatching((CFDictionaryRef)query, &result); -#endif - - if (status != noErr && error != NULL) { - *error = [NSError errorWithDomain:kSSKeychainErrorDomain code:status userInfo:nil]; - return nil; - } - -#if __has_feature(objc_arc) - return (__bridge_transfer NSData *)result; -#else - return [(NSData *)result autorelease]; -#endif -} - - -#pragma mark - Deleting Passwords - -+ (BOOL)deletePasswordForService:(NSString *)service account:(NSString *)account { - return [self deletePasswordForService:service account:account error:nil]; -} - - -+ (BOOL)deletePasswordForService:(NSString *)service account:(NSString *)account error:(NSError **)error { - OSStatus status = SSKeychainErrorBadArguments; - if (service && account) { - NSMutableDictionary *query = [self _queryForService:service account:account]; -#if __has_feature(objc_arc) - status = SecItemDelete((__bridge CFDictionaryRef)query); -#else - status = SecItemDelete((CFDictionaryRef)query); -#endif - } - if (status != noErr && error != NULL) { - *error = [NSError errorWithDomain:kSSKeychainErrorDomain code:status userInfo:nil]; - } - return (status == noErr); - -} - - -#pragma mark - Setting Passwords - -+ (BOOL)setPassword:(NSString *)password forService:(NSString *)service account:(NSString *)account { - return [self setPassword:password forService:service account:account error:nil]; -} - - -+ (BOOL)setPassword:(NSString *)password forService:(NSString *)service account:(NSString *)account error:(NSError **)error { - NSData *data = [password dataUsingEncoding:NSUTF8StringEncoding]; - return [self setPasswordData:data forService:service account:account error:error]; -} - - -+ (BOOL)setPasswordData:(NSData *)password forService:(NSString *)service account:(NSString *)account { - return [self setPasswordData:password forService:service account:account error:nil]; -} - - -+ (BOOL)setPasswordData:(NSData *)password forService:(NSString *)service account:(NSString *)account error:(NSError **)error { - OSStatus status = SSKeychainErrorBadArguments; - if (password && service && account) { - [self deletePasswordForService:service account:account]; - NSMutableDictionary *query = [self _queryForService:service account:account]; -#if __has_feature(objc_arc) - [query setObject:password forKey:(__bridge id)kSecValueData]; -#else - [query setObject:password forKey:(id)kSecValueData]; -#endif - -#if __IPHONE_4_0 && TARGET_OS_IPHONE - if (SSKeychainAccessibilityType) { -#if __has_feature(objc_arc) - [query setObject:(id)[self accessibilityType] forKey:(__bridge id)kSecAttrAccessible]; -#else - [query setObject:(id)[self accessibilityType] forKey:(id)kSecAttrAccessible]; -#endif - } -#endif - -#if __has_feature(objc_arc) - status = SecItemAdd((__bridge CFDictionaryRef)query, NULL); -#else - status = SecItemAdd((CFDictionaryRef)query, NULL); -#endif - } - if (status != noErr && error != NULL) { - *error = [NSError errorWithDomain:kSSKeychainErrorDomain code:status userInfo:nil]; - } - return (status == noErr); -} - - -#pragma mark - Configuration - -#if __IPHONE_4_0 && TARGET_OS_IPHONE -+ (CFTypeRef)accessibilityType { - return SSKeychainAccessibilityType; -} - - -+ (void)setAccessibilityType:(CFTypeRef)accessibilityType { - CFRetain(accessibilityType); - if (SSKeychainAccessibilityType) { - CFRelease(SSKeychainAccessibilityType); - } - SSKeychainAccessibilityType = accessibilityType; -} -#endif - - -#pragma mark - Private - -+ (NSMutableDictionary *)_queryForService:(NSString *)service account:(NSString *)account { - NSMutableDictionary *dictionary = [NSMutableDictionary dictionaryWithCapacity:3]; -#if __has_feature(objc_arc) - [dictionary setObject:(__bridge id)kSecClassGenericPassword forKey:(__bridge id)kSecClass]; -#else - [dictionary setObject:(id)kSecClassGenericPassword forKey:(id)kSecClass]; -#endif - - if (service) { -#if __has_feature(objc_arc) - [dictionary setObject:service forKey:(__bridge id)kSecAttrService]; -#else - [dictionary setObject:service forKey:(id)kSecAttrService]; -#endif - } - - if (account) { -#if __has_feature(objc_arc) - [dictionary setObject:account forKey:(__bridge id)kSecAttrAccount]; -#else - [dictionary setObject:account forKey:(id)kSecAttrAccount]; -#endif - } - - return dictionary; -} - -@end diff --git a/Classes_cocos/UICKeyChainStore.h b/Classes_cocos/UICKeyChainStore.h new file mode 100644 index 0000000..095720a --- /dev/null +++ b/Classes_cocos/UICKeyChainStore.h @@ -0,0 +1,289 @@ +// +// UICKeyChainStore.h +// UICKeyChainStore +// +// Created by Kishikawa Katsumi on 11/11/20. +// Copyright (c) 2011 Kishikawa Katsumi. All rights reserved. +// + +#import + +#if !__has_feature(nullability) +#define NS_ASSUME_NONNULL_BEGIN +#define NS_ASSUME_NONNULL_END +#define nullable +#define nonnull +#define null_unspecified +#define null_resettable +#define __nullable +#define __nonnull +#define __null_unspecified +#endif + +#if __has_extension(objc_generics) +#define UIC_KEY_TYPE +#define UIC_CREDENTIAL_TYPE *> +#else +#define UIC_KEY_TYPE +#define UIC_CREDENTIAL_TYPE +#endif + +NS_ASSUME_NONNULL_BEGIN + +extern NSString * const UICKeyChainStoreErrorDomain; + +typedef NS_ENUM(NSInteger, UICKeyChainStoreErrorCode) { + UICKeyChainStoreErrorInvalidArguments = 1, +}; + +typedef NS_ENUM(NSInteger, UICKeyChainStoreItemClass) { + UICKeyChainStoreItemClassGenericPassword = 1, + UICKeyChainStoreItemClassInternetPassword, +}; + +typedef NS_ENUM(NSInteger, UICKeyChainStoreProtocolType) { + UICKeyChainStoreProtocolTypeFTP = 1, + UICKeyChainStoreProtocolTypeFTPAccount, + UICKeyChainStoreProtocolTypeHTTP, + UICKeyChainStoreProtocolTypeIRC, + UICKeyChainStoreProtocolTypeNNTP, + UICKeyChainStoreProtocolTypePOP3, + UICKeyChainStoreProtocolTypeSMTP, + UICKeyChainStoreProtocolTypeSOCKS, + UICKeyChainStoreProtocolTypeIMAP, + UICKeyChainStoreProtocolTypeLDAP, + UICKeyChainStoreProtocolTypeAppleTalk, + UICKeyChainStoreProtocolTypeAFP, + UICKeyChainStoreProtocolTypeTelnet, + UICKeyChainStoreProtocolTypeSSH, + UICKeyChainStoreProtocolTypeFTPS, + UICKeyChainStoreProtocolTypeHTTPS, + UICKeyChainStoreProtocolTypeHTTPProxy, + UICKeyChainStoreProtocolTypeHTTPSProxy, + UICKeyChainStoreProtocolTypeFTPProxy, + UICKeyChainStoreProtocolTypeSMB, + UICKeyChainStoreProtocolTypeRTSP, + UICKeyChainStoreProtocolTypeRTSPProxy, + UICKeyChainStoreProtocolTypeDAAP, + UICKeyChainStoreProtocolTypeEPPC, + UICKeyChainStoreProtocolTypeNNTPS, + UICKeyChainStoreProtocolTypeLDAPS, + UICKeyChainStoreProtocolTypeTelnetS, + UICKeyChainStoreProtocolTypeIRCS, + UICKeyChainStoreProtocolTypePOP3S, +}; + +typedef NS_ENUM(NSInteger, UICKeyChainStoreAuthenticationType) { + UICKeyChainStoreAuthenticationTypeNTLM = 1, + UICKeyChainStoreAuthenticationTypeMSN, + UICKeyChainStoreAuthenticationTypeDPA, + UICKeyChainStoreAuthenticationTypeRPA, + UICKeyChainStoreAuthenticationTypeHTTPBasic, + UICKeyChainStoreAuthenticationTypeHTTPDigest, + UICKeyChainStoreAuthenticationTypeHTMLForm, + UICKeyChainStoreAuthenticationTypeDefault, +}; + +typedef NS_ENUM(NSInteger, UICKeyChainStoreAccessibility) { + UICKeyChainStoreAccessibilityWhenUnlocked = 1, + UICKeyChainStoreAccessibilityAfterFirstUnlock, + UICKeyChainStoreAccessibilityAlways, + UICKeyChainStoreAccessibilityWhenPasscodeSetThisDeviceOnly + __OSX_AVAILABLE_STARTING(__MAC_10_10, __IPHONE_8_0), + UICKeyChainStoreAccessibilityWhenUnlockedThisDeviceOnly, + UICKeyChainStoreAccessibilityAfterFirstUnlockThisDeviceOnly, + UICKeyChainStoreAccessibilityAlwaysThisDeviceOnly, +} +__OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_4_0); + +typedef NS_ENUM(unsigned long, UICKeyChainStoreAuthenticationPolicy) { + UICKeyChainStoreAuthenticationPolicyUserPresence = 1 << 0, + UICKeyChainStoreAuthenticationPolicyTouchIDAny NS_ENUM_AVAILABLE(10_12_1, 9_0) = 1u << 1, + UICKeyChainStoreAuthenticationPolicyTouchIDCurrentSet NS_ENUM_AVAILABLE(10_12_1, 9_0) = 1u << 3, + UICKeyChainStoreAuthenticationPolicyDevicePasscode NS_ENUM_AVAILABLE(10_11, 9_0) = 1u << 4, + UICKeyChainStoreAuthenticationPolicyControlOr NS_ENUM_AVAILABLE(10_12_1, 9_0) = 1u << 14, + UICKeyChainStoreAuthenticationPolicyControlAnd NS_ENUM_AVAILABLE(10_12_1, 9_0) = 1u << 15, + UICKeyChainStoreAuthenticationPolicyPrivateKeyUsage NS_ENUM_AVAILABLE(10_12_1, 9_0) = 1u << 30, + UICKeyChainStoreAuthenticationPolicyApplicationPassword NS_ENUM_AVAILABLE(10_12_1, 9_0) = 1u << 31, +}__OSX_AVAILABLE_STARTING(__MAC_10_10, __IPHONE_8_0); + +@interface UICKeyChainStore : NSObject + +@property (nonatomic, readonly) UICKeyChainStoreItemClass itemClass; + +@property (nonatomic, readonly, nullable) NSString *service; +@property (nonatomic, readonly, nullable) NSString *accessGroup; + +@property (nonatomic, readonly, nullable) NSURL *server; +@property (nonatomic, readonly) UICKeyChainStoreProtocolType protocolType; +@property (nonatomic, readonly) UICKeyChainStoreAuthenticationType authenticationType; + +@property (nonatomic) UICKeyChainStoreAccessibility accessibility; +@property (nonatomic, readonly) UICKeyChainStoreAuthenticationPolicy authenticationPolicy +__OSX_AVAILABLE_STARTING(__MAC_10_10, __IPHONE_8_0); +@property (nonatomic) BOOL useAuthenticationUI; + +@property (nonatomic) BOOL synchronizable; + +@property (nonatomic, nullable) NSString *authenticationPrompt +__OSX_AVAILABLE_STARTING(__MAC_NA, __IPHONE_8_0); + +@property (nonatomic, readonly, nullable) NSArray UIC_KEY_TYPE *allKeys; +@property (nonatomic, readonly, nullable) NSArray *allItems; + ++ (NSString *)defaultService; ++ (void)setDefaultService:(NSString *)defaultService; + ++ (UICKeyChainStore *)keyChainStore; ++ (UICKeyChainStore *)keyChainStoreWithService:(nullable NSString *)service; ++ (UICKeyChainStore *)keyChainStoreWithService:(nullable NSString *)service accessGroup:(nullable NSString *)accessGroup; + ++ (UICKeyChainStore *)keyChainStoreWithServer:(NSURL *)server protocolType:(UICKeyChainStoreProtocolType)protocolType; ++ (UICKeyChainStore *)keyChainStoreWithServer:(NSURL *)server protocolType:(UICKeyChainStoreProtocolType)protocolType authenticationType:(UICKeyChainStoreAuthenticationType)authenticationType; + +- (instancetype)init; +- (instancetype)initWithService:(nullable NSString *)service; +- (instancetype)initWithService:(nullable NSString *)service accessGroup:(nullable NSString *)accessGroup; + +- (instancetype)initWithServer:(NSURL *)server protocolType:(UICKeyChainStoreProtocolType)protocolType; +- (instancetype)initWithServer:(NSURL *)server protocolType:(UICKeyChainStoreProtocolType)protocolType authenticationType:(UICKeyChainStoreAuthenticationType)authenticationType; + ++ (nullable NSString *)stringForKey:(NSString *)key; ++ (nullable NSString *)stringForKey:(NSString *)key service:(nullable NSString *)service; ++ (nullable NSString *)stringForKey:(NSString *)key service:(nullable NSString *)service accessGroup:(nullable NSString *)accessGroup; ++ (BOOL)setString:(nullable NSString *)value forKey:(NSString *)key; ++ (BOOL)setString:(nullable NSString *)value forKey:(NSString *)key service:(nullable NSString *)service; ++ (BOOL)setString:(nullable NSString *)value forKey:(NSString *)key service:(nullable NSString *)service accessGroup:(nullable NSString *)accessGroup; + ++ (nullable NSData *)dataForKey:(NSString *)key; ++ (nullable NSData *)dataForKey:(NSString *)key service:(nullable NSString *)service; ++ (nullable NSData *)dataForKey:(NSString *)key service:(nullable NSString *)service accessGroup:(nullable NSString *)accessGroup; ++ (BOOL)setData:(nullable NSData *)data forKey:(NSString *)key; ++ (BOOL)setData:(nullable NSData *)data forKey:(NSString *)key service:(nullable NSString *)service; ++ (BOOL)setData:(nullable NSData *)data forKey:(NSString *)key service:(nullable NSString *)service accessGroup:(nullable NSString *)accessGroup; + +- (BOOL)contains:(nullable NSString *)key; + +- (BOOL)setString:(nullable NSString *)string forKey:(nullable NSString *)key; +- (BOOL)setString:(nullable NSString *)string forKey:(nullable NSString *)key label:(nullable NSString *)label comment:(nullable NSString *)comment; +- (nullable NSString *)stringForKey:(NSString *)key; + +- (BOOL)setData:(nullable NSData *)data forKey:(NSString *)key; +- (BOOL)setData:(nullable NSData *)data forKey:(NSString *)key label:(nullable NSString *)label comment:(nullable NSString *)comment; +- (nullable NSData *)dataForKey:(NSString *)key; + ++ (BOOL)removeItemForKey:(NSString *)key; ++ (BOOL)removeItemForKey:(NSString *)key service:(nullable NSString *)service; ++ (BOOL)removeItemForKey:(NSString *)key service:(nullable NSString *)service accessGroup:(nullable NSString *)accessGroup; + ++ (BOOL)removeAllItems; ++ (BOOL)removeAllItemsForService:(nullable NSString *)service; ++ (BOOL)removeAllItemsForService:(nullable NSString *)service accessGroup:(nullable NSString *)accessGroup; + +- (BOOL)removeItemForKey:(NSString *)key; + +- (BOOL)removeAllItems; + +- (nullable NSString *)objectForKeyedSubscript:(NSString *)key; +- (void)setObject:(nullable NSString *)obj forKeyedSubscript:(NSString *)key; + ++ (nullable NSArray UIC_KEY_TYPE *)allKeysWithItemClass:(UICKeyChainStoreItemClass)itemClass; +- (nullable NSArray UIC_KEY_TYPE *)allKeys; + ++ (nullable NSArray *)allItemsWithItemClass:(UICKeyChainStoreItemClass)itemClass; +- (nullable NSArray *)allItems; + +- (void)setAccessibility:(UICKeyChainStoreAccessibility)accessibility authenticationPolicy:(UICKeyChainStoreAuthenticationPolicy)authenticationPolicy +__OSX_AVAILABLE_STARTING(__MAC_10_10, __IPHONE_8_0); + +#if TARGET_OS_IOS +- (void)sharedPasswordWithCompletion:(nullable void (^)(NSString * __nullable account, NSString * __nullable password, NSError * __nullable error))completion; +- (void)sharedPasswordForAccount:(NSString *)account completion:(nullable void (^)(NSString * __nullable password, NSError * __nullable error))completion; + +- (void)setSharedPassword:(nullable NSString *)password forAccount:(NSString *)account completion:(nullable void (^)(NSError * __nullable error))completion; +- (void)removeSharedPasswordForAccount:(NSString *)account completion:(nullable void (^)(NSError * __nullable error))completion; + ++ (void)requestSharedWebCredentialWithCompletion:(nullable void (^)(NSArray UIC_CREDENTIAL_TYPE *credentials, NSError * __nullable error))completion; ++ (void)requestSharedWebCredentialForDomain:(nullable NSString *)domain account:(nullable NSString *)account completion:(nullable void (^)(NSArray UIC_CREDENTIAL_TYPE *credentials, NSError * __nullable error))completion; + ++ (NSString *)generatePassword; +#endif + +@end + +@interface UICKeyChainStore (ErrorHandling) + ++ (nullable NSString *)stringForKey:(NSString *)key error:(NSError * __nullable __autoreleasing * __nullable)error; ++ (nullable NSString *)stringForKey:(NSString *)key service:(nullable NSString *)service error:(NSError * __nullable __autoreleasing * __nullable)error; ++ (nullable NSString *)stringForKey:(NSString *)key service:(nullable NSString *)service accessGroup:(nullable NSString *)accessGroup error:(NSError * __nullable __autoreleasing * __nullable)error; + ++ (BOOL)setString:(nullable NSString *)value forKey:(NSString *)key error:(NSError * __nullable __autoreleasing * __nullable)error; ++ (BOOL)setString:(nullable NSString *)value forKey:(NSString *)key service:(nullable NSString *)service error:(NSError * __nullable __autoreleasing * __nullable)error; ++ (BOOL)setString:(nullable NSString *)value forKey:(NSString *)key service:(nullable NSString *)service accessGroup:(nullable NSString *)accessGroup error:(NSError * __nullable __autoreleasing * __nullable)error; + ++ (nullable NSData *)dataForKey:(NSString *)key error:(NSError * __nullable __autoreleasing * __nullable)error; ++ (nullable NSData *)dataForKey:(NSString *)key service:(nullable NSString *)service error:(NSError * __nullable __autoreleasing * __nullable)error; ++ (nullable NSData *)dataForKey:(NSString *)key service:(nullable NSString *)service accessGroup:(nullable NSString *)accessGroup error:(NSError * __nullable __autoreleasing * __nullable)error; + ++ (BOOL)setData:(nullable NSData *)data forKey:(NSString *)key error:(NSError * __nullable __autoreleasing * __nullable)error; ++ (BOOL)setData:(nullable NSData *)data forKey:(NSString *)key service:(nullable NSString *)service error:(NSError * __nullable __autoreleasing * __nullable)error; ++ (BOOL)setData:(nullable NSData *)data forKey:(NSString *)key service:(nullable NSString *)service accessGroup:(nullable NSString *)accessGroup error:(NSError * __nullable __autoreleasing * __nullable)error; + +- (BOOL)setString:(nullable NSString *)string forKey:(NSString * )key error:(NSError * __nullable __autoreleasing * __nullable)error; +- (BOOL)setString:(nullable NSString *)string forKey:(NSString * )key label:(nullable NSString *)label comment:(nullable NSString *)comment error:(NSError * __nullable __autoreleasing * __nullable)error; + +- (BOOL)setData:(nullable NSData *)data forKey:(NSString *)key error:(NSError * __nullable __autoreleasing * __nullable)error; +- (BOOL)setData:(nullable NSData *)data forKey:(NSString *)key label:(nullable NSString *)label comment:(nullable NSString *)comment error:(NSError * __nullable __autoreleasing * __nullable)error; + +- (nullable NSString *)stringForKey:(NSString *)key error:(NSError * __nullable __autoreleasing * __nullable)error; +- (nullable NSData *)dataForKey:(NSString *)key error:(NSError * __nullable __autoreleasing * __nullable)error; + ++ (BOOL)removeItemForKey:(NSString *)key error:(NSError * __nullable __autoreleasing * __nullable)error; ++ (BOOL)removeItemForKey:(NSString *)key service:(nullable NSString *)service error:(NSError * __nullable __autoreleasing * __nullable)error; ++ (BOOL)removeItemForKey:(NSString *)key service:(nullable NSString *)service accessGroup:(nullable NSString *)accessGroup error:(NSError * __nullable __autoreleasing * __nullable)error; + ++ (BOOL)removeAllItemsWithError:(NSError * __nullable __autoreleasing * __nullable)error; ++ (BOOL)removeAllItemsForService:(nullable NSString *)service error:(NSError * __nullable __autoreleasing * __nullable)error; ++ (BOOL)removeAllItemsForService:(nullable NSString *)service accessGroup:(nullable NSString *)accessGroup error:(NSError * __nullable __autoreleasing * __nullable)error; + +- (BOOL)removeItemForKey:(NSString *)key error:(NSError * __nullable __autoreleasing * __nullable)error; +- (BOOL)removeAllItemsWithError:(NSError * __nullable __autoreleasing * __nullable)error; + +@end + +@interface UICKeyChainStore (ForwardCompatibility) + ++ (BOOL)setString:(nullable NSString *)value forKey:(NSString *)key genericAttribute:(nullable id)genericAttribute; ++ (BOOL)setString:(nullable NSString *)value forKey:(NSString *)key genericAttribute:(nullable id)genericAttribute error:(NSError * __nullable __autoreleasing * __nullable)error; + ++ (BOOL)setString:(nullable NSString *)value forKey:(NSString *)key service:(nullable NSString *)service genericAttribute:(nullable id)genericAttribute; ++ (BOOL)setString:(nullable NSString *)value forKey:(NSString *)key service:(nullable NSString *)service genericAttribute:(nullable id)genericAttribute error:(NSError * __nullable __autoreleasing * __nullable)error; + ++ (BOOL)setString:(nullable NSString *)value forKey:(NSString *)key service:(nullable NSString *)service accessGroup:(nullable NSString *)accessGroup genericAttribute:(nullable id)genericAttribute; ++ (BOOL)setString:(nullable NSString *)value forKey:(NSString *)key service:(nullable NSString *)service accessGroup:(nullable NSString *)accessGroup genericAttribute:(nullable id)genericAttribute error:(NSError * __nullable __autoreleasing * __nullable)error; + ++ (BOOL)setData:(nullable NSData *)data forKey:(NSString *)key genericAttribute:(nullable id)genericAttribute; ++ (BOOL)setData:(nullable NSData *)data forKey:(NSString *)key genericAttribute:(nullable id)genericAttribute error:(NSError * __nullable __autoreleasing * __nullable)error; + ++ (BOOL)setData:(nullable NSData *)data forKey:(NSString *)key service:(nullable NSString *)service genericAttribute:(nullable id)genericAttribute; ++ (BOOL)setData:(nullable NSData *)data forKey:(NSString *)key service:(nullable NSString *)service genericAttribute:(nullable id)genericAttribute error:(NSError * __nullable __autoreleasing * __nullable)error; + ++ (BOOL)setData:(nullable NSData *)data forKey:(NSString *)key service:(nullable NSString *)service accessGroup:(nullable NSString *)accessGroup genericAttribute:(nullable id)genericAttribute; ++ (BOOL)setData:(nullable NSData *)data forKey:(NSString *)key service:(nullable NSString *)service accessGroup:(nullable NSString *)accessGroup genericAttribute:(nullable id)genericAttribute error:(NSError * __nullable __autoreleasing * __nullable)error; + +- (BOOL)setString:(nullable NSString *)string forKey:(NSString *)key genericAttribute:(nullable id)genericAttribute; +- (BOOL)setString:(nullable NSString *)string forKey:(NSString *)key genericAttribute:(nullable id)genericAttribute error:(NSError * __nullable __autoreleasing * __nullable)error; + +- (BOOL)setData:(nullable NSData *)data forKey:(NSString *)key genericAttribute:(nullable id)genericAttribute; +- (BOOL)setData:(nullable NSData *)data forKey:(NSString *)key genericAttribute:(nullable id)genericAttribute error:(NSError * __nullable __autoreleasing * __nullable)error; + +@end + +@interface UICKeyChainStore (Deprecation) + +- (void)synchronize __attribute__((deprecated("calling this method is no longer required"))); +- (BOOL)synchronizeWithError:(NSError * __nullable __autoreleasing * __nullable)error __attribute__((deprecated("calling this method is no longer required"))); + +@end + +NS_ASSUME_NONNULL_END diff --git a/Classes_cocos/UICKeyChainStore.m b/Classes_cocos/UICKeyChainStore.m new file mode 100644 index 0000000..413de04 --- /dev/null +++ b/Classes_cocos/UICKeyChainStore.m @@ -0,0 +1,1407 @@ +// +// UICKeyChainStore.m +// UICKeyChainStore +// +// Created by Kishikawa Katsumi on 11/11/20. +// Copyright (c) 2011 Kishikawa Katsumi. All rights reserved. +// + +#import "UICKeyChainStore.h" + +NSString * const UICKeyChainStoreErrorDomain = @"com.kishikawakatsumi.uickeychainstore"; +static NSString *_defaultService; + +@interface UICKeyChainStore () + +@end + +@implementation UICKeyChainStore + ++ (NSString *)defaultService +{ + if (!_defaultService) { + _defaultService = [[NSBundle mainBundle] bundleIdentifier] ?: @""; + } + + return _defaultService; +} + ++ (void)setDefaultService:(NSString *)defaultService +{ + _defaultService = defaultService; +} + +#pragma mark - + ++ (UICKeyChainStore *)keyChainStore +{ + return [[self alloc] initWithService:nil accessGroup:nil]; +} + ++ (UICKeyChainStore *)keyChainStoreWithService:(NSString *)service +{ + return [[self alloc] initWithService:service accessGroup:nil]; +} + ++ (UICKeyChainStore *)keyChainStoreWithService:(NSString *)service accessGroup:(NSString *)accessGroup +{ + return [[self alloc] initWithService:service accessGroup:accessGroup]; +} + +#pragma mark - + ++ (UICKeyChainStore *)keyChainStoreWithServer:(NSURL *)server protocolType:(UICKeyChainStoreProtocolType)protocolType +{ + return [[self alloc] initWithServer:server protocolType:protocolType authenticationType:UICKeyChainStoreAuthenticationTypeDefault]; +} + ++ (UICKeyChainStore *)keyChainStoreWithServer:(NSURL *)server protocolType:(UICKeyChainStoreProtocolType)protocolType authenticationType:(UICKeyChainStoreAuthenticationType)authenticationType +{ + return [[self alloc] initWithServer:server protocolType:protocolType authenticationType:authenticationType]; +} + +#pragma mark - + +- (instancetype)init +{ + return [self initWithService:[self.class defaultService] accessGroup:nil]; +} + +- (instancetype)initWithService:(NSString *)service +{ + return [self initWithService:service accessGroup:nil]; +} + +- (instancetype)initWithService:(NSString *)service accessGroup:(NSString *)accessGroup +{ + self = [super init]; + if (self) { + _itemClass = UICKeyChainStoreItemClassGenericPassword; + + if (!service) { + service = [self.class defaultService]; + } + _service = service.copy; + _accessGroup = accessGroup.copy; + [self commonInit]; + } + + return self; +} + +#pragma mark - + +- (instancetype)initWithServer:(NSURL *)server protocolType:(UICKeyChainStoreProtocolType)protocolType +{ + return [self initWithServer:server protocolType:protocolType authenticationType:UICKeyChainStoreAuthenticationTypeDefault]; +} + +- (instancetype)initWithServer:(NSURL *)server protocolType:(UICKeyChainStoreProtocolType)protocolType authenticationType:(UICKeyChainStoreAuthenticationType)authenticationType +{ + self = [super init]; + if (self) { + _itemClass = UICKeyChainStoreItemClassInternetPassword; + + _server = server.copy; + _protocolType = protocolType; + _authenticationType = authenticationType; + + [self commonInit]; + } + + return self; +} + +#pragma mark - + +- (void)commonInit +{ + _accessibility = UICKeyChainStoreAccessibilityAfterFirstUnlock; + _useAuthenticationUI = YES; +} + +#pragma mark - + ++ (NSString *)stringForKey:(NSString *)key +{ + return [self stringForKey:key service:nil accessGroup:nil error:nil]; +} + ++ (NSString *)stringForKey:(NSString *)key error:(NSError *__autoreleasing *)error +{ + return [self stringForKey:key service:nil accessGroup:nil error:error]; +} + ++ (NSString *)stringForKey:(NSString *)key service:(NSString *)service +{ + return [self stringForKey:key service:service accessGroup:nil error:nil]; +} + ++ (NSString *)stringForKey:(NSString *)key service:(NSString *)service error:(NSError *__autoreleasing *)error +{ + return [self stringForKey:key service:service accessGroup:nil error:error]; +} + ++ (NSString *)stringForKey:(NSString *)key service:(NSString *)service accessGroup:(NSString *)accessGroup +{ + return [self stringForKey:key service:service accessGroup:accessGroup error:nil]; +} + ++ (NSString *)stringForKey:(NSString *)key service:(NSString *)service accessGroup:(NSString *)accessGroup error:(NSError *__autoreleasing *)error +{ + if (!key) { + NSError *e = [self argumentError:NSLocalizedString(@"the key must not to be nil", nil)]; + if (error) { + *error = e; + } + return nil; + } + if (!service) { + service = [self defaultService]; + } + + UICKeyChainStore *keychain = [UICKeyChainStore keyChainStoreWithService:service accessGroup:accessGroup]; + return [keychain stringForKey:key error:error]; +} + +#pragma mark - + ++ (BOOL)setString:(NSString *)value forKey:(NSString *)key +{ + return [self setString:value forKey:key service:nil accessGroup:nil genericAttribute:nil error:nil]; +} + ++ (BOOL)setString:(NSString *)value forKey:(NSString *)key error:(NSError *__autoreleasing *)error +{ + return [self setString:value forKey:key service:nil accessGroup:nil genericAttribute:nil error:error]; +} + ++ (BOOL)setString:(NSString *)value forKey:(NSString *)key genericAttribute:(id)genericAttribute +{ + return [self setString:value forKey:key service:nil accessGroup:nil genericAttribute:genericAttribute error:nil]; +} + ++ (BOOL)setString:(NSString *)value forKey:(NSString *)key genericAttribute:(id)genericAttribute error:(NSError * __autoreleasing *)error +{ + return [self setString:value forKey:key service:nil accessGroup:nil genericAttribute:genericAttribute error:error]; +} + ++ (BOOL)setString:(NSString *)value forKey:(NSString *)key service:(NSString *)service +{ + return [self setString:value forKey:key service:service accessGroup:nil genericAttribute:nil error:nil]; +} + ++ (BOOL)setString:(NSString *)value forKey:(NSString *)key service:(NSString *)service error:(NSError *__autoreleasing *)error +{ + return [self setString:value forKey:key service:service accessGroup:nil genericAttribute:nil error:error]; +} + ++ (BOOL)setString:(NSString *)value forKey:(NSString *)key service:(NSString *)service genericAttribute:(id)genericAttribute +{ + return [self setString:value forKey:key service:service accessGroup:nil genericAttribute:genericAttribute error:nil]; +} + ++ (BOOL)setString:(NSString *)value forKey:(NSString *)key service:(NSString *)service genericAttribute:(id)genericAttribute error:(NSError * __autoreleasing *)error +{ + return [self setString:value forKey:key service:service accessGroup:nil genericAttribute:genericAttribute error:error]; +} + ++ (BOOL)setString:(NSString *)value forKey:(NSString *)key service:(NSString *)service accessGroup:(NSString *)accessGroup +{ + return [self setString:value forKey:key service:service accessGroup:accessGroup genericAttribute:nil error:nil]; +} + ++ (BOOL)setString:(NSString *)value forKey:(NSString *)key service:(NSString *)service accessGroup:(NSString *)accessGroup error:(NSError *__autoreleasing *)error +{ + return [self setString:value forKey:key service:service accessGroup:accessGroup genericAttribute:nil error:error]; +} + ++ (BOOL)setString:(NSString *)value forKey:(NSString *)key service:(NSString *)service accessGroup:(NSString *)accessGroup genericAttribute:(id)genericAttribute +{ + return [self setString:value forKey:key service:service accessGroup:accessGroup genericAttribute:genericAttribute error:nil]; +} + ++ (BOOL)setString:(NSString *)value forKey:(NSString *)key service:(NSString *)service accessGroup:(NSString *)accessGroup genericAttribute:(id)genericAttribute error:(NSError * __autoreleasing *)error +{ + if (!value) { + return [self removeItemForKey:key service:service accessGroup:accessGroup error:error]; + } + NSData *data = [value dataUsingEncoding:NSUTF8StringEncoding]; + if (data) { + return [self setData:data forKey:key service:service accessGroup:accessGroup genericAttribute:genericAttribute error:error]; + } + NSError *e = [self conversionError:NSLocalizedString(@"failed to convert string to data", nil)]; + if (error) { + *error = e; + } + return NO; +} + +#pragma mark - + ++ (NSData *)dataForKey:(NSString *)key +{ + return [self dataForKey:key service:nil accessGroup:nil error:nil]; +} + ++ (NSData *)dataForKey:(NSString *)key error:(NSError *__autoreleasing *)error +{ + return [self dataForKey:key service:nil accessGroup:nil error:error]; +} + ++ (NSData *)dataForKey:(NSString *)key service:(NSString *)service +{ + return [self dataForKey:key service:service accessGroup:nil error:nil]; +} + ++ (NSData *)dataForKey:(NSString *)key service:(NSString *)service error:(NSError *__autoreleasing *)error +{ + return [self dataForKey:key service:service accessGroup:nil error:error]; +} + ++ (NSData *)dataForKey:(NSString *)key service:(NSString *)service accessGroup:(NSString *)accessGroup +{ + return [self dataForKey:key service:service accessGroup:accessGroup error:nil]; +} + ++ (NSData *)dataForKey:(NSString *)key service:(NSString *)service accessGroup:(NSString *)accessGroup error:(NSError *__autoreleasing *)error +{ + if (!key) { + NSError *e = [self argumentError:NSLocalizedString(@"the key must not to be nil", nil)]; + if (error) { + *error = e; + } + return nil; + } + if (!service) { + service = [self defaultService]; + } + + UICKeyChainStore *keychain = [UICKeyChainStore keyChainStoreWithService:service accessGroup:accessGroup]; + return [keychain dataForKey:key error:error]; +} + +#pragma mark - + ++ (BOOL)setData:(NSData *)data forKey:(NSString *)key +{ + return [self setData:data forKey:key service:nil accessGroup:nil genericAttribute:nil error:nil]; +} + ++ (BOOL)setData:(NSData *)data forKey:(NSString *)key error:(NSError *__autoreleasing *)error +{ + return [self setData:data forKey:key service:nil accessGroup:nil genericAttribute:nil error:error]; +} + ++ (BOOL)setData:(NSData *)data forKey:(NSString *)key genericAttribute:(id)genericAttribute +{ + return [self setData:data forKey:key service:nil accessGroup:nil genericAttribute:genericAttribute error:nil]; +} + ++ (BOOL)setData:(NSData *)data forKey:(NSString *)key genericAttribute:(id)genericAttribute error:(NSError * __autoreleasing *)error +{ + return [self setData:data forKey:key service:nil accessGroup:nil genericAttribute:genericAttribute error:error]; +} + ++ (BOOL)setData:(NSData *)data forKey:(NSString *)key service:(NSString *)service +{ + return [self setData:data forKey:key service:service accessGroup:nil genericAttribute:nil error:nil]; +} + ++ (BOOL)setData:(NSData *)data forKey:(NSString *)key service:(NSString *)service error:(NSError *__autoreleasing *)error +{ + return [self setData:data forKey:key service:service accessGroup:nil genericAttribute:nil error:error]; +} + ++ (BOOL)setData:(NSData *)data forKey:(NSString *)key service:(NSString *)service genericAttribute:(id)genericAttribute +{ + return [self setData:data forKey:key service:service accessGroup:nil genericAttribute:genericAttribute error:nil]; +} + ++ (BOOL)setData:(NSData *)data forKey:(NSString *)key service:(NSString *)service genericAttribute:(id)genericAttribute error:(NSError * __autoreleasing *)error +{ + return [self setData:data forKey:key service:service accessGroup:nil genericAttribute:genericAttribute error:error]; +} + ++ (BOOL)setData:(NSData *)data forKey:(NSString *)key service:(NSString *)service accessGroup:(NSString *)accessGroup +{ + return [self setData:data forKey:key service:service accessGroup:accessGroup genericAttribute:nil error:nil]; +} + ++ (BOOL)setData:(NSData *)data forKey:(NSString *)key service:(NSString *)service accessGroup:(NSString *)accessGroup error:(NSError *__autoreleasing *)error +{ + return [self setData:data forKey:key service:service accessGroup:accessGroup genericAttribute:nil error:error]; +} + ++ (BOOL)setData:(NSData *)data forKey:(NSString *)key service:(NSString *)service accessGroup:(NSString *)accessGroup genericAttribute:(id)genericAttribute +{ + return [self setData:data forKey:key service:service accessGroup:accessGroup genericAttribute:genericAttribute error:nil]; +} + ++ (BOOL)setData:(NSData *)data forKey:(NSString *)key service:(NSString *)service accessGroup:(NSString *)accessGroup genericAttribute:(id)genericAttribute error:(NSError * __autoreleasing *)error +{ + if (!key) { + NSError *e = [self argumentError:NSLocalizedString(@"the key must not to be nil", nil)]; + if (error) { + *error = e; + } + return NO; + } + if (!service) { + service = [self defaultService]; + } + + UICKeyChainStore *keychain = [UICKeyChainStore keyChainStoreWithService:service accessGroup:accessGroup]; + return [keychain setData:data forKey:key genericAttribute:genericAttribute]; +} + +#pragma mark - + +- (BOOL)contains:(NSString *)key +{ + NSMutableDictionary *query = [self query]; + query[(__bridge __strong id)kSecAttrAccount] = key; + + OSStatus status = SecItemCopyMatching((__bridge CFDictionaryRef)query, NULL); + return status == errSecSuccess || status == errSecInteractionNotAllowed; +} + +#pragma mark - + +- (NSString *)stringForKey:(id)key +{ + return [self stringForKey:key error:nil]; +} + +- (NSString *)stringForKey:(id)key error:(NSError *__autoreleasing *)error +{ + NSData *data = [self dataForKey:key error:error]; + if (data) { + NSString *string = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; + if (string) { + return string; + } + NSError *e = [self.class conversionError:NSLocalizedString(@"failed to convert data to string", nil)]; + if (error) { + *error = e; + } + return nil; + } + + return nil; +} + +#pragma mark - + +- (BOOL)setString:(NSString *)string forKey:(NSString *)key +{ + return [self setString:string forKey:key genericAttribute:nil label:nil comment:nil error:nil]; +} + +- (BOOL)setString:(NSString *)string forKey:(NSString *)key error:(NSError *__autoreleasing *)error +{ + return [self setString:string forKey:key genericAttribute:nil label:nil comment:nil error:error]; +} + +- (BOOL)setString:(NSString *)string forKey:(NSString *)key genericAttribute:(id)genericAttribute +{ + return [self setString:string forKey:key genericAttribute:genericAttribute label:nil comment:nil error:nil]; +} + +- (BOOL)setString:(NSString *)string forKey:(NSString *)key genericAttribute:(id)genericAttribute error:(NSError * __autoreleasing *)error +{ + return [self setString:string forKey:key genericAttribute:genericAttribute label:nil comment:nil error:error]; +} + +- (BOOL)setString:(NSString *)string forKey:(NSString *)key label:(NSString *)label comment:(NSString *)comment +{ + return [self setString:string forKey:key genericAttribute:nil label:label comment:comment error:nil]; +} + +- (BOOL)setString:(NSString *)string forKey:(NSString *)key label:(NSString *)label comment:(NSString *)comment error:(NSError *__autoreleasing *)error +{ + return [self setString:string forKey:key genericAttribute:nil label:label comment:comment error:error]; +} + +- (BOOL)setString:(NSString *)string forKey:(NSString *)key genericAttribute:(id)genericAttribute label:(NSString *)label comment:(NSString *)comment error:(NSError *__autoreleasing *)error +{ + if (!string) { + return [self removeItemForKey:key error:error]; + } + NSData *data = [string dataUsingEncoding:NSUTF8StringEncoding]; + if (data) { + return [self setData:data forKey:key genericAttribute:genericAttribute label:label comment:comment error:error]; + } + NSError *e = [self.class conversionError:NSLocalizedString(@"failed to convert string to data", nil)]; + if (error) { + *error = e; + } + return NO; +} + +#pragma mark - + +- (NSData *)dataForKey:(NSString *)key +{ + return [self dataForKey:key error:nil]; +} + +- (NSData *)dataForKey:(NSString *)key error:(NSError *__autoreleasing *)error +{ + NSMutableDictionary *query = [self query]; + query[(__bridge __strong id)kSecMatchLimit] = (__bridge id)kSecMatchLimitOne; + query[(__bridge __strong id)kSecReturnData] = (__bridge id)kCFBooleanTrue; + + query[(__bridge __strong id)kSecAttrAccount] = key; + + CFTypeRef data = nil; + OSStatus status = SecItemCopyMatching((__bridge CFDictionaryRef)query, &data); + + if (status == errSecSuccess) { + NSData *ret = [NSData dataWithData:(__bridge NSData *)data]; + if (data) { + CFRelease(data); + return ret; + } else { + NSError *e = [self.class unexpectedError:NSLocalizedString(@"Unexpected error has occurred.", nil)]; + if (error) { + *error = e; + } + return nil; + } + } else if (status == errSecItemNotFound) { + return nil; + } + + NSError *e = [self.class securityError:status]; + if (error) { + *error = e; + } + return nil; +} + +#pragma mark - + +- (BOOL)setData:(NSData *)data forKey:(NSString *)key +{ + return [self setData:data forKey:key genericAttribute:nil label:nil comment:nil error:nil]; +} + +- (BOOL)setData:(NSData *)data forKey:(NSString *)key error:(NSError *__autoreleasing *)error +{ + return [self setData:data forKey:key genericAttribute:nil label:nil comment:nil error:error]; +} + +- (BOOL)setData:(NSData *)data forKey:(NSString *)key genericAttribute:(id)genericAttribute +{ + return [self setData:data forKey:key genericAttribute:genericAttribute label:nil comment:nil error:nil]; +} + +- (BOOL)setData:(NSData *)data forKey:(NSString *)key genericAttribute:(id)genericAttribute error:(NSError * __autoreleasing *)error +{ + return [self setData:data forKey:key genericAttribute:genericAttribute label:nil comment:nil error:error]; +} + +- (BOOL)setData:(NSData *)data forKey:(NSString *)key label:(NSString *)label comment:(NSString *)comment +{ + return [self setData:data forKey:key genericAttribute:nil label:label comment:comment error:nil]; +} + +- (BOOL)setData:(NSData *)data forKey:(NSString *)key label:(NSString *)label comment:(NSString *)comment error:(NSError *__autoreleasing *)error +{ + return [self setData:data forKey:key genericAttribute:nil label:label comment:comment error:error]; +} + +- (BOOL)setData:(NSData *)data forKey:(NSString *)key genericAttribute:(id)genericAttribute label:(NSString *)label comment:(NSString *)comment error:(NSError *__autoreleasing *)error +{ + if (!key) { + NSError *e = [self.class argumentError:NSLocalizedString(@"the key must not to be nil", nil)]; + if (error) { + *error = e; + } + return NO; + } + if (!data) { + return [self removeItemForKey:key error:error]; + } + + NSMutableDictionary *query = [self query]; + query[(__bridge __strong id)kSecAttrAccount] = key; +#if TARGET_OS_IOS + if (floor(NSFoundationVersionNumber) > floor(1144.17)) { // iOS 9+ + query[(__bridge __strong id)kSecUseAuthenticationUI] = (__bridge id)kSecUseAuthenticationUIFail; +#if __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_9_0 + } else if (floor(NSFoundationVersionNumber) > floor(1047.25)) { // iOS 8+ + query[(__bridge __strong id)kSecUseNoAuthenticationUI] = (__bridge id)kCFBooleanTrue; +#endif + } +#elif TARGET_OS_WATCH || TARGET_OS_TV + query[(__bridge __strong id)kSecUseAuthenticationUI] = (__bridge id)kSecUseAuthenticationUIFail; +#endif + + OSStatus status = SecItemCopyMatching((__bridge CFDictionaryRef)query, NULL); + if (status == errSecSuccess || status == errSecInteractionNotAllowed) { + query = [self query]; + query[(__bridge __strong id)kSecAttrAccount] = key; + + NSError *unexpectedError = nil; + NSMutableDictionary *attributes = [self attributesWithKey:nil value:data error:&unexpectedError]; + + if (genericAttribute) { + attributes[(__bridge __strong id)kSecAttrGeneric] = genericAttribute; + } + if (label) { + attributes[(__bridge __strong id)kSecAttrLabel] = label; + } + if (comment) { + attributes[(__bridge __strong id)kSecAttrComment] = comment; + } + + if (unexpectedError) { + NSLog(@"error: [%@] %@", @(unexpectedError.code), NSLocalizedString(@"Unexpected error has occurred.", nil)); + if (error) { + *error = unexpectedError; + } + return NO; + } else { + + if (status == errSecInteractionNotAllowed && floor(NSFoundationVersionNumber) <= floor(1140.11)) { // iOS 8.0.x + if ([self removeItemForKey:key error:error]) { + return [self setData:data forKey:key label:label comment:comment error:error]; + } + } else { + status = SecItemUpdate((__bridge CFDictionaryRef)query, (__bridge CFDictionaryRef)attributes); + } + if (status != errSecSuccess) { + NSError *e = [self.class securityError:status]; + if (error) { + *error = e; + } + return NO; + } + } + } else if (status == errSecItemNotFound) { + NSError *unexpectedError = nil; + NSMutableDictionary *attributes = [self attributesWithKey:key value:data error:&unexpectedError]; + + if (genericAttribute) { + attributes[(__bridge __strong id)kSecAttrGeneric] = genericAttribute; + } + if (label) { + attributes[(__bridge __strong id)kSecAttrLabel] = label; + } + if (comment) { + attributes[(__bridge __strong id)kSecAttrComment] = comment; + } + + if (unexpectedError) { + NSLog(@"error: [%@] %@", @(unexpectedError.code), NSLocalizedString(@"Unexpected error has occurred.", nil)); + if (error) { + *error = unexpectedError; + } + return NO; + } else { + status = SecItemAdd((__bridge CFDictionaryRef)attributes, NULL); + if (status != errSecSuccess) { + NSError *e = [self.class securityError:status]; + if (error) { + *error = e; + } + return NO; + } + } + } else { + NSError *e = [self.class securityError:status]; + if (error) { + *error = e; + } + return NO; + } + + return YES; +} + +#pragma mark - + ++ (BOOL)removeItemForKey:(NSString *)key +{ + return [self removeItemForKey:key service:nil accessGroup:nil error:nil]; +} + ++ (BOOL)removeItemForKey:(NSString *)key error:(NSError *__autoreleasing *)error +{ + return [self removeItemForKey:key service:nil accessGroup:nil error:error]; +} + ++ (BOOL)removeItemForKey:(NSString *)key service:(NSString *)service +{ + return [self removeItemForKey:key service:service accessGroup:nil error:nil]; +} + ++ (BOOL)removeItemForKey:(NSString *)key service:(NSString *)service error:(NSError *__autoreleasing *)error +{ + return [self removeItemForKey:key service:service accessGroup:nil error:error]; +} + ++ (BOOL)removeItemForKey:(NSString *)key service:(NSString *)service accessGroup:(NSString *)accessGroup +{ + return [self removeItemForKey:key service:service accessGroup:accessGroup error:nil]; +} + ++ (BOOL)removeItemForKey:(NSString *)key service:(NSString *)service accessGroup:(NSString *)accessGroup error:(NSError *__autoreleasing *)error +{ + if (!key) { + NSError *e = [self.class argumentError:NSLocalizedString(@"the key must not to be nil", nil)]; + if (error) { + *error = e; + } + return NO; + } + if (!service) { + service = [self defaultService]; + } + + UICKeyChainStore *keychain = [UICKeyChainStore keyChainStoreWithService:service accessGroup:accessGroup]; + return [keychain removeItemForKey:key error:error]; +} + +#pragma mark - + ++ (BOOL)removeAllItems +{ + return [self removeAllItemsForService:nil accessGroup:nil error:nil]; +} + ++ (BOOL)removeAllItemsWithError:(NSError *__autoreleasing *)error +{ + return [self removeAllItemsForService:nil accessGroup:nil error:error]; +} + ++ (BOOL)removeAllItemsForService:(NSString *)service +{ + return [self removeAllItemsForService:service accessGroup:nil error:nil]; +} + ++ (BOOL)removeAllItemsForService:(NSString *)service error:(NSError *__autoreleasing *)error +{ + return [self removeAllItemsForService:service accessGroup:nil error:error]; +} + ++ (BOOL)removeAllItemsForService:(NSString *)service accessGroup:(NSString *)accessGroup +{ + return [self removeAllItemsForService:service accessGroup:accessGroup error:nil]; +} + ++ (BOOL)removeAllItemsForService:(NSString *)service accessGroup:(NSString *)accessGroup error:(NSError *__autoreleasing *)error +{ + UICKeyChainStore *keychain = [UICKeyChainStore keyChainStoreWithService:service accessGroup:accessGroup]; + return [keychain removeAllItemsWithError:error]; +} + +#pragma mark - + +- (BOOL)removeItemForKey:(NSString *)key +{ + return [self removeItemForKey:key error:nil]; +} + +- (BOOL)removeItemForKey:(NSString *)key error:(NSError *__autoreleasing *)error +{ + NSMutableDictionary *query = [self query]; + query[(__bridge __strong id)kSecAttrAccount] = key; + + OSStatus status = SecItemDelete((__bridge CFDictionaryRef)query); + if (status != errSecSuccess && status != errSecItemNotFound) { + NSError *e = [self.class securityError:status]; + if (error) { + *error = e; + } + return NO; + } + + return YES; +} + +#pragma mark - + +- (BOOL)removeAllItems +{ + return [self removeAllItemsWithError:nil]; +} + +- (BOOL)removeAllItemsWithError:(NSError *__autoreleasing *)error +{ + NSMutableDictionary *query = [self query]; +#if !TARGET_OS_IPHONE + query[(__bridge id)kSecMatchLimit] = (__bridge id)kSecMatchLimitAll; +#endif + + OSStatus status = SecItemDelete((__bridge CFDictionaryRef)query); + if (status != errSecSuccess && status != errSecItemNotFound) { + NSError *e = [self.class securityError:status]; + if (error) { + *error = e; + } + return NO; + } + + return YES; +} + +#pragma mark - + +- (NSString *)objectForKeyedSubscript:(NSString *)key +{ + return [self stringForKey:key]; +} + +- (void)setObject:(NSString *)obj forKeyedSubscript:(NSString *)key +{ + if (!obj) { + [self removeItemForKey:key]; + } else { + [self setString:obj forKey:key]; + } +} + +#pragma mark - + +- (NSArray UIC_KEY_TYPE *)allKeys +{ + NSArray *items = [self.class prettify:[self itemClassObject] items:[self items]]; + NSMutableArray *keys = [[NSMutableArray alloc] init]; + for (NSDictionary *item in items) { + NSString *key = item[@"key"]; + if (key) { + [keys addObject:key]; + } + } + return keys.copy; +} + ++ (NSArray UIC_KEY_TYPE *)allKeysWithItemClass:(UICKeyChainStoreItemClass)itemClass +{ + CFTypeRef itemClassObject = kSecClassGenericPassword; + if (itemClass == UICKeyChainStoreItemClassGenericPassword) { + itemClassObject = kSecClassGenericPassword; + } else if (itemClass == UICKeyChainStoreItemClassInternetPassword) { + itemClassObject = kSecClassInternetPassword; + } + + NSMutableDictionary *query = [[NSMutableDictionary alloc] init]; + query[(__bridge __strong id)kSecClass] = (__bridge id)itemClassObject; + query[(__bridge __strong id)kSecMatchLimit] = (__bridge id)kSecMatchLimitAll; + query[(__bridge __strong id)kSecReturnAttributes] = (__bridge id)kCFBooleanTrue; + + CFArrayRef result = nil; + CFDictionaryRef cfquery = (CFDictionaryRef)CFBridgingRetain(query); + OSStatus status = SecItemCopyMatching(cfquery, (CFTypeRef *)&result); + CFRelease(cfquery); + + if (status == errSecSuccess) { + NSArray *items = [self prettify:itemClassObject items:(__bridge NSArray *)result]; + NSMutableArray *keys = [[NSMutableArray alloc] init]; + for (NSDictionary *item in items) { + if (itemClassObject == kSecClassGenericPassword) { + [keys addObject:@{@"service": item[@"service"] ?: @"", @"key": item[@"key"] ?: @""}]; + } else if (itemClassObject == kSecClassInternetPassword) { + [keys addObject:@{@"server": item[@"service"] ?: @"", @"key": item[@"key"] ?: @""}]; + } + } + return keys.copy; + } else if (status == errSecItemNotFound) { + return @[]; + } + + return nil; +} + ++ (NSArray *)allItemsWithItemClass:(UICKeyChainStoreItemClass)itemClass +{ + CFTypeRef itemClassObject = kSecClassGenericPassword; + if (itemClass == UICKeyChainStoreItemClassGenericPassword) { + itemClassObject = kSecClassGenericPassword; + } else if (itemClass == UICKeyChainStoreItemClassInternetPassword) { + itemClassObject = kSecClassInternetPassword; + } + + NSMutableDictionary *query = [[NSMutableDictionary alloc] init]; + query[(__bridge __strong id)kSecClass] = (__bridge id)itemClassObject; + query[(__bridge __strong id)kSecMatchLimit] = (__bridge id)kSecMatchLimitAll; + query[(__bridge __strong id)kSecReturnAttributes] = (__bridge id)kCFBooleanTrue; +#if TARGET_OS_IPHONE + query[(__bridge __strong id)kSecReturnData] = (__bridge id)kCFBooleanTrue; +#endif + + CFArrayRef result = nil; + CFDictionaryRef cfquery = (CFDictionaryRef)CFBridgingRetain(query); + OSStatus status = SecItemCopyMatching(cfquery, (CFTypeRef *)&result); + CFRelease(cfquery); + + if (status == errSecSuccess) { + return [self prettify:itemClassObject items:(__bridge NSArray *)result]; + } else if (status == errSecItemNotFound) { + return @[]; + } + + return nil; +} + +- (NSArray *)allItems +{ + return [self.class prettify:[self itemClassObject] items:[self items]]; +} + +- (NSArray *)items +{ + NSMutableDictionary *query = [self query]; + query[(__bridge __strong id)kSecMatchLimit] = (__bridge id)kSecMatchLimitAll; + query[(__bridge __strong id)kSecReturnAttributes] = (__bridge id)kCFBooleanTrue; +#if TARGET_OS_IPHONE + query[(__bridge __strong id)kSecReturnData] = (__bridge id)kCFBooleanTrue; +#endif + + CFArrayRef result = nil; + OSStatus status = SecItemCopyMatching((__bridge CFDictionaryRef)query,(CFTypeRef *)&result); + + if (status == errSecSuccess) { + return CFBridgingRelease(result); + } else if (status == errSecItemNotFound) { + return @[]; + } + + return nil; +} + ++ (NSArray *)prettify:(CFTypeRef)itemClass items:(NSArray *)items +{ + NSMutableArray *prettified = [[NSMutableArray alloc] init]; + + for (NSDictionary *attributes in items) { + NSMutableDictionary *item = [[NSMutableDictionary alloc] init]; + if (itemClass == kSecClassGenericPassword) { + item[@"class"] = @"GenericPassword"; + id service = attributes[(__bridge id)kSecAttrService]; + if (service) { + item[@"service"] = service; + } + id accessGroup = attributes[(__bridge id)kSecAttrAccessGroup]; + if (accessGroup) { + item[@"accessGroup"] = accessGroup; + } + } else if (itemClass == kSecClassInternetPassword) { + item[@"class"] = @"InternetPassword"; + id server = attributes[(__bridge id)kSecAttrServer]; + if (server) { + item[@"server"] = server; + } + id protocolType = attributes[(__bridge id)kSecAttrProtocol]; + if (protocolType) { + item[@"protocol"] = protocolType; + } + id authenticationType = attributes[(__bridge id)kSecAttrAuthenticationType]; + if (authenticationType) { + item[@"authenticationType"] = authenticationType; + } + } + id key = attributes[(__bridge id)kSecAttrAccount]; + if (key) { + item[@"key"] = key; + } + NSData *data = attributes[(__bridge id)kSecValueData]; + NSString *string = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; + if (string) { + item[@"value"] = string; + } else { + item[@"value"] = data; + } + + id accessible = attributes[(__bridge id)kSecAttrAccessible]; + if (accessible) { + item[@"accessibility"] = accessible; + } + + if (floor(NSFoundationVersionNumber) > floor(993.00)) { // iOS 7+ + id synchronizable = attributes[(__bridge id)kSecAttrSynchronizable]; + if (synchronizable) { + item[@"synchronizable"] = synchronizable; + } + } + + [prettified addObject:item]; + } + + return prettified.copy; +} + +#pragma mark - + +- (void)setSynchronizable:(BOOL)synchronizable +{ + _synchronizable = synchronizable; + if (_authenticationPolicy) { + NSLog(@"%@", @"Cannot specify both an authenticationPolicy and a synchronizable"); + } +} + +- (void)setAccessibility:(UICKeyChainStoreAccessibility)accessibility authenticationPolicy:(UICKeyChainStoreAuthenticationPolicy)authenticationPolicy +{ + _accessibility = accessibility; + _authenticationPolicy = authenticationPolicy; + if (_synchronizable) { + NSLog(@"%@", @"Cannot specify both an authenticationPolicy and a synchronizable"); + } +} + +#pragma mark - + +#if TARGET_OS_IOS && !TARGET_OS_MACCATALYST +- (void)sharedPasswordWithCompletion:(void (^)(NSString *account, NSString *password, NSError *error))completion +{ + NSString *domain = self.server.host; + if (domain.length > 0) { + [self.class requestSharedWebCredentialForDomain:domain account:nil completion:^(NSArray *credentials, NSError *error) { + NSDictionary *credential = credentials.firstObject; + if (credential) { + NSString *account = credential[@"account"]; + NSString *password = credential[@"password"]; + if (completion) { + completion(account, password, error); + } + } else { + if (completion) { + completion(nil, nil, error); + } + } + }]; + } else { + NSError *error = [self.class argumentError:NSLocalizedString(@"the server property must not to be nil, should use 'keyChainStoreWithServer:protocolType:' initializer to instantiate keychain store", nil)]; + if (completion) { + completion(nil, nil, error); + } + } +} + +- (void)sharedPasswordForAccount:(NSString *)account completion:(void (^)(NSString *password, NSError *error))completion +{ + NSString *domain = self.server.host; + if (domain.length > 0) { + [self.class requestSharedWebCredentialForDomain:domain account:account completion:^(NSArray *credentials, NSError *error) { + NSDictionary *credential = credentials.firstObject; + if (credential) { + NSString *password = credential[@"password"]; + if (completion) { + completion(password, error); + } + } else { + if (completion) { + completion(nil, error); + } + } + }]; + } else { + NSError *error = [self.class argumentError:NSLocalizedString(@"the server property must not to be nil, should use 'keyChainStoreWithServer:protocolType:' initializer to instantiate keychain store", nil)]; + if (completion) { + completion(nil, error); + } + } +} + +- (void)setSharedPassword:(NSString *)password forAccount:(NSString *)account completion:(void (^)(NSError *error))completion +{ + NSString *domain = self.server.host; + if (domain.length > 0) { + SecAddSharedWebCredential((__bridge CFStringRef)domain, (__bridge CFStringRef)account, (__bridge CFStringRef)password, ^(CFErrorRef error) { + if (completion) { + completion((__bridge NSError *)error); + } + }); + } else { + NSError *error = [self.class argumentError:NSLocalizedString(@"the server property must not to be nil, should use 'keyChainStoreWithServer:protocolType:' initializer to instantiate keychain store", nil)]; + if (completion) { + completion(error); + } + } +} + +- (void)removeSharedPasswordForAccount:(NSString *)account completion:(void (^)(NSError *error))completion +{ + [self setSharedPassword:nil forAccount:account completion:completion]; +} + ++ (void)requestSharedWebCredentialWithCompletion:(void (^)(NSArray UIC_CREDENTIAL_TYPE *credentials, NSError *error))completion +{ + [self requestSharedWebCredentialForDomain:nil account:nil completion:completion]; +} + ++ (void)requestSharedWebCredentialForDomain:(NSString *)domain account:(NSString *)account completion:(void (^)(NSArray UIC_CREDENTIAL_TYPE *credentials, NSError *error))completion +{ + SecRequestSharedWebCredential((__bridge CFStringRef)domain, (__bridge CFStringRef)account, ^(CFArrayRef credentials, CFErrorRef error) { + if (error) { + NSError *e = (__bridge NSError *)error; + if (e.code != errSecItemNotFound) { + NSLog(@"error: [%@] %@", @(e.code), e.localizedDescription); + } + } + + NSMutableArray *sharedCredentials = [[NSMutableArray alloc] init]; + for (NSDictionary *credential in (__bridge NSArray *)credentials) { + NSMutableDictionary *sharedCredential = [[NSMutableDictionary alloc] init]; + NSString *server = credential[(__bridge __strong id)kSecAttrServer]; + if (server) { + sharedCredential[@"server"] = server; + } + NSString *account = credential[(__bridge __strong id)kSecAttrAccount]; + if (account) { + sharedCredential[@"account"] = account; + } + NSString *password = credential[(__bridge __strong id)kSecSharedPassword]; + if (password) { + sharedCredential[@"password"] = password; + } + [sharedCredentials addObject:sharedCredential]; + } + + if (completion) { + completion(sharedCredentials.copy, (__bridge NSError *)error); + } + }); +} + ++ (NSString *)generatePassword +{ + return (NSString *)CFBridgingRelease(SecCreateSharedWebCredentialPassword()); +} + +#endif + +#pragma mark - + +- (NSString *)description +{ + NSArray *items = [self allItems]; + if (items.count == 0) { + return @"()"; + } + NSMutableString *description = [[NSMutableString alloc] initWithString:@"(\n"]; + for (NSDictionary *item in items) { + [description appendFormat:@" %@", item]; + } + [description appendString:@")"]; + return description.copy; +} + +- (NSString *)debugDescription +{ + return [NSString stringWithFormat:@"%@", [self items]]; +} + +#pragma mark - + +- (NSMutableDictionary *)query +{ + NSMutableDictionary *query = [[NSMutableDictionary alloc] init]; + + CFTypeRef itemClass = [self itemClassObject]; + query[(__bridge __strong id)kSecClass] =(__bridge id)itemClass; + if (floor(NSFoundationVersionNumber) > floor(993.00)) { // iOS 7+ (NSFoundationVersionNumber_iOS_6_1) + query[(__bridge __strong id)kSecAttrSynchronizable] = (__bridge id)kSecAttrSynchronizableAny; + } + + if (itemClass == kSecClassGenericPassword) { + query[(__bridge __strong id)(kSecAttrService)] = _service; +#if !TARGET_OS_SIMULATOR + if (_accessGroup) { + query[(__bridge __strong id)kSecAttrAccessGroup] = _accessGroup; + } +#endif + } else { + if (_server.host) { + query[(__bridge __strong id)kSecAttrServer] = _server.host; + } + if (_server.port != nil) { + query[(__bridge __strong id)kSecAttrPort] = _server.port; + } + CFTypeRef protocolTypeObject = [self protocolTypeObject]; + if (protocolTypeObject) { + query[(__bridge __strong id)kSecAttrProtocol] = (__bridge id)protocolTypeObject; + } + CFTypeRef authenticationTypeObject = [self authenticationTypeObject]; + if (authenticationTypeObject) { + query[(__bridge __strong id)kSecAttrAuthenticationType] = (__bridge id)authenticationTypeObject; + } + } + +#if TARGET_OS_IOS + if (_authenticationPrompt) { + if (floor(NSFoundationVersionNumber) > floor(1047.25)) { // iOS 8+ (NSFoundationVersionNumber_iOS_7_1) + query[(__bridge __strong id)kSecUseOperationPrompt] = _authenticationPrompt; + } else { + NSLog(@"%@", @"Unavailable 'authenticationPrompt' attribute on iOS versions prior to 8.0."); + } + } +#endif + + if (!_useAuthenticationUI) { +#if TARGET_OS_IOS + if (floor(NSFoundationVersionNumber) > floor(1144.17)) { // iOS 9+ + query[(__bridge __strong id)kSecUseAuthenticationUI] = (__bridge id)kSecUseAuthenticationUIFail; +#if __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_9_0 + } else if (floor(NSFoundationVersionNumber) > floor(1047.25)) { // iOS 8+ + query[(__bridge __strong id)kSecUseNoAuthenticationUI] = (__bridge id)kCFBooleanTrue; +#endif + } +#elif TARGET_OS_WATCH || TARGET_OS_TV + query[(__bridge __strong id)kSecUseAuthenticationUI] = (__bridge id)kSecUseAuthenticationUIFail; +#endif + } + + return query; +} + +- (NSMutableDictionary *)attributesWithKey:(NSString *)key value:(NSData *)value error:(NSError *__autoreleasing *)error +{ + NSMutableDictionary *attributes; + + if (key) { + attributes = [self query]; + attributes[(__bridge __strong id)kSecAttrAccount] = key; + } else { + attributes = [[NSMutableDictionary alloc] init]; + } + + attributes[(__bridge __strong id)kSecValueData] = value; + +#if TARGET_OS_IOS + double iOS_7_1_or_10_9_2 = 1047.25; // NSFoundationVersionNumber_iOS_7_1 +#else + double iOS_7_1_or_10_9_2 = 1056.13; // NSFoundationVersionNumber10_9_2 +#endif + CFTypeRef accessibilityObject = [self accessibilityObject]; + if (_authenticationPolicy && accessibilityObject) { + if (floor(NSFoundationVersionNumber) > floor(iOS_7_1_or_10_9_2)) { // iOS 8+ or OS X 10.10+ + CFErrorRef securityError = NULL; + SecAccessControlRef accessControl = SecAccessControlCreateWithFlags(kCFAllocatorDefault, accessibilityObject, (SecAccessControlCreateFlags)_authenticationPolicy, &securityError); + if (securityError) { + NSError *e = (__bridge NSError *)securityError; + NSLog(@"error: [%@] %@", @(e.code), e.localizedDescription); + if (error) { + *error = e; + CFRelease(accessControl); + return nil; + } + } + if (!accessControl) { + NSString *message = NSLocalizedString(@"Unexpected error has occurred.", nil); + NSError *e = [self.class unexpectedError:message]; + if (error) { + *error = e; + } + return nil; + } + attributes[(__bridge __strong id)kSecAttrAccessControl] = (__bridge_transfer id)accessControl; + } else { +#if TARGET_OS_IOS + NSLog(@"%@", @"Unavailable 'Touch ID integration' on iOS versions prior to 8.0."); +#else + NSLog(@"%@", @"Unavailable 'Touch ID integration' on OS X versions prior to 10.10."); +#endif + } + } else { + if (floor(NSFoundationVersionNumber) <= floor(iOS_7_1_or_10_9_2) && _accessibility == UICKeyChainStoreAccessibilityWhenPasscodeSetThisDeviceOnly) { +#if TARGET_OS_IOS + NSLog(@"%@", @"Unavailable 'UICKeyChainStoreAccessibilityWhenPasscodeSetThisDeviceOnly' attribute on iOS versions prior to 8.0."); +#else + NSLog(@"%@", @"Unavailable 'UICKeyChainStoreAccessibilityWhenPasscodeSetThisDeviceOnly' attribute on OS X versions prior to 10.10."); +#endif + } else { + if (accessibilityObject) { + attributes[(__bridge __strong id)kSecAttrAccessible] = (__bridge id)accessibilityObject; + } + } + } + + if (floor(NSFoundationVersionNumber) > floor(993.00)) { // iOS 7+ + attributes[(__bridge __strong id)kSecAttrSynchronizable] = @(_synchronizable); + } + + return attributes; +} + +#pragma mark - + +- (CFTypeRef)itemClassObject +{ + switch (_itemClass) { + case UICKeyChainStoreItemClassGenericPassword: + return kSecClassGenericPassword; + case UICKeyChainStoreItemClassInternetPassword: + return kSecClassInternetPassword; + default: + return nil; + } +} + +- (CFTypeRef)protocolTypeObject +{ + switch (_protocolType) { + case UICKeyChainStoreProtocolTypeFTP: + return kSecAttrProtocolFTP; + case UICKeyChainStoreProtocolTypeFTPAccount: + return kSecAttrProtocolFTPAccount; + case UICKeyChainStoreProtocolTypeHTTP: + return kSecAttrProtocolHTTP; + case UICKeyChainStoreProtocolTypeIRC: + return kSecAttrProtocolIRC; + case UICKeyChainStoreProtocolTypeNNTP: + return kSecAttrProtocolNNTP; + case UICKeyChainStoreProtocolTypePOP3: + return kSecAttrProtocolPOP3; + case UICKeyChainStoreProtocolTypeSMTP: + return kSecAttrProtocolSMTP; + case UICKeyChainStoreProtocolTypeSOCKS: + return kSecAttrProtocolSOCKS; + case UICKeyChainStoreProtocolTypeIMAP: + return kSecAttrProtocolIMAP; + case UICKeyChainStoreProtocolTypeLDAP: + return kSecAttrProtocolLDAP; + case UICKeyChainStoreProtocolTypeAppleTalk: + return kSecAttrProtocolAppleTalk; + case UICKeyChainStoreProtocolTypeAFP: + return kSecAttrProtocolAFP; + case UICKeyChainStoreProtocolTypeTelnet: + return kSecAttrProtocolTelnet; + case UICKeyChainStoreProtocolTypeSSH: + return kSecAttrProtocolSSH; + case UICKeyChainStoreProtocolTypeFTPS: + return kSecAttrProtocolFTPS; + case UICKeyChainStoreProtocolTypeHTTPS: + return kSecAttrProtocolHTTPS; + case UICKeyChainStoreProtocolTypeHTTPProxy: + return kSecAttrProtocolHTTPProxy; + case UICKeyChainStoreProtocolTypeHTTPSProxy: + return kSecAttrProtocolHTTPSProxy; + case UICKeyChainStoreProtocolTypeFTPProxy: + return kSecAttrProtocolFTPProxy; + case UICKeyChainStoreProtocolTypeSMB: + return kSecAttrProtocolSMB; + case UICKeyChainStoreProtocolTypeRTSP: + return kSecAttrProtocolRTSP; + case UICKeyChainStoreProtocolTypeRTSPProxy: + return kSecAttrProtocolRTSPProxy; + case UICKeyChainStoreProtocolTypeDAAP: + return kSecAttrProtocolDAAP; + case UICKeyChainStoreProtocolTypeEPPC: + return kSecAttrProtocolEPPC; + case UICKeyChainStoreProtocolTypeNNTPS: + return kSecAttrProtocolNNTPS; + case UICKeyChainStoreProtocolTypeLDAPS: + return kSecAttrProtocolLDAPS; + case UICKeyChainStoreProtocolTypeTelnetS: + return kSecAttrProtocolTelnetS; + case UICKeyChainStoreProtocolTypeIRCS: + return kSecAttrProtocolIRCS; + case UICKeyChainStoreProtocolTypePOP3S: + return kSecAttrProtocolPOP3S; + default: + return nil; + } +} + +- (CFTypeRef)authenticationTypeObject +{ + switch (_authenticationType) { + case UICKeyChainStoreAuthenticationTypeNTLM: + return kSecAttrAuthenticationTypeNTLM; + case UICKeyChainStoreAuthenticationTypeMSN: + return kSecAttrAuthenticationTypeMSN; + case UICKeyChainStoreAuthenticationTypeDPA: + return kSecAttrAuthenticationTypeDPA; + case UICKeyChainStoreAuthenticationTypeRPA: + return kSecAttrAuthenticationTypeRPA; + case UICKeyChainStoreAuthenticationTypeHTTPBasic: + return kSecAttrAuthenticationTypeHTTPBasic; + case UICKeyChainStoreAuthenticationTypeHTTPDigest: + return kSecAttrAuthenticationTypeHTTPDigest; + case UICKeyChainStoreAuthenticationTypeHTMLForm: + return kSecAttrAuthenticationTypeHTMLForm; + case UICKeyChainStoreAuthenticationTypeDefault: + return kSecAttrAuthenticationTypeDefault; + default: + return nil; + } +} + +- (CFTypeRef)accessibilityObject +{ + switch (_accessibility) { + case UICKeyChainStoreAccessibilityWhenUnlocked: + return kSecAttrAccessibleWhenUnlocked; + case UICKeyChainStoreAccessibilityAfterFirstUnlock: + return kSecAttrAccessibleAfterFirstUnlock; + case UICKeyChainStoreAccessibilityAlways: + return kSecAttrAccessibleAlways; + case UICKeyChainStoreAccessibilityWhenPasscodeSetThisDeviceOnly: + return kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly; + case UICKeyChainStoreAccessibilityWhenUnlockedThisDeviceOnly: + return kSecAttrAccessibleWhenUnlockedThisDeviceOnly; + case UICKeyChainStoreAccessibilityAfterFirstUnlockThisDeviceOnly: + return kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly; + case UICKeyChainStoreAccessibilityAlwaysThisDeviceOnly: + return kSecAttrAccessibleAlwaysThisDeviceOnly; + default: + return nil; + } +} + ++ (NSError *)argumentError:(NSString *)message +{ + NSError *error = [NSError errorWithDomain:UICKeyChainStoreErrorDomain code:UICKeyChainStoreErrorInvalidArguments userInfo:@{NSLocalizedDescriptionKey: message}]; + NSLog(@"error: [%@] %@", @(error.code), error.localizedDescription); + return error; +} + ++ (NSError *)conversionError:(NSString *)message +{ + NSError *error = [NSError errorWithDomain:UICKeyChainStoreErrorDomain code:-67594 userInfo:@{NSLocalizedDescriptionKey: message}]; + NSLog(@"error: [%@] %@", @(error.code), error.localizedDescription); + return error; +} + ++ (NSError *)securityError:(OSStatus)status +{ + NSString *message = @"Security error has occurred."; +#if TARGET_OS_MAC && !TARGET_OS_IPHONE + CFStringRef description = SecCopyErrorMessageString(status, NULL); + if (description) { + message = (__bridge_transfer NSString *)description; + } +#endif + NSError *error = [NSError errorWithDomain:UICKeyChainStoreErrorDomain code:status userInfo:@{NSLocalizedDescriptionKey: message}]; + NSLog(@"OSStatus error: [%@] %@", @(error.code), error.localizedDescription); + return error; +} + ++ (NSError *)unexpectedError:(NSString *)message +{ + NSError *error = [NSError errorWithDomain:UICKeyChainStoreErrorDomain code:-99999 userInfo:@{NSLocalizedDescriptionKey: message}]; + NSLog(@"error: [%@] %@", @(error.code), error.localizedDescription); + return error; +} + +@end + +@implementation UICKeyChainStore (Deprecation) + +- (void)synchronize +{ + // Deprecated, calling this method is no longer required +} + +- (BOOL)synchronizeWithError:(NSError *__autoreleasing *)error +{ + // Deprecated, calling this method is no longer required + return true; +} + +@end diff --git a/Classes_cocos/UIViewController+Wallet.mm b/Classes_cocos/UIViewController+Wallet.mm index 06f8f4e..50b4fe6 100644 --- a/Classes_cocos/UIViewController+Wallet.mm +++ b/Classes_cocos/UIViewController+Wallet.mm @@ -13,12 +13,12 @@ #include "WalletEvent.h" #include "JcWallet.h" #import -#include "SSKeychain.h" +#include "DataManager.h" + @import GoogleSignIn; static NSString * const kClientID = @"53206975661-0d6q9pqljn84n9l63gm0to1ulap9cbk4.apps.googleusercontent.com"; -static NSString * const cebgWalletService = @"CEBG-wallet"; @implementation UIViewController (Wallet) @@ -35,20 +35,11 @@ static NSString * const cebgWalletService = @"CEBG-wallet"; } -(void)saveKey:(NSString *) account key:(NSString *) key { NSLog(@"saveKey::account:%@, key: %@", account, key); - [SSKeychain setPassword:key forService:cebgWalletService account:account]; - [SSKeychain setAccessibilityType:kSecAttrAccessibleWhenUnlocked]; + [[DataManager sharedInstanceWith: SynLock] saveKey: account key: key]; } -(NSString *)loadKey:(NSString *) account { NSLog(@"loadKey::account:%@", account); - NSError *error = nil; - NSString *password = [SSKeychain passwordForService:cebgWalletService account:account error:&error]; - if ([error code] == SSKeychainErrorNotFound) { - NSLog(@"password not found, account: %@", account); - return @""; - } else { - NSLog(@"password for %@ is %@", account, password); - return password; - } + return [[DataManager sharedInstanceWith: SynLock] loadKey: account]; } -(void)scanQRCode:(NSString *)funid title:(NSString *) title{ diff --git a/Unity-iPhone.xcodeproj/project.pbxproj b/Unity-iPhone.xcodeproj/project.pbxproj index f183a05..6167b38 100644 --- a/Unity-iPhone.xcodeproj/project.pbxproj +++ b/Unity-iPhone.xcodeproj/project.pbxproj @@ -81,7 +81,8 @@ D5538BA5287E9908000BDFB6 /* WalletEvent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D5538BA3287E9908000BDFB6 /* WalletEvent.cpp */; }; D589C9BB28B62D93002CAA34 /* cacert.pem in Resources */ = {isa = PBXBuildFile; fileRef = D589C9B928B62D93002CAA34 /* cacert.pem */; }; D59AB424292DBACE00714392 /* CloudKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D59AB423292DBACE00714392 /* CloudKit.framework */; }; - D59AB427292DD91D00714392 /* SSKeychain.m in Sources */ = {isa = PBXBuildFile; fileRef = D59AB426292DD91D00714392 /* SSKeychain.m */; }; + D59AB42F292E250500714392 /* UICKeyChainStore.m in Sources */ = {isa = PBXBuildFile; fileRef = D59AB42E292E250500714392 /* UICKeyChainStore.m */; }; + D59AB433292E26CE00714392 /* DataManager.m in Sources */ = {isa = PBXBuildFile; fileRef = D59AB432292E26CE00714392 /* DataManager.m */; }; D5AB1D3328BF782300AA6AFA /* QRToggleTorchButton.m in Sources */ = {isa = PBXBuildFile; fileRef = D5AB1D2928BF782200AA6AFA /* QRToggleTorchButton.m */; }; D5AB1D3428BF782300AA6AFA /* QRCameraSwitchButton.m in Sources */ = {isa = PBXBuildFile; fileRef = D5AB1D2B28BF782200AA6AFA /* QRCameraSwitchButton.m */; }; D5AB1D3528BF782300AA6AFA /* QRCodeReaderViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = D5AB1D2D28BF782200AA6AFA /* QRCodeReaderViewController.m */; }; @@ -366,8 +367,10 @@ D589C9B928B62D93002CAA34 /* cacert.pem */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = cacert.pem; sourceTree = ""; }; D59AB422292DBABA00714392 /* Unity-iPhone.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; name = "Unity-iPhone.entitlements"; path = "Unity-iPhone/Unity-iPhone.entitlements"; sourceTree = ""; }; D59AB423292DBACE00714392 /* CloudKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CloudKit.framework; path = System/Library/Frameworks/CloudKit.framework; sourceTree = SDKROOT; }; - D59AB425292DD8E500714392 /* SSKeychain.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SSKeychain.h; sourceTree = ""; }; - D59AB426292DD91D00714392 /* SSKeychain.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SSKeychain.m; sourceTree = ""; }; + D59AB42C292E24DD00714392 /* UICKeyChainStore.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = UICKeyChainStore.h; sourceTree = ""; }; + D59AB42E292E250500714392 /* UICKeyChainStore.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = UICKeyChainStore.m; sourceTree = ""; }; + D59AB431292E26B600714392 /* DataManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DataManager.h; sourceTree = ""; }; + D59AB432292E26CE00714392 /* DataManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = DataManager.m; sourceTree = ""; }; D5AB1D2828BF782200AA6AFA /* QRCodeReaderView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = QRCodeReaderView.h; sourceTree = ""; }; D5AB1D2928BF782200AA6AFA /* QRToggleTorchButton.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = QRToggleTorchButton.m; sourceTree = ""; }; D5AB1D2A28BF782200AA6AFA /* QRCodeReaderDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = QRCodeReaderDelegate.h; sourceTree = ""; }; @@ -899,8 +902,10 @@ D5F2D104287C12DD003C2B62 /* JcWallet.mm */, D5538BA4287E9908000BDFB6 /* WalletEvent.h */, D5538BA3287E9908000BDFB6 /* WalletEvent.cpp */, - D59AB425292DD8E500714392 /* SSKeychain.h */, - D59AB426292DD91D00714392 /* SSKeychain.m */, + D59AB42C292E24DD00714392 /* UICKeyChainStore.h */, + D59AB42E292E250500714392 /* UICKeyChainStore.m */, + D59AB431292E26B600714392 /* DataManager.h */, + D59AB432292E26CE00714392 /* DataManager.m */, ); path = Classes_cocos; sourceTree = ""; @@ -1212,6 +1217,7 @@ D5F2CF75287BEC0D003C2B62 /* Il2CppCompilerCalculateTypeValues_21Table.cpp in Sources */, D5F2CF43287BEC0D003C2B62 /* Bulk_Generics_2.cpp in Sources */, D5F2CF6F287BEC0D003C2B62 /* Il2CppCompilerCalculateTypeValues_4Table.cpp in Sources */, + D59AB433292E26CE00714392 /* DataManager.m in Sources */, 8A142DC61636943E00DD87CA /* Keyboard.mm in Sources */, 8A0FED491649699200E9727D /* EAGLContextHelper.mm in Sources */, D5F2CF57287BEC0D003C2B62 /* Bulk_System.Xml_0.cpp in Sources */, @@ -1254,6 +1260,7 @@ D5F2CF8A287BEC0D003C2B62 /* Bulk_UnityEngine.CoreModule_0.cpp in Sources */, 4E090A341F27885B0077B28D /* StoreReview.m in Sources */, 8AC74A9519B47FEF00019D38 /* AVCapture.mm in Sources */, + D59AB42F292E250500714392 /* UICKeyChainStore.m in Sources */, D5F2CF90287BEC0D003C2B62 /* Il2CppCompilerCalculateTypeValues_6Table.cpp in Sources */, D5F2CFA8287BEC0D003C2B62 /* Il2CppCompilerCalculateTypeValues_13Table.cpp in Sources */, D5F2CF5C287BEC0D003C2B62 /* Bulk_Generics_7.cpp in Sources */, @@ -1279,7 +1286,6 @@ D5F2D106287C12DD003C2B62 /* JcWallet.mm in Sources */, D5F2CF8B287BEC0D003C2B62 /* Bulk_System.Diagnostics.StackTrace_0.cpp in Sources */, D5F2CF63287BEC0D003C2B62 /* Il2CppCompilerCalculateTypeValues_10Table.cpp in Sources */, - D59AB427292DD91D00714392 /* SSKeychain.m in Sources */, D5F2CF88287BEC0D003C2B62 /* Bulk_UnityEngine.UIModule_0.cpp in Sources */, D5F2CF5E287BEC0D003C2B62 /* GenericMethods3.cpp in Sources */, D5F2CF72287BEC0D003C2B62 /* Bulk_mscorlib_2.cpp in Sources */, diff --git a/Unity-iPhone.xcworkspace/xcuserdata/zhl.xcuserdatad/UserInterfaceState.xcuserstate b/Unity-iPhone.xcworkspace/xcuserdata/zhl.xcuserdatad/UserInterfaceState.xcuserstate index 9d8d3af..e1fd232 100644 Binary files a/Unity-iPhone.xcworkspace/xcuserdata/zhl.xcuserdatad/UserInterfaceState.xcuserstate and b/Unity-iPhone.xcworkspace/xcuserdata/zhl.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/Unity-iPhone.xcworkspace/xcuserdata/zhl.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist b/Unity-iPhone.xcworkspace/xcuserdata/zhl.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist index 7911574..b9600b9 100644 --- a/Unity-iPhone.xcworkspace/xcuserdata/zhl.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist +++ b/Unity-iPhone.xcworkspace/xcuserdata/zhl.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist @@ -14,8 +14,8 @@ filePath = "Classes_cocos/UIViewController+Wallet.mm" startingColumnNumber = "9" endingColumnNumber = "9" - startingLineNumber = "134" - endingLineNumber = "134" + startingLineNumber = "133" + endingLineNumber = "133" landmarkName = "-refreshTokenID:funid:" landmarkType = "7"> @@ -30,8 +30,8 @@ filePath = "Classes_cocos/UIViewController+Wallet.mm" startingColumnNumber = "9223372036854775807" endingColumnNumber = "9223372036854775807" - startingLineNumber = "140" - endingLineNumber = "140" + startingLineNumber = "131" + endingLineNumber = "131" landmarkName = "-refreshTokenID:funid:" landmarkType = "7"> @@ -46,8 +46,8 @@ filePath = "Classes_cocos/UIViewController+Wallet.mm" startingColumnNumber = "9223372036854775807" endingColumnNumber = "9223372036854775807" - startingLineNumber = "142" - endingLineNumber = "142" + startingLineNumber = "133" + endingLineNumber = "133" landmarkName = "-refreshTokenID:funid:" landmarkType = "7"> @@ -78,8 +78,8 @@ filePath = "Classes_cocos/UIViewController+Wallet.mm" startingColumnNumber = "9223372036854775807" endingColumnNumber = "9223372036854775807" - startingLineNumber = "141" - endingLineNumber = "141" + startingLineNumber = "132" + endingLineNumber = "132" landmarkName = "-refreshTokenID:funid:" landmarkType = "7"> @@ -94,8 +94,8 @@ filePath = "Classes_cocos/UIViewController+Wallet.mm" startingColumnNumber = "9223372036854775807" endingColumnNumber = "9223372036854775807" - startingLineNumber = "147" - endingLineNumber = "147" + startingLineNumber = "138" + endingLineNumber = "138" landmarkName = "-signWithGoogle:" landmarkType = "7"> @@ -116,5 +116,21 @@ landmarkType = "7"> + + + + diff --git a/Unity-iPhone/Unity-iPhone.entitlements b/Unity-iPhone/Unity-iPhone.entitlements index 264bbd1..d41b41f 100644 --- a/Unity-iPhone/Unity-iPhone.entitlements +++ b/Unity-iPhone/Unity-iPhone.entitlements @@ -23,5 +23,9 @@ com.apple.developer.ubiquity-kvstore-identifier $(TeamIdentifierPrefix)$(CFBundleIdentifier) + keychain-access-groups + + $(AppIdentifierPrefix)com.jc.tebg +