2016-10-24 14 views
0

私のデータベースからいくつかのフィールドを取得し、それを私のiOS Appに保存するHTTP POST要求をWebサーバーに送信するカスタム関数がありますKeychainWrapperを使用して、そのフィールド値をキーチェーン項目として返します。KeychainWrapperが同じ関数でデータを保存していても動作していない

私のiOSアプリケーションは、HTTP POSTを再度使用してmySQLデータベースでユーザーの資格情報が正しいかどうかを確認する簡単なログイン画面です。正しい場合は、KeychainWrapperを使用して情報を表示して表示するはずのユーザーページに移動します。

私が直面している問題は、ログインページのログインボタンを押してユーザーページに着くたびに、すべてのフィールドがnullとして表示されることです。しかし、ビルドをやめて再ビルドすると、今回ロードされたフィールドでそのページにロードされます。 ユーザーページに初めてアクセスすると、キーチェーンにはまだフィールドが保存されませんが、再構築するとそこからロードされます。

私はコードを短くして、この質問に関連性を保つためにコードからいくつかの部分を削除します。ここではMySQLデータベースからメタフィールドを要求する私の機能は次のとおりです。ここで

func requestMetaField(metaField:String) -> String { 

     let userEmail: String = KeychainWrapper.standard.string(forKey: "email")!; 
     let userPassword: String = KeychainWrapper.standard.string(forKey: "password")!; 
     let meta = metaField; 

     // Send data to server side 
     // Classic HTTP POST Request using JSONSerialization here. 

        if(resultValue=="Success") { 

         // Save downloaded data to keychain 
         self.saveDataToKeychain(value: metaValue, key: meta); 
        } 

     // End of the HTTP POST Request and else statements. 

     if let metaValue: String = KeychainWrapper.standard.string(forKey: meta) { 
     return metaValue; 
     } else { 
      return "N/A"; 
     } 

    } 

は私のsaveDataToKeychain機能である:私はそれを適用するには、ユーザーのページ機能を使うのはここ

func saveDataToKeychain(value:String, key:String) -> Bool { 
     let saveSuccessful: Bool = KeychainWrapper.standard.set(value, forKey: key); 
     return saveSuccessful; 
    } 

ですラベル:私は、ログインボタンを使用するとき、私はキーチェーンにメール&パスワードを保存する場所を

override func viewDidLoad() { 
     super.viewDidLoad() 

     logoutButton.layer.cornerRadius = 6; 

     let firstName = requestMetaField(metaField: "first_name"); 
     let lastName = requestMetaField(metaField: "last_name"); 
     userFullName.text = "\(firstName) \(lastName)"; 

     let userMinuteBalance = requestMetaField(metaField: "mycred_default_total"); 
     userBalance.text = "\(userMinuteBalance) min"; 
    } 

そして、ここでは、次のとおりです。

if(resultValue=="Success") { 

         // Login is successful 
         UserDefaults.standard.set(true, forKey: "isUserLoggedIn"); 
         UserDefaults.standard.synchronize(); 

         // Save email & password in keychain 
         self.saveDataToKeychain(value: userEmail!, key: "email"); 
         self.saveDataToKeychain(value: userPassword!, key: "password"); 

         isUserLoggedIn = true; 
} 

私はログインするとすぐにどのようにデータにアクセスできるのですか?

また、私はこれがユーザー情報の中で最も安全だということを読んだので私はキーチェーンの方法を使用しましたが、誰かがキーチェーンを使うより簡単な方法があると思うならば、私は他のオプションを開いています。

お世話になりましたことをありがとうございました!

答えて

0

私は、非同期のときに、同期関数としてrequestMetaFieldを扱っているというのが問題だと思います。 requestMetaFieldが返されてからしばらくすると、HTTPリクエストは終了しません。

もう1つの方法は、要求が完了したときに呼び出されるコールバック関数を使用するrequestMetaFieldのバージョンを記述することです。その後、コールバックからUIを更新することができます。以下のようになりますviewDidLoad

func requestMetaField(metaField:String, callback: @escaping (String) -> Void) { 

     let userEmail: String = KeychainWrapper.standard.string(forKey: "email")!; 
     let userPassword: String = KeychainWrapper.standard.string(forKey: "password")!; 
     let meta = metaField; 

     // Send data to server side 
     // Classic HTTP POST Request using JSONSerialization here. 

        if(resultValue=="Success") { 

         // Save downloaded data to keychain 
         self.saveDataToKeychain(value: metaValue, key: meta); 

         // call callback with value 
         callback(metaValue) 
        } 

コード:ここで

は、このようなrequestMetaFieldは、次のようになりますそれはそれでなければなりませんはい、

私が見
requestMetaField(metaField: "first_name") { firstName in 
     requestMetaField(metaField: "last_name") { lastName in 
      DispatchQueue.main.async {   
       userFullName.text = "\(firstName) \(lastName)" 
      } 
     } 
    } 

    requestMetaField(metaField: "mycred_default_total") { userMinuteBalance in 
     DispatchQueue.main.async {   
      userBalance.text = "\(userMinuteBalance) min" 
     } 
    } 
+0

、私は迅速にちょっと新たなんです開発、私はそれを逃した可能性があります。コールバック関数にはあまり慣れていません。私はあなたの「他のアプローチ」を完成させるために使用できるドキュメントやガイドを知っていますか?あなたの答えをありがとう! –

+1

マイナス私はXcode(コールバックに 'value'を置くことができませんでした)に従わなければならなかったいくつかの変更:(value:String)'これは私が必要としていたものです。 –

+1

誰かがここでこの作業をしようとすると、 'callback:'の後ろに '@ escaping'を置いていました! –

関連する問題