2017-10-24 3 views
0

iphoneのメッセージアプリケーションの最初の表示と同様に、送信した、または送信した最後のメッセージでユーザーのテーブルビューを作成しようとしています。私はこのコードを持っているが、それは私がユーザーに送信され、期待される結果を返すされたすべてのメッセージの中にスナップショットを保つ辞書の配列を反復処理するために動作しません:SwiftのsnapShot値を使用してTableViewCellを設定する

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell{ 
    let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! MyTableViewCell 

func getMsg()-> Int{ 
    var getIndex = Int() 
    let messageDb = Database.database().reference().child("iMessenger/Messages") 
    messageDb.observe(.childAdded) { (snapshot) in 

    if let snapshotvalue = snapshot.value as? [String:Any], let sender = snapshotvalue["sender"] as? String, let key = snapshotvalue["key"] as? String{ 

// I thought that I could iterate through my array of dictionaries taking care to find a matching sender value for the user at indexpath.row and the key for the message 

    for (index, dict) in newMessageDictArr.enumerated(){ 
    if self.users[indexPath.row].userPhone == sender && dict["key"] == key{getIndex = index}}}} 

    return getIndex} 


if newMessageDictArr.count != 0{ 
cell.userMessage.text = newMessageDictArr[getMsg()]["messageBody"]} 

return cell} 

私は問題をコードを持つことは

cell.userMessage.text = newMessageDictArr[getMsg()]["messageBody"] 

はすべて私の細胞が[「するmessagebody」]の最初の値を持っているので、それは私のユーザーは私に同じメッセージを送っているように見えたすべてのようなものだなることです。私が間違ったところを見つけようとしています...

私のFireBase構造もありがとうございます。

