2017-08-17 20 views
1

我有一個應用程序有一個用戶名/密碼登錄。登錄後,用戶應保持登錄狀態,直到他們註銷爲止,即即使用戶沒有連接,用戶仍保持登錄狀態。我是否可以將Realm用於所有數據存儲,還是應該使用NSUserDefaults來存儲用戶名/密碼?

目前我正在對用戶進行身份驗證,但我無法讓他們保持登錄狀態。我應該將用戶詳細信息存儲在NSUserDefaults中以便在啓動時登錄,還是有一種方法可以讓用戶使用Realm登錄?

在此先感謝!

SyncUser.logIn(with: userCredentials, server: (url! as URL)) { user, error in 
    guard user != nil else { 
     // Handles error 
    } 
    DispatchQueue.main.async { 
     let configuration = Realm.Configuration(
      syncConfiguration: SyncConfiguration(user: user!, realmURL: URL(string: "realm://127.0.0.1:9080/~/realmtasks")!) 
     ) 
     Realm.Configuration.defaultConfiguration = configuration 

     self.performSegue(withIdentifier: "logInSegue", sender: self) 
    } 
} 

更新:也許我的問題的答案是Apple Keychain?

+0

請提供代碼示例,但請始終關注問題。 – DarkMukke

+0

請始終提供支持代碼,以便人們更好地理解您的問題並更快地提供有用的解決方案。 – Roshan

+2

使用'NSCoding'並存檔,然後保存在'userDefaults'中。但是將密碼保存在'userDefaluts'中並不是很大! –

回答

2

你不應該存儲密碼或任何敏感信息內部NSUserDefault,通過使用可以讀取存儲在它的所有數據進行簡單的文件管理器,它確實是不安全的。
你甚至不需要數據庫或類型。存儲敏感信息的正確位置是設備的鑰匙串。
github上有很多libs可以幫助你使用它。
請注意,即使在刪除應用程序後,您保存在鑰匙串中的內容仍會保留。

1

您可以考慮在鑰匙串中保存憑證。只需要創建一個Objective-c文件並將其導入到項目的橋接頭文件中。

.H

#import <Foundation/Foundation.h> 

@interface KeychainUserPass : NSObject 

+ (void)save:(NSString *)service data:(id)data; 
+ (id)load:(NSString *)service; 
+ (void)delete:(NSString *)service; 

@end 

.M

#import "KeychainUserPass.h" 

@implementation KeychainUserPass 

+ (NSMutableDictionary *)getKeychainQuery:(NSString *)service { 

    return [NSMutableDictionary dictionaryWithObjectsAndKeys: 
      (__bridge id)kSecClassGenericPassword, (__bridge id)kSecClass, 
      service, (__bridge id)kSecAttrService, 
      service, (__bridge id)kSecAttrAccount, 
      (__bridge id)kSecAttrAccessibleAfterFirstUnlock, (__bridge id)kSecAttrAccessible, 
      nil]; 
} 

+ (void)save:(NSString *)service data:(id)data { 

    NSMutableDictionary *keychainQuery = [self getKeychainQuery:service]; 
    SecItemDelete((__bridge CFDictionaryRef)keychainQuery); 
    [keychainQuery setObject:[NSKeyedArchiver archivedDataWithRootObject:data] forKey:(__bridge id)kSecValueData]; 
    SecItemAdd((__bridge CFDictionaryRef)keychainQuery, NULL); 
} 

+ (id)load:(NSString *)service { 

    id ret = nil; 
    NSMutableDictionary *keychainQuery = [self getKeychainQuery:service]; 
    [keychainQuery setObject:(id)kCFBooleanTrue forKey:(__bridge id)kSecReturnData]; 
    [keychainQuery setObject:(__bridge id)kSecMatchLimitOne forKey:(__bridge id)kSecMatchLimit]; 
    CFDataRef keyData = NULL; 

    if (SecItemCopyMatching((__bridge CFDictionaryRef)keychainQuery, (CFTypeRef *)&keyData) == noErr) { 
     @try { 
      ret = [NSKeyedUnarchiver unarchiveObjectWithData:(__bridge NSData *)keyData]; 
     } 
     @catch (NSException *e) { 
      NSLog(@"Unarchive of %@ failed: %@", service, e); 
     } 
     @finally {} 
    } 
    if (keyData) CFRelease(keyData); 
    return ret; 
} 

+ (void)delete:(NSString *)service { 

    NSMutableDictionary *keychainQuery = [self getKeychainQuery:service]; 
    SecItemDelete((__bridge CFDictionaryRef)keychainQuery); 
} 


@end 

使用

節省:KeychainUserPass.save("email", data: self.YOUR_TEXT_FIELD.text!)

負載:YOUR_STRING = KeychainUserPass.load("email") as? String

刪除:KeychainUserPass.delete("email")

相關問題