anyunzhong / MongoIM-iOS

即时通信 IM 支持发送文字 语音 图片 短视频 位置 红包 名片...

Home Page:http://mongo.im

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

MongoIM

支持发送文字 语音 图片 短视频 位置 红包 名片...

http://file-cdn.datafans.net/github/mongoimios/cover1.jpg


架构

http://file-cdn.datafans.net/github/mongoimios/arch1.png


### UI层风格可切换 目前已经实现微信风格 你也可以自定义风格 完全自定义风格的相关逻辑还需要开发
### 消息处理层可切换 目前已经对接上融云 支持单聊 群聊 讨论组 聊天室
其它公有IM云服务还在计划中.....
IM后端逻辑相对复杂 MongoIM消息处理和服务端还在开发中.... 远期目标是开发一套稳定的可部署在私有云的IM服务
### 多终端支持 iOS:[https://github.com/anyunzhong/MongoIM-iOS](https://github.com/anyunzhong/MongoIM-iOS)
Android:[https://github.com/anyunzhong/MongoIM-Android](https://github.com/anyunzhong/MongoIM-Android)
Server:开发中....
MongoIM-iOS ============= [![Version](https://img.shields.io/cocoapods/v/MongoIM.svg?style=flat)](http://cocoapods.org/pods/MongoIM) [![License](https://img.shields.io/cocoapods/l/MongoIM.svg?style=flat)](http://cocoapods.org/pods/MongoIM) [![Platform](https://img.shields.io/cocoapods/p/MongoIM.svg?style=flat)](http://cocoapods.org/pods/MongoIM) [![Gitter](https://badges.gitter.im/Join Chat.svg)](https://gitter.im/anyunzhong/MongoIM-iOS)
安装 ============
pod 'MongoIM'

快速开始 ===============
#import "MongoIM.h"

####初始化

MongoIM *im = [MongoIM sharedInstance];

####设置消息处理器(消息的接收和存储 连接等)

#####1.默认消息消息处理器 目前还在完善中 需要配合MongoIM服务端项目使用 目前还在开发中

    DFMongoMessageHandler *messageHandler = [[DFMongoMessageHandler alloc] init];
    im.messageHandler = messageHandler;
    

#####2.融云消息处理器 具体请参考 http://rongcloud.cn 引入融云框架

pod 'RongCloudIMLib', '~> 2.4.5'

然后将MongoIM/Extend/Vendor/RongCloud文件夹拖到工程 (因为融云的pod不是开源代码 打包成了framework形式 所以没有集成到Mongo.pod中 这样有另外一个好处 按需定制 你不需要集成融云 就不用拖入扩展类)

设置消息处理器为融云

    DFRongCloudMessageHandler *messageHandler = [[DFRongCloudMessageHandler alloc] initWithAppKey:@"你的融云Appkey" token:@"通过融云获取到的token"];
    im.messageHandler = messageHandler;

####会话列表 ```obj-c DFConversationViewController *conversationController = [[DFConversationViewController alloc] init]; ```
####聊天 ```obj-c DFMessageViewController *messageViewController = [[DFMessageViewController alloc] initWithTargetId:@"目标用户ID" conversationType:@"聊天类型"]; ```
界面及相关逻辑 ===============

####设置用户头像 昵称等

    UserInfoProvider provider = ^(NSString *userId, UserInfoCallback callback){
        
        可以直接从本地读取 也可以从网络获取
        DFUserInfo *userinfo = [[DFUserInfo alloc] init];
        
        userinfo.userId = userId;
        if ([userId isEqual:@"100010"]) {
            userinfo.avatar = @"http://file-cdn.datafans.net/avatar/1.jpeg";
            userinfo.nick = @"Allen";
        }else  if ([userId isEqual:@"100020"]) {
            userinfo.avatar = @"http://file-cdn.datafans.net/avatar/2.jpg";
            userinfo.nick = @"Yanhua";
        }else{
            userinfo.avatar = @"";
            userinfo.nick = userId;
        }
        
        //回调信息
        callback(userinfo);
        
    };
    im.userInfoProvider = provider;

####添加表情包

    NSMutableArray *items = [NSMutableArray array];
    for (int i=1; i<=32; i++) {
        DFPackageEmotionItem *item = [[DFPackageEmotionItem alloc] init];
        item.remoteGif = [NSString stringWithFormat:@"http://file-cdn.datafans.net/emotion/yellow_chicken/gif/%d.gif", i];
        item.remoteThumb = [NSString stringWithFormat:@"http://file-cdn.datafans.net/emotion/yellow_chicken/png/%d.png", i];
        //item.localGif 本地gif 如果有 优先显示本地的资源
        //item.localThumb 本地静态图 如果存在 优先显示本地资源
        
        item.name = [NSString stringWithFormat:@"小黄鸡%d",i];
        [items addObject:item];
    }
    
    //用于聊天窗口 表情窗底部那一排显示在tab上的小图标
    NSString *iconPath = @"http://file-cdn.datafans.net/emotion/yellow_chicken/icon3x.png";
    DFPackageEmotion *emotion = [[DFPackageEmotion alloc] initWithIcon:iconPath total:items.count items:items];
    [[MongoIM sharedInstance] addEmotionPackage:emotion];


    //模拟一组小鸟动态表情 一共16个
    
    NSMutableArray *items2 = [NSMutableArray array];
    for (int i=1; i<=16; i++) {
        DFPackageEmotionItem *item = [[DFPackageEmotionItem alloc] init];
        item.remoteGif = [NSString stringWithFormat:@"http://file-cdn.datafans.net/emotion/bird/gif/%d.gif", i];
        item.remoteThumb = [NSString stringWithFormat:@"http://file-cdn.datafans.net/emotion/bird/png/%d.png", i];
        //item.localGif 本地gif 如果有 优先显示本地的资源
        //item.localThumb 本地静态图 如果存在 优先显示本地资源
        
        item.name = [NSString stringWithFormat:@"蓝小鸟%d",i];
        [items2 addObject:item];
    }
    
    //用于聊天窗口 表情窗底部那一排显示在tab上的小图标
    NSString *iconPath2 = @"http://file-cdn.datafans.net/emotion/bird/icon3x.png";
    DFPackageEmotion *emotion2 = [[DFPackageEmotion alloc] initWithIcon:iconPath2 total:items2.count items:items2];
    [[MongoIM sharedInstance] addEmotionPackage:emotion2];

####点击插件后弹出的界面

    //默认已经实现的有 照片选择 拍照 选地点 如果需要自定义弹出界面 直接通过注册的方式覆盖原有实现即可
    //其它的都需要你去实现 通过传入的_plugin来发送消息 发送后记得dismiss当前controller
    //如果是自定义plugin 则直接覆盖基类onClick方法即可实现相同效果
    //收藏
    DFFavouriteChooseController *favouriteController = [[DFFavouriteChooseController alloc] init];
    UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:favouriteController];
    [[MongoIM sharedInstance] registerPresentController:[DFFavouritePlugin class] controller:nav];
    
    //红包
    DFRedBagCreateController *redBagController = [[DFRedBagCreateController alloc] init];
    UINavigationController *nav2 = [[UINavigationController alloc] initWithRootViewController:redBagController];
    [[MongoIM sharedInstance] registerPresentController:[DFRedBagPlugin class] controller:nav2];
    
    //名片
    DFNameCardChooseController *nameCardController = [[DFNameCardChooseController alloc] init];
    UINavigationController *nav3 = [[UINavigationController alloc] initWithRootViewController:nameCardController];
    [[MongoIM sharedInstance] registerPresentController:[DFNameCardPlugin class] controller:nav3];

####配置需要使用的插件

    DFRedBagPlugin *plugin = [[DFRedBagPlugin alloc] init];
    NSArray *plugins = @[plugin];
    [[MongoIM sharedInstance] resetPlugins:plugins];

####点击消息气泡执行的动作

    //默认实现的有 图片 分享 位置三种消息 如果要设置系统自带消息的点击行为 则通过注册消息点击handler的方式执行
    //如果是自己定义的消息显示cell 则直接覆盖基类onClick方法即可实现同样效果
    [[MongoIM sharedInstance] registerMessageClickHandler:MessageContentTypeRedBag delegate:self];

    -(void)onClick:(DFMessage *)message controller:(UINavigationController *)controller
    {
        UIAlertView * alert = [[UIAlertView alloc]initWithTitle:@"点击了消息" message:@"抢到红包了吗?" delegate:self cancelButtonTitle:@"取消" otherButtonTitles:@"确定", nil];
        [alert show];
    }

####位置发送和显示 需要使用高德地图

    //申请地址: http://lbs.amap.com/
    //注意: key和bundleId需要对应
    [MAMapServices sharedServices].apiKey = @"323c95e56dc16b7da2c9ebcb67b61f03";
    [AMapSearchServices sharedServices].apiKey = @"323c95e56dc16b7da2c9ebcb67b61f03";

自定义扩展 ============

####自定义新的消息及显示

1.新的消息类型

如果是媒体类消息(比如图片 文字 视频等) 直接继承 DFMediaMessageContent 如果是通知类消息(比如系统提示) 直接继承 DFNotifyMessageContent 当然你也可以直接继承DFMessageContent

注意消息的内容类型 需要与后面cell注册时的类型一样 也就是说是根据实体的类型找对应的cell来显示 另外 这个类型不要与系统已经有的一样 否则会冲突

    @interface YourMessageContent : DFMediaMessageContent
        @property (nonatomic, strong) NSString *your_field;
    @end

#####2. 消息显示 如果需要显示头像 直接继承DFMessageCell 如果不需要 直接继承DFBaseMessageCell 例如:定义一个需要显示头像类型的cell

   
@implementation DFYourMessageCell

- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
    if (self) {
        //初始化相关view
        [self.messageContentView addSubview:your_view];
    }
    return self;
}


-(void)updateWithMessage:(DFMessage *)message
{
    [super updateWithMessage:message];
    
    //将数据绑定到view上
    
}

-(CGSize)getMessageContentViewSize
{
    //返回中间内容需要的尺寸
    return CGSizeMake(宽度,高度);
}

-(CGFloat)getCellHeight:(DFMessage *)message
{
    return 内容的高度 + [super getCellHeight:message];
}

-(void)onClick:(DFMessage *)message controller:(UINavigationController *)controller
{
    //点击消息后处理
}


-(void)onMenuShow:(BOOL)show
{
    //长按显示菜单后处理 比如将bubble颜色变深
}
@end

不需要显示头像

@implementation DFYourMessageCell
- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
    if (self) {
        //初始化view
        [self.baseContentView addSubview:your_view];
    }
    return self;
}

