2017-06-21 39 views
2

FirebaseからデータをフェッチしてSwift配列のオブジェクトとして追加しようとしていますが、アプリケーションを実行するたびに配列が空になります。私がprintの声明を観測の中に入れたとき、私はそれを望むように各財布が印刷されますが、財布は決して配列に追加されません。Swift with Firebase辞書に配列を書き込む

var purses = [Purse]() 

override func viewDidLoad() { 
    fetchPurse(completion: {print(self.purses.count)}) 
} 

func fetchPurse(completion: @escaping() ->()){ 
    let ref = FIRDatabase.database().reference(fromURL: "https://test-database-ba3a2.firebaseio.com/") 
    let user = (FIRAuth.auth()?.currentUser?.uid)! 
    let userRef = ref.child("users").child(user).child("devices") 

    userRef.observe(.childAdded, with: { (snapshot) in 
     if let dictionary = snapshot.value as? [String: AnyObject]{ 
      let purse = Purse() 
      purse.setValuesForKeys(dictionary) 
      self.purses.append(purse) 
      completion() 
     } 
    }, withCancel: nil) 
} 
+0

ここで、アレイを印刷しようとしていますか?非同期関数で配列に値を設定しているので、完了ハンドラの外側にある値を監視しようとすると、配列が生成される前に配列が出力される可能性が高くなります。 –

+0

私は別の関数で配列を呼び出していますが、そこにいくつの袋があるかに基づいて、テーブルビューの特定の量のテーブルセルを読み込むために.countメソッドを使用しようとしています。 –

+0

fetchPurse()には完了ハンドラがあり、完了ハンドラから他の関数​​を呼び出す必要があります。 –

答えて

1

これは、非同期メソッドの動作の誤解のようです。

あなたは、このようなコードを使用する場合:

//at this point purses is empty.. 
fetchPurse() 
print("purses count = \(purses.count)") 

をあなたは常に空の財布列が表示されます。

問題は、fetchPurse()関数が、非ベースのFirebase関数observeを使用していることです。新しいエントリが追加されると、Firebaseはあなたが渡したコードをwith:クロージャとして実行するよう要求します。 observe関数は即座に戻り、FireBaseが新しい子オブジェクトを追加するときに、後で継承するクロージャを呼び出します。

結果として、fetchPurse()関数は、新しい財布オブジェクトがあなたの小銭の配列に追加される前にも戻ります。 DávidPásztorは彼のコメントで述べた@として

、あなたは財布の配列が更新されたときに呼び出される終了ハンドラ取るfetchPurseをリファクタリングする必要があります

func fetchPurse(completion:() ->){ 
    let ref = FIRDatabase.database().reference(fromURL: "https://test-database-ba3a2.firebaseio.com/") 
    let user = (FIRAuth.auth()?.currentUser?.uid)! 
    let userRef = ref.child("users").child(user).child("devices") 

    userRef.observe(.childAdded, with: { (snapshot) in 
     if let dictionary = snapshot.value as? [String: AnyObject]{ 
      let purse = Purse() 
      purse.setValuesForKeys(dictionary) 
      self.purses.append(purse) 
      //This is the new line that calls your new completion handler 
      completion() 
     } 
    }, withCancel: nil) 
} 

をそして、あなたはこのようにそれを呼びたい:

fetchPurse(completion: { 
    print("purses count = \(purses.count)") 
} 
+0

コードをどのように実装したのかという質問を更新しましたが、それでもまだ空の配列が表示されています。私はどこでfetchPurse関数を呼び出すのかを含めました –

+0

私はそれを得ても大丈夫です。本当にありがとう! –

関連する問題