【问题标题】:Storing received XMPP message in a NSMutableDictionary将收到的 XMPP 消息存储在 NSMutableDictionary 中
【发布时间】:2013-06-21 20:16:50
【问题描述】:

我正在使用 Robbie Hanson 的 XMPP 框架为 iOS 设计一个聊天应用程序:https://github.com/robbiehanson/XMPPFramework

我可以使用以下代码将我发送的消息存储到一个字典中,该字典是我的 tableview 的数据源:

- (IBAction)sendMessage {

    NSString *messageStr = messageField.text;
    if([messageStr length] > 0) {
        NSXMLElement *body = [NSXMLElement elementWithName:@"body"];
        [body setStringValue:messageStr];
        NSXMLElement *message = [NSXMLElement elementWithName:@"message"];
        [message addAttributeWithName:@"type" stringValue:@"chat"];
        [message addAttributeWithName:@"to" stringValue:chatWithUser];
        [message addChild:body];
        [[[self appDelegate] xmppStream] sendElement:message];

        NSMutableDictionary *m = [[NSMutableDictionary alloc] init];
        [m setObject:messageStr forKey:@"msg"];
        [m setObject:@"you" forKey:@"sender"];
        [messages addObject:m];
        [self.tView reloadData];
    }
}

但是 didReceiveMessage 是在 AppDelegate 中定义的,我无法将接收到的消息存储在本地字典中,因此无法在 TableView 中显示。我的 didReceiveMessage 函数如下所示:

- (void)xmppStream:(XMPPStream *)sender didReceiveMessage:(XMPPMessage *)message
{
    DDLogVerbose(@"%@: %@", THIS_FILE, THIS_METHOD);

    // A simple example of inbound message handling.

    if ([message isChatMessageWithBody])
    {
        XMPPUserCoreDataStorageObject *user = [xmppRosterStorage userForJID:[message from]
                                                                 xmppStream:xmppStream
                                                       managedObjectContext:[self managedObjectContext_roster]];

        NSString *messageBody = [[message elementForName:@"body"] stringValue];
        NSString *displayName = [user jidStr];

        if ([[UIApplication sharedApplication] applicationState] == UIApplicationStateActive)
        {

            UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:displayName
                                                              message:messageBody
                                                             delegate:nil 
                                                    cancelButtonTitle:@"Ok" 
                                                    otherButtonTitles:nil];
            [alertView show];

        }
        else
        {
            // We are not active, so use a local notification instead
            UILocalNotification *localNotification = [[UILocalNotification alloc] init];
            localNotification.alertAction = @"Ok";
            localNotification.alertBody = [NSString stringWithFormat:@"From: %@\n\n%@",displayName,messageBody];

            [[UIApplication sharedApplication] presentLocalNotificationNow:localNotification];
        }
    }
}

如何将消息存储到 ChatViewController.m 中定义了 sendMessage 的消息字典中?

【问题讨论】:

  • 保留对字典所在对象的引用,通过属性暴露字典,使用它。

标签: iphone ios xmpp xmppframework


【解决方案1】:

您可以激活一个名为XMPPMessageArchiving 的模块。使用此模块,您可以保存所有传出和传入的消息(已发送/已接收消息)。

XMPPMessageArchivingCoreDataStorage *xmppMessageStorage = [XMPPMessageArchivingCoreDataStorage sharedInstance];
XMPPMessageArchiving *xmppMessageArchiving = [[XMPPMessageArchiving alloc] initWithMessageArchivingStorage:xmppMessageStorage];

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

此扩展名为 XEP 136 (http://xmpp.org/extensions/xep-0136.html),您可以使用 XMPPFramework 中包含的所有类。顺便说一句,如果您在 Table View Controller 中显示所有消息,则可以在每次插入新对象(即发送或接收新消息)时使用 NSFetchedResultController 刷新该 Table View。

【讨论】:

  • 你好@moral,如果出现 MUC 怎么办?如何激活 XMPPRoomCoreDataStorage ?
【解决方案2】:

您可以为您的 ViewController 创建方法,例如 - (void)addMessage:(NSDictionary *)messageProperties,您可以在其中将该消息添加到您的数组并重新加载 tableView。如果您在 AppDelegate 中有对该 ViewController 的引用,则可以从那里调用它。

AppDelegates 方法中的调用如下所示:

[self.chatViewController addMessage:messageDictionary];

【讨论】:

  • 我是新手,我可以看一些代码来更好地理解它吗?特别是,如何从 AppDelegate 调用字典? AppDelegate 收到我的消息,我正在尝试从 ChatViewController 显示。
  • 我不能说在你的情况下如何准确地做到这一点,因为我没有关于你的应用程序布局的信息。如果 ChatViewController 恰好是您的 Windows rootViewController,您可以简单地转换该 rootViewController 并使用该方法。
【解决方案3】:

最好将它们存储在本地sqlite中,以便您以后可以轻松检索旧消息。

【讨论】:

    【解决方案4】:

    您可以通过这种方式使用协议管理信息

    AppDelegate中:

        protocol ChatDelegate {
        func MassageRecibed(name: String)
    }
    
    @UIApplicationMain
    class AppDelegate: UIResponder, UIApplicationDelegate, MessagingDelegate, UNUserNotificationCenterDelegate, XMPPStreamDelegate, XMPPRosterDelegate {
    
    
        var delegate:ChatDelegate! = nil
        func xmppStream(_ sender: XMPPStream, didReceive message: XMPPMessage) {
              delegate?.MassageRecibed(name: body)
           }
    
    }
    

    要在视图中获取所需的信息,您只需实现此协议,将委托实现到 Appdelegate。

    ChatViewController

        class ChatViewController: UIViewController, ChatDelegate {
    
         let appDelegate = UIApplication.shared.delegate as! AppDelegate
    
          override func viewDidLoad() {
                super.viewDidLoad()
    
                appDelegate.delegate = self
    
            }
    
            func MassageRecibed(name: String) {
                print("mensaje recibido", name)
    
            }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-03-15
      • 1970-01-01
      • 2016-06-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-12-18
      • 1970-01-01
      相关资源
      最近更新 更多