IOS

IOS

【社区精华|持续更新】收录本社区精华内容,手把手教学IM/RTC开发!

IM即时通讯admin 发表了文章 • 8 个评论 • 492 次浏览 • 2020-12-07 14:41 • 来自相关话题

本文收录了GeekOnline社区精华内容,希望帮助社区开发者学习IM+RTC知识,解答疑惑。赠人玫瑰,手有余香,如您有不错的内容需要收录,欢迎在在评论区投稿回复。Android篇融云即时通讯SDK集成 — 通知检查融云 IM SDK 集成 —- 刷新会话界面... ...查看全部

本文收录了GeekOnline社区精华内容,希望帮助社区开发者学习IM+RTC知识,解答疑惑。赠人玫瑰,手有余香,如您有不错的内容需要收录,欢迎在在评论区投稿回复。

微信截图_20201207144054.png

Android篇

融云即时通讯SDK集成 — 通知检查

融云 IM SDK 集成 —- 刷新会话界面和会话列表界面

Android 端如何添加自定义表情

解决融云 SDK 4.0 版本配置 https 导航报 SSLHandshakeException

融云清空历史消息 Android 端

唠一唠融云的消息扩展功能

融云 IMkit 拦截或监听所有发送消息

融云如何把图片消息的图片上传到自己的文件服务器

唠一唠融云 VIVO push 无法跳转的解决方案

融云即时通讯SDK集成 — 定制UI(一) ——会话界面小改动

融云即时通讯SDK集成 — 定制UI(二) ——添加自定义表情库

融云即时通讯SDK集成 — 定制UI(三) ——兼容Android Q

融云如何把图片消息的图片上传到自己的文件服务器

融云即时通讯SDK集成 — 华为推送的点击跳转处理

带你实现女朋友欲罢不能的 App

Flutter 集成融云 sdk

配置融云SDK的自签证书

自定义消息 包含 list 数组

关于融云聊天室KV 值的正确使用

融云 IM SDK 转 AndroidX

融云即时通讯SDK集成 — 国内厂商推送集成踩坑篇(Android平台)

在融云 IMkit 会话界面基础上添加消息已读未读

融云聊天室属性 kv

融云 ConversationListFragment 会话列表添加头部布局

融云即时通讯SDK集成 — FCM推送集成指南(Android平台)

融云集成之避坑指南-Android推送篇

融云IMKit 动态删除或添加plugin 的实现


iOS篇

iOS 基于实时音视频 SDK 实现屏幕共享功能——1

iOS 基于实时音视频 SDK 实现屏幕共享功能——2

iOS 基于实时音视频 SDK 实现屏幕共享功能——3

iOS 基于实时音视频 SDK 实现屏幕共享功能——4

如何隐藏融云输入框语音按钮

给融云的输入框上方加个功能按钮,怎么整?

融云 IM SDK 如何插入消息

集成融云 IMLib 时,如何实现一套类似于 IMKit 的用户信息管理机制

为融云聊天页面的输入框添加 Placeholder

30 分钟集成融云 IM 即时通讯

简单介绍融云 imkit 包含功能

融云的聊天页面在 iOS14 出现崩溃的解决办法

融云聊天页面长按消息后“翻译”功能的实现方法

使用融云 IM 点击最近聊天记录时跳转到 @ 自己的消息

如何设置融云用户信息

自定义融云会话列表 cell 选中背景

融云 IMKit 音频录制参数

融云会话页面刷新不及时问题

融云 Flutter IM SDK 解析

关于融云 SDK 在使用 p8 证书的坎坷~

融云 SDK 如何实现群组操作

如何利用融云 IMLib 来实现一个阅后即焚功能

干货分享——使用融云通讯能力库 IMLib 实现单群聊的阅读回执


Web篇

作为小白接融云 IM SDK 新路体验~

微信小程序集成融云 SDK (即时通讯) 集成必备条件

Web 端使用融云 SDK 集成实现滑动加载历史消息

融云IM SDK web 端集成 — 表情采坑篇

融云 Web SDK 如何实现表情的收发 ?

集成融云小程序 SDK 遇到的问题

使用融云 Web SDK 撤回消息

融云 RTC SDK 集成实现直播,趟坑之旅~~~

融云 Web SDK 删除历史消息

集成融云小程序 SDK 遇到的问题

Web 端集成融云 SDK 如何发送正确图片消息给移动端展示?

使用融云 IM SDK 实现 H5 直播聊天

WebRTC 实现实时音视频技术研究

融云发送语音消息

融云 CallLib 集成遇到的问题

结合融云 WebSDK 了解 WebSocket 基本原理

集成融云 Web 音视频通话踩坑之旅

SDK 兼容 JSON

融云 IM SDK 发送语音消息

集成融云 IM 问题总结

融云 Web SDK 如何实现只有一个设备登入

融云 Web 播放声音 — Flash 篇 (播放 AMR、WAV)

融云 IM 那些事儿

融云 AMR(Aduio) 播放 AMR 格式 Base64 码音频


社区福利

【领取见面礼】限量 100份 GeekOnline加油包!等你来拿

【有奖调研】Geek Online 2020 编程挑战赛参赛调研

【征稿活动】Geek Online 社区第一期投稿激励计划已启动!


GeekOnline编程挑战赛

Geek Online 2020 编程挑战赛官网

重磅!Geek Online 2020 编程挑战赛来了!

Geek Online 2020 编程挑战赛 GitHub 仓库

2 个月激烈角逐,15 支队伍突围决赛路演!Geek Online 2020 编程挑战赛完美收官!

一张图回顾 Geek Online 2020 编程挑战赛精彩瞬间!

“这些项目不是什么赚大钱的项目,但是它们足够有趣。”丨关于 Geek Online 2020 编程挑战赛,选手们如是说

融云 CTO 杨攀: Geek Online 2020 编程挑战赛 让开发者站上 C 位

【参赛攻略】你想了解的Geek Online 2020 编程挑战赛常见问题这里都有!

【融云集成常见问题整理】Geek Online 2020 编程挑战赛选手提问整理


求职招聘

【招聘】寻一枚熟悉融云IM的开发工程师,坐标合肥,待遇从优

和50万优质程序员一起成长——程序员客栈招聘

持续更新....

融云 IMKit 音频录制参数

IM即时通讯王叫兽 发表了文章 • 0 个评论 • 215 次浏览 • 2021-01-11 15:14 • 来自相关话题

场景:使用融云自带的界面进行语音消息的播放。自己进行音频录制。使用的融云的 RCHQMessage问题:语音消息 iOS 和 Android 不互通,接收到消息之后无法播放。解决方案:经过与融云开发者的确认,使用时必须保证如下录制参数:iOS AVA... ...查看全部

场景:

  1. 使用融云自带的界面进行语音消息的播放。

  2. 自己进行音频录制。

  3. 使用的融云的 RCHQMessage

问题:

  1. 语音消息 iOS 和 Android 不互通,接收到消息之后无法播放。

解决方案:

经过与融云开发者的确认,使用时必须保证如下录制参数:

iOS AVAudioRecorder 录制参数如下设置:

AVFormatIDKey : @(kAudioFormatMPEG4AAC_HE),
AVSampleRateKey : @(44100.0),
AVNumberOfChannelsKey : @1,
AVEncoderBitRateKey : @(16000)

Android MediaRecorder 录制参数如下:

setAudioSamplingRate(44100);
setAudioEncodingBitRate(16000);
setAudioChannels(1);
setAudioSource(MediaRecorder.AudioSource.MIC);
setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
setAudioEncoder(MediaRecorder.AudioEncoder.HE_AAC);

其他一些内容的使用可以自己去官网文档搜索:

融云文档:https://docs.rongcloud.cn/v4/


融云会话页面刷新不及时问题

IM即时通讯徐凤年 发表了文章 • 0 个评论 • 227 次浏览 • 2021-01-11 15:14 • 来自相关话题

项目用的融云 IMKit SDK,调试中发现收到消息的时候,不刷新,上拉一下才会显示。排查方法是直接使用 SDK 的会话页面,排除是子类代码的问题,替换后发现还是有此问题。后来和技术人员沟通发现是使用了 RCIMClient 中的初始化接口,这样会影响 UI ... ...查看全部

项目用的融云 IMKit SDK,调试中发现收到消息的时候,不刷新,上拉一下才会显示。排查方法是直接使用 SDK 的会话页面,排除是子类代码的问题,替换后发现还是有此问题。后来和技术人员沟通发现是使用了 RCIMClient 中的初始化接口,这样会影响 UI 刷新的。替换为 RCIM 的初始化方法,问题解决!希望此文字可以帮助到后续开发者!

/*!
 初始化融云SDK

 @param appKey  从融云开发者平台创建应用后获取到的App Key

 @discussion 您在使用融云SDK所有功能(包括显示SDK中或者继承于SDK的View)之前,您必须先调用此方法初始化SDK。
 在App整个生命周期中,您只需要执行一次初始化。

 @warning 如果您使用IMKit,请使用此方法初始化SDK;
 如果您使用IMLib,请使用RCIMClient中的同名方法初始化,而不要使用此方法。
 */
- (void)initWithAppKey:(NSString *)appKey;

友情提示融云官网:(www.rongcloud.cn)

融云自定义消息不显示

IM即时通讯徐凤年 发表了文章 • 0 个评论 • 118 次浏览 • 2021-01-11 15:14 • 来自相关话题

项目用的融云,IMKit SDK(自带 UI),但是出现一个问题,就是自定义消息在会话页面刚收到的时候能显示,但是退出会话页面再进入就不显示了。非常的纳闷啊。查询了存储策略,编解码方法,都没有问题。后来提交工单,技术人员给了反馈才发现自己把消息的注册放到了初始... ...查看全部

项目用的融云,IMKit SDK(自带 UI),但是出现一个问题,就是自定义消息在会话页面刚收到的时候能显示,但是退出会话页面再进入就不显示了。非常的纳闷啊。查询了存储策略,编解码方法,都没有问题。后来提交工单,技术人员给了反馈才发现自己把消息的注册放到了初始化 appkey 前边,然后人家融云写的很明确:使用融云SDK所有功能(包括显示SDK中或者继承于SDK的View)之前,您必须先调用此方法初始化 SDK。可见认真查看文档接口注释的重要性!!

/*!
 初始化融云SDK

 @param appKey  从融云开发者平台创建应用后获取到的App Key

 @discussion 您在使用融云SDK所有功能(包括显示SDK中或者继承于SDK的View)之前,您必须先调用此方法初始化SDK。
 在App整个生命周期中,您只需要执行一次初始化。

 @warning 如果您使用IMKit,请使用此方法初始化SDK;
 如果您使用IMLib,请使用RCIMClient中的同名方法初始化,而不要使用此方法。
 */
- (void)initWithAppKey:(NSString *)appKey;

融云(www.rongcloud.cn)

如何利用融云 IMLib 来实现一个阅后即焚功能

IM即时通讯柠檬^ 发表了文章 • 0 个评论 • 212 次浏览 • 2021-01-11 15:14 • 来自相关话题

场景项目需要在私聊中来实现一个阅后即焚的功能,即 A 用户给 B 用户发送消息,B 用户在进入聊天页面查看之后 A 用户删除此消息,B 用户开始进入倒计时,倒计时结束后,删除此消息。思考大体的梳理一下具体的逻辑A -> BB 进入会话页面B 将此消息开始... ...查看全部

场景

项目需要在私聊中来实现一个阅后即焚的功能,即 A 用户给 B 用户发送消息,B 用户在进入聊天页面查看之后 A 用户删除此消息,B 用户开始进入倒计时,倒计时结束后,删除此消息。

思考

  1. 大体的梳理一下具体的逻辑

    • A -> B

    • B 进入会话页面

    • B 将此消息开始倒计时

    • 通知 A 我已进行阅读

    • A 删除消息

  2. 从上面内容我们来大体的设计一下我们需要用户的技术

    • 单例类

    • 自定义消息,用来告诉 A 我已经开始阅读了,你删除吧

    • 一个用于维护阅后即焚消息的管理类

    • 一个存储 A 给 B 发送的所有的阅后即焚的消息的容器 A k 为 targetid ,v 为 messageIDs

    • 一个存储每条阅后即焚消息的容器 B k 为 messageId, v 为当前消息还剩的倒计时时间。

    • 一个用来存储所有阅后即焚消息的容器 C K:ID V:msg

    • 两个处理队列 一个处理时间 一个处理消息

  3. 对外暴露接口

    • 代理 接收方焚烧消息的每秒倒计时

    • 通知 接收方收到对方已阅读某条消息的通知

详解

  1. 初始化我们的所有容器

  2. 收到消息,在合适的业务时机将此消息加入到焚烧队列

  3. 查询消息是否已经在焚烧队列

  4. 如果不在,添加到 A B C容器

  5. 执行倒计时

倒计时操作

  1. 遍历 C 是否有消息

  2. 给发送方发送消息,通知我已经开始焚烧 A 里的消息了 并在 A 容器删除此会话

  3. 发送方收到消息发送通知

  4. 接收方遍历 B 容器,判断每条消息是否到时

  5. 如果消息焚烧时间到 在 A、B 容器删除,并触发代理

  6. 如果没到时间,就触发代理并修改 此消息在 B 容器的时长。


融云 SDK 如何实现群组操作

IM即时通讯柠檬^ 发表了文章 • 0 个评论 • 203 次浏览 • 2021-01-11 15:14 • 来自相关话题

融云 SDK 如何实现群组操作背景在集成融云 SDK 后,需要实现群组操作的消息通知。包括:群创建、销毁通知群公告通知群人员加入、退出通知群昵称修改通知...融云现有的 SDK 仅提供了 RCGroupNotificationMessage,内部封装... ...查看全部

融云 SDK 如何实现群组操作

背景

在集成融云 SDK 后,需要实现群组操作的消息通知。包括:

  • 群创建、销毁通知

  • 群公告通知

  • 群人员加入、退出通知

  • 群昵称修改通知

  • ...

融云现有的 SDK 仅提供了 RCGroupNotificationMessage,内部封装了几种简单的类型操作,且扩展性不强,无法完成现有的操作。

解决方案:

使用自定义消息重新来构建群组通知消息。

参考 sealtlak 中的 RCDGroupNotificationMessage,也是单独对群组操作内容,重新进行了封装处理

/*!
 群组通知消息
 */
@interface RCDGroupNotificationMessage : RCMessageContent

//操作名
@property (nonatomic, copy) NSString *operation;

//操作人
@property (nonatomic, copy) NSString *operatorUserId;

//操作对象
@property (nonatomic, strong) NSArray<NSString *> *targetUserIds;

//内容
@property (nonatomic, copy) NSString *message;

//获取摘要
- (NSString *)getDigest:(NSString *)groupId;
@end

这个类预定义了下面几种操作类型消息,具体内容可参考名字定义

extern NSString *const RCDGroupCreate;
extern NSString *const RCDGroupMemberAdd;
extern NSString *const RCDGroupMemberQuit;
extern NSString *const RCDGroupMemberKicked;
extern NSString *const RCDGroupRename;
extern NSString *const RCDGroupBulletin;
extern NSString *const RCDGroupOwnerTransfer;
extern NSString *const RCDGroupDismiss;
extern NSString *const RCDGroupMemberJoin;
extern NSString *const RCDGroupMemberManagerSet;
extern NSString *const RCDGroupMemberManagerRemove;
extern NSString *const RCDGroupMemberProtectionOpen;
extern NSString *const RCDGroupMemberProtectionClose;

.m 的实现还是按照自定义消息的实现进行处理。唯一有区别的是在获取摘要的方法,在这个方法中对消息内容进行了处理,根据操作名的不同,来对显示的内容进行各种适配。此处根据根据自己的业务进行修改。

- (NSString *)getDigest:(NSString *)groupId {

    NSString *content;

    //获取用户信息
    NSString *operationName = [self getDisplayNames:@[ self.operatorUserId?self.operatorUserId:@""] groupId:groupId];
    NSString *targetNames = [self getDisplayNames:self.targetUserIds groupId:groupId];

    //是否当前用户操作
    BOOL isMeOperate = NO;
    if ([self.operatorUserId isEqualToString:[RCIMClient sharedRCIMClient].currentUserInfo.userId]) {
        isMeOperate = YES;
    }

    //判断操作类型
    if ([self.operation isEqualToString:RCDGroupCreate]) {
        content =
            [NSString stringWithFormat:NSLocalizedStringFromTable(isMeOperate ? @"GroupHaveCreated" : @"GroupCreated",
                                                                  @"RongCloudKit", nil),
                                       operationName];
    } else if ([self.operation isEqualToString:RCDGroupMemberAdd]) {
        if (self.targetUserIds.count == 1 && [self.targetUserIds containsObject:self.operatorUserId]) {
            content = [NSString
                stringWithFormat:NSLocalizedStringFromTable(@"GroupJoin", @"RongCloudKit", nil), operationName];
        } else {
            content = [NSString
                stringWithFormat:NSLocalizedStringFromTable(isMeOperate ? @"GroupHaveInvited" : @"GroupInvited",
                                                            @"RongCloudKit", nil),
                                 operationName, targetNames];
        }
    } else if ([self.operation isEqualToString:RCDGroupMemberJoin]) {
        content =
            [NSString stringWithFormat:NSLocalizedStringFromTable(@"GroupJoin", @"RongCloudKit", nil), operationName];
    } else if ([self.operation isEqualToString:RCDGroupMemberQuit]) {
        content = [NSString stringWithFormat:NSLocalizedStringFromTable(isMeOperate ? @"GroupHaveQuit" : @"GroupQuit",
                                                                        @"RongCloudKit", nil),
                                             operationName];
    } else if ([self.operation isEqualToString:RCDGroupMemberKicked]) {
        content =
            [NSString stringWithFormat:NSLocalizedStringFromTable(isMeOperate ? @"GroupHaveRemoved" : @"GroupRemoved",
                                                                  @"RongCloudKit", nil),
                                       operationName, targetNames];
    } else if ([self.operation isEqualToString:RCDGroupRename]) {
        content = [NSString stringWithFormat:NSLocalizedStringFromTable(@"GroupChanged", @"RongCloudKit", nil),
                                             operationName, self.targetGroupName];
    } else if ([self.operation isEqualToString:RCDGroupDismiss]) {
        content =
            [NSString stringWithFormat:NSLocalizedStringFromTable(isMeOperate ? @"GroupHaveDismiss" : @"GroupDismiss",
                                                                  @"RongCloudKit", nil),
                                       operationName];
    } else if ([self.operation isEqualToString:RCDGroupOwnerTransfer]) {
        content = [NSString stringWithFormat:RCDLocalizedString(@"GroupHasNewOwner"), targetNames];
    } else if ([self.operation isEqualToString:RCDGroupMemberManagerSet]) {
        content = [NSString stringWithFormat:RCDLocalizedString(@"GroupSetManagerMessage"), targetNames];
    } else if ([self.operation isEqualToString:RCDGroupMemberProtectionOpen]) {
        content = RCDLocalizedString(@"openMemberProtection");
    } else if ([self.operation isEqualToString:RCDGroupMemberProtectionClose]) {
        content = [NSString stringWithFormat:RCDLocalizedString(@"closeMemberProtection"), operationName];
    } else {
        content = NSLocalizedStringFromTable(@"unknown_message_cell_tip", @"RongCloudKit", nil);
    }
    return content;
}

此外,还有一个获取名称的方法,用来维护用户信息。

- (NSString *)getDisplayNames:(NSArray<NSString *> *)userIds groupId:(NSString *)groupId


关于融云 SDK 在使用 p8 证书的坎坷~

IM即时通讯木土走召 发表了文章 • 0 个评论 • 208 次浏览 • 2021-01-11 15:14 • 来自相关话题

新上的项目使用了融云的 IM SDK,但在项目集成 APNs 推送的时候,尝鲜使用了一下开发者后台的 p8 证书,此文记录使用 p8 的辛酸史~P8 简介苹果文档传送门官网给出了这种更 "快" 的推送通道: Establishing a T... ...查看全部

新上的项目使用了融云的 IM SDK,但在项目集成 APNs 推送的时候,尝鲜使用了一下开发者后台的 p8 证书,此文记录使用 p8 的辛酸史~

P8 简介

苹果文档传送门

官网给出了这种更 "快" 的推送通道: Establishing a Token-Based Connection to APNs,并且这个生成的这个 key 可以适用于当前账户的所有 APP,为开发人员省了不少力气。福音啊~

想想那一堆证书...... 脑阔痛!

辛酸史

起因是这样的,在融云开发者后台上传了 p8 之后,发现 debug 环境,一直无法收到推送,在经过和融云提供的推送文档进行严格的比对之后,发现没毛病啊~

最后终于在融云开发人员的帮助下找到了问题~,融云后台目前阶段只支持生产环境~ OMG,我打你信不~

区别

p8 是可以同时支持生产和测试环境的,那么为什么融云收不到呢~

让我们大胆猜测一下:

之前基于证书进行校验的时候,一套证书是基于开发者后台一个 AppKey 绑定的,那么我用了哪个 AppKey,后端就基于 AppKey 解析对应的证书,这样就可以发送到对应的 push 环境去了,那么问题来了?使用了 p8 之后,他怎么区分呢?

我也不知道~ 哈哈哈,但我猜测应该是没有解析都去走了生产环境,因为提示我环境不匹配~

苹果 APNs 服务

传送门

Development server: api.sandbox.push.apple.com:443

Production server: api.push.apple.com:443

融云文档传送门


融云 Flutter IM SDK 解析

IM即时通讯木土走召 发表了文章 • 0 个评论 • 226 次浏览 • 2021-01-11 15:14 • 来自相关话题

最近准备使用融云的 Flutter SDK,所以顺便记录一下。融云 Flutter IM SDK 地址:传送门融云的 Flutter SDK 是基于 融云 IMLib 层做的封装,封装了 IMLib 的部分接口提供给 Flutter 开发者使用。此文章只介绍了... ...查看全部

最近准备使用融云的 Flutter SDK,所以顺便记录一下。

融云 Flutter IM SDK 地址:传送门

融云的 Flutter SDK 是基于 融云 IMLib 层做的封装,封装了 IMLib 的部分接口提供给 Flutter 开发者使用。此文章只介绍了 Flutter 层做的一些操作。

目录结构

image.png

整体 SDK 的结构规规矩矩,核心内容参考红色箭头即可。

SDK 层包含 三个目录:
android:此目录包含了和原生 SDK 交互的所有 Java 文件
ios:此目录包含了和原生 SDK 交互的所有 oc 文件
lib: 此目录为使用 dart 编写的 Flutter SDK 文件

其他目录:
doc:主要是融云开发者提供的一些文档相关
example:是融云开发者基于此 SDK 提供的一个简单示例,整体较为简陋,且有细微 bug,仅供参考

FunctionList.md 是融云开发者提供的一个功能清单,
大体如下:

# RongCloud IM Flutter SDK 功能清单

## 连接

初始化

连接

断开连接

连接状态兼容

## 配置

设置服务器地址( im 服务;文件服务)

## 会话

获取会话列表,支持全量获取,分页获取

获取单个会话

删除指定会话



## 消息

当前仅支持 文本消息,语音消息,图片消息,小视频消息

收发消息(可以携带 pushContent)

自定义消息

获取批量本地历史消息

获取单条本地历史消息

获取批量远端历史消息

插入消息

删除批量本地消息

获取未读数

清除指定会话未读数

## 免打扰

设置会话免打扰

获取会话免打扰

## 会话置顶

设置会话置顶

备注:获取会话是可以获取到会话置顶状态

## 黑名单

加入黑名单

移除黑名单

获取黑名单列表

检查特定用户的黑名单状态

## 聊天室

加入聊天室

退出聊天室

获取聊天室信息

都是一些接口层的操作。

剩下的文件基本可以忽略。

解析

我们开始从 lib 目录开始分析

image.png

这两个文件是核心文件,我们所有的调用接口都在这里。

rong_im_client.dart 是最新版本的接口类,我们只关心这个即可。

rong_im_plugin.dart 是旧版本的接口类,已经废弃。

common_define.dart 是定义了 SDK 内使用的所有枚举和状态码。

method_key.dart是定义了 Flutter SDK 和原生层进行交互时标识的唯一的常量字符串。

然后就是剩下的三个文件目录:
image.png

info: 其实就是对象 model 类

image.png

message: 这个是 Flutter SDK提供的所有内置的消息类型,包括聊天室KV消息、合并消息、文件消息、GIF消息、图片消息、位置消息、撤回消息、引用消息、图文消息、视频消息、文本消息、语音消息。

其中有一个比较特殊的 dart 类就是 message_content.dart, 这个类是所有消息的基类。

每个消息都需要继承此类,并复写里面的方法进行编解码。

image.png

util: 这个目录就是一个工具目录。

message_factory.dart 主要是进行消息封装,字典转模型,模型转字典,根本原因我猜就是 Flutter 和 原生仅有的交互类型限制。

type_util.dart:略

以上就是 SDK 在 Flutter 层做的所有的操作,内容整体不多,而且所有代码都是开源的,看看基本上都了解。

与原生层的交互

image.png

整体都是通过 invokeMethod 与原生进行通信的,后面的key 就是之前说的常量字符串,用来保证唯一性。

而在 iOS 和 Android 都提供了对应的定义。

image.png

image.png

并通过触发 iOS 和 Android 层对应的方法来进行处理。

image.png

image.png

原生层

Android:
image.png

整体核心的处理都在 RCIMFlutterWrapper.java 这个类处理了 dart 代码传递过来的数据,并与融云 IMLib 的 SDK 进行了处理。

iOS:
image.png

同样,iOS 的核心代码也都在 RCIMFlutterWrapper.m 这个类处理。具体内容大家可以自己看一下。

到此整个内容我们也就大体明白了。

整体看来其实就是 flutter 中 rong_im_client.dart 和 原生的两个 Wrapper 类做交互,其他的都是助攻。

整体看来不难,搞起~

融云文档:传送门


干货分享——使用融云通讯能力库 IMLib 实现单群聊的阅读回执

IM即时通讯王叫兽 发表了文章 • 0 个评论 • 219 次浏览 • 2021-01-11 15:14 • 来自相关话题

今天的干货分享是关于“阅读回执”功能,这是一个很普遍的功能,但是针对使用融云的 SDK 去实现,还是有些坑在等着我们的,下面就开始分(bì)享(kēng)喽~分享之前先做一些准备工作,先找到我们需要调用的接口文档文档:https://docs.rongclou... ...查看全部

今天的干货分享是关于“阅读回执”功能,这是一个很普遍的功能,但是针对使用融云的 SDK 去实现,还是有些坑在等着我们的,下面就开始分(bì)享(kēng)喽~

  1. 分享之前先做一些准备工作,先找到我们需要调用的接口文档

  2. 根据不同的会话类型以及消息的发送方和接收方,要分别处理

    • 单聊

      接收方 :在阅读消息后,调用 RCIMClient 类的发送阅读回执接口,参数如下:

      conversationType 单聊会话类型

      targetId 消息的会话 ID

      time 会话最后一条消息的发送时间(sentTime)

/*!
 发送某个会话中消息阅读的回执

 @param conversationType    会话类型
 @param targetId            会话 ID
 @param timestamp           该会话中已阅读的最后一条消息的发送时间戳
 @param successBlock        发送成功的回调
 @param errorBlock          发送失败的回调[nErrorCode: 失败的错误码]

 @discussion 此接口只支持单聊, 如果使用 IMLib 可以注册监听
 RCLibDispatchReadReceiptNotification 通知,使用 IMKit 直接设置RCIM.h
 中的 enabledReadReceiptConversationTypeList。

 @warning 目前仅支持单聊。

 @remarks 高级功能
 */
- (void)sendReadReceiptMessage:(RCConversationType)conversationType
                      targetId:(NSString *)targetId
                          time:(long long)timestamp
                       success:(void (^)(void))successBlock
                         error:(void (^)(RCErrorCode nErrorCode))errorBlock;

发送方:监听下面这个通知,在接收后修改消息的展示

/*!
 @const 收到已读回执的 Notification

 @discussion 收到消息已读回执之后,IMLib 会分发此通知。

 Notification 的 object 为 nil,userInfo 为 NSDictionary 对象,
 其中 key 值分别为 @"cType"、@"tId"、@"messageTime",
 对应的 value 为会话类型的 NSNumber 对象 、会话的 targetId 、已阅读的最后一条消息的 sendTime。
 如:
 NSNumber *ctype = [notification.userInfo objectForKey:@"cType"];
 NSNumber *time = [notification.userInfo objectForKey:@"messageTime"];
 NSString *targetId = [notification.userInfo objectForKey:@"tId"];
 NSString *fromUserId = [notification.userInfo objectForKey:@"fId"];

 收到这个消息之后可以更新这个会话中 messageTime 以前的消息 UI 为已读(底层数据库消息状态已经改为已读)。

 @remarks 事件监听
 */
FOUNDATION_EXPORT NSString *const RCLibDispatchReadReceiptNotification;

群聊

发送方

在发送消息 A 后,需要针对该消息发送回执请求,message 传之前发的消息 A

/*!
 请求消息阅读回执

 @param message      要求阅读回执的消息
 @param successBlock 请求成功的回调
 @param errorBlock   请求失败的回调[nErrorCode: 失败的错误码]

 @discussion 通过此接口,可以要求阅读了这条消息的用户发送阅读回执。

 @remarks 高级功能
 */
