美文网首页iOS 开发每天分享优质文章
OC即时聊天-对接融云填坑攻略

OC即时聊天-对接融云填坑攻略

作者: 8a420e49153d | 来源:发表于2018-09-25 14:05 被阅读73次

最近一段时间,开了一个新项目,涉及到即时聊天.对接的融云,也是踩了无数个坑.在这里总结一下,供大家参考.
如果你也遇到了问题.欢迎留言,自我感觉也是踩完大部分坑了.

一.注册融云 下载并接入SDK
这个其实没啥说的, https://www.rongcloud.cn/docs/ios.html 官方链接,可以帮你完成基本的接入及使用问题.

二.信息提供者
这是最坑的地方,也是融云核心所在. 涉及到的东西有点多,可能会说的有点乱.

先看官方说法:
融云认为,每一个设计良好且功能健全的 App 都应该能够在本地获取、缓存并在合适的时机更新 App 中的用户信息。所以,融云不维护和管理用户基本信息(用户ID、昵称、头像)的获取、缓存、变更和同步。
核心模式解答:
官方的意思就是说,我不保存头像和昵称这些信息. 我只有对话信息. app服务器(自己的接口)和融云都有聊天对象的id,用id来识别.完成整个数据的拼接组合.而这个过程的入口,就是信息提供者的几个方法.

我贴一下我的实现代码.和实现逻辑. 为了完成单聊和群聊.这几个代理都实现了.

1.在AppDelegate初始化融云,并创建信息提供者单例类,CTRongManager.

- (void)initRongClound:(UIApplication *)application{
    
    [UIApplication sharedApplication].applicationIconBadgeNumber = 0;
    
    //融云
    [[RCIM sharedRCIM] initWithAppKey:key_rongyun];
    //设置用户信息提供者为 [RCDataManager shareManager]
    [RCIM sharedRCIM].userInfoDataSource = [CTRongManager shareManager];
    //设置群组信息提供者为 [RCDataManager shareManager]
    [RCIM sharedRCIM].groupInfoDataSource = [CTRongManager shareManager];
    //群成员数据源
    [RCIM sharedRCIM].groupMemberDataSource = [CTRongManager shareManager];
    //群成员名片
    [RCIM sharedRCIM].groupUserInfoDataSource = [CTRongManager shareManager];;
    //头像设置
    [RCIM sharedRCIM].portraitImageViewCornerRadius = 15;
    //开启消息@功能(只支持群聊和讨论组, App需要实现群成员数据源groupMemberDataSource)
    [RCIM sharedRCIM].enableMessageMentioned = YES;
    //开启消息撤回功能
    [RCIM sharedRCIM].enableMessageRecall = YES;
    //开启用户信息和群组信息的持久化
    [RCIM sharedRCIM].enablePersistentUserInfoCache = YES;
    //SDK中全局的导航按钮字体颜色
    [RCIM sharedRCIM].globalNavigationBarTintColor = [UIColor blackColor];
    //关闭声音
    [RCIM sharedRCIM].disableMessageAlertSound = YES;
    
    [RCIM sharedRCIM].receiveMessageDelegate = self;
    
    /**
     * 推送处理1
     */
    if ([application
         respondsToSelector:@selector(registerUserNotificationSettings:)]) {
        //注册推送, 用于iOS8以及iOS8之后的系统
        UIUserNotificationSettings *settings = [UIUserNotificationSettings
                                                settingsForTypes:(UIUserNotificationTypeBadge |
                                                                  UIUserNotificationTypeSound |
                                                                  UIUserNotificationTypeAlert)
                                                categories:nil];
        [application registerUserNotificationSettings:settings];
    } else {
        //注册推送,用于iOS8之前的系统
        UIRemoteNotificationType myTypes = UIRemoteNotificationTypeBadge |
        UIRemoteNotificationTypeAlert |
        UIRemoteNotificationTypeSound;
        [application registerForRemoteNotificationTypes:myTypes];
    }

    
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(didReceiveMessageNotification:)
                                                 name:RCKitDispatchMessageNotification
                                               object:nil];

}

我们开启了很多功能 用不到的话,可以不开启.

下面是核心代码,CTRongManager单例类.
CTRongManager.h

#import <Foundation/Foundation.h>
#import <RongIMKit/RongIMKit.h>
@interface CTRongManager : NSObject <RCIMUserInfoDataSource,RCIMGroupInfoDataSource,RCIMGroupUserInfoDataSource,RCIMGroupMemberDataSource>

/**
 *  CTRongManager单例对象
 *
 *  @return CTRongManager单例
 */
+(CTRongManager *) shareManager;

/**
 *  登录融云服务器(connect,用token去连接)
 *
 *  @param token    token令牌
 */
-(void)loginRongCloud;

/**
 *  刷新tabbar的角标
 */
-(void) refreshBadgeValue;


//获取个人信息
- (void)getUserInfoWithUserId:(NSString*)userId completion:(void (^)(RCUserInfo*))completion;
//获取获取群信息信息
- (void)getGroupInfoWithGroupId:(NSString *)groupId
                     completion:(void (^)(RCGroup *groupInfo))completion;
//获取群组内的用户信息。
- (void)getUserInfoWithUserId:(NSString *)userId
                      inGroup:(NSString *)groupId
                   completion:(void (^)(RCUserInfo *userInfo))completion;


@end

CTRongManager.m (都有注释)

#import "CTRongManager.h"
#import "CTRongCloudHandle.h"
#import "CTRongGroupModel.h"
@implementation CTRongManager

- (instancetype)init{
    if (self = [super init]) {
        [RCIM sharedRCIM].userInfoDataSource = self;
        [RCIM sharedRCIM].groupInfoDataSource = self;
        [RCIM sharedRCIM].groupUserInfoDataSource = self;
        [RCIM sharedRCIM].groupMemberDataSource = self;

    }
    return self;
}

+ (CTRongManager *)shareManager{
    static CTRongManager* manager = nil;
    static dispatch_once_t predicate;
    dispatch_once(&predicate, ^{
        manager = [[[self class] alloc] init];
    });
    return manager;
}

//获取rongcloudToken
-(void)loginRongCloud{

    [CTRongCloudHandle getRongCloudWithsuccess:^(NSDictionary * obj) {
        [self connectRongClound:obj[@"rongcloudToken"]];
    } failed:^(id obj) {
        [SVProgressHUD showErrorWithStatus:obj];
    }];

}

//链接融云
-(void)connectRongClound:(NSString *)rongcloudToken{
    [SVProgressHUD show];
    [[RCIM sharedRCIM] connectWithToken:rongcloudToken  success:^(NSString *userId) {
        [SVProgressHUD dismiss];
        NSLog(@"登陆成功。当前登录的用户ID:%@", userId);

//设置用户自己,这个很重要,不写的话,在对话页面可能看不到自己的头像信息.
        RCUserInfo * user = [[RCUserInfo alloc]initWithUserId:[CTUserInfor shareUser].userId name:[CTUserInfor shareUser].nickName portrait:[CTUserInfor shareUser].avatarUrl];
        [[RCIM sharedRCIM] setCurrentUserInfo:user];
        [[CTRongManager shareManager] refreshBadgeValue];
        

        //下面的两个请求算是优化,在开始的时候,请求数据,存数据库.可以做到使用的时候,直接取.
        //获取好友关系
        [CTRongCloudHandle getContactRelationShipWithsuccess:^(id obj) {
            NSLog(@"好友信息");
        } failed:^(id obj) {
            
        }];
        
        //获取群组关系
        [CTRongCloudHandle getGroupRelationShipWithsuccess:^(id obj) {
            NSLog(@"群组信息");
            //同步群成员信息
            for (CTRongGroupModel *model in obj) {
                [CTRongCloudHandle getGroupMembersWithgroupId:model.groupId success:^(NSArray * obj) {
                    
                } failed:^(id obj) {
                  
                }];
            }
            
        } failed:^(id obj) {
            
        }];
  
    } error:^(RCConnectErrorCode status) {
        NSLog(@"登陆的错误码为:%ld", (long)status);
        [SVProgressHUD dismiss];
        UIAlertController *alertText = [UIAlertController alertControllerWithTitle:@"提示" message:@"聊天系统连接失败,请点击重连" preferredStyle:UIAlertControllerStyleAlert];
        
        [alertText addAction:[UIAlertAction actionWithTitle:@"算了,不连了" style:UIAlertActionStyleCancel handler:^(UIAlertAction *action) {
        }]];
        
        [alertText addAction:[UIAlertAction actionWithTitle:@"重新连接" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
            //重新连接
            [self connectRongClound:rongcloudToken];
            
        }]];
        [kKeyWindow.rootViewController presentViewController:alertText animated:YES completion:nil];
        
    } tokenIncorrect:^{
        [SVProgressHUD dismiss];
        //token过期或者不正确。
        //如果设置了token有效期并且token过期,请重新请求您的服务器获取新的token
        //如果没有设置token有效期却提示token错误,请检查您客户端和服务器的appkey是否匹配,还有检查您获取token的流程。
        NSLog(@"token错误");
        UIAlertController *alertText = [UIAlertController alertControllerWithTitle:@"提示" message:@"聊天系统连接失败,请点击重连" preferredStyle:UIAlertControllerStyleAlert];

        [alertText addAction:[UIAlertAction actionWithTitle:@"算了,不连了" style:UIAlertActionStyleCancel handler:^(UIAlertAction *action) {
        }]];
    
        [alertText addAction:[UIAlertAction actionWithTitle:@"重新连接" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
            //连token一起重新请求,连接
            [self loginRongCloud];
            
        }]];
        [kKeyWindow.rootViewController presentViewController:alertText animated:YES completion:nil];

    }];
}


