2016-04-16 12 views
1

Firebaseログインを使用しているときに、ViewDidAppearメソッドでデータを正しく読み込むことができません。ユーザーがログインボタンを押すと、Firebaseからユーザーの情報を取得し、次のビューコントローラー(新しいタブバーコントローラーの一部)に表示することができます。Firebaseログインからデータを取得する前にコントローラをロードする - Swift

ブレークポイントを使用すると、新しいビューが表示され、次にデータがFirebaseから取得されたことがわかります。ビューが表示される前にFirebaseからデータをロードする必要があります。ここで

は、ログインボタンのための私のコードです:ここでは

let userSettings = NSUserDefaults.standardUserDefaults() 

@IBAction func signInButton(sender: AnyObject) { 

    ref.authUser(emailTextField.text, password: passwordTextField.text) { (error, authData) -> Void in 

     if error != nil { 

      let accountError = UIAlertController(title: "Error logging in", message: "Please try again", preferredStyle: .Alert) 
      accountError.addAction(UIAlertAction(title: "Ok", style: .Default, handler: nil)) 
      self.presentViewController(accountError, animated: true, completion: nil) 


     } else {     

      userID = ref.authData!.uid 

      userSettings.setObject(userID!, forKey: "firebaseUserID") 

      let playNumberRef = Firebase(url:"https://(removed for security).firebaseIO.com/users/\(userID!)/playNumber") 


      //Check Firebase for the user's last playnumber and set it in the user defaults 

      playNumberRef.observeSingleEventOfType(.Value, withBlock: { snap in 

       //Convert type AnyObject to NSNumber so that we can check its value 

       if let checkPlay = snap.value as? NSNumber { 

        userSettings.setInteger(Int(checkPlay), forKey: "playNumber") 

       }}) 

はviewWillAppearメソッドでは私のコードです:

var playNumber = userSettings.integerForKey("playNumber") 

dayCounterLabel.text = "Day \(playNumber)" 

ビューが最初に表示されたら、dayCounterLabel.textが更新されていません。別のタブに移動してから戻ると、それが更新されます。

ビューが表示される前にデータをユーザーのデフォルトに保存するにはどうすればよいですか?

+0

次のビューコントローラを起動するために、私は次のコードを使用しています: vc = self.storyboard!.instantiateViewControllerWithIdentifier( "autoLogin")as! UITabBarController vc.selectedIndex = 0 self.presentViewController(VC、アニメーション:真、完了:ゼロ) –

+0

は、なぜあなたは、デフォルトではラベル表示を隠し、Firebaseからのデータはあなたの閉鎖に引っ張られたときにそれを示しませんでしたか? – pkacprzak

答えて

2

これは共通の問題である:

Firebaseは非同期であり、Firebaseがデータを返すまでの時間を持っていた前に、viewWillAppearが発生しています。このコード

playNumberRef.observeSingleEventOfType 

はブロックであり、アプリケーションは、そのブロックが返されたデータを有するまでビューを表示するために進むべきではありません。

つまり

そのブロック内から次のビューを表示し、私はあなたのコードの残りの部分が設定されているのか分からないが、ここで急ごしらえの例を示します(テストされていないので、ペーストをコピーしません。 )

は、我々は、ユーザーがログイン後のメインアプリビューのために、ユーザのログイン、およびmainViewControllerをすることができますloginViewControllerがあるとします。

AppDelegateで、我々は

を持っています3210

ので、あなたの場合にはブロックがthusly変更することができます

playNumberRef.observeSingleEventOfType(.Value, withBlock: { snap in 

    if let checkPlay = snap.value as? NSNumber { 

    userSettings.setInteger(Int(checkPlay), forKey: "playNumber") 

    let appDelegate = NSApplication.sharedApplication().delegate as! AppDelegate 

    appDelegate.showMainView() //prepare to sho the main view 

    self.view.window?.close() //get rid of this one 

}}) 

Firebaseは、データを返すために時間を過ごしたとVARSが移入されたときにそう、メインビューコントローラのみが表示されます。

+0

ありがとうございました!ブロック内のコードを動かすと、完璧に動作しました! –

0
if let checkPlay = snap.value as? NSNumber { 
    dispatch_async(dispatch_get_main_queue(),{ 
     userSettings.setInteger(Int(checkPlay), forKey: "playNumber") 
    }) 
}}) 

これを試すと、 お手数ですが、

+0

何らかの理由で、この解決策は問題に影響を与えませんでした。 Firebaseのドキュメンテーションでは、「バリューイベントは常に最後にトリガーされ、そのスナップショットが取られる前に発生した他のイベントからのアップデートを含むことが保証されているからです。 –

関連する問題