简体   繁体   English

我可以将Realm用于所有数据存储,还是应该使用NSUserDefaults来存储用户名/密码?

[英]Can I use Realm for all data storage, or should I use NSUserDefaults for storing username/password?

I have an application which has a username/password login. 我有一个用户名/密码登录的应用程序。 Once logged in, the user should remain logged in until they log out, ie the user remains logged in even if they have no connection. 登录后,用户应保持登录状态,直到他们退出为止,即即使用户没有连接,用户仍会保持登录状态。

Currently I am authenticating the user, but I am unable to keep them logged in. Should I store the user details in NSUserDefaults for logging in on launch, or is there a way of keeping the user logged in using just Realm? 目前我正在验证用户,但我无法让他们登录。我应该将用户详细信息存储在NSUserDefaults中以便在启动时登录,还是有办法让用户只使用Realm登录?

Thanks in advance! 提前致谢!

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)
    }
}

Update: Maybe the answer to my problem is Apple Keychain? 更新:也许我的问题的答案是Apple Keychain?

You should not store passwords or any sensitive information inside NSUserDefault , by using a simple file manager you can read all the data stored in it, it is really unsafe. 您不应该在NSUserDefault存储密码或任何敏感信息,通过使用简单的文件管理器,您可以读取存储在其中的所有数据,这实际上是不安全的。
you don't even need a database or sort of. 你甚至不需要数据库或者那种。 The right place to store sensitive info is the keychain of your device. 存储敏感信息的正确位置是您设备的钥匙串。
There are a lot of libs on github that can help you in using it. github上有很多lib可以帮助你使用它。
Pay attention that what you save inside the keychain will persist even after you remove the application. 请注意,即使在删除应用程序后,您在钥匙串中保存的内容也会保留。

You can consider this for saving credentials in the keychain. 您可以考虑将其保存在钥匙串中。 Just need to create an Objective-c file and import it in the Bridging-header-file of your project. 只需要创建一个Objective-c文件并将其导入项目的Bridging-header文件中。

.h 。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 .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

Usage : 用法

Save: KeychainUserPass.save("email", data: self.YOUR_TEXT_FIELD.text!) 保存: KeychainUserPass.save("email", data: self.YOUR_TEXT_FIELD.text!)

Load: YOUR_STRING = KeychainUserPass.load("email") as? String 加载: YOUR_STRING = KeychainUserPass.load("email") as? String YOUR_STRING = KeychainUserPass.load("email") as? String

Delete: KeychainUserPass.delete("email") 删除: KeychainUserPass.delete("email")

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 iOS:我应该使用Core Data还是NSUserDefaults? - iOS: Should I use Core Data or NSUserDefaults? 我应该使用存储库for Realm(ios) - Should I use repository for Realm(ios) 对于给定的配置,我应该尝试使用NSUserDefaults还是转到CoreData? - for the given configuration should I attempt to use NSUserDefaults or go to CoreData? 有什么办法可以用来构建领域结构和数据吗? - Is there any way i can use to build realm structure as well as data? 如何在内存中同时使用默认领域和领域? - How can i use Default Realm and Realm in memory at the same time? 使用Realm,我应该使用List对象或Results对象作为UITableView的数据源吗? - With Realm, should I use a List object or Results object as the data source for a UITableView? 我可以使用NSUserDefaults保存应用程序的表格单元格值吗? - Can I use NSUserDefaults to save the app’s table cell values? NSUserDefaults setObject和IntegerForKey,在同一密钥上使用,如果没有,我该如何解决? - NSUserDefaults setObject and IntegerForKey, use on the same key, if not how can I workaround? 我可以使用iCloud同步NSUserDefaults plist文件 - Can I use iCloud to sync the NSUserDefaults plist file 我应该使用NSFetchedResultController还是Dictionary覆盖CoreData领域? - Realm over CoreData should I use NSFetchedResultController or a Dictionary?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM