MongoIM 1.0.3

MongoIM 1.0.3

TestsTested
LangLanguage Obj-CObjective C
License Apache 2
ReleasedLast Release Mar 2016

Maintained by anyunzhong.



 
Depends on:
DFCommon~> 1.3.7
AFNetworking~> 2.6.0
SDWebImage~> 3.7.3
FMDB~> 2.5
MBProgressHUD~> 0.9.1
MLLabel~> 1.7
MJRefresh~> 2.4.11
ODRefreshControl~> 1.2
MJPhotoBrowser~> 1.0.2
MMPopupView>= 0
TZImagePickerController>= 0
FLAnimatedImage~> 1.0.10
SWTableViewCell~> 0.3.7
MWPhotoBrowser>= 0
 

MongoIM 1.0.3

  • By
  • Fast-Dev-Kit

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

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
Android:https://github.com/anyunzhong/MongoIM-Android
Server:开发中....


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;


会话列表

    DFConversationViewController *conversationController = [[DFConversationViewController alloc] init];


聊天

    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]];