- (void)sendReadReceiptRequest:(RCMessage *)message
                       success:(void (^)(void))successBlock
                         error:(void (^)(RCErrorCode nErrorCode))errorBlock;

设置下面代理函数,在接收到发送方发来的阅读回执响应后,修改消息的展示

/*!
 IMlib消息接收的监听器

 @discussion
 设置IMLib的消息接收监听器请参考RCIMClient的setReceiveMessageDelegate:object:方法。

 @warning 如果您使用IMlib,可以设置并实现此Delegate监听消息接收;
 如果您使用IMKit,请使用RCIM中的RCIMReceiveMessageDelegate监听消息接收,而不要使用此监听器,否则会导致IMKit中无法自动更新UI!
 */
@protocol RCIMClientReceiveMessageDelegate <NSObject>

/*!
 消息已读回执响应(收到阅读回执响应,可以按照 messageUId 更新消息的阅读数)
 @param messageUId       请求已读回执的消息ID
 @param conversationType conversationType
 @param targetId         targetId
 @param userIdList 已读userId列表
 */
- (void)onMessageReceiptResponse:(RCConversationType)conversationType
                        targetId:(NSString *)targetId
                      messageUId:(NSString *)messageUId
                      readerList:(NSMutableDictionary *)userIdList;

接收方

设置下面代理函数,在接收到消息 A 后,还会接收到针对消息 A 的阅读回执请求

/*!
 IMlib消息接收的监听器

 @discussion
 设置IMLib的消息接收监听器请参考RCIMClient的setReceiveMessageDelegate:object:方法。

 @warning 如果您使用IMlib,可以设置并实现此Delegate监听消息接收;
 如果您使用IMKit,请使用RCIM中的RCIMReceiveMessageDelegate监听消息接收,而不要使用此监听器,否则会导致IMKit中无法自动更新UI!
 */
@protocol RCIMClientReceiveMessageDelegate <NSObject>

/*!
 请求消息已读回执(收到需要阅读时发送回执的请求,收到此请求后在会话页面已经展示该 messageUId 对应的消息或者调用
 getHistoryMessages 获取消息的时候,包含此 messageUId 的消息,需要调用 sendMessageReadReceiptResponse
 接口发送消息阅读回执)

 @param messageUId       请求已读回执的消息ID
 @param conversationType conversationType
 @param targetId         targetId
 */
- (void)onMessageReceiptRequest:(RCConversationType)conversationType
                       targetId:(NSString *)targetId
                     messageUId:(NSString *)messageUId;

在代理方法中,调用下面接口发送阅读回执响应给发送方

/*!
 发送阅读回执

 @param conversationType 会话类型
 @param targetId         会话 ID
 @param messageList      已经阅读了的消息列表
 @param successBlock     发送成功的回调
 @param errorBlock       发送失败的回调[nErrorCode: 失败的错误码]

 @discussion 当用户阅读了需要阅读回执的消息,可以通过此接口发送阅读回执,消息的发送方即可直接知道那些人已经阅读。

 @remarks 高级功能
 */
- (void)sendReadReceiptResponse:(RCConversationType)conversationType
                       targetId:(NSString *)targetId
                    messageList:(NSArray<RCMessage *> *)messageList
                        success:(void (^)(void))successBlock
                          error:(void (^)(RCErrorCode nErrorCode))errorBlock;

总结

阅读回执需要区分会话类型处理,且单聊的阅读回执是针对会话的,群聊的阅读回执是针对某一条消息的:

单聊:接收方阅读某个会话的消息后,发送阅读回执 ——发送方接到阅读回执,更新 UI

群聊:发送方发送消息 A, 针对该消息,发送阅读回执请求 —— 接收方实现监听代理,接收到消息 A 的阅读回执请求 —— 接收方发送阅读回执响应 —— 发送方收到阅读回执响应,更新 UI


如何设置融云用户信息

IM即时通讯dht1212 发表了文章 • 0 个评论 • 222 次浏览 • 2021-01-08 11:35 • 来自相关话题

最近在使用融云,由于第一次使用,遇到了一个小坑,在这里记录一下,希望能帮助到后续开发者问题是使用了融云的 IMKit 组件,也就是自带 UI 的,对于快速试错的产品来说,工期必须短,所以使用 IMKit 是非常方便的,省去了很大部分时间去搞界面。但是使用过程中... ...查看全部

最近在使用融云,由于第一次使用,遇到了一个小坑,在这里记录一下,希望能帮助到后续开发者

问题是使用了融云的 IMKit 组件,也就是自带 UI 的,对于快速试错的产品来说,工期必须短,所以使用 IMKit 是非常方便的,省去了很大部分时间去搞界面。但是使用过程中发现,没有用户的头像和昵称。后来经过阅读文档发现,需要设置“用户信息提供者”代理方法。SDK 在需要显示头像和昵称的时候,会通过这个代理找开发者索取用户信息,开发者只要遵循代理,且实现代理方法,返回用户信息即可。

上代码:

1.遵循代理

@interface AppDelegate () <RCIMUserInfoDataSource>
@end

2.设置代理

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    //必须先初始化
    [[RCIM sharedRCIM] initWithAppKey:"开发者自己的 appkey"];
    [[RCIM sharedRCIM] connectWithToken:"当前用户的 token" dbOpened:^(RCDBErrorCode code) {
        } success:^(NSString *userId) {
        } error:^(RCConnectErrorCode errorCode) {
        }];
    //设置当前用户信息
    RCUserInfo *currentUser = [[RCUserInfo alloc] initWithUserId:@"tiezhu" name:@"铁柱" portrait:@"https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1573646812313&di=116350f184eda99d91393304fa83a6ea&imgtype=0&src=http%3A%2F%2Fimg.jinse.com%2F712431_image3.png"];
    [RCIM sharedRCIM].currentUserInfo = currentUser;
    //设置代理
    [RCIM sharedRCIM].userInfoDataSource = self;
}

3.实现代理方法

- (void)getUserInfoWithUserId:(NSString *)userId completion:(void (^)(RCUserInfo *userInfo))completion {
    //这里最好是从开发者自己服务器获取用户信息,然后返回。此处仅为示例
    RCUserInfo *user = nil;
    if ([userId isEqualToString:@"tiezhu"]) {
        user = [[RCUserInfo alloc] initWithUserId:@"tiezhu" name:@"铁柱" portrait:@"https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1570172426&di=01d14daa81f320235376d9c4dede0493&imgtype=jpg&er=1&src=http%3A%2F%2Fgss0.baidu.com%2F-vo3dSag_xI4khGko9WTAnF6hhy%2Fzhidao%2Fpic%2Fitem%2Fd788d43f8794a4c240e9466f0ef41bd5ac6e39af.jpg"];
    }
    if (completion) {
        completion(user);
    }
}

到此就搞定了兄嘚,值一杯秋天的奶茶

【社区精华|持续更新】收录本社区精华内容,手把手教学IM/RTC开发!

IM即时通讯admin 发表了文章 • 8 个评论 • 492 次浏览 • 2020-12-07 14:41 • 来自相关话题

本文收录了GeekOnline社区精华内容,希望帮助社区开发者学习IM+RTC知识,解答疑惑。赠人玫瑰,手有余香,如您有不错的内容需要收录,欢迎在在评论区投稿回复。Android篇融云即时通讯SDK集成 — 通知检查融云 IM SDK 集成 —- 刷新会话界面... ...查看全部

本文收录了GeekOnline社区精华内容,希望帮助社区开发者学习IM+RTC知识,解答疑惑。赠人玫瑰,手有余香,如您有不错的内容需要收录,欢迎在在评论区投稿回复。

微信截图_20201207144054.png

Android篇

融云即时通讯SDK集成 — 通知检查

融云 IM SDK 集成 —- 刷新会话界面和会话列表界面

Android 端如何添加自定义表情

解决融云 SDK 4.0 版本配置 https 导航报 SSLHandshakeException

融云清空历史消息 Android 端

唠一唠融云的消息扩展功能

融云 IMkit 拦截或监听所有发送消息

融云如何把图片消息的图片上传到自己的文件服务器

唠一唠融云 VIVO push 无法跳转的解决方案

融云即时通讯SDK集成 — 定制UI(一) ——会话界面小改动

融云即时通讯SDK集成 — 定制UI(二) ——添加自定义表情库

融云即时通讯SDK集成 — 定制UI(三) ——兼容Android Q

融云如何把图片消息的图片上传到自己的文件服务器

融云即时通讯SDK集成 — 华为推送的点击跳转处理

带你实现女朋友欲罢不能的 App

Flutter 集成融云 sdk

配置融云SDK的自签证书

自定义消息 包含 list 数组

关于融云聊天室KV 值的正确使用

融云 IM SDK 转 AndroidX

融云即时通讯SDK集成 — 国内厂商推送集成踩坑篇(Android平台)

在融云 IMkit 会话界面基础上添加消息已读未读

融云聊天室属性 kv

融云 ConversationListFragment 会话列表添加头部布局

融云即时通讯SDK集成 — FCM推送集成指南(Android平台)

融云集成之避坑指南-Android推送篇

融云IMKit 动态删除或添加plugin 的实现


iOS篇

iOS 基于实时音视频 SDK 实现屏幕共享功能——1

iOS 基于实时音视频 SDK 实现屏幕共享功能——2

iOS 基于实时音视频 SDK 实现屏幕共享功能——3

iOS 基于实时音视频 SDK 实现屏幕共享功能——4

如何隐藏融云输入框语音按钮

给融云的输入框上方加个功能按钮,怎么整?

融云 IM SDK 如何插入消息

集成融云 IMLib 时,如何实现一套类似于 IMKit 的用户信息管理机制

为融云聊天页面的输入框添加 Placeholder

30 分钟集成融云 IM 即时通讯

简单介绍融云 imkit 包含功能

融云的聊天页面在 iOS14 出现崩溃的解决办法

