Reputation: 86
I have used XMPPFramework, since the user authentication and receiving only messages is done using XMPP. I am sending messages using RestApi. I have parsed the received xml message using SwiftyXMLParser library and now I have to store 'senderName', 'messageBody', 'time', 'senderNumber' in Realm database.
Initially the tableView in ContactsViewController is empty. When user sends the message, It will first get stored in database and then I have to show the sender's Number/Name and messageBody in the tableViewCell. If same user sends the message just update the messageBody text. If different user sends the message, check if user exists in db, if not, add the user in the tableView and so on... check user for every message and likewise populate the tableView.
Here is what I have done so far:
class ContactsViewController: UIViewController, UITableViewDelegate, UITableViewDataSource{
var messagesArray:[String] = [String]()
var messageBody : [String] = [String]()
var realm : Realm!
var userInfo = MessageData()
// viewDidLoad() // assign tableView delegate, datasource and register the Nib.
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return messagesArray.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = contactsTableView.dequeueReusableCell(withIdentifier: "contactscell", for: indexPath) as! ContactsListCell
cell.userNameLabel.text = messagesArray[indexPath.row]
cell.userImageView.image = UIImage(named: "default-user")
cell.messageBodyLabel.text = messageBody[indexPath.row]
return cell
}
} // end of class
extension ContactsViewController: XMPPStreamDelegate {
func xmppStream(_ sender: XMPPStream, didReceive message: XMPPMessage) {
let string = message.prettyXMLString()
let xml = try! XML.parse(string!)
let messageSenderNo = xml["message"]["data”][“phoneNumber”].text
let senderName = xml["message"]["data”][“name”].text
let messageText = xml["message"]["data”][“text”].text
let messageTime = xml["message"]["data"]["time"].text
userInfo.messageFrom = messageSenderNo
userInfo.messageBody = messageText
userInfo.senderName = senderName
realm = try! Realm()
try! realm.write {
realm.add(userInfo, update: true)
}
let senderOfMsg:[String] = realm.objects(MessageData.self).value(forKey: "messageFrom") as! [String]!
let textMessage:[String] = realm.objects(MessageData.self).value(forKey: "messageBody") as! [String]!
messagesArray = senderOfMsg
messageBody = textMessage
}
}
This is my Message Class:
class MessageData: Object{
dynamic var messageFrom:String = ""
dynamic var messageBody:String = ""
dynamic var messageTime:String = ""
dynamic var messageSenderName:String = ""
override static func primaryKey() -> String? {
return "messageFrom"
}
convenience init(messageFrom: String, messageBody: String, messageSenderFirstName: String, messageSenderLastName: String, message_id: String, messageTime: String){
self.init()
self.messageFrom = messageFrom
self.messageBody = messageBody
self.messageTime = messageTime
self.messageSenderName = messageSenderName
}
}
I am using Realm for first time, so I don't know If I have done some fatal mistake. If at all the data gets saved in the realm database. For the first time tableView should be blank , but after there is data in the database, the tableView must show the contacts and messageBody. It should show previous messages if any, just like WhatsApp when user launches the app again. The data in the tableView should persist. Please tell me what I am doing wrong or have not done. Thank you for your time.
Upvotes: 0
Views: 278
Reputation: 1787
In short, you need to call UITableView
's reloadData()
method (or one of the methods to insert, remove, or delete rows; see the "Inserting, Deleting, and Moving Rows and Sections" section), whenever you change the backing data. In this case that means when you set new values for messagesArray
and messagesBody
in your xmppStream()
method, you need to call reloadData()
or a similar method in order to tell the table view that its data source has been updated and that it needs to show new data.
More specifically: messagesArray
and messagesBody
aren't even necessary. Just use your Realm as a backing store. You can write your messages to a List
inside your Realm, and then your tableView(_:, cellForRowAt:)
method can directly call your model objects and load data out of them. You can then register a collection notifier on that List
so that whenever it changes, your application is automatically notified. Code inside your notifier can then reload the table view.
Upvotes: 1