2016-09-07 5 views
0

Firebaseでデータベースを管理するために、プロジェクトにクラスを定義しました。これまで私がクラスでやったことは次のとおりです。Firebaseでは、取得したデータは.observeEventTypeメソッドから取り出されません

import Foundation 
import Firebase 

class db{ 
    class func getPrim() -> [String]{ 
     var ret = [String]() 

     let ref = FIRDatabase.database().reference() 

     ref.child("bunya1").observeEventType(FIRDataEventType.Value, withBlock: { 
      s in 

      ret = s.value! as! [String] 

     }) 

     print("ret: \(ret)") 
     return ret 
    } 
} 

および方法はprint(db.getPrim())のように、print()方法で呼び出されます。しかし、コンソール(またはターミナル?とにかくxcode ..の底にある画面)は空の配列でしかないと言っています。私はprint("-----------------------")で上記のステートメントを受け入れました。

----------------------- 
ret: [] 
[] 
----------------------- 
2016-09-07 20:23:08.808 이모저모[36962:] <FIRAnalytics/INFO> Successfully created Firebase Analytics App Delegate Proxy automatically. To disable the proxy, set the flag FirebaseAppDelegateProxyEnabled to NO in the Info.plist 
2016-09-07 20:23:08.815 이모저모[36962:] <FIRAnalytics/INFO> Firebase Analytics enabled 

.observeEventType()方法でretは、メソッドのブロックのうち、その値をとらないように思えます。私の知る限りでは、データは保管されるはずです..誰も私にヒントを与えることができますか?メソッドのパラメータとしてコードブロックがどのように機能するかはまだ分かりません。 Thnx !!

+0

私は 'print =" ret:\(ret) ")を代入文' ret = s.value!の直下に書きました!として! [文字列] '。これは、私が投稿したコンソールメッセージが表示されてから数秒後に表示されました。 –

+2

すべてのfirebase操作は定義上非同期です。だからあなたのprintステートメントが呼び出された時点で、firebaseのデータはまだフェッチされていません。 –

+0

@AndréKoolAnswer –

答えて

3

すべてのfirebase操作は、非同期で定義されています。つまり、コード内の次の文に進む前に、プログラムがfirebaseからのデータを待つことはありません。だからあなたのprintステートメントが呼び出された時点で、firebaseのデータはまだフェッチされていません。

詳細については、this answerをご覧ください。

0

André(そしてVikrumの答えへのリンク)が実際に起こっている理由です。しかし、それはあなたのコードにいくつかのログステートメントを追加する場合に理解するために、通常は最も簡単です:

class func getPrim() -> [String]{ 
    let ref = FIRDatabase.database().reference() 

    print("Before observer"); 
    ref.child("bunya1").observeEventType(FIRDataEventType.Value, withBlock: { 
     s in 

     print("In observer block"); 

    }) 
    print("After observer"); 

    return "..." 
} 

あなたはこのコードを実行すると、ロギングがこの順になります。

オブザーバー

前にオブザーバのコールバックで観測

これはおそらく、表示されると思われる順序ではありません。しかし、それは間違いなくあなたのスニペットに空の配列を返す理由を説明します。ブロック内のコードがまだ実行されていない場合、項目はまだ配列に追加されていません。

この順序が逆になっている理由は、AndréとVikrumが言っているように、Firebaseの呼び出しが非同期で起こることです。 (特にデータベースに初めてアクセスする場合は)時間がかかることがあるため、Swiftコードは実行し続けてアプリが応答し続けるようにします。 Firebaseからデータが戻ってくるとブロックが呼び出されます(そのため、コールバックと呼ばれることもあります)、データを取得します。

+0

ありがとう!それで 'sleep()'メソッドなどを使って '.observeEventType()'の実行が終了するのを待つ必要がありますか? –

+0

あなたは「まずこれをやってからそれをやる」から離れて、「これが起これば、私はそれをやります」という考え方を採用するべきです。 Andreがその例としてリンクしているVikrumの答えを見てください。 –

関連する問題