2017-10-24 27 views
0

아이폰의 메시지 앱에 대한 초기보기처럼 보낸 사람 또는 보낸 사람의 마지막 메시지를 사용하여 내 사용자의 테이블 뷰를 채우려고합니다. 이 코드를 가지고 있지만 그것은 내가 사용자에게 전송하고 예상 된 결과 반환 된 모든 메시지에 스냅 샷을 유지 사전의 배열을 통해 반복 작동하지 않습니다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 콘솔 -> JSON 내보내기를 통해 Firebase 구조를 가져올 수 있습니다. 작은 스 니펫 만 포함하면 쿼리하려는 내용을 이해할 수 있습니다. (텍스트로 포함!) – Jay

+0

그래요, tableview에서 스냅 샷을 찍는 것은 나쁜 생각이었습니다. 내 tableView는 현재 2 개의 fireBase 위치에서 데이터를 가져옵니다. iMessenger/Users 및 iMessenger/Messages. 한 데이터베이스에서만 tableview를 채울 수있는 방법을 찾아야합니까? 나가 의미 한 무엇을 나가 나의 전화에 app를 달릴 때 얼마나 많은 새로운 메시지가 보내지는지 상관없이 그 tableVIew에 영원히 사용자를위한 cell.message.text에있는 첫번째 messageBody [ "Hello world"]를 본 때이었다. – KarmaDeli

답변

0

문제는 조금 불분명하지만 내가 그것을 샷주게 :

개념적으로있는 tableView는 데이터의 배열에 의해 뒷받침된다. 해당 데이터가 변경되면 배열을 업데이트해야하며 tableView.reloadData를 호출하여 tableView의 내용을 새로 고쳐야합니다. 일반적으로이 기술은 사용자에게 가장 매끄러운 환경을 제공합니다.

IMO의 경우 해당 디자인 패턴을 따르도록 코드를 다시 작성해야합니다. 나는 모든 코드를 작성하지는 않을 것이지만, 당신에게 어떤 방향을 제시 할 수있는 흐름과 몇 가지 코드 스 니펫을 제공 할 것이다. 이들은 테스트되지 않았으므로 복사하여 붙여 넣지 마십시오. 첫 번째, messagesArray, 당신의있는 tableView 우리는 갈거야

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

을위한 DataSource에있을 것입니다 -

먼저, 다음 데이터를 추적하는 두 배열은 두 개의 클래스

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 
    } 
} 

시작 앱에 수백 명의 사용자가 있다고 가정하면 앱 시작시 모든 사용자 데이터를로드합니다. 명심 새 사용자가 추가되면, 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 기능에, DataSource에 messagesArray에서 각 행을 얻을 작성하고 각 셀을 채 웁니다.

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

고맙습니다. @jay – KarmaDeli

+0

당신은 틀림없이 tableview 별주 개체마다 그것을 가지고있는 배열이 최선의 방법입니다. 필자는 Firebase에서 추출한 스냅 샷 사전 값을 가지고있는 한 데이터와 함께 할 수 있다고 생각하는 정도에 막혔습니다. 이제 테이블 뷰와 배열이 PB와 J. 같이 함께 간다는 것을 이해했습니다. queryOrderedID를 사용하는 대신 익숙하지 않기 때문에 메시지가 사용자에게 보내 졌는지 사용자에게 전달되었는지를 결정하기 위해 부울을 사용했습니다. 처음에는 논리가 결함이었고 버그가 발생했습니다. 이제 모든 것이 고쳐졌습니다. 다시 감사드립니다. – KarmaDeli