2017-06-13 33 views
0

私は、テーブルビューの各セクションが部屋であり、すべての行が各部屋の家具である、TableViewControllerでSwift Firebaseアプリケーションを作成しています。ジョイント値の変更時にFirebaseデータが更新されない

問題が発生しました:最初にすべてが正常に動作し、いずれかの部屋がバックエンドから変更または削除されると、テーブルビューの更新はうまくいきます。しかし、家具の値が更新されたときにデータをリロードするのに問題があります。私はこのコードを変更する方法がわからない。データの構造が正しくないと思っていますか?この問題を解決するにはどうすればよいですか?

Firebaseデータベースの構造は、この(私はちょうどので、実際の構造は、複数の値を有し、簡単にするために構造からいくつかのキー/値を削除)である:私はデータをロードするために使用するコード

rooms: 
{ 
    "room 1": { 
     "name": "Bedroom", 
     "somedata": 1 
    }, 
    "room 2": { 
     "name": "Living room", 
     "somedata": 2 
    } 
} 

furniture: 
{ 
    "room 1": { 
     "furniture 2": { 
      "name": "Chair" 
     }, 
     "furniture 3": { 
      "name": "Sofa" 
     } 
    }, 
    "room 2": { 
     "furniture 1": { 
      "name": "Table" 
     } 
    } 
} 

TableViewControllerは次のとおりです。

override func viewWillAppear(_ animated: Bool) { 
    super.viewWillAppear(animated) 

    DataManager.shared.getRooms(completion: { (rooms) in 
     self.rooms = rooms 
     self.tableView.reloadData() 
    }) 
} 

データマネージャー:

func getRooms(completion:@escaping ([Room])->Void) { 
    FIRDatabase.database().reference(withPath: "rooms").observe(.value, with: { snapshot in 
     var rooms: [Room] = [] 
     var counter: UInt = 0 
     for roomItem in snapshot.children { 
      let room = Room(snapshot: roomItem as! FIRDataSnapshot) 
      FIRDatabase.database().reference(withPath: "furniture/\(room.key)").observe(.value, with: { snap in 
       for furnitureItem in snap.children { 
        let furniture = Furniture(snapshot: furnitureItem as! FIRDataSnapshot) 
        room.furnitureList.append(furniture) 
       } 

       counter = counter + 1 
       if (counter == snapshot.childrenCount) { 
        completion(rooms) 
       } 
      }) 

      rooms.append(room) 
     } 
    }) 
} 

感謝助けるために!

+0

ここでそれを突破しようとしているかもしれませんが、完了呼び出しをディスパッチ非同期で折り返して試してみてください。 – TNguyen

+0

私はそれが必要ではないと思いますか?以下のコメントを参照してください – Martin

+0

うーん、それだけを見ることができて問題を指摘するのは難しいです。家具を変えた後にコールバックが呼び出されているかどうかを確認するために二重チェックを試みることはできますか? – TNguyen

答えて

0

あなたはそうのようなself.tableView.reloadData()を呼び出していないする必要があります、また

DispatchQueue.main.async { 
    self.tableView.reloadData() 
} 

viewDidAppearで関数を呼び出す必要が。 viewDidLoadに電話してください。

+0

ありがとう!私の理解から、少なくともこの記事によれば、これはメインスレッドで既に起こっているので、DispatchQueueを使う必要はありません:https://stackoverflow.com/questions/39178165/firebase-asynchronous-function-whats-in- the-background-queue-and-whats-not – Martin

+0

私はviewWillAppearに入れました。このブログ投稿がhttps://firebase.googleblog.com/2015/10/best-practices-for-ios-uiviewcontroller_6.htmlの場合は"viewDisLoadではなく、viewWillAppearでリスナーを作成する"。それは正しいのではないですか? – Martin

+0

観察する場所について:https://stackoverflow.com/questions/37895171/new-firebase-retrieve-data-and-put-on-the-tableview-swift –

関連する問題