2016-11-28 71 views
0

我正在構建應用程序,其中人們需要能夠從iOS照片應用程序共享照片。要做到這一點,人們需要登錄到應用程序。iOS KeyChain項目未在應用程序的多個目標之間更新

所以我創建了一個新的iOS目標共享。 現在我正在使用KeychainItemWrapper來存儲用戶憑證。 因此,主要目標和共享表目標都使用iOS Keychain來檢索登錄信息。

現在,當我從主應用程序註銷,然後以其他用戶身份登錄後,我開始分享表單,看起來分享表仍然包含上一位用戶的舊數據。

這怎麼可能?我如何確保兩個目標始終使用鑰匙串中最新最好的數據?

#import "KeychainManager.h" 
#import "KeychainItemWrapper.h" 

NSString * const CREDENTIALS_IDENTIFIER = @"credentials"; 
NSString * const COOKIES_IDENTIFIER = @"cookies"; 

static KeychainManager *keychainManager; 

@implementation KeychainManager 

+ (instancetype)sharedCredentailsManager { 
    static dispatch_once_t onceToken; 
    dispatch_once(&onceToken, ^{ 
     keychainManager = [[KeychainManager alloc] init]; 
    }); 
    return keychainManager; 
} 

#pragma mark - Getter 
- (KeychainItemWrapper *)credentialsKeychainItem { 
    return [[KeychainItemWrapper alloc] initWithIdentifier:CREDENTIALS_IDENTIFIER accessGroup:nil]; 
} 

- (KeychainItemWrapper *)cookiesKeychainItem { 
    return [[KeychainItemWrapper alloc] initWithIdentifier:COOKIES_IDENTIFIER accessGroup:nil]; 
} 

- (NSString *)domainName { 
    NSString *domainName = [self.credentialsKeychainItem objectForKey:(__bridge id)(kSecAttrService)]; 
    return (domainName.length > 0) ? domainName : @""; 
} 

- (NSString *)userName { 
    NSString *userName = [self.credentialsKeychainItem objectForKey:(__bridge id)(kSecAttrAccount)]; 
    return (userName.length > 0) ? userName : @""; 
} 

- (NSString *)password { 
    NSData *password = [self.credentialsKeychainItem objectForKey:(__bridge id)(kSecValueData)]; 
    if ([password isKindOfClass:[NSString class]] && password.length > 0) { 
     return (NSString *)password; 
    } else if ([password isKindOfClass:[NSData class]] && password.length > 0) { 
     NSString *passwordString = [[NSString alloc] initWithData:password encoding:NSUTF8StringEncoding]; 
     return (passwordString.length > 0) ? password : @""; 
    } else { 
     return @""; 
    } 
} 

- (NSArray *)cookies { 
    NSLog(@"Getting cookies"); 
    NSData *cookieData = [self.cookiesKeychainItem objectForKey:(__bridge id)(kSecAttrAccount)]; 
    if ([cookieData isKindOfClass:[NSData class]] && cookieData.length > 0) { 
     NSArray *array = [NSKeyedUnarchiver unarchiveObjectWithData:cookieData]; 
     NSLog(@"%lu cookies in keychain", (unsigned long)array.count); 
     return array; 
    } else { 
     NSLog(@"No cookies found in KeyChain"); 
     return nil; 
    } 
} 

#pragma mark - Setter 
- (void)setDomainName:(NSString *)domainName { 
    [self.credentialsKeychainItem setObject:domainName forKey:(__bridge id)(kSecAttrService)]; 
} 

- (void)setUserName:(NSString *)userName { 
    [self.credentialsKeychainItem setObject:userName forKey:(__bridge id)(kSecAttrAccount)]; 
} 

- (void)setPassword:(NSString *)password { 
    [self.credentialsKeychainItem setObject:password forKey:(__bridge id)(kSecValueData)]; 
} 

- (void)setCookies:(NSArray *)cookies { 
    NSMutableArray *mutableCookies = [[NSMutableArray alloc] init]; 
    for (NSHTTPCookie *cookie in cookies) { 
     NSLog(@"storing cookie: %@", cookie); 
     NSDictionary *cookieProperties = cookie.properties; 
     [mutableCookies addObject:cookieProperties]; 
    } 
    NSArray *unmutableCookies = [mutableCookies copy]; 
    NSData * encodedData = [NSKeyedArchiver archivedDataWithRootObject:unmutableCookies]; 
    [self.cookiesKeychainItem setObject:encodedData forKey:(__bridge id)(kSecAttrAccount)]; 
} 

# pragma mark - Clear data 
- (void)clearAll { 
    [self clearCredentials]; 
    [self clearCookies]; 
} 

- (void)clearCredentials { 
    [self.credentialsKeychainItem resetKeychainItem]; 
} 

- (void)clearCookies { 
    [self.cookiesKeychainItem resetKeychainItem]; 
} 

@end 

所以症狀的函數來獲取用戶名,密碼,域或餅乾都給同一應用程序的不同目標之間不同的結果。

回答

0

我發現了這個問題。我必須在兩個目標的權利中設置Keychain共享。

如何設置這方面的一個指南這裏找到:

http://evgenii.com/blog/sharing-keychain-in-ios/

然後你有你的鑰匙串項存儲庫的訪問小組。當我嘗試時,KeychainItemWrapper在我想存儲Keychain中的某些東西時給出了一些Assertion Failures,然後我可以使用以下鏈接來解決: KeychainItemWrapper error when specifying an access group