使用XMPPFramework在iOS中存储消息?

28

我不确定如何使用XMPPFramework的核心数据来存储收到的消息。有没有关于如何做这个的教程?我看到了User对象,可以有许多“资源”。每个接收到的消息都应该是我创建和持久化的一个新资源吗?

我不知道消息历史记录的哪部分是我的责任,哪部分是框架提供的。我可以拦截每个传入的消息。那么我是否应该使用核心数据在一个Messages表内创建和存储每个消息?我会有一个Message实体。然后每个XMPP用户都会有一个Message对象的数组。但那样我不就是在自己开发一个解决方案,这违反了该框架的原则吗?

谢谢!


3
如果你确认一个回答对你有帮助,那么应该接受它。 - Mark Molina
1
以下任何一种解决方案对您有用吗? - Rohit Mandiwal
4个回答

52

我知道这是一个旧的帖子,但是由于我目前正在iOS上使用XMPP,所以必须说XMPP内置了消息存档支持。

我下载了iOS的XMPP框架,在其中有一个标记为XEP-0136的文件夹。在XCode中导入文件夹,并通过在实例化XMPP客户端的类中使用以下代码来激活客户端侧的归档功能:

xmppMessageArchivingStorage = [XMPPMessageArchivingCoreDataStorage sharedInstance];
xmppMessageArchivingModule = [[XMPPMessageArchiving alloc] initWithMessageArchivingStorage:xmppMessageArchivingStorage];

下面这行代码可以帮助你避免向XMPP服务器发送特定于存档的部分,因为服务器很可能会回复“service-not-implemented”。

[xmppMessageArchivingModule setClientSideMessageArchivingOnly:YES];

[xmppMessageArchivingModule activate:xmppStream];
[xmppMessageArchivingModule  addDelegate:self delegateQueue:dispatch_get_main_queue()];

完成了。从那一刻起,消息(发送和接收)将被存储在框架创建的表中。

如果您需要更多信息,请评论,我会回复您。

@PraviJay

我是这样做的:

-(void)testMessageArchiving{
            XMPPMessageArchivingCoreDataStorage *storage = [XMPPMessageArchivingCoreDataStorage sharedInstance];
            NSManagedObjectContext *moc = [storage mainThreadManagedObjectContext];
            NSEntityDescription *entityDescription = [NSEntityDescription entityForName:@"XMPPMessageArchiving_Message_CoreDataObject"
                                                                 inManagedObjectContext:moc];
            NSFetchRequest *request = [[NSFetchRequest alloc]init];
            [request setEntity:entityDescription];
            NSError *error;
            NSArray *messages = [moc executeFetchRequest:request error:&error];

            [self print:[[NSMutableArray alloc]initWithArray:messages]];
}

-(void)print:(NSMutableArray*)messages{
         @autoreleasepool {
            for (XMPPMessageArchiving_Message_CoreDataObject *message in messages) {
                NSLog(@"messageStr param is %@",message.messageStr);
                NSXMLElement *element = [[NSXMLElement alloc] initWithXMLString:message.messageStr error:nil];
                NSLog(@"to param is %@",[element attributeStringValueForName:@"to"]);
                NSLog(@"NSCore object id param is %@",message.objectID);
                NSLog(@"bareJid param is %@",message.bareJid);
                NSLog(@"bareJidStr param is %@",message.bareJidStr);
                NSLog(@"body param is %@",message.body);
                NSLog(@"timestamp param is %@",message.timestamp);
                NSLog(@"outgoing param is %d",[message.outgoing intValue]);
            }
        }
}

希望这有所帮助 :)


1
如何从xmppMessageArchivingModule获取消息历史记录。 - Prabhjot Singh Gogana
1
@PraviJay 如果你有任何问题,请告诉我,也许我也遇到过类似的问题。 - Simon
1
谢谢,伙计。我卡在这一行代码上了:NSArray *messages = [moc executeFetchRequest:request error:&error]; 但你做得很好,真是救星啊,谢谢你! - Prabhjot Singh Gogana
2
这是一段很棒的代码片段。我在下面发布了一个直接加载到表视图中的代码片段。 - deepwinter
2
@Smita 刚完成。前往 XMPPMessageArchiving_Message_CoreDataObject 并选择您要筛选结果的变量。在我的情况下,因为我有多个连接,所以我接收到的每条消息的“to”字段都不同,因此我添加了一个“to”属性。基于此,我添加了以下内容:NSString *predicateFrmt = @"to ==%@"; NSPredicate *predicate = [NSPredicate predicateWithFormat:predicateFrmt,@“aBareJid”]; request.predicate = predicate; 希望有帮助。 - Simon
显示剩余36条评论

