Ios XMPPFramework-从Openfire服务器检索归档邮件

Ios XMPPFramework-从Openfire服务器检索归档邮件,ios,xmpp,openfire,xmppframework,Ios,Xmpp,Openfire,Xmppframework,我正在使用XMPP和openfire server为iPhone开发一个聊天应用程序,openfire server正在存储用户之间的所有聊天历史记录,但当我尝试检索特定用户的聊天历史记录时,我只得到聊天信息的日期和数量,而不是实际的文本信息 我已经在openfire上安装了用于邮件存档的OpenArchive插件 这是我传递给Openfire Server的一节 <iq type='get' id='pk1'> <list xmlns='urn:xmpp:ar

我正在使用XMPP和openfire server为iPhone开发一个聊天应用程序,openfire server正在存储用户之间的所有聊天历史记录,但当我尝试检索特定用户的聊天历史记录时,我只得到聊天信息的日期和数量,而不是实际的文本信息

我已经在openfire上安装了用于邮件存档的OpenArchive插件

这是我传递给Openfire Server的一节

    <iq type='get' id='pk1'>
    <list xmlns='urn:xmpp:archive'
    with='piyush@openfire'>
    <set xmlns='http://jabber.org/protocol/rsm'>
    <max>30</max>
    </set>
    </list>
    </iq>

30
这是我从服务器收到的结果

  <iq type="result" id="pk1" to="vivek@openfire/iphone">
  <list xmlns="urn:xmpp:archive">
  <chat with="piyush@openfire" start="2012-07-04T13:16:12.291Z"/>
  <chat with="piyush@openfire" start="2012-07-05T08:25:31.555Z"/>
  <chat with="piyush@openfire" start="2012-07-05T12:38:24.098Z"/>
  <set xmlns="http://jabber.org/protocol/rsm">
  <first index="0">15</first>
  <last>25</last>
  <count>3</count>
  </set>
  </list>
  </iq>

15
25
3.
这是我想要的结果,也是我期望的结果

 <iq type='result' to='vivek@openfire/iphone' id='page1'>
 <chat xmlns='urn:xmpp:archive'
    with='piyush@openfire'
    start='2012-07-04T13:16:12.291Z'
    subject='She speaks!'
    version='4'>
<from secs='0'><body>Art thou not Romeo, and a Montague?</body></from>
<to secs='11'><body>Neither, fair saint, if either thee dislike.</body></to>
.
[98 more messages]
.
<from secs='9'><body>How cam'st thou hither, tell me, and wherefore?</body></from>
<set xmlns='http://jabber.org/protocol/rsm'>
  <first index='0'>0</first>
  <last>99</last>
  <count>217</count>
</set>

你不是罗密欧和蒙太古吗?
都不是,美丽的圣徒,如果你不喜欢的话。
.
[98更多信息]
.
你怎么会到这里来,告诉我,为什么?
0
99
217

请帮我得到想要的结果


谢谢您必须使用
执行请求(请参阅),然后您可以从收到的
结果中提取特定时间。例如:

发送:

    <iq type='get' id='pk1'>
       <list xmlns='urn:xmpp:archive'
               with='piyush@openfire'>
        <set xmlns='http://jabber.org/protocol/rsm'>
            <max>30</max>
        </set>
      </list>
   </iq>
您将收到如下内容(取决于最大值->最大值=30,实体=30):


你不是罗密欧和蒙太古吗?
都不是,美丽的圣徒,如果你不喜欢的话。
.
[28更多信息]
.
告诉我,你是怎么来到这里的?
0
29
检索聊天的具体时间 发送它以获取时间:

 NSXMLElement *iq1 = [NSXMLElement elementWithName:@"iq"];
 [iq1 addAttributeWithName:@"type" stringValue:@"get"];
 [iq1 addAttributeWithName:@"id" stringValue:@"pk1"];
 NSXMLElement *retrieve = [NSXMLElement elementWithName:@"list" xmlns:@"urn:xmpp:archive"];
 [retrieve addAttributeWithName:@"with" stringValue:@"amit@openfire"];
 NSXMLElement *set = [NSXMLElement elementWithName:@"set" xmlns:@"http://jabber.org/protocol/rsm"];
 NSXMLElement *max = [NSXMLElement elementWithName:@"max" stringValue:@"100"];
 [iq1 addChild:retrieve];
 [retrieve addChild:set];


 [set addChild:max];


 [xmppStream sendElement:iq1];