融云聊天页面长按消息后“翻译”功能的实现方法

使用融云 IM 点击最近聊天记录时跳转到 @ 自己的消息

如何设置融云用户信息

自定义融云会话列表 cell 选中背景

融云 IMKit 音频录制参数

融云会话页面刷新不及时问题

融云 Flutter IM SDK 解析

关于融云 SDK 在使用 p8 证书的坎坷~

融云 SDK 如何实现群组操作

如何利用融云 IMLib 来实现一个阅后即焚功能

干货分享——使用融云通讯能力库 IMLib 实现单群聊的阅读回执


Web篇

作为小白接融云 IM SDK 新路体验~

微信小程序集成融云 SDK (即时通讯) 集成必备条件

Web 端使用融云 SDK 集成实现滑动加载历史消息

融云IM SDK web 端集成 — 表情采坑篇

融云 Web SDK 如何实现表情的收发 ?

集成融云小程序 SDK 遇到的问题

使用融云 Web SDK 撤回消息

融云 RTC SDK 集成实现直播,趟坑之旅~~~

融云 Web SDK 删除历史消息

集成融云小程序 SDK 遇到的问题

Web 端集成融云 SDK 如何发送正确图片消息给移动端展示?

使用融云 IM SDK 实现 H5 直播聊天

WebRTC 实现实时音视频技术研究

融云发送语音消息

融云 CallLib 集成遇到的问题

结合融云 WebSDK 了解 WebSocket 基本原理

集成融云 Web 音视频通话踩坑之旅

SDK 兼容 JSON

融云 IM SDK 发送语音消息

集成融云 IM 问题总结

融云 Web SDK 如何实现只有一个设备登入

融云 Web 播放声音 — Flash 篇 (播放 AMR、WAV)

融云 IM 那些事儿

融云 AMR(Aduio) 播放 AMR 格式 Base64 码音频


社区福利

【领取见面礼】限量 100份 GeekOnline加油包!等你来拿

【有奖调研】Geek Online 2020 编程挑战赛参赛调研

【征稿活动】Geek Online 社区第一期投稿激励计划已启动!


GeekOnline编程挑战赛

Geek Online 2020 编程挑战赛官网

重磅!Geek Online 2020 编程挑战赛来了!

Geek Online 2020 编程挑战赛 GitHub 仓库

2 个月激烈角逐,15 支队伍突围决赛路演!Geek Online 2020 编程挑战赛完美收官!

一张图回顾 Geek Online 2020 编程挑战赛精彩瞬间!

“这些项目不是什么赚大钱的项目,但是它们足够有趣。”丨关于 Geek Online 2020 编程挑战赛,选手们如是说

融云 CTO 杨攀: Geek Online 2020 编程挑战赛 让开发者站上 C 位

【参赛攻略】你想了解的Geek Online 2020 编程挑战赛常见问题这里都有!

【融云集成常见问题整理】Geek Online 2020 编程挑战赛选手提问整理


求职招聘

【招聘】寻一枚熟悉融云IM的开发工程师,坐标合肥,待遇从优

和50万优质程序员一起成长——程序员客栈招聘

持续更新....

【社区精华|持续更新】收录本社区精华内容,手把手教学IM/RTC开发!

IM即时通讯admin 发表了文章 • 8 个评论 • 492 次浏览 • 2020-12-07 14:41 • 来自相关话题

本文收录了GeekOnline社区精华内容,希望帮助社区开发者学习IM+RTC知识,解答疑惑。赠人玫瑰,手有余香,如您有不错的内容需要收录,欢迎在在评论区投稿回复。Android篇融云即时通讯SDK集成 — 通知检查融云 IM SDK 集成 —- 刷新会话界面... ...查看全部

本文收录了GeekOnline社区精华内容,希望帮助社区开发者学习IM+RTC知识,解答疑惑。赠人玫瑰,手有余香,如您有不错的内容需要收录,欢迎在在评论区投稿回复。

微信截图_20201207144054.png

Android篇

融云即时通讯SDK集成 — 通知检查

融云 IM SDK 集成 —- 刷新会话界面和会话列表界面

Android 端如何添加自定义表情

解决融云 SDK 4.0 版本配置 https 导航报 SSLHandshakeException

融云清空历史消息 Android 端

唠一唠融云的消息扩展功能

融云 IMkit 拦截或监听所有发送消息

融云如何把图片消息的图片上传到自己的文件服务器

唠一唠融云 VIVO push 无法跳转的解决方案

融云即时通讯SDK集成 — 定制UI(一) ——会话界面小改动

融云即时通讯SDK集成 — 定制UI(二) ——添加自定义表情库

融云即时通讯SDK集成 — 定制UI(三) ——兼容Android Q

融云如何把图片消息的图片上传到自己的文件服务器

融云即时通讯SDK集成 — 华为推送的点击跳转处理

带你实现女朋友欲罢不能的 App

Flutter 集成融云 sdk

配置融云SDK的自签证书

自定义消息 包含 list 数组

关于融云聊天室KV 值的正确使用

融云 IM SDK 转 AndroidX

融云即时通讯SDK集成 — 国内厂商推送集成踩坑篇(Android平台)

在融云 IMkit 会话界面基础上添加消息已读未读

融云聊天室属性 kv

融云 ConversationListFragment 会话列表添加头部布局

融云即时通讯SDK集成 — FCM推送集成指南(Android平台)

融云集成之避坑指南-Android推送篇

融云IMKit 动态删除或添加plugin 的实现


iOS篇

iOS 基于实时音视频 SDK 实现屏幕共享功能——1

iOS 基于实时音视频 SDK 实现屏幕共享功能——2

iOS 基于实时音视频 SDK 实现屏幕共享功能——3

iOS 基于实时音视频 SDK 实现屏幕共享功能——4

如何隐藏融云输入框语音按钮

给融云的输入框上方加个功能按钮,怎么整?

融云 IM SDK 如何插入消息

集成融云 IMLib 时,如何实现一套类似于 IMKit 的用户信息管理机制

为融云聊天页面的输入框添加 Placeholder

30 分钟集成融云 IM 即时通讯

简单介绍融云 imkit 包含功能

融云的聊天页面在 iOS14 出现崩溃的解决办法

融云聊天页面长按消息后“翻译”功能的实现方法

使用融云 IM 点击最近聊天记录时跳转到 @ 自己的消息

如何设置融云用户信息

自定义融云会话列表 cell 选中背景

融云 IMKit 音频录制参数

融云会话页面刷新不及时问题

融云 Flutter IM SDK 解析

关于融云 SDK 在使用 p8 证书的坎坷~

融云 SDK 如何实现群组操作

如何利用融云 IMLib 来实现一个阅后即焚功能

干货分享——使用融云通讯能力库 IMLib 实现单群聊的阅读回执


Web篇

作为小白接融云 IM SDK 新路体验~

微信小程序集成融云 SDK (即时通讯) 集成必备条件

Web 端使用融云 SDK 集成实现滑动加载历史消息

融云IM SDK web 端集成 — 表情采坑篇

融云 Web SDK 如何实现表情的收发 ?

集成融云小程序 SDK 遇到的问题

使用融云 Web SDK 撤回消息

融云 RTC SDK 集成实现直播,趟坑之旅~~~

融云 Web SDK 删除历史消息

集成融云小程序 SDK 遇到的问题

Web 端集成融云 SDK 如何发送正确图片消息给移动端展示?

使用融云 IM SDK 实现 H5 直播聊天

WebRTC 实现实时音视频技术研究

融云发送语音消息

融云 CallLib 集成遇到的问题

结合融云 WebSDK 了解 WebSocket 基本原理

集成融云 Web 音视频通话踩坑之旅

SDK 兼容 JSON

融云 IM SDK 发送语音消息

集成融云 IM 问题总结

融云 Web SDK 如何实现只有一个设备登入

融云 Web 播放声音 — Flash 篇 (播放 AMR、WAV)

融云 IM 那些事儿

融云 AMR(Aduio) 播放 AMR 格式 Base64 码音频


社区福利

【领取见面礼】限量 100份 GeekOnline加油包!等你来拿

【有奖调研】Geek Online 2020 编程挑战赛参赛调研

【征稿活动】Geek Online 社区第一期投稿激励计划已启动!


GeekOnline编程挑战赛

Geek Online 2020 编程挑战赛官网

重磅!Geek Online 2020 编程挑战赛来了!

Geek Online 2020 编程挑战赛 GitHub 仓库

2 个月激烈角逐,15 支队伍突围决赛路演!Geek Online 2020 编程挑战赛完美收官!

一张图回顾 Geek Online 2020 编程挑战赛精彩瞬间!

“这些项目不是什么赚大钱的项目,但是它们足够有趣。”丨关于 Geek Online 2020 编程挑战赛,选手们如是说

融云 CTO 杨攀: Geek Online 2020 编程挑战赛 让开发者站上 C 位

【参赛攻略】你想了解的Geek Online 2020 编程挑战赛常见问题这里都有!

【融云集成常见问题整理】Geek Online 2020 编程挑战赛选手提问整理


求职招聘

【招聘】寻一枚熟悉融云IM的开发工程师,坐标合肥,待遇从优

和50万优质程序员一起成长——程序员客栈招聘

持续更新....

融云 IMKit 音频录制参数

IM即时通讯王叫兽 发表了文章 • 0 个评论 • 215 次浏览 • 2021-01-11 15:14 • 来自相关话题

场景:使用融云自带的界面进行语音消息的播放。自己进行音频录制。使用的融云的 RCHQMessage问题:语音消息 iOS 和 Android 不互通,接收到消息之后无法播放。解决方案:经过与融云开发者的确认,使用时必须保证如下录制参数:iOS AVA... ...查看全部

场景:

  1. 使用融云自带的界面进行语音消息的播放。

  2. 自己进行音频录制。

  3. 使用的融云的 RCHQMessage

问题:

  1. 语音消息 iOS 和 Android 不互通,接收到消息之后无法播放。