10

表明XMPP框架不保存历史记录的回复是不正确的。

要将结果集成到表格视图中,请使用:

XMPPMessageArchivingCoreDataStorage *storage = [XMPPMessageArchivingCoreDataStorage sharedInstance];
NSManagedObjectContext *moc = [storage mainThreadManagedObjectContext];
NSEntityDescription *entityDescription = [NSEntityDescription entityForName:@"XMPPMessageArchiving_Contact_CoreDataObject"
                                                     inManagedObjectContext:moc];
NSFetchRequest *request = [[NSFetchRequest alloc]init];
[request setEntity:entityDescription];

_contactsController = [[NSFetchedResultsController alloc] initWithFetchRequest:request managedObjectContext:moc sectionNameKeyPath:nil cacheName:@"MessagesContactListCache"];

NSError *error;
BOOL rval = [_contactsController performFetch:&error];

你好,如何获取聊天记录?这段代码应该放在哪里? - ramesh bhuja

0

一个在 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
                if message?.body != nil {
                    body = (message?.body)!
                } else {
                    body = ""
                }



                if element.attributeStringValue(forName: "to") == JabberIDFriend {
                    sender = jabberIDCliente
                    isIncomings = false

                } else {
                    sender = "test2@example.com"
                    isIncomings = true

                }


                    var m: [AnyHashable : Any] = [:]
                    m["msg"] = message?.body

                    print("body", message?.body)

                    print("test", element.attributeStringValue(forName: "to"))
                    print("test2", element.attributeStringValue(forName: "body"))


            }
        } catch _ {
            //catch fetch error here
        }

    }

-4

XMPPFramework不会存储消息记录,我建议您最好使用Core Data。创建一个表格,将发送者、接收者、消息和时间作为列。在调用“发送消息”和“接收消息”方法时插入记录...

-(void)saveChatHistory:(NSString *)sender:(NSString*)receiver:(NSString*)message:(NSString*)time
{
    NSManagedObjectContext *context=[[self appDelegate] managedObjectContext];
    NSManagedObject *newContext=[NSEntityDescription insertNewObjectForEntityForName:@"ChatHistory" inManagedObjectContext:context];
    [newContext setValue:sender forKey:@"sender"];
    [newContext setValue:receiver forKey:@"receiver"];
    [newContext setValue:message forKey:@"message"];
    [newContext setValue:time forKey:@"time"];
    NSError *error;
    if(![context save:&error])
    {
        UIAlertView *alertView=[[UIAlertView alloc] initWithTitle:@"Error Occured" message:@"Data is not Stored in Database Try Again" delegate:self cancelButtonTitle:@"ok" otherButtonTitles:nil];
        [alertView show];

    }

}

从表视图中选择特定用户时检索聊天记录...以下方法显示如何检索聊天记录...并从didSelectRowAtIndexPath方法调用此方法,并将目标ID作为参数传递

-(void)getChatHistory:(NSString*)jidString1
{


    NSManagedObjectContext *context=[[self appDelegate] managedObjectContext];
    NSEntityDescription *entity=[NSEntityDescription entityForName:@"ChatHistory" inManagedObjectContext:context];
    NSFetchRequest *req=[[NSFetchRequest alloc] init];

    NSPredicate *predicate=[NSPredicate predicateWithFormat:@"receiver=%@",jidString1];
    [req setEntity:entity];
    [req setPredicate:predicate];
    NSManagedObject *matchRecords=nil;
    NSError *error;
    NSArray *objects=[context executeFetchRequest:req error:&error];

    if([objects count]==0)
    {
        UIAlertView *alertView=[[UIAlertView alloc] initWithTitle:@"No Record found" message:@"there is no previous chat history" delegate:self cancelButtonTitle:@"ok" otherButtonTitles:nil];
        [alertView show];
    }
    else 
    {
        for(int i=0;i<[objects count];i++)
        {
         matchRecords=[objects objectAtIndex:i ];
         NSLog(@"sender is %@",[matchRecords valueForKey:@"sender"]);
         NSLog(@"reciver is %@",[matchRecords valueForKey:@"receiver"]);
         NSLog(@"messages is %@",[matchRecords valueForKey:@"message"]);
         NSLog(@"time is %@",[matchRecords valueForKey:@"time"]);
       }
     }


}

我希望这对你有用


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接