检索聊天历史记录的步骤 使用开始日期并发送:

 NSXMLElement *iq1 = [NSXMLElement elementWithName:@"iq"];
 [iq1 addAttributeWithName:@"type" stringValue:@"get"];
 [iq1 addAttributeWithName:@"id" stringValue:@"pk1"];

 NSXMLElement *retrieve = [NSXMLElement elementWithName:@"retrieve" xmlns:@"urn:xmpp:archive"];
 [retrieve addAttributeWithName:@"with" stringValue:@"amit@openfire"];
 [retrieve addAttributeWithName:@"start" stringValue:@"2013-11-18T05:11:53.460Z"];
 NSXMLElement *set = [NSXMLElement elementWithName:@"set" xmlns:@"http://jabber.org/protocol/rsm"];
 NSXMLElement *max = [NSXMLElement elementWithName:@"max" stringValue:@"100"];
 [iq1 addChild:retrieve];
 [retrieve addChild:set];
 [set addChild:max];
 [xmppStream sendElement:iq1];

首先,要从openfire检索聊天历史记录,您需要安装OpenArchive插件,因为监视插件仅用于在管理面板上监视和记录聊天历史记录,所以一旦安装OpenArchive,您将不会收到代码为“500”的任何错误

您可以从以下链接下载并学习安装Open Archive

上面代码中的另一个问题是,当您在请求中提到start标记时,它与具有确切时间戳的聊天匹配,这就是它返回错误代码“404”的原因。我从我的请求中输入了开始标记,并编写了以下代码,返回与用户的整个聊天历史记录

NSXMLElement *iq1 = [NSXMLElement elementWithName:@"iq"];
[iq1 addAttributeWithName:@"type" stringValue:@"get"];
[iq1 addAttributeWithName:@"id" stringValue:@"pk1"];

NSXMLElement *retrieve = [NSXMLElement elementWithName:@"retrieve" xmlns:@"urn:xmpp:archive"];

[retrieve addAttributeWithName:@"with" stringValue:@"rahul@vishals-mac-pro.local"];
NSXMLElement *set = [NSXMLElement elementWithName:@"set" xmlns:@"http://jabber.org/protocol/rsm"];
NSXMLElement *max = [NSXMLElement elementWithName:@"max" stringValue:@"100"];

[iq1 addChild:retrieve];
[retrieve addChild:set];
[set addChild:max];
[[[self appDelegate] xmppStream] sendElement:iq1]; 
在这里,它将以XML响应的形式返回用户Rahul和当前登录的用户之间的整个聊天历史记录


有关更多详细信息,请参阅本博客

从openfire server获取存档邮件的Swift版本 请求:

答复:

func xmppStream(sender: XMPPStream!, didReceiveIQ iq: XMPPIQ!) -> Bool {
        let chat = iq.elementForName("chat")
        let chats = (chat as DDXMLElement).children()
        for chat in chats{
            let msg = chat
            let body = (msg as! DDXMLElement).elementForName("body")
            if body != nil{
                if body.stringValue() != nil{
                    //print(body.stringValue()!)
                    chatMessages.append(body.stringValue()!)
                    if msg.attributeForName("jid") == nil{
                        type.append("Send")
                    }
                    else{
                        type.append("Receive")
                    }
                }
            }
        }
        print("Did receive IQ")
        return false
    }

*with是您要获取其存档邮件的人的jid,是在Swift 4中获取存档邮件的示例

声明并初始化变量XMPPMessageArchivingCoreDataStorage,我在其中初始化XMPPStream

var xmppMessageStorage: XMPPMessageArchivingCoreDataStorage?
var xmppMessageArchiving: XMPPMessageArchiving?