解决方案:

经过与融云开发者的确认,使用时必须保证如下录制参数:

iOS AVAudioRecorder 录制参数如下设置:

AVFormatIDKey : @(kAudioFormatMPEG4AAC_HE),
AVSampleRateKey : @(44100.0),
AVNumberOfChannelsKey : @1,
AVEncoderBitRateKey : @(16000)

Android MediaRecorder 录制参数如下:

setAudioSamplingRate(44100);
setAudioEncodingBitRate(16000);
setAudioChannels(1);
setAudioSource(MediaRecorder.AudioSource.MIC);
setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
setAudioEncoder(MediaRecorder.AudioEncoder.HE_AAC);

其他一些内容的使用可以自己去官网文档搜索:

融云文档:https://docs.rongcloud.cn/v4/


融云会话页面刷新不及时问题

IM即时通讯徐凤年 发表了文章 • 0 个评论 • 227 次浏览 • 2021-01-11 15:14 • 来自相关话题

项目用的融云 IMKit SDK,调试中发现收到消息的时候,不刷新,上拉一下才会显示。排查方法是直接使用 SDK 的会话页面,排除是子类代码的问题,替换后发现还是有此问题。后来和技术人员沟通发现是使用了 RCIMClient 中的初始化接口,这样会影响 UI ... ...查看全部

项目用的融云 IMKit SDK,调试中发现收到消息的时候,不刷新,上拉一下才会显示。排查方法是直接使用 SDK 的会话页面,排除是子类代码的问题,替换后发现还是有此问题。后来和技术人员沟通发现是使用了 RCIMClient 中的初始化接口,这样会影响 UI 刷新的。替换为 RCIM 的初始化方法,问题解决!希望此文字可以帮助到后续开发者!

/*!
 初始化融云SDK

 @param appKey  从融云开发者平台创建应用后获取到的App Key

 @discussion 您在使用融云SDK所有功能(包括显示SDK中或者继承于SDK的View)之前,您必须先调用此方法初始化SDK。
 在App整个生命周期中,您只需要执行一次初始化。

 @warning 如果您使用IMKit,请使用此方法初始化SDK;
 如果您使用IMLib,请使用RCIMClient中的同名方法初始化,而不要使用此方法。
 */
- (void)initWithAppKey:(NSString *)appKey;

友情提示融云官网:(www.rongcloud.cn)

融云自定义消息不显示

IM即时通讯徐凤年 发表了文章 • 0 个评论 • 118 次浏览 • 2021-01-11 15:14 • 来自相关话题

项目用的融云,IMKit SDK(自带 UI),但是出现一个问题,就是自定义消息在会话页面刚收到的时候能显示,但是退出会话页面再进入就不显示了。非常的纳闷啊。查询了存储策略,编解码方法,都没有问题。后来提交工单,技术人员给了反馈才发现自己把消息的注册放到了初始... ...查看全部

项目用的融云,IMKit SDK(自带 UI),但是出现一个问题,就是自定义消息在会话页面刚收到的时候能显示,但是退出会话页面再进入就不显示了。非常的纳闷啊。查询了存储策略,编解码方法,都没有问题。后来提交工单,技术人员给了反馈才发现自己把消息的注册放到了初始化 appkey 前边,然后人家融云写的很明确:使用融云SDK所有功能(包括显示SDK中或者继承于SDK的View)之前,您必须先调用此方法初始化 SDK。可见认真查看文档接口注释的重要性!!

/*!
 初始化融云SDK

 @param appKey  从融云开发者平台创建应用后获取到的App Key

 @discussion 您在使用融云SDK所有功能(包括显示SDK中或者继承于SDK的View)之前,您必须先调用此方法初始化SDK。
 在App整个生命周期中,您只需要执行一次初始化。

 @warning 如果您使用IMKit,请使用此方法初始化SDK;
 如果您使用IMLib,请使用RCIMClient中的同名方法初始化,而不要使用此方法。
 */
- (void)initWithAppKey:(NSString *)appKey;

融云(www.rongcloud.cn)

如何利用融云 IMLib 来实现一个阅后即焚功能

IM即时通讯柠檬^ 发表了文章 • 0 个评论 • 212 次浏览 • 2021-01-11 15:14 • 来自相关话题

场景项目需要在私聊中来实现一个阅后即焚的功能,即 A 用户给 B 用户发送消息,B 用户在进入聊天页面查看之后 A 用户删除此消息,B 用户开始进入倒计时,倒计时结束后,删除此消息。思考大体的梳理一下具体的逻辑A -> BB 进入会话页面B 将此消息开始... ...查看全部

场景

项目需要在私聊中来实现一个阅后即焚的功能,即 A 用户给 B 用户发送消息,B 用户在进入聊天页面查看之后 A 用户删除此消息,B 用户开始进入倒计时,倒计时结束后,删除此消息。

思考

  1. 大体的梳理一下具体的逻辑

    • A -> B

    • B 进入会话页面

    • B 将此消息开始倒计时

    • 通知 A 我已进行阅读

    • A 删除消息

  2. 从上面内容我们来大体的设计一下我们需要用户的技术

    • 单例类

    • 自定义消息,用来告诉 A 我已经开始阅读了,你删除吧

    • 一个用于维护阅后即焚消息的管理类

    • 一个存储 A 给 B 发送的所有的阅后即焚的消息的容器 A k 为 targetid ,v 为 messageIDs

    • 一个存储每条阅后即焚消息的容器 B k 为 messageId, v 为当前消息还剩的倒计时时间。

    • 一个用来存储所有阅后即焚消息的容器 C K:ID V:msg

    • 两个处理队列 一个处理时间 一个处理消息

  3. 对外暴露接口

    • 代理 接收方焚烧消息的每秒倒计时

    • 通知 接收方收到对方已阅读某条消息的通知

详解

  1. 初始化我们的所有容器

  2. 收到消息,在合适的业务时机将此消息加入到焚烧队列

  3. 查询消息是否已经在焚烧队列

  4. 如果不在,添加到 A B C容器

  5. 执行倒计时

倒计时操作

  1. 遍历 C 是否有消息

  2. 给发送方发送消息,通知我已经开始焚烧 A 里的消息了 并在 A 容器删除此会话

  3. 发送方收到消息发送通知

  4. 接收方遍历 B 容器,判断每条消息是否到时

  5. 如果消息焚烧时间到 在 A、B 容器删除,并触发代理

  6. 如果没到时间,就触发代理并修改 此消息在 B 容器的时长。


融云 SDK 如何实现群组操作

IM即时通讯柠檬^ 发表了文章 • 0 个评论 • 203 次浏览 • 2021-01-11 15:14 • 来自相关话题

融云 SDK 如何实现群组操作背景在集成融云 SDK 后,需要实现群组操作的消息通知。包括:群创建、销毁通知群公告通知群人员加入、退出通知群昵称修改通知...融云现有的 SDK 仅提供了 RCGroupNotificationMessage,内部封装... ...查看全部

融云 SDK 如何实现群组操作

背景

在集成融云 SDK 后,需要实现群组操作的消息通知。包括:

  • 群创建、销毁通知

  • 群公告通知

  • 群人员加入、退出通知

  • 群昵称修改通知

  • ...

融云现有的 SDK 仅提供了 RCGroupNotificationMessage,内部封装了几种简单的类型操作,且扩展性不强,无法完成现有的操作。

解决方案:

使用自定义消息重新来构建群组通知消息。

参考 sealtlak 中的 RCDGroupNotificationMessage,也是单独对群组操作内容,重新进行了封装处理

/*!
 群组通知消息
 */
@interface RCDGroupNotificationMessage : RCMessageContent

//操作名
@property (nonatomic, copy) NSString *operation;

//操作人
@property (nonatomic, copy) NSString *operatorUserId;

//操作对象
@property (nonatomic, strong) NSArray<NSString *> *targetUserIds;

//内容
@property (nonatomic, copy) NSString *message;

//获取摘要
- (NSString *)getDigest:(NSString *)groupId;
@end

这个类预定义了下面几种操作类型消息,具体内容可参考名字定义

extern NSString *const RCDGroupCreate;
extern NSString *const RCDGroupMemberAdd;
extern NSString *const RCDGroupMemberQuit;
extern NSString *const RCDGroupMemberKicked;
extern NSString *const RCDGroupRename;
extern NSString *const RCDGroupBulletin;
extern NSString *const RCDGroupOwnerTransfer;
extern NSString *const RCDGroupDismiss;
extern NSString *const RCDGroupMemberJoin;
extern NSString *const RCDGroupMemberManagerSet;
extern NSString *const RCDGroupMemberManagerRemove;
extern NSString *const RCDGroupMemberProtectionOpen;
extern NSString *const RCDGroupMemberProtectionClose;

.m 的实现还是按照自定义消息的实现进行处理。唯一有区别的是在获取摘要的方法,在这个方法中对消息内容进行了处理,根据操作名的不同,来对显示的内容进行各种适配。此处根据根据自己的业务进行修改。

