IOSアプリにログイン画面があります。ユーザー名とパスワードはNSUserDefaults
に保存され、アプリを再起動すると再びログイン画面にロードされます(もちろん、NSUserDefaults
は永続的です)。
今、ユーザーはユーザー名/パスワードの保存機能を無効にする可能性があります。
そのためNSUserDefaults
はクリアされます。
しかし、私のアプリでは、ユーザーのデータベースクエリにこのユーザー名/パスワードが必要です。だから:NSUserDefaults
以外のデータをどこに格納するの? (この場所は、ユーザーがアプリを終了したりログアウトしたりするときに削除できます)。
ユーザー名とパスワードの保存には常にKeychainを使用する必要があります。また、安全に保存されており、アプリからしかアクセスできないため、アプリの終了時に削除する必要はありません(心配な場合)。
Appleは サンプルコード キーチェーンアイテムの保存、読み込み、削除を提供しています。キーチェーンの使い方を非常に簡単にするそのサンプルからキーチェーンラッパークラスを使う方法があります。
Security.frameworkをインクルード(Xcode 3ではframeworksフォルダを右クリックし、既存のフレームワークを追加します。Xcode 4ではプロジェクトを選択してからターゲットを選択し、Build Phasesタブに移動してLink Binaryの下の+をクリックします。 Files)およびKeychainItemWrapperの.h&.mファイルを使用して、keychainを使用する必要がある場所に.hファイルを#importしてから、このクラスのインスタンスを作成します。
KeychainItemWrapper *keychainItem = [[KeychainItemWrapper alloc] initWithIdentifier:@"YourAppLogin" accessGroup:nil];
(YourAppLoginは、キーチェーンアイテムを呼び出すために選択したもので、必要に応じて複数のアイテムを持つことができます)
その後、ユーザー名とパスワードを設定します。
[keychainItem setObject:@"password you are saving" forKey:kSecValueData];
[keychainItem setObject:@"username you are saving" forKey:kSecAttrAccount];
それらを使用して取得します。
NSString *password = [keychainItem objectForKey:kSecValueData];
NSString *username = [keychainItem objectForKey:kSecAttrAccount];
またはを使用してそれらを削除します。
[keychainItem resetKeychainItem];
ARCバージョンのラッパーが必要な場合は、ここにリンクがあります https://Gist.github.com/1170641 おかげで
Keychains による非常に簡単な解決策。
これはシステムキーチェーンのシンプルなラッパーです。 SSKeychain.h
、SSKeychain.m
、SSKeychainQuery.h
、SSKeychainQuery.m
の各ファイルをプロジェクトに追加し、Security.frameworkをターゲットに追加するだけです。
パスワードを保存するには
[SSKeychain setPassword:@"AnyPassword" forService:@"AnyService" account:@"AnyUser"]
パスワードを取得するには
NSString *password = [SSKeychain passwordForService:@"AnyService" account:@"AnyUser"];
ここでsetPassword
は保存したい値、forService
は保存したい変数、accountはパスワードを含むユーザー/オブジェクト、その他の情報です。
単にNSURLCredential
を使用することができます、それはちょうど2行のコードでキーチェーンにユーザー名とパスワードの両方を保存します。
私の詳細を参照してください 答え 。
Obj-CとARCを使ってiOS 8でキーチェーンを使う方法に答えることにしました。
1)GistのkeychainItemWrapper(ARCifiefバージョン)を使用しました。 https://Gist.github.com/dhoerl/1170641/download - KeychainItemWrapper.hと.mを追加(+コピー)します。プロジェクト
2)プロジェクトにセキュリティフレームワークを追加します(プロジェクト>ビルドフェーズ>ライブラリとバイナリのリンクのチェックイン)。
3)セキュリティライブラリ(#import)とKeychainItemWrapper(#import "KeychainItemWrapper.h")を、キーチェーンを使用する.hファイルと.mファイルに追加します。
4)キーチェーンにデータを保存する
NSString *emailAddress = self.txtEmail.text;
NSString *password = self.txtPasword.text;
//because keychain saves password as NSData object
NSData *pwdData = [password dataUsingEncoding:NSUTF8StringEncoding];
//Save item
self.keychainItem = [[KeychainItemWrapper alloc] initWithIdentifier:@"YourAppLogin" accessGroup:nil];
[self.keychainItem setObject:emailAddress forKey:(__bridge id)(kSecAttrAccount)];
[self.keychainItem setObject:pwdData forKey:(__bridge id)(kSecValueData)];
5)データを読み込む(おそらくロード時にログイン画面> viewDidLoad):
self.keychainItem = [[KeychainItemWrapper alloc] initWithIdentifier:@"YourAppLogin" accessGroup:nil];
self.txtEmail.text = [self.keychainItem objectForKey:(__bridge id)(kSecAttrAccount)];
//because label uses NSString and password is NSData object, conversion necessary
NSData *pwdData = [self.keychainItem objectForKey:(__bridge id)(kSecValueData)];
NSString *password = [[NSString alloc] initWithData:pwdData encoding:NSUTF8StringEncoding];
self.txtPassword.text = password;
楽しい!
キーチェーンラッパーを使用してパスワードを取得する際に問題がある場合は、次のコードを使用してください。
NSData *pass =[keychain objectForKey:(__bridge id)(kSecValueData)];
NSString *passworddecoded = [[NSString alloc] initWithData:pass
encoding:NSUTF8StringEncoding];
これをチェックしてください サンプルコード 最初にサンプルコードからAppleのラッパーを試してみましたが、これは私にとってはずっと簡単です。
これを試してください。
KeychainItemWrapper *keychainItem = [[KeychainItemWrapper alloc] initWithIdentifier:@"YourAppLogin" accessGroup:nil];
[keychainItem setObject:@"password you are saving" forKey:kSecValueData];
[keychainItem setObject:@"username you are saving" forKey:kSecAttrAccount];
助けになるかもしれません。
この質問を更新するには
Swiftチェックアウトを使用している人のために、Mihai Costeaによる、このドラッグアンドドロップによるSwiftの実装をサポートするアクセスグループ:
https://github.com/macostea/KeychainItemWrapper.Swift/blob/master/KeychainItemWrapper.Swift
キーチェーンを使用する前に:パスワードを保存する前に2回検討してください。多くの場合、認証トークン(永続セッションIDなど)と電子メール名またはアカウント名を格納するだけで十分です。不正なアクセスをブロックするために認証トークンを簡単に無効にすることができます。ユーザーは侵入先のデバイスに再度ログインする必要がありますが、パスワードの再設定は不要です。
私はKeychainItemWrapper(ARC版)を使ってみましたが、Objective Cのラッパーが望みどおりに健全であるとは思いませんでした。
このソリューション by Kishikawa Katsumi を使用したので、コードの作成が少なくなり、NSString値を格納するためにキャストを使用する必要がなくなりました。
格納の2つの例
[UICKeyChainStore setString:@"kishikawakatsumi" forKey:@"username"];
[UICKeyChainStore setString:@"P455_w0rd$1$G$Z$" forKey:@"password"];
検索の2つの例
UICKeyChainStore *store = [UICKeyChainStore keyChainStore];
// or
UICKeyChainStore *store = [UICKeyChainStore keyChainStoreWithService:@"YOUR_SERVICE"];
NSString *username = [store stringForKey:@"username"];
NSString *password = [store stringForKey:@"password"];
上記のコードには小さなバグがあります(ところでDaveは非常に役に立ちました。投稿ありがとうございます)。
認証情報を保存する部分では、正しく機能するために次のコードも必要です。
[self.keychainItem setObject:@"myCredentials" forKey:(__bridge id)(kSecAttrService)];
おそらく、2回目に同じ認証情報を使用して(再)サインインしようとすると、キーチェーン項目に割り当てられていることが判明し、アプリケーションがクラッシュするためです。上記のコードでそれは魅力のように働きます。
しかし、今、あなたはキーチェーンラッパーの代わりにNURLCredentialに行くことができます。それは我々がする必要があることをします。
以下はうまくいくはずです。
KeychainItemWrapper *keychainItem = [[KeychainItemWrapper alloc] initWithIdentifier:@"YourAppLogin" accessGroup:nil];
[keychainItem setObject:@"password you are saving" forKey:kSecValueData];
[keychainItem setObject:@"username you are saving" forKey:kSecAttrAccount];