xmpp整理筆記:聊天信息的發送與顯示
任何一個信息的發送都需要關註兩個部分,信息的發出,和信息在界面中的顯示
往期回顧:
xmpp整理筆記:環境的快速配置(附安裝包) http://www.cnblogs.com/dsxniubility/p/4304570.html
xmpp整理筆記:xmppFramework框架的導入和介紹 http://www.cnblogs.com/dsxniubility/p/4307057.html
xmpp整理筆記:用戶網絡連接及好友管理 http://www.cnblogs.com/dsxniubility/p/4307066.html
需要註意一點:
聊天界面輸入框並不是textField而是textView,因為textView可以控制多行信息間的上下滾動編輯,如果微信下面的聊天框用的是普通的textField你可以想象會出現什麽情況。
用模擬器程序和小鴨子聊天效果圖如下:
如果你不是在董鉑然博客園看到本文 請點擊查看原文
一。信息的發送
首先要有一個結果調度器
這是通過coredata從SQLlite取數據的必要操作。所有代碼寫在這個懶加載中
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
- ( NSFetchedResultsController *)fetchedResultsController {
// 推薦寫法,減少嵌套的層次
if (_fetchedResultsController != nil ) {
return _fetchedResultsController;
}
// 先確定需要用到哪個實體
NSFetchRequest *request = [ NSFetchRequest fetchRequestWithEntityName:@ "XMPPMessageArchiving_Message_CoreDataObject" ];
// 排序
NSSortDescriptor *sort = [ NSSortDescriptor sortDescriptorWithKey:@ "timestamp" ascending: YES ];
request.sortDescriptors = @[sort];
// 每一個聊天界面,只關心聊天對象的消息
request.predicate = [ NSPredicate predicateWithFormat:@ "bareJidStr = %@" , self .chatJID.bare];
// 從自己寫的工具類裏的屬性中得到上下文
NSManagedObjectContext *ctx = [SXXMPPTools sharedXMPPTools].xmppMessageArchivingCoreDataStorage.mainThreadManagedObjectContext;
// 實例化,裏面要填上上面的各種參數
_fetchedResultsController = [[ NSFetchedResultsController alloc]
initWithFetchRequest:request managedObjectContext:ctx sectionNameKeyPath: nil cacheName: nil ];
_fetchedResultsController.delegate = self ;
return _fetchedResultsController;
}
|
寫完了結果調度器之後要切記在viewdidload頁面首次加載中加上一句,否則不幹活
1 2 |
// 查詢數據
[ self .fetchedResultsController performFetch: NULL ];
|
發送出消息
因為textView裏面沒有類似textField的shouldReturn的方法 直接發送信息
所以只能對textView的《代理方法之文本改變方法》 稍加處理達到文本發送的目的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
#pragma mark - ******************** textView代理方法
- ( BOOL )textView:(UITextView *)textView shouldChangeTextInRange:( NSRange )range replacementText:( NSString *)text
{
// 判斷按下的是不是回車鍵。
if ([text isEqualToString:@ "\n" ]) {
// 自定義的信息發送方法,傳入字符串直接發出去。
[ self sendMessage:textView.text];
self .textView.text = nil ;
return NO ;
}
return YES ;
}
|
在輸入時如果按下回車鍵那觸發代理方法傳入的這個字符就是"\n" 就會調用自己寫的 這個sendMessage方法,傳入一個字符串直接發出去。
這個方法內部把傳入的文本先addBody 再用自己手寫的單例類的xmpp流 發出去。
1 2 3 4 5 6 7 8 9 10 |
#pragma mark - ******************** 發送消息方法
/** 發送信息 */
- ( void )sendMessage:( NSString *)message
{
XMPPMessage *msg = [XMPPMessage messageWithType:@ "chat" to: self .chatJID];
[msg addBody:message];
[[SXXMPPTools sharedXMPPTools].xmppStream sendElement:msg];
}
|
二。信息在tableView中的顯示
是在tableView的數據源方法中,先從數據庫中取出當前的信息,再判斷是發出去的還是接收的。取到不同的可重用標識符,然後賦值
1 2 3 4 5 6 |
// 取出當前行的消息
XMPPMessageArchiving_Message_CoreDataObject *message = [ self .fetchedResultsController objectAtIndexPath:indexPath];
// 判斷是發出消息還是接收消息
NSString *ID = ([message.outgoing intValue] == 1) ? @ "SendCell" : @ "ReciveCell" ;
SXChatCell *cell = [tableview dequeueReusableCellWithIdentifier:ID];
cell.messageLabel.text = message.body;
|
其中sx開的的類名都是我自定義的類,裏面都是常規寫法。
關於上面提到的工具類SXXmppTools裏 這個模塊需要用到得屬性和方法有
1 2 3 4 5 6 7 8 9 |
/** xmpp流 */
@property ( nonatomic ,strong, readonly ) XMPPStream * xmppStream;
/** 消息歸檔 */
@property ( nonatomic , strong, readonly ) XMPPMessageArchiving *xmppMessageArchiving;
/** 消息歸檔存儲 */
@property ( nonatomic , strong, readonly ) XMPPMessageArchivingCoreDataStorage *xmppMessageArchivingCoreDataStorage;
+ (instancetype)sharedXMPPTools;
|
這裏有一點需要註意,
因為默認情況下你一進入一位好友的聊天頁面,你和所有好友的聊天記錄都會顯示。因為都是存在同一個數據表裏的啊,因此需要做一層過濾,就是懶加載中的這行代碼
1 2 |
// 每一個聊天界面,只關心聊天對象的消息
request.predicate = [ NSPredicate predicateWithFormat:@ "bareJidStr = %@" , self .chatJID.bare];
|
如果你不是在董鉑然博客園看到本文 請點擊查看原文
正在整理音頻文件和圖片文件的發送方法,有興趣的可以關註我。
xmpp整理筆記:聊天信息的發送與顯示