#pragma mark
#pragma mark - RCIMUserInfoDataSource
- (void)getUserInfoWithUserId:(NSString*)userId completion:(void (^)(RCUserInfo*))completion
{
    
    if ([userId isEqualToString:[CTUserInfor shareUser].userId]) {
        RCUserInfo * user = [[RCUserInfo alloc]initWithUserId:[CTUserInfor shareUser].userId name:[CTUserInfor shareUser].nickName portrait:[CTUserInfor shareUser].avatarUrl];
        
        completion(user);
    }else{
        CTRongUserModel * model = [[CTDataBaseManager shareInstance] getUserByUserId:userId];
        
        if (model.friendUserId) {
            RCUserInfo * user = [[RCUserInfo alloc]initWithUserId:model.friendUserId name:model.friendNickName portrait:model.avatarUrl];
            completion(user);
        }else{
            //获取 任何人都行
            [CTRongCloudHandle getUserinforWithUserId:userId success:^(CTRongUserModel * userModel) {
                RCUserInfo * user = [[RCUserInfo alloc]initWithUserId:userModel.friendUserId name:userModel.friendNickName portrait:userModel.avatarUrl];
                completion(user);
            } failed:^(id obj) {
                
            }];
        }
    }

}

#pragma mark - RCIMGroupInfoDataSource
- (void)getGroupInfoWithGroupId:(NSString *)groupId
                     completion:(void (^)(RCGroup *groupInfo))completion{
    
   CTRongGroupModel * model = [[CTDataBaseManager shareInstance] getGroupByGroupId:groupId];
    if (model.groupId) {
        RCGroup * group = [[RCGroup alloc]initWithGroupId:model.groupId groupName:model.groupName portraitUri:model.avatarUrl];
        
        completion(group);
    }else{
        
        [CTRongCloudHandle getRelationshipWithfriendGroupIds:groupId success:^(NSArray * list) {
            CTRongGroupModel * groupModel = list[0];
            RCGroup * group = [[RCGroup alloc]initWithGroupId:groupModel.groupId groupName:groupModel.groupName portraitUri:groupModel.avatarUrl];
            completion(group);
        } failed:^(id obj) {
            
        }];
    }
    
}

#pragma mark - RCIMGroupUserInfoDataSource

/**
 *  获取群组内的用户信息。
 *  如果群组内没有设置用户信息,请注意:1,不要调用别的接口返回全局用户信息,直接回调给我们nil就行,SDK会自己巧用用户信息提供者;2一定要调用completion(nil),这样SDK才能继续往下操作。
 *
 *  @param groupId  群组ID.
 *  @param completion 获取完成调用的BLOCK.
 */
- (void)getUserInfoWithUserId:(NSString *)userId
                      inGroup:(NSString *)groupId
                   completion:(void (^)(RCUserInfo *userInfo))completion {
    //在这里查询该group内的群名片信息,如果能查到,调用completion返回。如果查询不到也一定要调用completion(nil)
   
    //数据库取
    NSArray * members = [[CTDataBaseManager shareInstance] getGroupMember:groupId];
    
    if (members.count > 0) {
        for (RCUserInfo * user in members) {
            if ([user.userId isEqualToString:userId]) {
                completion(user);
            }
        }
    }else{
        //没取到 请求  获取 任何人都行
       [CTRongCloudHandle getUserinforWithUserId:userId success:^(CTRongUserModel * userModel) {
            RCUserInfo * user = [[RCUserInfo alloc]initWithUserId:userModel.friendUserId name:userModel.friendNickName portrait:userModel.avatarUrl];
            completion(user);
        } failed:^(id obj) {
            completion(nil);
        }];
        
    }
    
    
}


