在做App開發(fā)的時候柿顶,我們往往會用到即時通訊唯蝶,而其中最常用的就是單聊了。
今天就給大家分享一下最新的環(huán)信3.x單聊集成详瑞。在文章結束處有Demo地址掂林。
首先要有一個環(huán)信賬號
點擊到環(huán)信官網注冊按照官方文檔來完成注冊開發(fā)者賬號和注冊項目
制作并上傳證書
按照文檔注冊證書
如果不需要實現離線推送功能,請忽略這步坝橡。一般我們都需要離線功能泻帮。
SDK導入
通過Cocoapods下載地址
不包含實時語音版本SDK(HyphenateSDK),引用時 #import <HyphenateSDK/EMSDK.h>
pod 'HyphenateSDK', :git => 'https://github.com/easemob/hyphenate-cocoapods.git'
包含實時語音版本SDK(HyphenateFullSDK)计寇,引用時 #import <HyphenateFullSDK/EMSDKFull.h>
pod 'HyphenateFullSDK', :git => 'https://github.com/easemob/hyphenate-full-cocoapods.git'
注意導入的SDK中不包含EaseUI锣杂,如果要使用EaseUI,要導入如下文件番宁,ChatView是一個官方的單聊控制器文件夾元莫,如果不需要可以不導入
初始化SDK和EaseUI
#import "AppDelegate.h"
#import <HyphenateFullSDK/EMSDKFull.h>
@interface AppDelegate ()
@end
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
//AppKey:注冊的appKey(在你創(chuàng)建項目的時候會獲得appKey)
//apnsCertName:推送證書名(不需要加后綴)
EMOptions *options = [EMOptions optionsWithAppkey:@"mmengyiqu#will"];
options.apnsCertName = @"istore_dev";
[[EMClient sharedClient] initializeSDKWithOptions:options];
//初始化EaseUI
[[EaseSDKHelper shareHelper] easemobApplication:application
didFinishLaunchingWithOptions:launchOptions
appkey:@"mmengyiqu#will"
apnsCertName:@"istore_dev"
otherConfig:@{kSDKConfigEnableConsoleLogger:[NSNumber numberWithBool:YES]}];
return YES;
}
// App進入后臺
- (void)applicationDidEnterBackground:(UIApplication *)application
{
[[EMClient sharedClient] applicationDidEnterBackground:application];
}
// App將要從后臺返回
- (void)applicationWillEnterForeground:(UIApplication *)application
{
[[EMClient sharedClient] applicationWillEnterForeground:application];
}
登錄界面
代碼如下
#import "ViewController.h"
#import <HyphenateFullSDK/EMSDKFull.h>
@interface ViewController ()
@property (weak, nonatomic) IBOutlet UITextField *nameTextField;//用戶名
@property (weak, nonatomic) IBOutlet UITextField *passwordTextField;//密碼
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
}
- (IBAction)loginAction:(UIButton *)sender {
//登錄
EMError *error = [[EMClient sharedClient] loginWithUsername:self.nameTextField.text password:self.passwordTextField.text];
if (!error) {
NSLog(@"登陸成功");
//從數據庫中獲得數據
[[EMClient sharedClient].chatManager loadAllConversationsFromDB];
UINavigationController* nv=[[UIStoryboard storyboardWithName:@"Main" bundle:nil] instantiateViewControllerWithIdentifier:@"FriendListNavigationController"];
[self presentViewController:nv animated:YES completion:^{
}];
}else{
NSLog(@"登錄失敗");
}
}
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
[self.view endEditing:YES];
}
- 登錄時掉用這個接口,username是用戶名蝶押,password是密碼
EMError *error = [[EMClient sharedClient] loginWithUsername: password: ];if (!error) { NSLog(@"登陸成功");}
- 登錄成功之后從數據庫中獲得之前的聊天記錄柒竞,如果沒有這句,那么每當你退出之后再進入聊天播聪,記錄就消失了
[[EMClient sharedClient].chatManager loadAllConversationsFromDB];
注冊界面
代碼如下
#import "RegisterViewController.h"
#import <HyphenateFullSDK/EMSDKFull.h>
@interface RegisterViewController ()
@property (weak, nonatomic) IBOutlet UITextField *nameTextField;//用戶名
@property (weak, nonatomic) IBOutlet UITextField *password;//密碼
@end
@implementation RegisterViewController
- (void)viewDidLoad {
[super viewDidLoad];
}
- (IBAction)SureAction:(UIButton *)sender {
//注冊
EMError *error = [[EMClient sharedClient] registerWithUsername:self.nameTextField.text password:self.password.text];
if (error==nil) {
NSLog(@"注冊成功");
[self dismissViewControllerAnimated:YES completion:^{
}];
}else{
NSLog(@"注冊失敗");
}
}
- (IBAction)cancelAction:(UIButton *)sender {
[self dismissViewControllerAnimated:YES completion:^{
}];
}
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
[self.view endEditing:YES];
}
- 注冊時調用這個接口朽基,username是用戶名,password是密碼
EMError *error = [[EMClient sharedClient] registerWithUsername: password: ];if (error==nil) { NSLog(@"注冊成功");}
添加好友頁
代碼如下
#import "AddFriendViewController.h"
#import <HyphenateFullSDK/EMSDKFull.h>
@interface AddFriendViewController ()
@property (weak, nonatomic) IBOutlet UITextField *nameTextField;
@end
@implementation AddFriendViewController
- (void)viewDidLoad {
[super viewDidLoad];
}
- (IBAction)addFriendAction:(UIButton *)sender {
//發(fā)送添加好友申請
EMError *error = [[EMClient sharedClient].contactManager addContact:self.nameTextField.text message:@"我想加您為好友"];
if (!error) {
NSLog(@"添加成功");
[self.navigationController popViewControllerAnimated:YES];
}else{
NSLog(@"添加好友失斃胩铡-------%@",error);
}
}
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
[self.view endEditing:YES];
}
- 發(fā)送添加好友申請
EMError *error = [[EMClient sharedClient].contactManager addContact:@"6001" message:@"我想加您為好友"];
if (!error) { NSLog(@"添加成功");}
好友界面
代碼如下
#import "FriendListTableViewController.h"
#import <HyphenateFullSDK/EMSDKFull.h>
#import "FriendListTableViewCell.h"
#import "EaseMessageViewController.h"http://單聊基礎界面
#import "ChatViewController.h"http://單聊chat界面
@interface FriendListTableViewController ()<EMContactManagerDelegate>
{
NSMutableArray* _nameArr;//接收好友列表
}
@end
@implementation FriendListTableViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.title=@"我的好友";
self.tableView.backgroundColor=[UIColor whiteColor];
_nameArr=[[NSMutableArray alloc]init];
[self getFridendListAndReloadTableView];//獲取好友列表并刷新tableView
//注冊好友回調
[[EMClient sharedClient].contactManager addDelegate:self delegateQueue:nil];
}
//獲取好友列表并刷新tableView
-(void)getFridendListAndReloadTableView
{
//獲取好友列表
EMError *error = nil;
NSArray *userlist = [[EMClient sharedClient].contactManager getContactsFromServerWithError:&error];
if (!error) {
NSLog(@"好友獲取成功 -- %@",userlist);
[_nameArr removeAllObjects];
[_nameArr addObjectsFromArray:userlist];
[self.tableView reloadData];
}
}
#pragma mark - 監(jiān)聽添加好友回調
//監(jiān)聽回調
/*!
* 用戶A發(fā)送加用戶B為好友的申請稼虎,用戶B會收到這個回調
*
* @param aUsername 用戶名
* @param aMessage 附屬信息
*/
- (void)didReceiveFriendInvitationFromUsername:(NSString *)aUsername
message:(NSString *)aMessage
{
UIAlertController * alertController = [UIAlertController alertControllerWithTitle:[NSString stringWithFormat:@"收到來自%@的請求", aUsername] message:aMessage preferredStyle:(UIAlertControllerStyleAlert)];
UIAlertAction * acceptAction = [UIAlertAction actionWithTitle:@"好" style:(UIAlertActionStyleDefault) handler:^(UIAlertAction * _Nonnull action)
{
// 同意好友請求的方法
EMError *agreeError = [[EMClient sharedClient].contactManager acceptInvitationForUsername:aUsername];
if (!agreeError) {
NSLog(@"發(fā)送同意成功");
[self getFridendListAndReloadTableView];//獲取好友列表并刷新tableView
}
}];
UIAlertAction * rejectAction = [UIAlertAction actionWithTitle:@"NO" style:(UIAlertActionStyleCancel) handler:^(UIAlertAction * _Nonnull action) {
// 拒絕好友請求的方法
EMError *rejectError = [[EMClient sharedClient].contactManager declineInvitationForUsername:aUsername];
if (!rejectError) {
NSLog(@"發(fā)送拒絕成功");
}
}];
[alertController addAction:acceptAction];
[alertController addAction:rejectAction];
[self showDetailViewController:alertController sender:nil];
}
//好友申請?zhí)幚斫Y果回調
//監(jiān)聽回調
- (void)didReceiveAgreedFromUsername:(NSString *)aUsername
{
NSLog(@"%@同意了我的好友請求",aUsername);
[self getFridendListAndReloadTableView];//獲取好友列表并刷新tableView
}
- (void)didReceiveDeclinedFromUsername:(NSString *)aUsername
{
NSLog(@"%@拒絕了我的好友請求",aUsername);
}
#pragma mark -
- (IBAction)exitAction:(UIBarButtonItem *)sender {
//退出登錄
EMError *error = [[EMClient sharedClient] logout:YES];
if (!error) {
NSLog(@"退出成功");
[self dismissViewControllerAnimated:YES completion:^{
}];
}else{
NSLog(@"退出失敗");
}
}
#pragma mark - Table view data source
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return _nameArr.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
FriendListTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"FriendListTableViewCell" forIndexPath:indexPath];
NSString* username=_nameArr[indexPath.row];
cell.nameLabel.text=username;
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// //創(chuàng)建聊天會話,傳遞用戶或群id和會話類型(EMConversationType)
// EaseMessageViewController *chatController = [[EaseMessageViewController alloc] initWithConversationChatter:_nameArr[indexPath.row] conversationType:EMConversationTypeChat];
// chatController.title=_nameArr[indexPath.row];
// [self.navigationController pushViewController:chatController animated:YES];
//創(chuàng)建聊天會話,傳遞用戶或群id和會話類型(EMConversationType)
ChatViewController *chatController = [[ChatViewController alloc] initWithConversationChatter:_nameArr[indexPath.row] conversationType:EMConversationTypeChat];
chatController.title=_nameArr[indexPath.row];
[self.navigationController pushViewController:chatController animated:YES];
}
- 獲取好友列表
EMError *error = nil; NSArray *userlist = [[EMClient sharedClient].contactManager getContactsFromServerWithError:&error];
- 好友申請
- 發(fā)送加好友申請
如果您已經發(fā)過,并且對方沒有處理招刨,您將不能再次發(fā)送
EMError *error = [[EMClient sharedClient].contactManager addContact:@"6001" message:@"我想加您為好友"];
if (!error) { NSLog(@"添加成功");}
- 監(jiān)聽加好友請求
當您收到好友請求霎俩,如果您沒有處理,請自己保存數據沉眶,新協議下不會每次都發(fā)送
//注冊好友回調
[[EMClient sharedClient].contactManager addDelegate:self delegateQueue:nil];
//移除好友回調
[[EMClient sharedClient].contactManager removeDelegate:self];
- 監(jiān)聽回調
用戶A發(fā)送加用戶B為好友的申請打却,用戶B會收到這個回調
aUsername 用戶名
aMessage 附屬信息
-(void)didReceiveFriendInvitationFromUsername:(NSString *)aUsername message:(NSString *)aMessage;
- 同意加好友申請
EMError *error = [[EMClient sharedClient].contactManager acceptInvitationForUsername:@"8001"];
if (!error) { NSLog(@"發(fā)送同意成功");}
- 拒絕加好友申請
EMError *error = [[EMClient sharedClient].contactManager declineInvitationForUsername:@"8001"];
if (!error) { NSLog(@"發(fā)送拒絕成功");}
- 好友申請?zhí)幚斫Y果回調
監(jiān)聽回調
用戶A發(fā)送加用戶B為好友的申請,用戶B同意后谎倔,用戶A會收到這個回調
-(void)didReceiveAgreedFromUsername:(NSString *)aUsername;
用戶A發(fā)送加用戶B為好友的申請柳击,用戶B拒絕后,用戶A會收到這個回調
-(void)didReceiveDeclinedFromUsername:(NSString *)aUsername;
- 退出登錄
EMError *error = [[EMClient sharedClient] logout:YES];
if (!error) { NSLog(@"退出成功");}
- 大家可能注意到了片习,我導入了這2個文件
#import "EaseMessageViewController.h"http://單聊基礎界面
#import "ChatViewController.h"http://單聊chat界面
這2個控制器都是環(huán)信提供給我們的單聊控制器,EaseMessageViewController
這是基礎的控制器捌肴,如果我們想要使用這個控制器蹬叭,但又覺得這個控制器滿足不了我們的要求的話,我們有2個辦法状知。1.使用ChatViewController
2.我們可以仿照ChatViewController
寫一個繼承EaseMessageViewController
的控制器秽五。
如果你對控制器有更高定制要求的話,可以根據文檔來自己實現相應的功能饥悴,而不局限于EaseMessageViewController
注意
- 有一個bug坦喘,用模擬器播放錄音會崩潰,在手機上播放就沒問題
- 環(huán)信不會保存我們的頭像西设,所以我們可以從app服務器獲取頭像
- 比如我們使用的是
ChatViewController
起宽,我們可以在ChatViewController.m文件的EaseMessageViewControllerDataSource
中的
-(id<IMessageModel>)messageViewController:(EaseMessageViewController *)viewController
modelForMessage:(EMMessage *)message
{
}
中來改變頭像
-(id<IMessageModel>)messageViewController:(EaseMessageViewController *)viewController
modelForMessage:(EMMessage *)message
{
id<IMessageModel> model = nil;
model = [[EaseMessageModel alloc] initWithMessage:message];
if (model.isSender) {//自己的頭像 昵稱
model.avatarImage=[UIImage imageNamed:@"蠟筆小新.jpg"];
model.nickname=@"我";
}else{
model.avatarImage=[UIImage imageNamed:@"美女.jpg"];
}
model.failImageName = @"imageDownloadFail";
return model;
}
我們可以通過model.avatarURLPath=@""
來從網絡獲取頭像
也可以通過model.avatarImage
來改變頭像
- 改變氣泡,還是拿
ChatViewController
舉例济榨,我們可以在ChatViewController.m
的viewDidLoad
中,改變此處的圖片名稱
[[EaseBaseMessageCell appearance] setSendBubbleBackgroundImage:[[UIImage imageNamed:@"chat_sender_bg"] stretchableImageWithLeftCapWidth:5 topCapHeight:35]];
[[EaseBaseMessageCell appearance] setRecvBubbleBackgroundImage:[[UIImage imageNamed:@"chat_receiver_bg"] stretchableImageWithLeftCapWidth:35 topCapHeight:35]];
這樣我們就簡單的集成了3.x的單聊,在此點擊下載Demo
界面在Main.storyboard中,選中左側一列绿映。
注:相關內容我會繼續(xù)更新擒滑。如果想找一些iOS方面的代碼可以關注我的簡書,我會持續(xù)更新叉弦,大家一起探討探討
在此謝謝大家閱讀