- (NSString *)getDigest:(NSString *)groupId {

    NSString *content;

    //获取用户信息
    NSString *operationName = [self getDisplayNames:@[ self.operatorUserId?self.operatorUserId:@""] groupId:groupId];
    NSString *targetNames = [self getDisplayNames:self.targetUserIds groupId:groupId];

    //是否当前用户操作
    BOOL isMeOperate = NO;
    if ([self.operatorUserId isEqualToString:[RCIMClient sharedRCIMClient].currentUserInfo.userId]) {
        isMeOperate = YES;
    }

    //判断操作类型
    if ([self.operation isEqualToString:RCDGroupCreate]) {
        content =
            [NSString stringWithFormat:NSLocalizedStringFromTable(isMeOperate ? @"GroupHaveCreated" : @"GroupCreated",
                                                                  @"RongCloudKit", nil),
                                       operationName];
    } else if ([self.operation isEqualToString:RCDGroupMemberAdd]) {
        if (self.targetUserIds.count == 1 && [self.targetUserIds containsObject:self.operatorUserId]) {
            content = [NSString
                stringWithFormat:NSLocalizedStringFromTable(@"GroupJoin", @"RongCloudKit", nil), operationName];
        } else {
            content = [NSString
                stringWithFormat:NSLocalizedStringFromTable(isMeOperate ? @"GroupHaveInvited" : @"GroupInvited",
                                                            @"RongCloudKit", nil),
                                 operationName, targetNames];
        }
    } else if ([self.operation isEqualToString:RCDGroupMemberJoin]) {
        content =
            [NSString stringWithFormat:NSLocalizedStringFromTable(@"GroupJoin", @"RongCloudKit", nil), operationName];
    } else if ([self.operation isEqualToString:RCDGroupMemberQuit]) {
        content = [NSString stringWithFormat:NSLocalizedStringFromTable(isMeOperate ? @"GroupHaveQuit" : @"GroupQuit",
                                                                        @"RongCloudKit", nil),
                                             operationName];
    } else if ([self.operation isEqualToString:RCDGroupMemberKicked]) {
        content =
            [NSString stringWithFormat:NSLocalizedStringFromTable(isMeOperate ? @"GroupHaveRemoved" : @"GroupRemoved",
                                                                  @"RongCloudKit", nil),
                                       operationName, targetNames];
    } else if ([self.operation isEqualToString:RCDGroupRename]) {
        content = [NSString stringWithFormat:NSLocalizedStringFromTable(@"GroupChanged", @"RongCloudKit", nil),
                                             operationName, self.targetGroupName];
    } else if ([self.operation isEqualToString:RCDGroupDismiss]) {
        content =
            [NSString stringWithFormat:NSLocalizedStringFromTable(isMeOperate ? @"GroupHaveDismiss" : @"GroupDismiss",
                                                                  @"RongCloudKit", nil),
                                       operationName];
    } else if ([self.operation isEqualToString:RCDGroupOwnerTransfer]) {
        content = [NSString stringWithFormat:RCDLocalizedString(@"GroupHasNewOwner"), targetNames];
    } else if ([self.operation isEqualToString:RCDGroupMemberManagerSet]) {
        content = [NSString stringWithFormat:RCDLocalizedString(@"GroupSetManagerMessage"), targetNames];
    } else if ([self.operation isEqualToString:RCDGroupMemberProtectionOpen]) {
        content = RCDLocalizedString(@"openMemberProtection");
    } else if ([self.operation isEqualToString:RCDGroupMemberProtectionClose]) {
        content = [NSString stringWithFormat:RCDLocalizedString(@"closeMemberProtection"), operationName];
    } else {
        content = NSLocalizedStringFromTable(@"unknown_message_cell_tip", @"RongCloudKit", nil);
    }
    return content;
}

此外,还有一个获取名称的方法,用来维护用户信息。

- (NSString *)getDisplayNames:(NSArray<NSString *> *)userIds groupId:(NSString *)groupId


关于融云 SDK 在使用 p8 证书的坎坷~

IM即时通讯木土走召 发表了文章 • 0 个评论 • 208 次浏览 • 2021-01-11 15:14 • 来自相关话题

新上的项目使用了融云的 IM SDK,但在项目集成 APNs 推送的时候,尝鲜使用了一下开发者后台的 p8 证书,此文记录使用 p8 的辛酸史~P8 简介苹果文档传送门官网给出了这种更 "快" 的推送通道: Establishing a T... ...查看全部

新上的项目使用了融云的 IM SDK,但在项目集成 APNs 推送的时候,尝鲜使用了一下开发者后台的 p8 证书,此文记录使用 p8 的辛酸史~

P8 简介

苹果文档传送门

官网给出了这种更 "快" 的推送通道: Establishing a Token-Based Connection to APNs,并且这个生成的这个 key 可以适用于当前账户的所有 APP,为开发人员省了不少力气。福音啊~

想想那一堆证书...... 脑阔痛!

辛酸史

起因是这样的,在融云开发者后台上传了 p8 之后,发现 debug 环境,一直无法收到推送,在经过和融云提供的推送文档进行严格的比对之后,发现没毛病啊~

最后终于在融云开发人员的帮助下找到了问题~,融云后台目前阶段只支持生产环境~ OMG,我打你信不~

区别

p8 是可以同时支持生产和测试环境的,那么为什么融云收不到呢~

让我们大胆猜测一下:

之前基于证书进行校验的时候,一套证书是基于开发者后台一个 AppKey 绑定的,那么我用了哪个 AppKey,后端就基于 AppKey 解析对应的证书,这样就可以发送到对应的 push 环境去了,那么问题来了?使用了 p8 之后,他怎么区分呢?

我也不知道~ 哈哈哈,但我猜测应该是没有解析都去走了生产环境,因为提示我环境不匹配~

苹果 APNs 服务

传送门

Development server: api.sandbox.push.apple.com:443

Production server: api.push.apple.com:443

融云文档传送门


融云 Flutter IM SDK 解析

IM即时通讯木土走召 发表了文章 • 0 个评论 • 226 次浏览 • 2021-01-11 15:14 • 来自相关话题

最近准备使用融云的 Flutter SDK,所以顺便记录一下。融云 Flutter IM SDK 地址:传送门融云的 Flutter SDK 是基于 融云 IMLib 层做的封装,封装了 IMLib 的部分接口提供给 Flutter 开发者使用。此文章只介绍了... ...查看全部

最近准备使用融云的 Flutter SDK,所以顺便记录一下。

融云 Flutter IM SDK 地址:传送门

融云的 Flutter SDK 是基于 融云 IMLib 层做的封装,封装了 IMLib 的部分接口提供给 Flutter 开发者使用。此文章只介绍了 Flutter 层做的一些操作。

目录结构

image.png

整体 SDK 的结构规规矩矩,核心内容参考红色箭头即可。

SDK 层包含 三个目录:
android:此目录包含了和原生 SDK 交互的所有 Java 文件
ios:此目录包含了和原生 SDK 交互的所有 oc 文件
lib: 此目录为使用 dart 编写的 Flutter SDK 文件

其他目录:
doc:主要是融云开发者提供的一些文档相关
example:是融云开发者基于此 SDK 提供的一个简单示例,整体较为简陋,且有细微 bug,仅供参考

FunctionList.md 是融云开发者提供的一个功能清单,
大体如下:

# RongCloud IM Flutter SDK 功能清单

## 连接

初始化

连接

断开连接

连接状态兼容

## 配置

设置服务器地址( im 服务;文件服务)

## 会话

获取会话列表,支持全量获取,分页获取

获取单个会话

删除指定会话



## 消息

当前仅支持 文本消息,语音消息,图片消息,小视频消息

收发消息(可以携带 pushContent)

自定义消息

获取批量本地历史消息

获取单条本地历史消息

获取批量远端历史消息

插入消息

删除批量本地消息

获取未读数

清除指定会话未读数

## 免打扰

设置会话免打扰

获取会话免打扰

## 会话置顶

设置会话置顶

备注:获取会话是可以获取到会话置顶状态

## 黑名单

加入黑名单

移除黑名单

获取黑名单列表

检查特定用户的黑名单状态

## 聊天室

加入聊天室

退出聊天室

获取聊天室信息

都是一些接口层的操作。

剩下的文件基本可以忽略。

解析

我们开始从 lib 目录开始分析

image.png

这两个文件是核心文件,我们所有的调用接口都在这里。

rong_im_client.dart 是最新版本的接口类,我们只关心这个即可。

rong_im_plugin.dart 是旧版本的接口类,已经废弃。

common_define.dart 是定义了 SDK 内使用的所有枚举和状态码。

method_key.dart是定义了 Flutter SDK 和原生层进行交互时标识的唯一的常量字符串。

然后就是剩下的三个文件目录:
image.png

info: 其实就是对象 model 类

image.png

message: 这个是 Flutter SDK提供的所有内置的消息类型,包括聊天室KV消息、合并消息、文件消息、GIF消息、图片消息、位置消息、撤回消息、引用消息、图文消息、视频消息、文本消息、语音消息。

其中有一个比较特殊的 dart 类就是 message_content.dart, 这个类是所有消息的基类。

每个消息都需要继承此类,并复写里面的方法进行编解码。

image.png

util: 这个目录就是一个工具目录。

message_factory.dart 主要是进行消息封装,字典转模型,模型转字典,根本原因我猜就是 Flutter 和 原生仅有的交互类型限制。

type_util.dart:略

以上就是 SDK 在 Flutter 层做的所有的操作,内容整体不多,而且所有代码都是开源的,看看基本上都了解。

与原生层的交互

image.png

整体都是通过 invokeMethod 与原生进行通信的,后面的key 就是之前说的常量字符串,用来保证唯一性。

而在 iOS 和 Android 都提供了对应的定义。

image.png

image.png

并通过触发 iOS 和 Android 层对应的方法来进行处理。

image.png

image.png

原生层

Android:
image.png

整体核心的处理都在 RCIMFlutterWrapper.java 这个类处理了 dart 代码传递过来的数据,并与融云 IMLib 的 SDK 进行了处理。

iOS:
image.png

同样,iOS 的核心代码也都在 RCIMFlutterWrapper.m 这个类处理。具体内容大家可以自己看一下。

到此整个内容我们也就大体明白了。

整体看来其实就是 flutter 中 rong_im_client.dart 和 原生的两个 Wrapper 类做交互,其他的都是助攻。

整体看来不难,搞起~

融云文档:传送门


干货分享——使用融云通讯能力库 IMLib 实现单群聊的阅读回执

IM即时通讯王叫兽 发表了文章 • 0 个评论 • 219 次浏览 • 2021-01-11 15:14 • 来自相关话题

今天的干货分享是关于“阅读回执”功能,这是一个很普遍的功能,但是针对使用融云的 SDK 去实现,还是有些坑在等着我们的,下面就开始分(bì)享(kēng)喽~分享之前先做一些准备工作,先找到我们需要调用的接口文档文档:https://docs.rongclou... ...查看全部

