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 |
目前已经实现微信风格 你也可以自定义风格 完全自定义风格的相关逻辑还需要开发
目前已经对接上融云 支持单聊 群聊 讨论组 聊天室
其它公有IM云服务还在计划中.....
IM后端逻辑相对复杂 MongoIM消息处理和服务端还在开发中.... 远期目标是开发一套稳定的可部署在私有云的IM服务
iOS:https://github.com/anyunzhong/MongoIM-iOS
Android:https://github.com/anyunzhong/MongoIM-Android
Server:开发中....
pod 'MongoIM'
#import "MongoIM.h"
MongoIM *im = [MongoIM sharedInstance];
DFMongoMessageHandler *messageHandler = [[DFMongoMessageHandler alloc] init];
im.messageHandler = messageHandler;
引入融云框架
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";
如果是媒体类消息(比如图片 文字 视频等) 直接继承 DFMediaMessageContent 如果是通知类消息(比如系统提示) 直接继承 DFNotifyMessageContent 当然你也可以直接继承DFMessageContent
注意消息的内容类型 需要与后面cell注册时的类型一样 也就是说是根据实体的类型找对应的cell来显示 另外 这个类型不要与系统已经有的一样 否则会冲突
@interface YourMessageContent : DFMediaMessageContent
@property (nonatomic, strong) NSString *your_field;
@end
如果需要显示头像 直接继承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
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]];