- (void)getAllMembersOfGroup:(NSString *)groupId result:(void (^)(NSArray<NSString *> *userIdList))resultBlock{
    
    NSArray * members = [[CTDataBaseManager shareInstance] getGroupMember:groupId];
    
    if (members.count > 0) {
        
        NSMutableArray *ret = [[NSMutableArray alloc] init];
        for (RCUserInfo *user in members) {
            [ret addObject:user.userId];
        }
        resultBlock(ret);

    }else{
        [CTRongCloudHandle getGroupMembersWithgroupId:groupId success:^(NSArray * obj) {
            NSMutableArray *ret = [[NSMutableArray alloc] init];
            for (RCUserInfo *user in obj) {
                [ret addObject:user.userId];
            }
            resultBlock(ret);
        } failed:^(id obj) {
            
        }];
    }
    
}




//刷新角标
-(void)refreshBadgeValue{
    
    dispatch_async(dispatch_get_main_queue(), ^{
        
        NSInteger unreadMsgCount = (NSInteger)[[RCIMClient sharedRCIMClient] getUnreadCount:@[@(ConversationType_PRIVATE),@(ConversationType_GROUP)]];
        
        UINavigationController  *chatNav = ((CTTabBarController*)kKeyWindow.rootViewController).viewControllers[1];
        if (unreadMsgCount == 0) {
            chatNav.tabBarItem.badgeValue = nil;
        }else{
            if (unreadMsgCount>=100) {
                chatNav.tabBarItem.badgeValue = @"99+";
            }else{
                chatNav.tabBarItem.badgeValue = [NSString stringWithFormat:@"%li",(long)unreadMsgCount];
            }
        }
    });
}



@end

上面就是各种信息提供者的各种实现,有几点需要注意
1.实现代理要遵守代理.别忘了
[RCIM sharedRCIM].userInfoDataSource = self;
[RCIM sharedRCIM].groupInfoDataSource = self;
[RCIM sharedRCIM].groupUserInfoDataSource = self;
[RCIM sharedRCIM].groupMemberDataSource = self;
2.实现的代理就是信息提供者.实现的思路是:首先去数据库取(因为链接融云之后 我们进行了数据请求,获取到了部分用户数据并存入了数据库,数据库创建下面会提到),取不到的话就请求接口(这里就需要一个可以获取任何人信息的接口,用来补充数据.)

三.数据库的创建
fmdb的使用,主要存储用户和群组信息
CTDataBaseManager.h

#import <Foundation/Foundation.h>
#import <Foundation/Foundation.h>
#import <RongIMKit/RongIMKit.h>
#import "CTRongUserModel.h"
#import "CTRongGroupModel.h"
@interface CTDataBaseManager : NSObject

+ (CTDataBaseManager *)shareInstance;

- (void)closeDBForDisconnect;

//存储用户信息
- (void)insertUserToDB:(CTRongUserModel *)user;

- (void)insertUserListToDB:(NSMutableArray *)userList complete:(void (^)(BOOL))result;

//从表中获取用户信息
- (CTRongUserModel *)getUserByUserId:(NSString *)userId;



//存储群组信息
- (void)insertGroupToDB:(CTRongGroupModel *)group;

//会崩溃(已弃用)
- (void)insertGroupsToDB:(NSMutableArray *)groupList complete:(void (^)(BOOL))result;

//从表中获取群组信息
- (CTRongGroupModel *)getGroupByGroupId:(NSString *)groupId;

//删除表中的群组信息
- (void)deleteGroupToDB:(NSString *)groupId;



//清空表中的所有的群组信息
- (BOOL)clearGroupfromDB;

//清空群组缓存数据
- (void)clearGroupsData;


//存储群组成员信息
- (void)insertGroupMemberToDB:(NSMutableArray *)groupMemberList
                      groupId:(NSString *)groupId
                     complete:(void (^)(BOOL))result;

//从表中获取群组成员信息
- (NSMutableArray *)getGroupMember:(NSString *)groupId;


/*
 * 获取所有用户信息
 */
- (NSArray *)getAllUserInfo:(void (^)(void))completion;
/*
 * 获取所有群组信息
 */
- (NSArray *)getAllGroupInfo:(void (^)(void))completion;





@end

CTDataBaseManager.m

#import "CTDataBaseManager.h"
#import "FMDatabase.h"
#import "FMDatabaseQueue.h"

@interface CTDataBaseManager ()

@property(nonatomic, strong) FMDatabaseQueue *dbQueue;

@end

@implementation CTDataBaseManager

