利用环信集成聊天所遇到的坑以及解决的办法

本文介绍了作为环信新手在集成聊天功能时的步骤,包括环信账号注册、SDK的使用、登录逻辑以及聊天列表的展示。特别讨论了在模拟器上注册问题的解决办法,授权注册的流程,以及客户端如何处理后台接收消息并显示本地通知的实现细节。

身为一个环信小白,要利用环信集成聊天功能要怎么办呢?

当然首先是去看官方文档咯!下载SDk~

首先你要注册环信的账号,没有账号怎么聊天,鬼知道发给谁!

当时不知道是不是因为模拟器的原因还是网的问题始终不能注册环信账号,只好用真机来跑,一下就成功了:


注册模式分两种,开放注册和授权注册。

  • 只有开放注册时,才可以客户端注册。开放注册是为了测试使用,正式环境中不推荐使用该方式注册环信账号。
  • 授权注册的流程应该是您服务器通过环信提供的 REST  API 注册,之后保存到您的服务器或返回给客户端。
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 = [[EaseMessageModel alloc] initWithMessage:message];

    model.avatarImage = [UIImage imageNamed:@"1.jpg"]; // 默认头像

    model.avatarURLPath = [HuanshiUser huanshiUser].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 = [[NSUserDefaults standardUserDefaults] objectForKey:[NSString stringWithFormat:@"%@%@", conversation.conversationId, @"user_nick"]];

        cell.titleLabel.text = nickname;

        NSString *avatar = [[NSUserDefaults standardUserDefaults] objectForKey:[NSString stringWithFormat:@"%@%@", conversation.conversationId, @"user_avatar"]];

        [cell.avatarView.imageView sd_setImageWithURL:[NSURL URLWithString:avatar]];

    } else {

        cell.titleLabel.text = lastRecivedMessage.ext[@"user_nick"];

        [cell.avatarView.imageView sd_setImageWithURL:lastRecivedMessage.ext[@"user_avatar"]];

    }

    

    EaseMessageModel *model = [[EaseMessageModel alloc] initWithMessage:lastMessage];

    cell.detailLabel.text = model.text;

    cell.timeLabel.text = [NSString stringWithFormat:@"%@ %@",[self timeTransformTimesTemp:lastMessage.timestamp], [self tempsTranformTime:lastMessage.timestamp]];

    cell.avatarView.badge = conversation.unreadMessagesCount;

    cell.avatarView.imageView.layer.cornerRadius = 30;

    cell.avatarView.imageView.clipsToBounds = YES;

至于消息的推送环信能用离线推送和本地通知,离线推送可参考官方文档很详细;

本地通知并没有讲得很详细:当时也是困扰了很久

当程序刚刚进入后台的时候,程序并没有被杀死,这个时候发来的消息会走我们之前设置的那个接收消息的代理方法,在这个方法里处理本地通知:

在appdelegate里完成的,你也可以在rootViewController中来写,是一样的

- (void)messagesDidReceive:(NSArray *)aMessages {

    

    [[NSNotificationCenter defaultCenter] postNotificationName:YXMessagesDidReceive object:nil];

    

    if ([UIApplication sharedApplication].applicationState == UIApplicationStateBackground) {

        [self showNotificationWithMessage:[aMessages lastObject]];

    }

    

    [self updateTotalUnreadMessageCount];

}


- (void)showNotificationWithMessage:(EMMessage *)message {

    

    // 本地推送

    EaseMessageModel *easeMessageModel = [[EaseMessageModel alloc] initWithMessage:message];

    if (IS_iOS10) {

//因为适配了IOS10 所以舍弃了iOS8一下的,有需要的可以自己加上

        UNUserNotificationCenter *userNotificationCenter = [UNUserNotificationCenter currentNotificationCenter];

        UNMutableNotificationContent *mutableNotificationContent = [[UNMutableNotificationContent alloc] init];

        mutableNotificationContent.body = [[NSString alloc] initWithFormat:@"%@:%@", message.ext[@"user_nick"], easeMessageModel.text];

        mutableNotificationContent.sound = [UNNotificationSound defaultSound];

        UNTimeIntervalNotificationTrigger* trigger = [UNTimeIntervalNotificationTrigger triggerWithTimeInterval:0.1 repeats:NO];

        UNNotificationRequest *request = [UNNotificationRequest requestWithIdentifier:@"now" content:mutableNotificationContent trigger:trigger];

        [userNotificationCenter addNotificationRequest:request withCompletionHandler:^(NSError * _Nullable error) {

            if (!error) {

                HSLog(@"本地推送成功");

            }

        }];

    } else {

        UILocalNotification *notification = [[UILocalNotification alloc] init];

        notification.fireDate = [NSDate date];

        notification.repeatCalendar = [NSCalendar currentCalendar];

        notification.alertBody = [[NSString alloc] initWithFormat:@"%@:%@", message.ext[@"user_nick"], easeMessageModel.text];

        notification.alertAction = NSLocalizedString(@"open", @"Open");

        notification.timeZone = [NSTimeZone defaultTimeZone];

        notification.repeatInterval = 0;

        NSMutableDictionary *userInfo = [NSMutableDictionary dictionary];

        notification.userInfo = userInfo;

        notification.alertLaunchImage = @"Default";

        notification.soundName = @"msg.caf";

        [[UIApplication sharedApplication] scheduleLocalNotification:notification];

    }

}

大致的我遇到的问题就是这些了,还有就是要和安卓那边对应好字段,比如消息的拓展,不然就不能喝安卓手机对聊啦!



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值