xmppMessageStorage = XMPPMessageArchivingCoreDataStorage.sharedInstance()
    xmppMessageArchiving = XMPPMessageArchiving(messageArchivingStorage: xmppMessageStorage)

    xmppMessageArchiving?.clientSideMessageArchivingOnly = true
    xmppMessageArchiving?.activate(stream)
    xmppMessageArchiving?.addDelegate(self, delegateQueue: DispatchQueue.main)
这样做,无论消息何时到达,都将导致它被归档,而无需执行任何其他操作

然后,检索已存档的邮件

func RecibedMessageArchiving(idFriend: String) {

        let JabberIDFriend = idFriend   //id friend chat, example test1@example.com


        let moc = xmppMessageStorage?.mainThreadManagedObjectContext
        let entityDescription = NSEntityDescription.entity(forEntityName: "XMPPMessageArchiving_Message_CoreDataObject", in: moc!)
        let request = NSFetchRequest<NSFetchRequestResult>()
        let predicateFormat = "bareJidStr like %@ "
        let predicate = NSPredicate(format: predicateFormat, JabberIDFriend)

        request.predicate = predicate
        request.entity = entityDescription

        //jabberID id del usuario, cliente
        var jabberIDCliente = ""
        if let jabberj = globalChat.value(forKey: "jabberID"){
            jabberIDCliente = jabberj as! String
        }


        do {
            let results = try moc?.fetch(request)

            for message: XMPPMessageArchiving_Message_CoreDataObject? in results as? [XMPPMessageArchiving_Message_CoreDataObject?] ?? [] {

                var element: DDXMLElement!
                do {
                    element = try DDXMLElement(xmlString: (message as AnyObject).messageStr)
                } catch _ {
                    element = nil
                }

                let body: String
                let sender: String
                let date: NSDate
                let isIncomings: Bool
func RecibedMessageArchiving(idFriend:String){
例如,让JabberIDFriend=idFriend//id朋友聊天test1@example.com
让moc=xmppMessageStorage?.mainThreadManagedObjectContext
让entityDescription=NSEntityDescription.entity(forEntityName:“XMPPMessageArchiving\u Message\u CoreDataObject”,in:moc!)
let request=NSFetchRequest()
让predicateFormat=“bareJidStr like%@”
let predicate=NSPredicate(格式:predicateFormat,JabberIDFriend)
request.predicate=谓词
request.entity=entityDescription
//乌萨里奥先生,客户
var jabberidclient=“”
如果让jabberj=globalChat.value(forKey:“jabberID”){
jabberidclient=jabberj as!String
}
做{
let results=尝试moc?.fetch(请求)
对于消息:XMPPMessageArchiving\u message\u CoreDataObject?结果为[XMPPMessageArchiving\u message\u CoreDataObject?]??[]{
var元素:ddxmlement!
做{
element=尝试ddxmlement(xmlString:(消息作为AnyObject.messageStr)
}接住{
元素=零
}
正文:字符串
让发送者:字符串
出租日期:NSDate
让我告诉你:布尔

我认为这与其说是iOS问题,不如说是OpenFire API问题。嘿,皮尤斯,我也在努力实现同样的目标。但是(请原谅我的无知)我不知道如何将这一节发送到openfire服务器。有api调用吗?你介意详细说明一下吗bit@PiyushKashyap您是如何启用聊天历史记录的,因为我已经安装了
监控
插件,但是当我在上面的节中启动时,它返回的功能没有实现。请看一看:希望它会有帮助。@KeithOYS,兄弟,你能帮我解决这个问题吗?@Amit Gupta是的,我也被困在这里。请告诉我这里的pk1是什么?如果我执行上述代码,那么xmppstream委托方法即didReceiveMessage将调用,但我没有得到任何结果,我使用的是open fire,所以我可以在我的服务器上进行任何操作,请帮助我。我收到错误500,功能未实现错误,怎么办??Pk1是自定义id名称。你可以使用任何你想要的id名称。没有问题。我发现错误503服务不可用。我正在使用OpenFire。你能告诉我原因吗。有关详细信息,请检查:这是用户id(JabberID)不,pk1这里是发送iq节的唯一id。如果您使用某种xmpp客户端api,您可以忽略它,因为该api(如果支持)将处理id的设置。我们可以在xmpp服务器端存储聊天历史记录吗?它支持MUC(即)将MUC存档吗messages@DRMA,你能帮我解决这个问题吗?
func getArchieveMessages(){
        let iQ = DDXMLElement.elementWithName("iq")
        iQ.addAttributeWithName("type", stringValue: "get")
        iQ.addAttributeWithName("id", stringValue: "page1")
        let list = DDXMLElement.elementWithName("retrieve")
        list.addAttributeWithName("xmlns", stringValue: "urn:xmpp:archive")
        list.addAttributeWithName("with", stringValue: "partner@domain")
        let set = DDXMLElement.elementWithName("set")
        set.addAttributeWithName("xmlns", stringValue: "http://jabber.org/protocol/rsm")
        let max = DDXMLElement.elementWithName("max")
        max.addAttributeWithName("xmlns", stringValue: "http://jabber.org/protocol/rsm")
        //(max as! DDXMLElement).setStringValue("30")
        (set as! DDXMLElement).addChild(max as! DDXMLNode)
        list.addChild(set as! DDXMLNode)
        iQ.addChild(list as! DDXMLNode)
        xmppStream.sendElement(iQ as! DDXMLElement)
    }
func xmppStream(sender: XMPPStream!, didReceiveIQ iq: XMPPIQ!) -> Bool {
        let chat = iq.elementForName("chat")
        let chats = (chat as DDXMLElement).children()
        for chat in chats{
            let msg = chat
            let body = (msg as! DDXMLElement).elementForName("body")
            if body != nil{
                if body.stringValue() != nil{
                    //print(body.stringValue()!)
                    chatMessages.append(body.stringValue()!)
                    if msg.attributeForName("jid") == nil{
                        type.append("Send")
                    }
                    else{
                        type.append("Receive")
                    }
                }
            }
        }
        print("Did receive IQ")
        return false
    }
var xmppMessageStorage: XMPPMessageArchivingCoreDataStorage?
var xmppMessageArchiving: XMPPMessageArchiving?

xmppMessageStorage = XMPPMessageArchivingCoreDataStorage.sharedInstance()
    xmppMessageArchiving = XMPPMessageArchiving(messageArchivingStorage: xmppMessageStorage)

    xmppMessageArchiving?.clientSideMessageArchivingOnly = true
    xmppMessageArchiving?.activate(stream)
    xmppMessageArchiving?.addDelegate(self, delegateQueue: DispatchQueue.main)
func RecibedMessageArchiving(idFriend: String) {

        let JabberIDFriend = idFriend   //id friend chat, example test1@example.com


        let moc = xmppMessageStorage?.mainThreadManagedObjectContext
        let entityDescription = NSEntityDescription.entity(forEntityName: "XMPPMessageArchiving_Message_CoreDataObject", in: moc!)
        let request = NSFetchRequest<NSFetchRequestResult>()
        let predicateFormat = "bareJidStr like %@ "
        let predicate = NSPredicate(format: predicateFormat, JabberIDFriend)

        request.predicate = predicate
        request.entity = entityDescription

        //jabberID id del usuario, cliente
        var jabberIDCliente = ""
        if let jabberj = globalChat.value(forKey: "jabberID"){
            jabberIDCliente = jabberj as! String
        }


        do {
            let results = try moc?.fetch(request)

            for message: XMPPMessageArchiving_Message_CoreDataObject? in results as? [XMPPMessageArchiving_Message_CoreDataObject?] ?? [] {

                var element: DDXMLElement!
                do {
                    element = try DDXMLElement(xmlString: (message as AnyObject).messageStr)
                } catch _ {
                    element = nil
                }

                let body: String
                let sender: String
                let date: NSDate
                let isIncomings: Bool