利用環信整合聊天所遇到的坑以及解決的辦法
身為一個環信小白,要利用環信整合聊天功能要怎麼辦呢?
當然首先是去看官方文件咯!下載SDk~
首先你要註冊環信的賬號,沒有賬號怎麼聊天,鬼知道發給誰!
當時不知道是不是因為模擬器的原因還是網的問題始終不能註冊環信賬號,只好用真機來跑,一下就成功了:
註冊模式分兩種,開放註冊和授權註冊。
EMError *error = [[EMClient sharedClient] registerWithUsername: @"8001" password:@"111111"];
if (error==nil) {
NSLog(@"註冊成功");
}
登入:呼叫 SDK 的登入介面進行的操作。
EMError *error = [[EMClient sharedClient] loginWithUsername:@"8001" password:@"111111"];
if (!error) {
NSLog(@"登入成功");
}
第 1 步:引入相關標頭檔案 #import “EMSDK.h”。
第 2 步:在工程的 AppDelegate 中的以下方法中,呼叫 SDK 對應方法。
- ( BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
//AppKey:註冊的AppKey,詳細見下面註釋。
//apnsCertName:推送證書名(不需要加字尾),詳細見下面註釋。
EMOptions *options = [EMOptions optionsWithAppkey:@"douser#istore"];
options.apnsCertName = @"istore_dev";
[[EMClient sharedClient] initializeSDKWithOptions:options];
return YES;
}
// APP進入後臺
- (void)applicationDidEnterBackground:(UIApplication *)application
{
//這個很重要,不然SDK無法判斷你的程式是在前臺還是後臺,如果沒有設定,那麼訊息離線推送將不能成功
//簡直大坑,都不跟我有什麼用,開始就沒用,導致利息那推送哪裡用好長的時間;
[[EMClient sharedClient] applicationDidEnterBackground:application];
}
// APP將要從後臺返回
- (void)applicationWillEnterForeground:(UIApplication *)application
{
[[EMClient sharedClient] applicationWillEnterForeground:application];
}
對於訊息的接受就是下面的代理方法了,但是要注意的是一定要移除通知,不然在其他的介面就無法接受到訊息的回調了,如果被註冊了多次,那麼你的聊天介面會很好看,全是重複的訊息,不要問我為什麼,想哭。
//訊息回撥:EMChatManagerChatDelegate
//移除訊息回撥
[[EMClient sharedClient].chatManager removeDelegate:self];
//註冊訊息回撥
[[EMClient sharedClient].chatManager addDelegate:self delegateQueue:nil];
因為不想自己去寫邏輯,所以用的是EaseUI來完成的聊天,但是頭像部分還是自己寫的邏輯:
- (id<IMessageModel>)messageViewController:(EaseMessageViewController *)viewController modelForMessage:(EMMessage *)message {
// 使用者可以根據自己的使用者體系, 根據message設定使用者暱稱和頭像.
id<IMessageModel> model = nil;
model = [[EaseMessageModelalloc] initWithMessage:message];
model.avatarImage = [UIImageimageNamed:@"1.jpg"]; // 預設頭像
model.avatarURLPath = [HuanshiUserhuanshiUser].logo_url; // 頭像網路地址
model.nickname = @""; // 使用者暱稱
if (!model.isSender) {
model.nickname = @"";
model.avatarURLPath = self.comment.logo_url;
}
return model;
}
聊天列表的展示邏輯是自己寫的,大部分的時間都是在頭像和最後一句訊息的展示上:
EMConversation *conversation = self.conversationData[indexPath.section];
EMMessage *lastMessage = [conversation latestMessage];
EMMessage *lastRecivedMessage = [conversation lastReceivedMessage];
if (!lastRecivedMessage) {
NSString *nickname = [[NSUserDefaultsstandardUserDefaults] objectForKey:[NSStringstringWithFormat:@"%@%@", conversation.conversationId, @"user_nick"]];
cell.titleLabel.text = nickname;
NSString *avatar = [[NSUserDefaultsstandardUserDefaults] objectForKey:[NSStringstringWithFormat:@"%@%@", conversation.conversationId, @"user_avatar"]];
[cell.avatarView.imageViewsd_setImageWithURL:[NSURLURLWithString:avatar]];
} else {
cell.titleLabel.text = lastRecivedMessage.ext[@"user_nick"];
[cell.avatarView.imageViewsd_setImageWithURL:lastRecivedMessage.ext[@"user_avatar"]];
}
EaseMessageModel *model = [[EaseMessageModelalloc] initWithMessage:lastMessage];
cell.detailLabel.text = model.text;
cell.timeLabel.text = [NSStringstringWithFormat:@"%@ %@",[selftimeTransformTimesTemp:lastMessage.timestamp], [selftempsTranformTime:lastMessage.timestamp]];
cell.avatarView.badge = conversation.unreadMessagesCount;
cell.avatarView.imageView.layer.cornerRadius = 30;
cell.avatarView.imageView.clipsToBounds = YES;
至於訊息的推送環信能用離線推送和本地通知,離線推送可參考官方文件很詳細;本地通知並沒有講得很詳細:當時也是困擾了很久
當程式剛剛進入後臺的時候,程式並沒有被殺死,這個時候發來的訊息會走我們之前設定的那個接收訊息的代理方法,在這個方法裡處理本地通知:
在appdelegate裡完成的,你也可以在rootViewController中來寫,是一樣的
- (void)messagesDidReceive:(NSArray *)aMessages {
[[NSNotificationCenterdefaultCenter] postNotificationName:YXMessagesDidReceiveobject:nil];
if ([UIApplicationsharedApplication].applicationState == UIApplicationStateBackground) {
[selfshowNotificationWithMessage:[aMessages lastObject]];
}
[selfupdateTotalUnreadMessageCount];
}
- (void)showNotificationWithMessage:(EMMessage *)message {
// 本地推送
EaseMessageModel *easeMessageModel = [[EaseMessageModelalloc] initWithMessage:message];
if (IS_iOS10) {
//因為適配了IOS10 所以捨棄了iOS8一下的,有需要的可以自己加上
UNUserNotificationCenter *userNotificationCenter = [UNUserNotificationCentercurrentNotificationCenter];
UNMutableNotificationContent *mutableNotificationContent = [[UNMutableNotificationContentalloc] init];
mutableNotificationContent.body = [[NSStringalloc] initWithFormat:@"%@:%@", message.ext[@"user_nick"], easeMessageModel.text];
mutableNotificationContent.sound = [UNNotificationSounddefaultSound];
UNTimeIntervalNotificationTrigger* trigger = [UNTimeIntervalNotificationTriggertriggerWithTimeInterval:0.1repeats:NO];
UNNotificationRequest *request = [UNNotificationRequestrequestWithIdentifier:@"now"content:mutableNotificationContent trigger:trigger];
[userNotificationCenter addNotificationRequest:request withCompletionHandler:^(NSError * _Nullable error) {
if (!error) {
HSLog(@"本地推送成功");
}
}];
} else {
UILocalNotification *notification = [[UILocalNotificationalloc] init];
notification.fireDate = [NSDatedate];
notification.repeatCalendar = [NSCalendarcurrentCalendar];
notification.alertBody = [[NSStringalloc] initWithFormat:@"%@:%@", message.ext[@"user_nick"], easeMessageModel.text];
notification.alertAction = NSLocalizedString(@"open", @"Open");
notification.timeZone = [NSTimeZonedefaultTimeZone];
notification.repeatInterval = 0;
NSMutableDictionary *userInfo = [NSMutableDictionarydictionary];
notification.userInfo = userInfo;
notification.alertLaunchImage = @"Default";
notification.soundName = @"msg.caf";
[[UIApplicationsharedApplication] scheduleLocalNotification:notification];
}
}
大致的我遇到的問題就是這些了,還有就是要和安卓那邊對應好欄位,比如訊息的拓展,不然就不能喝安卓手機對聊啦!