查看: 2064|回复: 0

SAMIM iOS端 图片和视频消息发送处理及其优化

[复制链接]

4

主题

4

帖子

30

积分

积分
30
发表于 2018-11-16 18:01:25 | 显示全部楼层 |阅读模式
本帖最后由 kongdezhi 于 2018-11-16 18:53 编辑

SAMIM  iOS端 图片和视频消息发送处理及其优化
会话和消息
SIMSDK 中用户与同一个对象的聊天信息集合,称为一个会话,用 SIMSessionListModel 来表示。会话有单人会话,群组会话,聊天室会话等类型。
SIMSDK 中用于表示消息的结构为 SIMMessageModel。消息属于SAMIM即时通讯中最关键最重要的类,它是传递信息的基本模型。
消息发送
开发者需要通过 SIMSDK 里的 SIMChatManager 协议进行消息发送
原型
/**
*  发送消息
*
*  @param message 消息
*  @param session 接受方
*  @param error   错误 如果在准备发送消息阶段发生错误,这个error会被填充相应的信息
*
*  @return 是否调用成功,这里返回的 result 只是表示当前这个函数调用是否成功,需要后续的回调才能够判断消息是否已经发送至服务器
*/
- (BOOL)sendMessage: (SIMMessageModel *)message
          toSession: (SIMSessionListModel *)session
              error: (NSError * __nullable *)error;
之前iOS发送图片和视频消息是和其他消息类型放在一起的,现在更改为单独构造消息和发送,优化的粒度下沉,模块职责更加单一。
图片和视频消息构造由类SIMMessageMaker 处理

1.图片消息

/**
构造图片消息

@param image 图片
@return 返回构造的图片消息
*/
+ (SIMMessageModel *)msgWithImage: (UIImage *)image;


/**
构造图片消息

@param path 本地图片路径
@return 返回构造的图片消息
*/
+ (SIMMessageModel *)msgWithImagePath: (NSURL *)path;

2.视频消息
/**
构造视频消息

@param filePath 本地视频路径
@return 返回构造的视频消息
*/
+ (SIMMessageModel *)msgWithVideo: (NSString *)filePath;

聊天会话委托协议 如下
@protocol SIMChatManagerProtocol <NSObject>
/**
*  发送消息
*
*  @param message 消息
*  @param session 接受方
*  @param error   错误 如果在准备发送消息阶段发生错误,这个error会被填充相应的信息
*
*  @return 是否调用成功,这里返回的 result 只是表示当前这个函数调用是否成功,需要后续的回调才能够判断消息是否已经发送至服务器
*/
- (BOOL)sendMessage: (SIMMessageModel *)message
          toSession: (SIMSessionListModel *)session
              error: (NSError * __nullable *)error;

/**
*  添加聊天委托
*
*  @param delegate 聊天委托
*/
- (void)addDelegate: (id<SIMChatManagerDelegate>)delegate;

/**
*  移除聊天委托
*
*  @param delegate 聊天委托
*/
- (void)removeDelegate: (id<SIMChatManagerDelegate>)delegate;
@end

发送消息处理第一步,在聊天会话页面添加委托
[[SIMSDK sharedSDK].chatManager addDelegate:self];

第二步,在聊天会话页面实现代理协议
/**
*  聊天委托
*/
@protocol SIMChatManagerDelegate <NSObject>

@optional
/**
*  即将发送消息回调
*  @discussion 因为发消息之前可能会有个准备过程,所以需要在收到这个回调时才将消息加入到 Datasource 中
*  @param message 当前发送的消息
*/
- (void)willSendMessage: (SIMMessageModel *)message;


/**
*  收取消息附件回调
*  @param message  当前收取的消息
*  @param progress 进度
*  @discussion 附件包括:图片,视频的缩略图,语音文件
*/
- (void)fetchMessageAttachment: (SIMMessageModel *)message
                      progress: (float)progress;


/**
*  收取消息附件完成回调
*
*  @param message 当前收取的消息
*  @param error   错误返回,如果收取成功,error为nil
*/
- (void)fetchMessageAttachment: (SIMMessageModel *)message
          didCompleteWithError: (nullable NSError *)error;
@end

发送图片视频消息方法简化为以下两句代码

SIMMessageModel *message = [SIMMessageMaker msgWithImage:image];//构造消息
[[SIMSDK sharedSDK].chatManager sendMessage:message toSession:weakSelf.session error:nil];//发送消息到session会话

关于视频消息处理的说明
1.iphone由相机拍摄的视频是MOV格式 需要先行压缩处理为mp4格式

        [[SIMShowLoading sharedInstance] showText: @"正在压缩视频"];
        AVURLAsset *avAsset = [AVURLAsset URLAssetWithURL:[NSURL fileURLWithPath:filePath] options:nil];
        AVAssetExportSession *exportSession = [[AVAssetExportSession alloc]initWithAsset:avAsset presetName:AVAssetExportPresetPassthrough];
        NSString *exportPath = [NSString stringWithFormat: @"%@/%@.mp4",
                                [NSHomeDirectory() stringByAppendingString: @"/tmp"],
                                @"1"];
        NSFileManager *fileManager = [NSFileManager defaultManager];
        [fileManager removeItemAtURL:[NSURL fileURLWithPath:exportPath] error:NULL];
        exportSession.outputURL = [NSURL fileURLWithPath:exportPath];
        exportSession.outputFileType = AVFileTypeMPEG4;

        dispatch_semaphore_t sema = dispatch_semaphore_create(0);

        [exportSession exportAsynchronouslyWithCompletionHandler:^{
            if ([exportSession status] == AVAssetExportSessionStatusCompleted) {
                message.videoPath = exportPath;
                UIImage *img = [UIImage getVideoPreViewImageWithvideoPath:[NSURL fileURLWithPath:exportPath]];
                message.videoCoverImage = img;
                message.videoSize = [NSString getVideoInfoWithSourcePath:[NSURL fileURLWithPath:exportPath]];
                dispatch_semaphore_signal(sema);
            }
            else {
                message.videoPath = @"";
                dispatch_semaphore_signal(sema);
            }
        }];
        // 这里本来同步方法会立即返回,但信号量=0使得线程阻塞
        // 当异步方法回调之后,发送信号,信号量变为1,这里的阻塞将被解除,从而返回正确的结果
        dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);

        return message;
由于压缩处理是有系统异步方法实现的,因此在此用信号量处理为同步回调
使用信号量dispatch_semaphore
dispatch_semaphore通常是用来多线程执行多个并发任务时通过信号量的方式对并发执行数量的限制。当信号量不够(=0)的时候当前调用线程将被阻塞,所以我们可以通过模拟信号量不够的情况来阻塞同步方法的返回,直到方法内部的异步回调之后;

回复

使用道具 举报

友情链接

热点

返回列表 发新帖
您需要登录后才可以回帖 登录

本版积分规则

Copyright © 2018 SAMIM.All Rights Reserved

快速回复 返回顶部 返回列表