-(void)updateWithMessage:(DFMessage *)message
{
    [super updateWithMessage:message];
    
   //更新数据
    
}

-(CGFloat)getCellHeight:(DFMessage *)message
{
    return 内容的高度 + [super getCellHeight:message];
}
@end

#####3. 注册消息显示cell

   DFMessageCellManager *manager = [DFMessageCellManager sharedInstance];
   [manager registerCell:@"你的消息内容类型" cellClass:[DFYouressageCell class]];

####自定义插件

@interface YourPlugin : DFBasePlugin

@end



@implementation YourPlugin

- (instancetype)init
{
    self = [super init];
    if (self) {
        self.icon = @"sharemore_location";
        self.name = @"位置";
    }
    return self;
}

-(void)onClickDefault
{
    //处理点击后的行为
}

@end

注册插件

    DFPluginsManager *manager = [DFPluginsManager sharedInstance];
    YourPlugin *plugin = [[YourPlugin alloc] init];
    [manager addPlugin:plugin];

融云消息扩展 ============

####新增融云消息 具体可参照默认的红包 短视频等消息的实现 具体细节可以参考融云官方文档

@interface YourRongCloudMessage : RCMessageContent
@property (strong, nonatomic) NSString *title;
@end

@implementation YourRongCloudMessage

