我正在尝试从离线数据库中获取群聊离线消息。但是,当我尝试获取消息时,然后多次获取重复的消息。我不知道如何解决这个问题。请帮助我解决此问题。
我附上了XMPP实现的代码。...
这是我的XMPPController类,可以在其中使用服务器设置客户端。
class XMPPController: NSObject {
var xmppStream: XMPPStream
let hostName: String
let userJID: XMPPJID
let hostPort: UInt16
let password: String
var xmppStorage: XMPPMessageArchivingCoreDataStorage?
var messageArchiving: XMPPMessageArchiving?
init(hostName: String, userJIDString: String, hostPort: UInt16 = 5222, password: String) throws {
guard let userJID = XMPPJID(string: userJIDString) else {
throw XMPPControllerError.wrongUserJID
}
self.hostName = hostName
self.userJID = userJID
self.hostPort = hostPort
self.password = password
// Stream Configuration
self.xmppStream = XMPPStream()
self.xmppStream.hostName = hostName
self.xmppStream.hostPort = hostPort
self.xmppStream.startTLSPolicy = XMPPStreamStartTLSPolicy.allowed
self.xmppStream.myJID = userJID
super.init()
self.xmppStream.addDelegate(self, delegateQueue: DispatchQueue.main)
xmppStorage = XMPPMessageArchivingCoreDataStorage()
messageArchiving = XMPPMessageArchiving(messageArchivingStorage: xmppStorage)
messageArchiving?.clientSideMessageArchivingOnly = false
messageArchiving?.activate(xmppStream)
messageArchiving?.addDelegate(self, delegateQueue: DispatchQueue.main)
}
func connect() {
if !self.xmppStream.isDisconnected {
return
}
try! self.xmppStream.connect(withTimeout: XMPPStreamTimeoutNone)
}
}
extension XMPPController: XMPPStreamDelegate {
func xmppStreamDidConnect(_ stream: XMPPStream) {
print("Stream: Connected")
try! stream.authenticate(withPassword: self.password)
}
func xmppStreamDidAuthenticate(_ sender: XMPPStream) {
self.xmppStream.send(XMPPPresence())
print("Stream: Authenticated")
}
func xmppStream(_ sender: XMPPStream, didReceive message: XMPPMessage) {
print("Message XMPPController Called")
}
}
这是我的ViewController类实现。在这种情况下,我们可以创建和加入聊天室并分组发送消息。
class GroupMessagesViewController: UIViewController {
@IBOutlet weak var tableView: UITableView!
@IBOutlet weak var inputTextField: UITextField!
@IBOutlet weak var photosButton: UIPhotosButton!
var xmppController: XMPPController!
var messages = [Message]()
var xmppRoom: XMPPRoom!
var isXMPPRoomDidReceiveMsgCalled = false
override func viewDidLoad() {
super.viewDidLoad()
// Group Chat
self.createOrJoinRoom()
}
deinit {
xmppRoom.deactivate()
xmppRoom.removeDelegate(self)
xmppRoom = nil
}
func retrieveGroupMessagesFromOfflineDb() {
let fetchRequest = NSFetchRequest<XMPPMessageArchiving_Message_CoreDataObject>(entityName: "XMPPMessageArchiving_Message_CoreDataObject")
fetchRequest.returnsDistinctResults = true
// let predicate = NSPredicate(format: "bareJidStr == %@", "groupdemo@conference.chat.webolutionit.co.uk")
// fetchRequest.predicate = predicate
let predicate = NSPredicate(format: "messageStr CONTAINS[cd] %@ AND bareJidStr == %@", "groupchat", "groupdemo@conference.\(XMPPKeys.host)")
fetchRequest.predicate = predicate
let context = xmppController.xmppStorage?.mainThreadManagedObjectContext
do {
let messageHistoryArray = try context?.fetch(fetchRequest)
if messageHistoryArray?.count != 0 {
self.messages.removeAll()
messageHistoryArray?.forEach({ (msg) in
var message: Message!
if msg.body.contains(".jpg") {
message = Message(message: msg.body, from: msg.message.fromStr, to: msg.message.toStr, type: msg.message.type, contentType: .photo)
}
else {
message = Message(message: msg.body, from: msg.message.fromStr, to: msg.message.toStr, type: msg.message.type, contentType: .text)
}
self.messages.append(message)
})
isXMPPRoomDidReceiveMsgCalled = true
self.tableView.reloadData()
tableView.scrollToBottom()
}
}
catch {
isXMPPRoomDidReceiveMsgCalled = true
print(error.localizedDescription)
}
}
func createOrJoinRoom() {
let roomStorage = XMPPRoomMemoryStorage()
let roomId = XMPPJID(string: "groupdemo@conference.\(XMPPKeys.host)")
xmppRoom = XMPPRoom(roomStorage: roomStorage!, jid: roomId!, dispatchQueue: DispatchQueue.main)
let userId = XMPPJID(string: "testUser@chat.\(XMPPKeys.receiverJID)")
xmppRoom.inviteUser(userId!, withMessage: "Join Please")
xmppRoom.activate(xmppController.xmppStream)
xmppRoom.addDelegate(self, delegateQueue: DispatchQueue.main)
xmppRoom.join(usingNickname: XMPPKeys.senderJID, history: nil, password: nil)
}
// MARK:- IBACTIONS
@IBAction func backBtnPressed(_ sender: UIButton) {
_ = self.navigationController?.popViewController(animated: true)
}
@IBAction func sendBtnPressed(_ sender: UIButton) {
if let text = inputTextField.text {
if text != "" {
let message = XMLElement.element(withName: "message") as! XMLElement
message.addAttribute(withName: "from", stringValue: XMPPKeys.senderJID)
message.addAttribute(withName: "to", stringValue: "groupdemo@conference.\(XMPPKeys.host)")
message.addAttribute(withName: "type", stringValue: "groupchat")
message.addAttribute(withName: "id", stringValue: xmppController.xmppStream.generateUUID)
let uuid = UIDevice.current.identifierForVendor?.uuidString
message.addAttribute(withName: "uuid", stringValue: uuid.leoSafe())
let body = XMLElement.element(withName: "body") as! XMLElement
body.stringValue = text
message.addChild(body)
xmppController.xmppStream.send(message)
}
}
}
}
//MARK: UITableView Delegate & DataSource
extension GroupMessagesViewController: UITableViewDelegate, UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
print(messages.count)
return messages.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let message = messages[indexPath.row]
let currentUser = message.to.leoSafe().components(separatedBy: "/")[0]
if message.contentType == .text {
let cell = tableView.dequeueReusableCell(withIdentifier: XMPPKeys.senderJID.contains(currentUser) ? "MessageTableViewCell" : "UserMessageTableViewCell") as! MessageTableViewCell
cell.set(message)
return cell
}
let cell = tableView.dequeueReusableCell(withIdentifier: currentUser == XMPPKeys.senderJID ? "MessageAttachmentTableViewCell" : "UserMessageAttachmentTableViewCell") as! MessageAttachmentTableViewCell
cell.delegate = self
cell.set(message)
return cell
}
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
guard tableView.isDragging else { return }
cell.transform = CGAffineTransform(scaleX: 0.5, y: 0.5)
UIView.animate(withDuration: 0.3, animations: {
cell.transform = CGAffineTransform.identity
})
}
}
//MARK: UItextField Delegate
extension GroupMessagesViewController: UITextFieldDelegate {
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
return textField.resignFirstResponder()
}
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
return true
}
}
//MARK: MessageTableViewCellDelegate Delegate
extension GroupMessagesViewController: MessageTableViewCellDelegate {
func messageTableViewCellUpdate() {
tableView.beginUpdates()
tableView.endUpdates()
}
}
extension GroupMessagesViewController: XMPPRoomDelegate {
func xmppRoomDidJoin(_ sender: XMPPRoom) {
print("Room Joined")
sender.fetchConfigurationForm()
let a = xmppRoom.fetchMembersList()
self.retrieveGroupMessagesFromOfflineDb()
}
func xmppRoomDidCreate(_ sender: XMPPRoom) {
print("Room Created")
}
func xmppRoomDidLeave(_ sender: XMPPRoom) {
print("Room Leave")
}
func xmppRoomDidDestroy(_ sender: XMPPRoom) {
print("Room Destroyed")
}
func xmppRoom(_ sender: XMPPRoom, didReceive message: XMPPMessage, fromOccupant occupantJID: XMPPJID) {
print("Group Message Retrieved")
if isXMPPRoomDidReceiveMsgCalled {
if message.isGroupChatMessageWithBody {
var msg: Message!
if (message.body?.contains(".jpg"))! {
msg = Message(message: message.body, from: message.fromStr, to: message.toStr, type: message.type!, contentType: .photo)
}
else {
msg = Message(message: message.body, from: message.fromStr, to: message.toStr, type: message.type!, contentType: .text)
}
self.messages.append(msg)
self.tableView.reloadData()
self.tableView.scrollToBottom()
inputTextField.text = ""
}
}
}
func xmppRoom(_ sender: XMPPRoom, didFetchModeratorsList items: [Any]) {
print(items)
}
func xmppRoom(_ sender: XMPPRoom, didFetchMembersList items: [Any]) {
print(items)
}
}
// XMPPMUCDelegate METHODS
// ACCEPTING GROUP INVITATION
extension GroupMessagesViewController: XMPPMUCDelegate {
func xmppMUC(_ sender: XMPPMUC, roomJID: XMPPJID, didReceiveInvitation message: XMPPMessage) {
let x = message.element(forName: "x", xmlnsPrefix: XMPPMUCUserNamespace)
let invite = x?.elements(forName: "invite")
if !(invite?.isEmpty)! {
let conferenceRoomId = message.attribute(forName: "from")?.stringValue
self.joinMultiUserChat(roomName: conferenceRoomId.leoSafe())
}
}
func joinMultiUserChat(roomName: String) {
let roomJID = XMPPJID(string: roomName)
let xmppStorage = XMPPRoomMemoryStorage()
xmppRoom = XMPPRoom(roomStorage: xmppStorage!, jid: roomJID!, dispatchQueue: DispatchQueue.main)
xmppRoom.activate(xmppController.xmppStream)
xmppRoom.addDelegate(self, delegateQueue: DispatchQueue.main)
xmppRoom.join(usingNickname: xmppController!.xmppStream.myJID!.full, history: nil)
}
}