static NSString *const userTableName = @"USERTABLE";
static NSString *const groupTableName = @"GROUPTABLEV2";
static NSString *const groupMemberTableName = @"GROUPMEMBERTABLE";
+ (CTDataBaseManager *)shareInstance {
    static CTDataBaseManager *instance = nil;
    static dispatch_once_t predicate;
    dispatch_once(&predicate, ^{
        instance = [[[self class] alloc] init];
        [instance dbQueue];
    });
    return instance;
}

- (FMDatabaseQueue *)dbQueue {
    if ([RCIMClient sharedRCIMClient].currentUserInfo.userId == nil) {
        return nil;
    }
    
    if (!_dbQueue) {
        NSArray *paths = NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES);
        NSString *const roungCloud = @"RongCloud";
        NSString *library = [[paths objectAtIndex:0] stringByAppendingPathComponent:roungCloud];
        NSString *dbPath = [library
                            stringByAppendingPathComponent:[NSString
                                                            stringWithFormat:@"RongIMDemoDB%@",
                                                            [RCIMClient sharedRCIMClient].currentUserInfo.userId]];
        _dbQueue = [FMDatabaseQueue databaseQueueWithPath:dbPath];
        if (_dbQueue) {
            [self createUserTableIfNeed];
        }
    }
    return _dbQueue;
}

//创建用户存储表
- (void)createUserTableIfNeed {
    [self.dbQueue inDatabase:^(FMDatabase *db) {
        if (![self isTableOK:userTableName withDB:db]) {
            NSString *createTableSQL = @"CREATE TABLE USERTABLE (id integer PRIMARY "
            @"KEY autoincrement, friendUserId text,friendNickName text, "
            @"avatarUrl text)";
            [db executeUpdate:createTableSQL];
            NSString *createIndexSQL = @"CREATE unique INDEX idx_userid ON USERTABLE(friendUserId);";
            [db executeUpdate:createIndexSQL];
        }
        
        if (![self isTableOK:groupTableName withDB:db]) {
            NSString *createTableSQL = @"CREATE TABLE GROUPTABLEV2 (id integer PRIMARY KEY autoincrement, "
            @"groupId text,groupName text, avatarUrl text,displayName text,roleType "
            @"text ,notDisturb text ,groupBanState text,banState text, banDate "
            @"text)";
            [db executeUpdate:createTableSQL];
            NSString *createIndexSQL = @"CREATE unique INDEX idx_groupid ON GROUPTABLEV2(groupId);";
            [db executeUpdate:createIndexSQL];
        }
        
        if (![self isTableOK:groupMemberTableName withDB:db]) {
            NSString *createTableSQL = @"CREATE TABLE GROUPMEMBERTABLE (id integer "
            @"PRIMARY KEY autoincrement, groupid text, "
            @"userid text,name text, portraitUri text)";
            [db executeUpdate:createTableSQL];
            NSString *createIndexSQL = @"CREATE unique INDEX idx_groupmemberId ON "
            @"GROUPMEMBERTABLE(groupid,userid);";
            [db executeUpdate:createIndexSQL];
        }

    }];
}

- (void)closeDBForDisconnect {
    self.dbQueue = nil;
}


//存储用户信息(任何人)
- (void)insertUserToDB:(CTRongUserModel *)user {
    NSString *insertSql = @"REPLACE INTO USERTABLE (friendUserId, friendNickName, avatarUrl) VALUES (?, ?, ?)";
    [self.dbQueue inDatabase:^(FMDatabase *db) {
        [db executeUpdate:insertSql, user.friendUserId, user.friendNickName, user.avatarUrl];
    }];
}

//存储用户列表信息(任何人)
- (void)insertUserListToDB:(NSMutableArray *)userList complete:(void (^)(BOOL))result {
    
    if (userList == nil || [userList count] < 1)
        return;
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{
        [self.dbQueue inTransaction:^(FMDatabase *db, BOOL *rollback) {
            for (CTRongUserModel *user in userList) {
                NSString *insertSql = @"REPLACE INTO USERTABLE (friendUserId, friendNickName, avatarUrl) VALUES (?, ?, ?)";

                [db executeUpdate:insertSql, user.friendUserId, user.friendNickName, user.avatarUrl];
            }
        }];
        result(YES);
    });
}


//从表中获取用户信息
- (CTRongUserModel *)getUserByUserId:(NSString *)friendUserId {
    __block CTRongUserModel *model = nil;
    
    [self.dbQueue inDatabase:^(FMDatabase *db) {
        FMResultSet *rs = [db executeQuery:@"SELECT * FROM USERTABLE where friendUserId = ?", friendUserId];
        while ([rs next]) {
            model = [[CTRongUserModel alloc] init];
            model.friendUserId = [rs stringForColumn:@"friendUserId"];
            model.friendNickName = [rs stringForColumn:@"friendNickName"];
            model.avatarUrl = [rs stringForColumn:@"avatarUrl"];
        }
        [rs close];
    }];
    return model;
}

