点对点聊天吧

概要

瞎逛发现某广告的链接,点进去,发现某通讯SDK,瞅了下,好像不是太复杂,想想也算学了些IOS开发,好像没啥事做,拿来学学学习。

该SDK支持Cocoapod第三方库,所以安装比较简单的,不过注意只能使用两个库中的一个,因为IMKit包含了IMLib,其中IMLib是通讯库,没有实现界面组件,而IMKit在IMLib的基础上实现了界面,集成简单。

本例子力求简单点吧,做了一个好友聊天功能,同时加了个客服功能,直接集成IMKit到应用。

结果展示

主要技术点

  • 新建single工程,然后关闭工程,到工程的根目录下新建Podfile文件,在文件中添加

    pod 'RongCloudIMKit'

    然后使用命令

    pod install

    安装通讯库,然后生成.xcworkspace工程文件,此后所有的开发工作在此工程里面进行,直接使用XCode打开就好(其实这一步就是使用CocoaPod新建一个工程)

  • 在AppDelegate.m文件中完成APP初始化,需要引入融云的头文件RCIM.h,使用initWithAppKey:deviceToken:和APP Key完成融云应用的初始化,只需要初始化一次就好了,然后注册推送通知(虽然本程序没有示例推送),其主要代码如下所示
    // 初始化 SDK,传入 App Key,deviceToken 暂时为空,等待获取权限。
    [RCIM initWithAppKey:@"c9kqb3rdk7jjj" deviceToken:nil];
    
    #ifdef __IPHONE_8_0
    // 在 iOS 8 下注册苹果推送,申请推送权限。
    UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeBadge
                                                                                             |UIUserNotificationTypeSound
                                                                                             |UIUserNotificationTypeAlert) categories:nil];
    [[UIApplication sharedApplication] registerUserNotificationSettings:settings];
    #else
    // 注册苹果推送,申请推送权限。
    [[UIApplication sharedApplication] registerForRemoteNotificationTypes:UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound];
    #endif
  • 因为聊天时候需要切换视图,所以应该要使用导航视图控制器,所以需要将程序的根视图控制器修改为导航视图控制器。其主要代码如下所示
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    
    // 视图放在导航控制器里面,然后子视图能够通过导航切换视图
    // 如果是标签栏控件作根视图控制器,可给每个标签定义一个导航控制器
    ViewController* viewController = [[ViewController alloc] init];
    UINavigationController* navController = [[UINavigationController alloc] init];
    [navController addChildViewController:viewController];
    
    // 设置跟视图控制器
    self.window.rootViewController = navController;
  • 好友列表使用UITableView展现,因为没有服务器,所以好友列表直接在程序里面模拟获取,每个好友包括好友ID、好友名字、好友头像,如果要使用某个用户登录,需要获取某个用户的认证令牌(其规范流程是,APP客户端程序使用用户信息和APP Key向APP服务器发起令牌请求,APP服务器使用本地存储的Secret Key和APP客户端的请求信息融云服务器请求令牌,然后融云服务器向APP服务器返回令牌,APP服务器再将该令牌返回给客户端),可使用融云应用配置里面的API调试功能直接生成令牌,然后在客户端使用该令牌可登录系统。使用Token登录认证的主要代码如下所示
    - (void)login:(NSString*)token
    {
        // 连接融云服务器。
        [RCIM connectWithToken:token completion:^(NSString *userId)
        {
            // 此处处理连接成功。
            NSLog(@"Login successfully with userId: %@.", userId);
        } error:^(RCConnectErrorCode status)
        {
            // 此处处理连接错误。
            NSLog(@"Login failed.");
        }];
    }

    其中token是请求获取的令牌。

  • 好友列表展示使用UITabView,展现的头像直接使用网络地址也是可以的,如下所示
    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
    {
        UITableViewCell* cell = nil;
        NSString* kCellID = @"friend";
    
        cell = [_tableView dequeueReusableCellWithIdentifier:kCellID];
        if(cell == nil)
        {
            cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:kCellID];
        }
    
        RCUserInfo* user = [_frindList objectAtIndex:indexPath.row];
        cell.textLabel.text = user.name;
        NSString* url = [user.portraitUri stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
        cell.imageView.image = [UIImage imageWithData:[NSData dataWithContentsOfURL:[[NSURL alloc] initWithString:url]]];
    
        return cell;
    }
  • 当点击某个好友时,需要打开与该好友的单聊界面,这里的UI直接使用融云集成的UI,所以主要代码如下所示
    - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
    {
        [_tableView deselectRowAtIndexPath:indexPath animated:YES];
    
        UIViewController* chatController = nil;
        RCUserInfo* user = [_frindList objectAtIndex:indexPath.row];
    
        if([user.userId isEqualToString:@"kf"])
        {
            // 创建客服聊天视图控制器。
            RCChatViewController *chatViewController = [[RCIM sharedRCIM]createCustomerService:@"KEFU1420640265290" title:user.name completion:^()
            {
                // 创建 ViewController 后,调用的 Block,可以用来实现自定义行为。
            }];
    
            chatController = (UIViewController*)chatViewController;
        }
        else
        {
            // 创建单聊视图控制器。
            RCChatViewController *chatViewController = [[RCIM sharedRCIM] createPrivateChat:user.userId title:user.name completion:^()
            {
                // 创建 ViewController 后,调用的 Block,可以用来实现自定义行为。
            }];
    
            chatController = (UIViewController*)chatViewController;
        }
        // 把视图控制器添加到导航栈。
        [self.navigationController pushViewController:chatController animated:YES];
    }
  • 需要支持客服的话,需要在融云系统里的应用配置的功能模块开启,主要是验证客户管理员邮箱及设置密码,然后获取客户的customerServiceId,这样在用户与客服通讯时,传入该值,即可与客服通信,主要代码见上面好友的单聊中。