{ 
"iMessenger" : { 
"Messages" : { 
    "-KxDSQOBuCkpFdw4SPDh" : { 
     "messageBody" : "TEST ", 
     "receiver" : "+197862", 
     "sender" : "+16698" 
    }, 
    "-KxBjNM_iA2XaapyyC9o" : { 
    "key" : "-KxBjNM_iA2XaapyyC9o", 
    "messageBody" : "TEST", 
    "receiver" : "+197862", 
    "sender" : "+1914862" 
     }, 
"Messages+199862+197862" : { 
    "-KxB7P-vgdfxRpSdnwCT" : { 
    "messageBody" : "yo, wassup world", 
    "receiver" : "+197862", 
    "sender" : "+199862" 
    }, 
    "-KxB81fbn5_OHxdj4lcA" : { 
    "messageBody" : "Hello World", 
    "receiver" : "+19147862", 
    "sender" : "+1997862" 
    } 
}, 
"Users" : { 
    "-Kx41o03NIMBR68F2sCS" : { 
    "displayName" : "sleeping beauty ", 
    "firstName" : "", 
    "lastName" : "", 
    "phoneNumber" : "+165698" 
    }, 
    "-Kx42IXgN1z9D5Zoz0fk" : { 
    "displayName" : "KarmaDeli", 
    "firstName" : "", 
    "lastName" : "", 
    "phoneNumber" : "+1397862" 
    }}}} 
+0

このコードは正しく動作しません。奇妙なUIの問題を引き起こし、おそらく長期的には多くの作業になるでしょう。概念はノードにオブザーバーを添付し、アプリケーションがデータの追加、変更、または削除のイベントを受け取ったときに、それに応じてtableViewデータソース(通常は配列)を更新し、その配列からテーブルを読み込むtableViewをリロードします。あなたは、tableView:cellForRowAtメソッド内にオブザーバを追加したくない。質問には、送信または送信された最後のメッセージが挿入されることが記載されています。文字通り、あなたはtableViewに単一のメッセージがあることを意味しますか? – Jay

+0

ああ、Firebaseの構造をTEXTとして追加してください。画像はありませんので、適切に回答をまとめることができます。 Firebaseのコンソール - > JSONの書き出しでFirebase構造を取得できます。小さなスニペットを含めるだけで、あなたが何を照会しようとしているのかを理解することができます。 (テキストを含む!) – Jay

+0

okだから、tableviewのスナップショットを撮るのは悪い考えでした。私のtableViewは、現在2つのfireBaseの場所iMessenger/UsersとiMessenger/Messagesからデータを受け取ります。 1つのデータベースからのみテーブルビューを作成する方法を見つける必要がありますか?私が意味していたのは、携帯電話でアプリケーションを実行したときに、最初のmessageBody ["Hello world"]が表示されたことです。たとえば、いくつの新しいメッセージが送信されたとしても、そのテーブルのeverユーザーのcell.message.textにあります。 – KarmaDeli

答えて

0

の質問は少し不明であるが、私はそれに打撃与えてみましょう:

概念的には、のtableViewは、データの配列によって支えられています。そのデータが変更されると、配列を更新し、tableView.reloadDataを呼び出してtableViewの内容を更新する必要があります。一般に、その技術はユーザーにとって最もスムーズな体験を提供します。

IMOの場合、そのデザインパターンに従ってコードを書き直す必要があります。私はすべてのコードを書くつもりはありませんが、あなたにある方向性を与えるために、フローとコードスニペットを提供します。これらはテストされていないので、コピーアンドペーストはしないでください。

まず、そのデータを追跡するには、2つのアレイ2つのクラス

class MessageClass { 
    var msgId = "" 
    var msgBody = "" 
    var msgSenderUid = "" 
    var msgReceiverUid = "" 
} 

class UserClass { 
    var uid = "" 
    var name = "" 
    func init(aUid: String, aName: String) { 
     self.uid = aUid 
     self.name = aName 
    } 
} 

で始まる - まず、messagesArrayは、我々がしようとしているあなたのtableView

var messagesArray = [MessageClass]() 
var usersArray = [UsersClass]() 

のデータソースになりますアプリが数百のユーザーを持っていると仮定して、アプリの開始時にすべてのユーザーデータを読み込むだけです。新しいユーザーが追加された場合、usersArrayは自動的に追加のユーザー

func viewDidLoad() { 
    let ref = firebaseRef.child("users") 
    ref.observe(.childAdded..... { snapshot in 
     let userDict = snapshot.value as! [String: Any] 
     let uid = userDict.key 
     let name = userDict["name"] as! String 
     let userClass = User(aUid: uid, aName: name) 
     self.usersArray.append(userClass) 

で更新され、また、あなたのアプリが新しいメッセージが通知されますので、メッセージノードにオブザーバーを追加することに注意してください。このユーザーがメッセージのみが通知されますように、我々は

let queryRef = firebaseRef.child("messages") 
    queryRef.queryOrdered(byChild: "msg_receiver_uid").query(equalTo: thisUsersUid) { 
     let dict = snapshot.value as! [String: Any] 
     let sendersUid = dict["msgSenderUid"] as! String 
     let msgText = dict["msgBody"] as! String 
     //create a MessageClass object and populate it with data 
     //add it to the messagesArray 
     tableView.reloadData() 

は最終的に、あなたのtableView機能で、データソースmessagesArrayから各行を取得し、各セルを作成し、移入それらのために意味Firebaseクエリオブザーバを活用しようとしています。

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell{ 
    let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! MyTableViewCell 
    let msg = self.messagesArray[indexPath.row] 
    let msgSenderUid = msg.msgSenderUid 
    let sendersName = //some function to look up the senders name from the users array 
    let msg = msg.msgBody 
    //populate cell with users name and msg body 
    return cell 

ここでも、これはコピー/ペーストではなく、フローの例を示します。

新しいメッセージがポストされると、このユーザー用のメッセージがクエリオブザーバを介してメッセージに通知され、イベントでメッセージが表示されます。メッセージはメッセージクラスオブジェクトに埋め込まれ、データソース配列に追加され、テーブルビューが更新されて表示されます。

これは、すべてのユーザーを読み込みたくない場合に注意してください。その場合、メッセージイベントが発生したときに、ユーザーノードでobserveSingleEventを実行してユーザー情報を取得します。そのクロージャ内で、messageClassを構築し、配列に追加してtableViewをリロードします。

希望に役立ちます。

+0

ありがとうalot @jay – KarmaDeli

+0

あなたは間違いなく、テーブルビューの別注オブジェクトごとに、それらを含む配列が行く方法です。私は、Firebaseからスナップショットの辞書の値を取り除いている限り、私がデータで行うことができると思っているように思えます。私はテーブルビューと配列がPBやJのように一緒になっていることを理解しています。 queryOrderedIDを使用するのではなく、私はそれに慣れていないので、いくつかのブール値を使用して、ロジックは最初は高レベルで欠陥があり、バグが発生しました。今はすべて修正済みですが、もう一度ありがとうございます。 – KarmaDeli

関連する問題