//从表中获取所有用户信息
- (NSArray *)getAllUserInfo {
    NSMutableArray *allUsers = [NSMutableArray new];
    
    [self.dbQueue inDatabase:^(FMDatabase *db) {
        FMResultSet *rs = [db executeQuery:@"SELECT * FROM USERTABLE"];
        while ([rs next]) {
            CTRongUserModel *model;
            model = [[CTRongUserModel alloc] init];
            model.friendUserId = [rs stringForColumn:@"friendUserId"];
            model.friendNickName = [rs stringForColumn:@"friendNickName"];
            model.avatarUrl = [rs stringForColumn:@"avatarUrl"];
            [allUsers addObject:model];
        }
        [rs close];
    }];
    return allUsers;
}


//存储群组信息
- (void)insertGroupToDB:(CTRongGroupModel *)group {
    if (group == nil || [group.groupId length] < 1)
        return;

    NSString *insertSql = @"REPLACE INTO GROUPTABLEV2 (groupId, "
    @"groupName,avatarUrl,displayName,roleType,notDisturb,"
    @"groupBanState,banState,banDate) VALUES "
    @"(?,?,?,?,?,?,?,?,?)";
    
    [self.dbQueue inDatabase:^(FMDatabase *db) {
       [db executeUpdate:insertSql, group.groupId, group.groupName, group.avatarUrl, group.displayName, group.roleType,
         group.notDisturb, group.groupBanState, group.banState,
          group.banDate];
        
    }];
}

- (void)insertGroupsToDB:(NSMutableArray *)groupList complete:(void (^)(BOOL))result {
    
    if (groupList == nil || [groupList count] < 1)
        return;
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{
        [self.dbQueue inTransaction:^(FMDatabase *db, BOOL *rollback) {
            for (CTRongGroupModel *group in groupList) {
                NSString *insertSql = @"REPLACE INTO GROUPTABLEV2 (groupId, "
                @"groupName,avatarUrl,displayName,roleType,notDisturb,"
                @"groupBanState,banState,banDate) VALUES "
                @"(?,?,?,?,?,?,?,?,?)";
                [db executeUpdate:insertSql, group.groupId, group.groupName, group.avatarUrl, group.displayName, group.roleType,
                 group.notDisturb, group.groupBanState, group.banState,
                 group.banDate];
            }
        }];
        result(YES);
    });
}

//从表中获取群组信息
- (CTRongGroupModel *)getGroupByGroupId:(NSString *)groupId {
    __block CTRongGroupModel *model = nil;
    
    [self.dbQueue inDatabase:^(FMDatabase *db) {
        FMResultSet *rs = [db executeQuery:@"SELECT * FROM GROUPTABLEV2 where groupId = ?", groupId];
        while ([rs next]) {
            model = [[CTRongGroupModel alloc] init];
            model.groupId = [rs stringForColumn:@"groupId"];
            model.groupName = [rs stringForColumn:@"groupName"];
            model.avatarUrl = [rs stringForColumn:@"avatarUrl"];
            model.displayName = [rs stringForColumn:@"displayName"];
            model.roleType = [rs stringForColumn:@"roleType"];
            model.notDisturb = [rs stringForColumn:@"notDisturb"];
            model.groupBanState = [rs stringForColumn:@"groupBanState"];
            model.banState = [rs stringForColumn:@"banState"];
            model.banDate = [rs stringForColumn:@"banDate"];
        }
        [rs close];
    }];
    return model;
}

//删除表中的群组信息
- (void)deleteGroupToDB:(NSString *)groupId {
    if ([groupId length] < 1)
        return;
    NSString *deleteSql =
    [NSString stringWithFormat:@"delete from %@ where %@ = '%@'", @"GROUPTABLEV2", @"groupid", groupId];
    
    [self.dbQueue inDatabase:^(FMDatabase *db) {
        [db executeUpdate:deleteSql];
    }];
}

//清空表中的所有的群组信息
- (BOOL)clearGroupfromDB {
    __block BOOL result = NO;
    NSString *clearSql = [NSString stringWithFormat:@"DELETE FROM GROUPTABLEV2"];
    
    [self.dbQueue inDatabase:^(FMDatabase *db) {
        result = [db executeUpdate:clearSql];
    }];
    return result;
}