主要代码

//
//  ViewController.m
//  RCDemo
//
//  Created by God Lin on 15/1/7.
//  Copyright (c) 2015年 arbboter. All rights reserved.
//

#import "ViewController.h"
// 融云头文件
#import "RCIM.h"

#define USER_JJF @"Un/MhUnZaA7mN9KPIMqFjsOWN+Jz2/18SGCwCc9gCOoB8MIFranJjJgCDBD53R3Jc7rSCaUdONXk/CvO9+uPKA=="

@interface ViewController () <UITableViewDataSource, UITableViewDelegate,RCIMFriendsFetcherDelegate, RCIMUserInfoFetcherDelegagte, RCIMGroupInfoFetcherDelegate>

@property (nonatomic, strong) UITableView* tableView;
@property (nonatomic, strong) NSMutableArray* frindList;

@end

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];

    _frindList = [NSMutableArray arrayWithArray:[self getFriends]];
    _tableView = [[UITableView alloc] initWithFrame:CGRectMake(self.view.frame.origin.x, self.view.frame.origin.y+20, self.view.frame.size.width, self.view.frame.size.height-20)];
    _tableView.tableFooterView= [[UITableView alloc] init];
    _tableView.delegate = self;
    _tableView.dataSource = self;
    [self.view addSubview:_tableView];

    [self login:USER_JJF];
}

- (void)login:(NSString*)token
{
    // 连接融云服务器。
    [RCIM connectWithToken:token completion:^(NSString *userId)
    {
        // 此处处理连接成功。
        NSLog(@"Login successfully with userId: %@.", userId);
    } error:^(RCConnectErrorCode status)
    {
        // 此处处理连接错误。
        NSLog(@"Login failed.");
    }];
}