-(NSData *)encode
{
    NSMutableDictionary *dic = [NSMutableDictionary dictionary];
    [dic setObject:_title forKey:@"title"];
    return [NSDictionary dic2jsonData:dic];
}

-(void)decodeWithData:(NSData *)data
{
    NSDictionary *dic = [NSDictionary jsonData2Dic:data];
    _title = [dic objectForKey:@"title"];
}

+(NSString *)getObjectName
{
    return @"你定义的融云消息类型";
}


+(RCMessagePersistent)persistentFlag
{
    return MessagePersistent_ISPERSISTED | MessagePersistent_ISCOUNTED;
}

####注册融云消息

[[RCIMClient sharedRCIMClient] registerMessageType:[YourRongCloudMessage class]];

####对接融云消息

将融云消息转换为MongoIM消息

@interface RongCloudToMongoYourMessageContentAdapter : RongCloudToMongoMessageContentAdapter
@end

@implementation RongCloudToMongoYourMessageContentAdapter

-(DFMessageContent *)getMongoMessageContent:(RCYourMessage *)yourgMessage
{
    YourMessageContent *messageContent = [[YourMessageContent alloc] init];
    messageContent.title = redBagMessage.title; //这里对应你设置的字段
    ........
    return messageContent;
}

-(NSString *)getMongoMessageType
{
    return @"你的自定义消息类型";  //不要与融云那边消息类型混淆了
}

-(NSString *)getConversationSubTitle:(RCRedBagMessage *)redBagMessage
{
    return @"会话列表需要显示的文字";
}

@end

将MongoIM的消息转换成融云的

@interface MongoToRongCloudYourMessageContentAdapter : MongoToRongCloudMessageContentAdapter
@end

@implementation MongoToRongCloudYourMessageContentAdapter

-(RCMessageContent *)getRongCloudMessageContent:(YourMessageContent *)yourMessage
{
    return [.......]; //你的转换逻辑
}
@end

注册新增的类型

 RongCloudToMongoMessageContentAdapterManager *rongManager = [RongCloudToMongoMessageContentAdapterManager sharedInstance];
 [rongManager registerAdapter:[YourRongCloudMessage class] adapterClazz:[RongCloudToMongoYourMessageContentAdapter class]];
 
 MongoToRongCloudMessageContentAdapterManager *mongoManager = [MongoToRongCloudMessageContentAdapterManager sharedInstance];
 [mongoManager registerAdapter:[YourMessageContent class] adapterClazz:[MongoToRongCloudYourMessageContentAdapter class]];

About

即时通信 IM 支持发送文字 语音 图片 短视频 位置 红包 名片...

http://mongo.im

License:Apache License 2.0


Languages

Language:Objective-C 99.5%Language:Ruby 0.5%