今天的干货分享是关于“阅读回执”功能,这是一个很普遍的功能,但是针对使用融云的 SDK 去实现,还是有些坑在等着我们的,下面就开始分(bì)享(kēng)喽~

  1. 分享之前先做一些准备工作,先找到我们需要调用的接口文档

  2. 根据不同的会话类型以及消息的发送方和接收方,要分别处理

    • 单聊

      接收方 :在阅读消息后,调用 RCIMClient 类的发送阅读回执接口,参数如下:

      conversationType 单聊会话类型

      targetId 消息的会话 ID

      time 会话最后一条消息的发送时间(sentTime)

/*!
 发送某个会话中消息阅读的回执

 @param conversationType    会话类型
 @param targetId            会话 ID
 @param timestamp           该会话中已阅读的最后一条消息的发送时间戳
 @param successBlock        发送成功的回调
 @param errorBlock          发送失败的回调[nErrorCode: 失败的错误码]

 @discussion 此接口只支持单聊, 如果使用 IMLib 可以注册监听
 RCLibDispatchReadReceiptNotification 通知,使用 IMKit 直接设置RCIM.h
 中的 enabledReadReceiptConversationTypeList。

 @warning 目前仅支持单聊。

 @remarks 高级功能
 */
- (void)sendReadReceiptMessage:(RCConversationType)conversationType
                      targetId:(NSString *)targetId
                          time:(long long)timestamp
                       success:(void (^)(void))successBlock
                         error:(void (^)(RCErrorCode nErrorCode))errorBlock;

发送方:监听下面这个通知,在接收后修改消息的展示

/*!
 @const 收到已读回执的 Notification

 @discussion 收到消息已读回执之后,IMLib 会分发此通知。

 Notification 的 object 为 nil,userInfo 为 NSDictionary 对象,
 其中 key 值分别为 @"cType"、@"tId"、@"messageTime",
 对应的 value 为会话类型的 NSNumber 对象 、会话的 targetId 、已阅读的最后一条消息的 sendTime。
 如:
 NSNumber *ctype = [notification.userInfo objectForKey:@"cType"];
 NSNumber *time = [notification.userInfo objectForKey:@"messageTime"];
 NSString *targetId = [notification.userInfo objectForKey:@"tId"];
 NSString *fromUserId = [notification.userInfo objectForKey:@"fId"];

 收到这个消息之后可以更新这个会话中 messageTime 以前的消息 UI 为已读(底层数据库消息状态已经改为已读)。

 @remarks 事件监听
 */
FOUNDATION_EXPORT NSString *const RCLibDispatchReadReceiptNotification;

群聊

发送方

在发送消息 A 后,需要针对该消息发送回执请求,message 传之前发的消息 A

/*!
 请求消息阅读回执

 @param message      要求阅读回执的消息
 @param successBlock 请求成功的回调
 @param errorBlock   请求失败的回调[nErrorCode: 失败的错误码]

 @discussion 通过此接口,可以要求阅读了这条消息的用户发送阅读回执。

 @remarks 高级功能
 */
- (void)sendReadReceiptRequest:(RCMessage *)message
                       success:(void (^)(void))successBlock
                         error:(void (^)(RCErrorCode nErrorCode))errorBlock;

设置下面代理函数,在接收到发送方发来的阅读回执响应后,修改消息的展示

/*!
 IMlib消息接收的监听器

 @discussion
 设置IMLib的消息接收监听器请参考RCIMClient的setReceiveMessageDelegate:object:方法。

 @warning 如果您使用IMlib,可以设置并实现此Delegate监听消息接收;
 如果您使用IMKit,请使用RCIM中的RCIMReceiveMessageDelegate监听消息接收,而不要使用此监听器,否则会导致IMKit中无法自动更新UI!
 */
@protocol RCIMClientReceiveMessageDelegate <NSObject>

/*!
 消息已读回执响应(收到阅读回执响应,可以按照 messageUId 更新消息的阅读数)
 @param messageUId       请求已读回执的消息ID
 @param conversationType conversationType
 @param targetId         targetId
 @param userIdList 已读userId列表
 */
- (void)onMessageReceiptResponse:(RCConversationType)conversationType
                        targetId:(NSString *)targetId
                      messageUId:(NSString *)messageUId
                      readerList:(NSMutableDictionary *)userIdList;

接收方

设置下面代理函数,在接收到消息 A 后,还会接收到针对消息 A 的阅读回执请求

/*!
 IMlib消息接收的监听器

 @discussion
 设置IMLib的消息接收监听器请参考RCIMClient的setReceiveMessageDelegate:object:方法。

 @warning 如果您使用IMlib,可以设置并实现此Delegate监听消息接收;
 如果您使用IMKit,请使用RCIM中的RCIMReceiveMessageDelegate监听消息接收,而不要使用此监听器,否则会导致IMKit中无法自动更新UI!
 */
@protocol RCIMClientReceiveMessageDelegate <NSObject>

/*!
 请求消息已读回执(收到需要阅读时发送回执的请求,收到此请求后在会话页面已经展示该 messageUId 对应的消息或者调用
 getHistoryMessages 获取消息的时候,包含此 messageUId 的消息,需要调用 sendMessageReadReceiptResponse
 接口发送消息阅读回执)

 @param messageUId       请求已读回执的消息ID
 @param conversationType conversationType
 @param targetId         targetId
 */
- (void)onMessageReceiptRequest:(RCConversationType)conversationType
                       targetId:(NSString *)targetId
                     messageUId:(NSString *)messageUId;

在代理方法中,调用下面接口发送阅读回执响应给发送方

/*!
 发送阅读回执

 @param conversationType 会话类型
 @param targetId         会话 ID
 @param messageList      已经阅读了的消息列表
 @param successBlock     发送成功的回调
 @param errorBlock       发送失败的回调[nErrorCode: 失败的错误码]

 @discussion 当用户阅读了需要阅读回执的消息,可以通过此接口发送阅读回执,消息的发送方即可直接知道那些人已经阅读。

 @remarks 高级功能
 */
- (void)sendReadReceiptResponse:(RCConversationType)conversationType
                       targetId:(NSString *)targetId
                    messageList:(NSArray<RCMessage *> *)messageList
                        success:(void (^)(void))successBlock
                          error:(void (^)(RCErrorCode nErrorCode))errorBlock;

总结

阅读回执需要区分会话类型处理,且单聊的阅读回执是针对会话的,群聊的阅读回执是针对某一条消息的:

单聊:接收方阅读某个会话的消息后,发送阅读回执 ——发送方接到阅读回执,更新 UI

群聊:发送方发送消息 A, 针对该消息,发送阅读回执请求 —— 接收方实现监听代理,接收到消息 A 的阅读回执请求 —— 接收方发送阅读回执响应 —— 发送方收到阅读回执响应,更新 UI


如何设置融云用户信息

IM即时通讯dht1212 发表了文章 • 0 个评论 • 222 次浏览 • 2021-01-08 11:35 • 来自相关话题

最近在使用融云,由于第一次使用,遇到了一个小坑,在这里记录一下,希望能帮助到后续开发者问题是使用了融云的 IMKit 组件,也就是自带 UI 的,对于快速试错的产品来说,工期必须短,所以使用 IMKit 是非常方便的,省去了很大部分时间去搞界面。但是使用过程中... ...查看全部

最近在使用融云,由于第一次使用,遇到了一个小坑,在这里记录一下,希望能帮助到后续开发者

问题是使用了融云的 IMKit 组件,也就是自带 UI 的,对于快速试错的产品来说,工期必须短,所以使用 IMKit 是非常方便的,省去了很大部分时间去搞界面。但是使用过程中发现,没有用户的头像和昵称。后来经过阅读文档发现,需要设置“用户信息提供者”代理方法。SDK 在需要显示头像和昵称的时候,会通过这个代理找开发者索取用户信息,开发者只要遵循代理,且实现代理方法,返回用户信息即可。

上代码:

1.遵循代理

@interface AppDelegate () <RCIMUserInfoDataSource>
@end

2.设置代理

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    //必须先初始化
    [[RCIM sharedRCIM] initWithAppKey:"开发者自己的 appkey"];
    [[RCIM sharedRCIM] connectWithToken:"当前用户的 token" dbOpened:^(RCDBErrorCode code) {
        } success:^(NSString *userId) {
        } error:^(RCConnectErrorCode errorCode) {
        }];
    //设置当前用户信息
    RCUserInfo *currentUser = [[RCUserInfo alloc] initWithUserId:@"tiezhu" name:@"铁柱" portrait:@"https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1573646812313&di=116350f184eda99d91393304fa83a6ea&imgtype=0&src=http%3A%2F%2Fimg.jinse.com%2F712431_image3.png"];
    [RCIM sharedRCIM].currentUserInfo = currentUser;
    //设置代理
    [RCIM sharedRCIM].userInfoDataSource = self;
}

3.实现代理方法

- (void)getUserInfoWithUserId:(NSString *)userId completion:(void (^)(RCUserInfo *userInfo))completion {
    //这里最好是从开发者自己服务器获取用户信息,然后返回。此处仅为示例
    RCUserInfo *user = nil;
    if ([userId isEqualToString:@"tiezhu"]) {
        user = [[RCUserInfo alloc] initWithUserId:@"tiezhu" name:@"铁柱" portrait:@"https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1570172426&di=01d14daa81f320235376d9c4dede0493&imgtype=jpg&er=1&src=http%3A%2F%2Fgss0.baidu.com%2F-vo3dSag_xI4khGko9WTAnF6hhy%2Fzhidao%2Fpic%2Fitem%2Fd788d43f8794a4c240e9466f0ef41bd5ac6e39af.jpg"];
    }
    if (completion) {
        completion(user);
    }
}

到此就搞定了兄嘚,值一杯秋天的奶茶