#pragma 融云协议
// 获取好友列表的方法。
-(NSArray*)getFriends
{
    NSMutableArray *array = [[NSMutableArray alloc]init];

    RCUserInfo *user = [[RCUserInfo alloc]init];
    user.userId = @"jjf";
    user.name = @"吉*峰";
    user.portraitUri = @"http://pic.sc.chinaz.com/Files/pic/icons128/5329/13233.png";
    [array addObject:user];

    /** 可继续添加 */

    user = [[RCUserInfo alloc]init];
    user.userId = @"kf";
    user.name = @"在线客服";
    user.portraitUri = @"http://pic.sc.chinaz.com/Files/pic/icons128/4919/2.png";
    [array addObject:user];

    return array;
}
- (void)getUserInfoWithUserId:(NSString *)userId completion:(void(^)(RCUserInfo* userInfo))completion
{
    for (NSInteger i=0; i<_frindList.count; i++)
    {
        RCUserInfo* user = [_frindList objectAtIndex:i];
        if([user.userId isEqualToString:userId])
        {
            completion(user);
            break;
        }
    }
}

-(void)getGroupInfoWithGroupId:(NSString*)groupId completion:(void(^)(RCGroup* groupInfo))completion
{

}
#pragma 协议UITableViewDataSource
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return [_frindList count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell* cell = nil;
    NSString* kCellID = @"friend";

    cell = [_tableView dequeueReusableCellWithIdentifier:kCellID];
    if(cell == nil)
    {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:kCellID];
    }

    RCUserInfo* user = [_frindList objectAtIndex:indexPath.row];
    cell.textLabel.text = user.name;
    NSString* url = [user.portraitUri stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
    cell.imageView.image = [UIImage imageWithData:[NSData dataWithContentsOfURL:[[NSURL alloc] initWithString:url]]];

    return cell;
}
#pragma 协议UITableViewDelegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    [_tableView deselectRowAtIndexPath:indexPath animated:YES];

    UIViewController* chatController = nil;
    RCUserInfo* user = [_frindList objectAtIndex:indexPath.row];

    if([user.userId isEqualToString:@"kf"])
    {
        // 创建客服聊天视图控制器。
        RCChatViewController *chatViewController = [[RCIM sharedRCIM]createCustomerService:@"KEFU1420640265290" title:user.name completion:^()
        {
            // 创建 ViewController 后,调用的 Block,可以用来实现自定义行为。
        }];

        chatController = (UIViewController*)chatViewController;
    }
    else
    {
        // 创建单聊视图控制器。
        RCChatViewController *chatViewController = [[RCIM sharedRCIM] createPrivateChat:user.userId title:user.name completion:^()
        {
            // 创建 ViewController 后,调用的 Block,可以用来实现自定义行为。
        }];

        chatController = (UIViewController*)chatViewController;
    }
    // 把视图控制器添加到导航栈。
    [self.navigationController pushViewController:chatController animated:YES];
}
@end

项目工程

时间: 2024-10-06 00:43:36

点对点聊天吧的相关文章

局域网间的点对点聊天

聊天已经成为我们日常生活的一部分,各种聊天的软件已经飞满了我们的世界.今天就让我们来探讨一下局域网间的点对点的聊天吧. 我们在Eclipse中创建我们的工程. 其中带有Frame名字字样的工程是有界面的.如何在Eclipse中创建有界面的工程呢?我使用的VE插件,具体怎么用,问问度娘吧. ServerThread: package com.server; import java.io.BufferedReader; import java.io.IOException; import java.

socket实现的一个基本点对点聊天程序

多个TCP连接或多个应用程序进程可能需要通过同一个 TCP协议端口传输数据.为了区别不同的应用程序进程和连接,许多计算机操作系统为应用程序与TCP/IP协议交互提供了称为套接字(Socket)的接口. 服务器监听是指服务端套接字并不定位具体的客户端套接字,而是处于等待连接的状态,实时监控网络状态. 客户端请求是由客户端的套接字提出连接请求,要连接的目标是服务器端套接字.为此,客户端的套接字必须首先描述它要连接的服务器的套接字,指出服务器套接字的地址和端口号,然后再向服务器端套接字提出连接请求.