//从表中获取所有群组信息
- (NSMutableArray *)getAllGroup {
    NSMutableArray *allGroups = [NSMutableArray new];
    
    [self.dbQueue inDatabase:^(FMDatabase *db) {
        FMResultSet *rs = [db executeQuery:@"SELECT * FROM GROUPTABLEV2"];
        while ([rs next]) {
            CTRongGroupModel *model;
            model = [[CTRongGroupModel alloc] init];
            model.groupId = [rs stringForColumn:@"groupId"];
            model.groupName = [rs stringForColumn:@"name"];
            model.avatarUrl = [rs stringForColumn:@"avatarUrl"];
            model.displayName = [rs stringForColumn:@"displayName"];
            model.roleType = [rs stringForColumn:@"roleType"];
            model.notDisturb = [rs stringForColumn:@"notDisturb"];
            model.groupBanState = [rs stringForColumn:@"groupBanState"];
            model.banState = [rs stringForColumn:@"banState"];
            model.banDate = [rs stringForColumn:@"banDate"];

            [allGroups addObject:model];
        }
        [rs close];
    }];
    return allGroups;
}


//存储群组成员信息
- (void)insertGroupMemberToDB:(NSMutableArray *)groupMemberList
                      groupId:(NSString *)groupId
                     complete:(void (^)(BOOL))result {
    if (groupMemberList == nil || [groupMemberList count] < 1)
        return;
    
    NSString *deleteSql =
    [NSString stringWithFormat:@"delete from %@ where %@ = '%@'", @"GROUPMEMBERTABLE", @"groupid", groupId];
    
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{
        [self.dbQueue inTransaction:^(FMDatabase *db, BOOL *rollback) {
            [db executeUpdate:deleteSql];
            for (RCUserInfo *user in groupMemberList) {
                NSString *insertSql = @"REPLACE INTO GROUPMEMBERTABLE (groupid, userId, "
                @"name, portraitUri) VALUES (?, ?, ?, ?)";
                
                [db executeUpdate:insertSql, groupId, user.userId, user.name, user.portraitUri];
            }
        }];
        result(YES);
    });
}


//从表中获取群组成员信息
- (NSMutableArray *)getGroupMember:(NSString *)groupId {
    NSMutableArray *allUsers = [NSMutableArray new];
    
    [self.dbQueue inDatabase:^(FMDatabase *db) {
        FMResultSet *rs = [db executeQuery:@"SELECT * FROM GROUPMEMBERTABLE where groupid=? order by id", groupId];
        while ([rs next]) {
            //            RCUserInfo *model;
            RCUserInfo *model;
            model = [[RCUserInfo alloc] init];
            model.userId = [rs stringForColumn:@"userId"];
            model.name = [rs stringForColumn:@"name"];
            model.portraitUri = [rs stringForColumn:@"portraitUri"];
            [allUsers addObject:model];
        }
        [rs close];
    }];
    return allUsers;
}




//清空群组缓存数据
- (void)clearGroupsData {
    NSString *deleteSql = @"DELETE FROM GROUPTABLEV2";
    
    [self.dbQueue inDatabase:^(FMDatabase *db) {
        [db executeUpdate:deleteSql];
    }];
}


- (NSArray *)getAllUserInfo:(void (^)(void))completion {
    return [[CTDataBaseManager shareInstance] getAllUserInfo];
}

- (NSArray *)getAllGroupInfo:(void (^)(void))completion {
    return [[CTDataBaseManager shareInstance] getAllGroup];
}


- (BOOL)isTableOK:(NSString *)tableName withDB:(FMDatabase *)db {
    BOOL isOK = NO;
    
    FMResultSet *rs = [db executeQuery:@"select count(*) as 'count' from sqlite_master where "
                       @"type ='table' and name = ?",
                       tableName];
    while ([rs next]) {
        NSInteger count = [rs intForColumn:@"count"];
        
        if (0 == count) {
            isOK = NO;
        } else {
            isOK = YES;
        }
    }
    [rs close];
    
    return isOK;
}

- (BOOL)isColumnExist:(NSString *)columnName inTable:(NSString *)tableName withDB:(FMDatabase *)db {
    BOOL isExist = NO;
    
    NSString *columnQurerySql = [NSString stringWithFormat:@"SELECT %@ from %@", columnName, tableName];
    FMResultSet *rs = [db executeQuery:columnQurerySql];
    if ([rs next]) {
        isExist = YES;
    } else {
        isExist = NO;
    }
    [rs close];
    
    return isExist;
}





