XMPPFramework的使用(三)---單聊,群聊

本人有若干成套學習視頻, 可試看! 可試看! 可試看, 重要的事情說三遍 包含Java, 數據結構與算法, iOS, 安卓, python, flutter等等, 如有需要, 聯系微信tsaievan.

看了一下 XMPPFramework 的源碼,真心看不懂啊,還是繼續我們簡單的內容吧

無論是使用單聊還是群聊, 我們都必須將三大節點之一的 message 節點加入到 XMPPStream 流中,這是完成消息傳輸的最重要的一步

其實,有這一步之后,我們的聊天消息是可以發送成功的,代碼如下:

我們在 textField 的文本輸入的文本取出,初始化消息 XMPPMessage 對象,再加入流中,就完成了消息的發送

#pragma mark *** textField代理 API ***

-(BOOL)textFieldShouldReturn:(UITextField *)textField
{
     /* 初始化一個聊天模型 */
    
    /**
     * 第一個參數: 聊天類型,"chat"表示單聊
     * 第二個參數: 聊天對象, 即聊天消息發送給誰
     */
    XMPPMessage *message = [[XMPPMessage alloc]initWithType:@"chat" to:self.jid];
    
     /* 添加聊天內容 */
    [message addBody:textField.text];
    
     /* 發送消息 */
    
    [kYFXMPPManager.xmppstream sendElement:message];
    
     /* 發送完畢之后清空文本 */
    textField.text = nil;
    [textField resignFirstResponder];
    return YES;
}

我們在另外一個客戶端給這個賬號發送消息,可以發現兩個代理方法都可以回調成功,控制臺都有相應的日志輸出

// -------- 流發送消息成功 --------
- (void)xmppStream:(XMPPStream *)sender didSendMessage:(XMPPMessage *)message
{
    NSLog(@"消息發送成功");
    !self.messageSendBlock ? :self.messageSendBlock(message);
}


// -------- 流接收消息成功 --------
- (void)xmppStream:(XMPPStream *)sender didReceiveMessage:(XMPPMessage *)message
{
    NSLog(@"消息接收成功");
   !self.messageReceiveBlock ? :self.messageReceiveBlock(message);
}

那么為什么在聊天界面不顯示消息信息呢?那是因為我們的消息只存在 XMPPStream 流中,并沒有進行數據持久化, 如果要做數據持久化的話,必須添加消息歸檔模塊,這里涉及到的一個關鍵類就是“消息歸檔類”---

XMPPMessageArchiving

我們將這個模塊添加到 XMPPStream 中就相當于將流截獲,進行數據->模型的轉換,然后用 CoreData框架保存在本地
斜體部分的功能 XMPPframework 框架已經幫我們完成


#import "YFXMPPManager+MessageArchive.h"

@implementation YFXMPPManager (MessageArchive)

- (void)addMessageArchivingModule
{
     /* 初始化 */
    self.xmppmessageArchiving = [[XMPPMessageArchiving alloc]initWithMessageArchivingStorage:[XMPPMessageArchivingCoreDataStorage sharedInstance] dispatchQueue:dispatch_get_main_queue()];
     /* 無需配置 */
    
     /* 激活 */
    [self.xmppmessageArchiving activate:self.xmppstream];
}

@end


這樣,我們在展示聊天信息的時候,就可以舒舒服服地使用 NSFetchResultsController 了

懶加載NSFetchResultsController(初始化)

#pragma mark *** Getter & Setter ***

- (NSFetchedResultsController *)fetchedResultsController
{
    if (!_fetchedResultsController) {
        /* 初始化查詢請求 */
        NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:@"XMPPMessageArchiving_Message_CoreDataObject"];
        fetchRequest.sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:@"timestamp" ascending:YES]];
        
        /* 設置謂詞,只顯示當前聊天者的聊天記錄 */
        fetchRequest.predicate = [NSPredicate predicateWithFormat:@"bareJidStr == %@",self.jid.bare];
        _fetchedResultsController = [[NSFetchedResultsController alloc]initWithFetchRequest:fetchRequest managedObjectContext:[XMPPMessageArchivingCoreDataStorage sharedInstance].mainThreadManagedObjectContext sectionNameKeyPath:nil cacheName:nil];
        
        /* 執行查詢 */
        [_fetchedResultsController performFetch:nil];
        
        /* 刷新 tableView */
        [self.tableView reloadData];
    }
    return _fetchedResultsController;
}

