首页 文章

iOS KeyChain项目在应用的多个目标之间未更新

提问于
浏览
0

我正在构建一个应用程序,人们需要能够从iOS照片应用程序共享照片 . 为此,人们需要登录到应用程序 .

所以我为共享创建了一个新的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

所以症状是获取用户名,密码,域或cookie的功能都会在同一个应用程序的不同目标之间产生不同的结果 .

1 回答

相关问题