2016-11-28 76 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