其實單聊和群聊是大同小異的, 有一點不同的就是,房間是要單獨創建的,不然群聊在哪里進行呢?房間的創建又需要一個新的 JID,和 nickname,創建成功后,有代理方法的回調,在代理方法中完成房間配置和邀請


房間創建過程
#import "YFXMPPGroupChatManager.h"
#import "YFXMPPManager.h"

@implementation YFXMPPGroupChatManager

+ (instancetype)sharedManager
{
    static id instanceType = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        instanceType = [[YFXMPPGroupChatManager alloc]init];
    });
    return instanceType;
}

/**
 *  @param jid      房間的 Jid
 *  @param nickname  房間的昵稱
 */
- (void)joinRoomWithJid:(XMPPJID *)jid andNickname:(NSString *)nickname
{
    /* 初始化房間 */
    self.xmppRoom = [[XMPPRoom alloc]initWithRoomStorage:[XMPPRoomCoreDataStorage sharedInstance] jid:jid dispatchQueue:dispatch_get_main_queue()];
    
    /* 配置,無需配置 */
    /* 只需要添加一個代理 */
    [self.xmppRoom addDelegate:self delegateQueue:dispatch_get_main_queue()];
    /* 激活 */
    [self.xmppRoom activate:kYFXMPPManager.xmppstream];
    
    /**
     * @參數1:nickname
     * @參數2:歷史記錄,填寫 nil, 表示不獲取歷史記錄
     */
    
    /* 如果加入的房間在服務器中不存在,則創建,如果存在,就直接加入 */
    [self.xmppRoom joinRoomUsingNickname:nickname history:nil];
}

#pragma mark *** Getter & Setter ***

// -------- 創建房間成功之后一定要做兩件事情,否則房間無法使用 --------
/**
 *  1. 配置房間
 *  2. 邀請人到房間
 */
- (void)xmppRoomDidCreate:(XMPPRoom *)sender
{
    /* 配置房間 */
    [sender configureRoomUsingOptions:nil];
    /* 查詢房間配置 */
    [sender fetchConfigurationForm];
    /* 邀請人到房間 */
    
    /**
     *  參數1: 邀請對象的 jid
     *  參數2: 邀請信息
     */
    [sender inviteUser:[XMPPJID jidWithUser:@"tsaievan" domain:@"tsaievan.com" resource:nil] withMessage:@"今天晚上放學別走"];
    
    [sender inviteUser:[XMPPJID jidWithUser:@"caiyifan" domain:@"tsaievan.com" resource:nil] withMessage:@"今晚放學別走"];
    
    [sender inviteUser:[XMPPJID jidWithUser:@"mary" domain:@"tsaievan.com" resource:nil] withMessage:@"今天晚上放學請你喝紅牛"];
}

// -------- 房間加入成功 --------
- (void)xmppRoomDidJoin:(XMPPRoom *)sender
{
    /* 配置房間 */
    [sender configureRoomUsingOptions:nil];
    /* 查詢房間配置 */
    [sender fetchConfigurationForm];
    /* 邀請人到房間 */
    
    /**
     *  參數1: 邀請對象的 jid
     *  參數2: 邀請信息
     */
    [sender inviteUser:[XMPPJID jidWithUser:@"tsaievan" domain:@"tsaievan.com" resource:nil] withMessage:@"今天晚上放學別走"];
    
    [sender inviteUser:[XMPPJID jidWithUser:@"caiyifan" domain:@"tsaievan.com" resource:nil] withMessage:@"今晚放學別走"];
    
    [sender inviteUser:[XMPPJID jidWithUser:@"mary" domain:@"tsaievan.com" resource:nil] withMessage:@"今天晚上放學請你喝紅牛"];
}

// -------- 房間解散成功 --------
- (void)xmppRoomDidLeave:(XMPPRoom *)sender
{
    
}


@end

單聊和群聊的過程基本上就是這樣,但是在實際寫代碼的時候還是會遇到很多坑,大家還是要自己敲一遍才可以深刻體會。

PS. 本人有若干成套學習視頻, 包含Java, 數據結構與算法, iOS, 安卓, python, flutter等等, 如有需要, 聯系微信tsaievan.

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容