@end

这就是用户信息的存储,这是必要的.不可能所有的信息每次都请求接口.
基本上都这么写,没啥好说的.

四:通知推送.
首先你要知道本地通知和远程推送.在程序进入后台一段时间后,app被杀死. 才进入远程推送.推送的开启和关闭,我这边最后的结果是这样做的.
首先进入app,默认关闭推送声音,

//关闭声音
    [RCIM sharedRCIM].disableMessageAlertSound = YES;

然后在设置里面给一个开关,这个开关没有那么详细.就是开启或者关闭推送和通知.只要你关闭了,无论是推送还是通知统统收不到.

-(void)totalSwitchClick:(UISwitch *)swiftch{
    
    [SVProgressHUD show];
    if (swiftch.on) {
        [[RCIMClient sharedRCIMClient] setNotificationQuietHours:@"00:00:00"
                                                        spanMins:1439
                                                         success:^{
                                                             [SVProgressHUD dismiss];
                                                             [CTUserInfor shareUser].isOpenMessage = @"1";
                                                         }
                                                           error:^(RCErrorCode status) {
                                                               [SVProgressHUD dismiss];
                                                               dispatch_async(dispatch_get_main_queue(), ^{
                                                                   UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"提示"
                                                                                                                   message:@"设置失败"
                                                                                                                  delegate:nil
                                                                                                         cancelButtonTitle:@"取消"
                                                                                                         otherButtonTitles:nil, nil];
                                                                   [alert show];
                                                                   swiftch.on = NO;
                                                               });
                                                           }];
    } else {
        
        [[RCIMClient sharedRCIMClient] removeNotificationQuietHours:^{
            [SVProgressHUD dismiss];
            [CTUserInfor shareUser].isOpenMessage = @"0";
        }
                                                              error:^(RCErrorCode status) {
                                                                  [SVProgressHUD dismiss];
                                                                  dispatch_async(dispatch_get_main_queue(), ^{
                                                                      UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"提示"
                                                                                                                      message:@"取消失败"
                                                                                                                     delegate:nil
                                                                                                            cancelButtonTitle:@"取消"
                                                                                                            otherButtonTitles:nil, nil];
                                                                      [alert show];
                                                                      swiftch.on = YES;
                                                                  });
                                                              }];
    }
    
}

剩下的就是一些ui的自定制什么的了.
整体来说,融云还是蛮难接的.

相关文章

  • OC即时聊天-对接融云填坑攻略

    最近一段时间,开了一个新项目,涉及到即时聊天.对接的融云,也是踩了无数个坑.在这里总结一下,供大家参考.如果你也遇...

  • iOS 融云即时聊天遇到的坑

    1: 使用IQKeyboardManager来管理键盘, 点击输入框, 整体界面会上移一段距离 原因:这是因为使用...

  • 融云即时通讯坑点总结2018-5-29

    项目中包含直播通讯聊天以及客服聊天功能,在这里我集成了融云即时通讯的sdk,当然了,也碰到了相应的坑点,在这里记录...

  • 2017--融云---获取token

    很多人在用融云做即时通信的时候,遇到大大小小很多坑,这里为大家解决第一个坑! 获取融云的token,一般都是后台开...

  • Swift集成融云即时聊天SDK

    首先感谢@Chaman_Elephant 参考他的做的这里是oc的融云集成 有兴趣的同学可以去看看他的文章 htt...

  • Android 即时聊天-融云IM集成。

    效果图: 开发前我们需要先去官网注册:融云官网 只需输入应用名称和描述即可创建成功。 为了集成更加方便,我们下载官...

  • 9.3融云 RongCloudKit 即时聊天软件

    本来推荐的是用环信,还没研究懂。学习下用融云吧。 1.配置环境 pod search RongCloudKitpo...

  • iOS 集成融云即时通讯出现的问题

    前段时间一个项目需要集成聊天功能,市面上的第三方即时通讯很多,有环信、融云等等,而我这里集成的是融云即时通讯,在集...

  • web即时通讯

    php实现即时聊天(基于融云通讯),目前只是简单的事例。今天看到了一个挺有意思的项目,即时聊天工具。虽然有QQ这样...

  • 「React Native」即时聊天-融云IM封装

    (一) 功能 在React Native封装了会话列表,支持跳转到会话详情,滑动删除,动态刷新会话列表等等。(会话...

网友评论

    本文标题:OC即时聊天-对接融云填坑攻略

    本文链接:https://www.haomeiwen.com/subject/mobkoftx.html