Activemq mqtt 点对点聊天实现(转载)

我这想到一个点对点聊天的方法,不用没割人都建立一个topic了,思路还是自定义一个分发策略,具体如下: 1.  建立一个topic,所有人都用匹配订阅的方式订阅以该topic为头的topic,例如:所有人都订阅PTP/#. 2.  例如A向B发送聊天信息,B的clientId是bbb,A只需要向PTP/bbb 推送聊天信息,我写的自定义策略会针对所有PTP开头的topic做自定义分发<policyEntry topic="PTP.>">,将topic里的clientI

Activemq mqtt 点对点聊天实现

我这想到一个点对点聊天的方法,不用没割人都建立一个topic了,思路还是自定义一个分发策略,具体如下: 1.  建立一个topic,所有人都用匹配订阅的方式订阅以该topic为头的topic,例如:所有人都订阅PTP/#. 2.  例如A向B发送聊天信息,B的clientId是bbb,A只需要向PTP/bbb 推送聊天信息,我写的自定义策略会针对所有PTP开头的topic做自定义分发<policyEntry topic="PTP.>">,将topic里的clientI

javaweb webSocket 实现简单的点对点聊天功能

本文依据 http://redstarofsleep.iteye.com/blog/1488639?page=4  内容修改完成,实现点对点聊天 需要 jdk 7 , tomcat需要支持websocket的版本 1.InitServlet 该类主要是用来初始化构造将来存储用户身份信息的map仓库,利用其初始化方法Init 初始化仓库, 利用其静态方法getSocketList 获得对应的用户身份信息. webSocket ,我认为MessageInbound 用来识别登录人的信息,用它来找到对

HTML5 WebSocket实现点对点聊天的示例代码

HTML5的websocket与Tomcat实现了多人聊天,那是最简单也是最基本的,其中注意的就是开发环境,要满足jdk1.7和tomcat8,当然了tom7的7.063也行,在网站上找到了用google关于websocket的点对点聊天,更好的是可以和大多数系统很好的配合起来看下效果图. 因为是模拟的,这里给出的是两个JSP页面A和B,里面分别向session里放了两个名字小明和小化,注意,这里的session是HttpSessionsession,之前多人聊天里的session是javax.

SignalR点对点聊天

public class ChatHub : Hub { //声明静态变量存储当前在线用户 public static class UserHandler { public static Dictionary<string, string> ConnectedIds = new Dictionary<string, string>(); } //用户进入页面时执行的(连接操作) public void userConnected(string name) { //进行编码,防止XS

Go语言实践_实现点对点聊天室

一.目的 使用Go语言实现一个服务器端与客户端的聊天室. 软件:Goland,Go1.9 二.思路 1,首先启动服务器端,使用listen_socket函数监听IP地址上的客户端连接: 2,启动客户端,并向服务器端发送数据,发送结束后端口阻塞,等待服务器端的消息: 3,服务器端接收到由客户端发送来的消息: 4,服务器端向客户端发送数据,发送结束后: 5,客户端接收到由服务器端发送来的消息,发送结束后端口阻塞,等待客户端的消息: 6,重复步骤2-5: 7,如果服务器端接收到由客户端发送来的“clo

聊天工具实现winform端实现

最近在找能够实现客户端点对点聊天的技术,通过github我发现了一个项目,它能够支持webscoket通讯,服务端是由c#socket完成. 我要的是winform端的通信,所以在他的基础上,增加了桌面的聊天,它同时支持web和winform.一个简易的聊天程序就算完成了,后面我将这个技术运用到实际的项目中. 上传我自己写的部分代码,为希望学习沟通程序的人提供参考,代码地址为 https://github.com/zuifengke/TTIM/ 来自为知笔记(Wiz)