123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295 |
- //
- // MediaMessageDownloader.m
- // WildFireChat
- //
- // Created by heavyrain lee on 2018/8/29.
- // Copyright © 2018 WildFireChat. All rights reserved.
- //
- #import "WFCUMediaMessageDownloader.h"
- #import "AFNetworking.h"
- #import <WFChatClient/WFCChatClient.h>
- #import "WFCUConfigManager.h"
- #import "WFCUUtilities.h"
- static WFCUMediaMessageDownloader *sharedSingleton = nil;
- @interface WFCUMediaMessageDownloader()
- @property(nonatomic, strong)NSMutableDictionary<NSString*, NSNumber*> *downloadingMessages;
- @end
- @implementation WFCUMediaMessageDownloader
- + (instancetype)sharedDownloader {
- if (sharedSingleton == nil) {
- @synchronized (self) {
- if (sharedSingleton == nil) {
- sharedSingleton = [[WFCUMediaMessageDownloader alloc] init];
- sharedSingleton.downloadingMessages = [[NSMutableDictionary alloc] init];
- }
- }
- }
-
- return sharedSingleton;
- }
- - (void)downloadFileWithURL:(NSString*)requestURLString
- parameters:(NSDictionary *)parameters
- savedPath:(NSString*)savedPath
- downloadSuccess:(void (^)(NSURLResponse *response, NSURL *filePath))success
- downloadFailure:(void (^)(NSError *error))failure
- downloadProgress:(void (^)(NSProgress *downloadProgress))progress
- {
-
- AFHTTPRequestSerializer *serializer = [AFHTTPRequestSerializer serializer];
- requestURLString = [requestURLString stringByRemovingPercentEncoding];
- NSMutableURLRequest *request =[serializer requestWithMethod:@"GET" URLString:requestURLString parameters:parameters error:nil];
- NSURLSessionDownloadTask *task = [[AFHTTPSessionManager manager] downloadTaskWithRequest:request progress:^(NSProgress * _Nonnull downloadProgress) {
- progress(downloadProgress);
- } destination:^NSURL * _Nonnull(NSURL * _Nonnull targetPath, NSURLResponse * _Nonnull response) {
- return [NSURL fileURLWithPath:[savedPath stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
- } completionHandler:^(NSURLResponse * _Nonnull response, NSURL * _Nullable filePath, NSError * _Nullable error) {
- if(error){
- failure(error);
- }else{
- success(response,filePath);
- }
- }];
- [task resume];
-
- }
- - (BOOL)tryDownload:(WFCCMessage *)msg
- success:(void(^)(long long messageUid, NSString *localPath))successBlock
- error:(void(^)(long long messageUid, int error_code))errorBlock {
- long long messageUid = msg.messageUid;
-
- if (!messageUid) {
- NSLog(@"Error, try download message have invalid uid");
- errorBlock(0, -2);
- return NO;
- }
-
- if (![msg.content isKindOfClass:[WFCCMediaMessageContent class]]) {
- NSLog(@"Error, try download message with id %lld, but it's not media message", messageUid);
- errorBlock(msg.messageUid, -1);
- return NO;
- }
-
- WFCCMediaMessageContent *mediaContent = (WFCCMediaMessageContent *)msg.content;
- if (mediaContent.localPath.length && [WFCUUtilities isFileExist:mediaContent.localPath]) {
- successBlock(msg.messageUid, mediaContent.localPath);
- return NO;
- }
-
- WFCCMediaMessagePayload *payload = (WFCCMediaMessagePayload *)[msg.content encode];
- NSString *cacheDir = [[WFCUConfigManager globalManager] cachePathOf:msg.conversation mediaType:payload.mediaType];
-
- if (self.downloadingMessages[mediaContent.remoteUrl] != nil) {
- return NO;
- }
-
- NSString *savedPath = [cacheDir stringByAppendingPathComponent:[NSString stringWithFormat:@"media_%lld", messageUid]];
- if ([mediaContent isKindOfClass:[WFCCSoundMessageContent class]]) {
- if ([mediaContent.remoteUrl pathExtension].length) {
- savedPath = [savedPath stringByAppendingFormat:@".%@", [mediaContent.remoteUrl pathExtension]];
- }
- } else if([mediaContent isKindOfClass:[WFCCVideoMessageContent class]]) {
- savedPath = [NSString stringWithFormat:@"%@.mp4", savedPath];
- } else if([mediaContent isKindOfClass:[WFCCImageMessageContent class]]) {
- savedPath = [NSString stringWithFormat:@"%@.jpg", savedPath];
- } else if([mediaContent isKindOfClass:[WFCCFileMessageContent class]]) {
- WFCCFileMessageContent *content = (WFCCFileMessageContent *)mediaContent;
- savedPath = [cacheDir stringByAppendingPathComponent:content.name];
- }
-
- savedPath = [WFCUUtilities getUnduplicatedPath:savedPath];
- NSFileManager *fileManager = [NSFileManager defaultManager];
- if ([fileManager fileExistsAtPath:savedPath]) {
- mediaContent.localPath = savedPath;
- [[WFCCIMService sharedWFCIMService] updateMessage:msg.messageId content:mediaContent];
-
- dispatch_async(dispatch_get_main_queue(), ^{
- successBlock(msg.messageUid, savedPath);
- });
- return NO;
- }
-
-
- [self.downloadingMessages setObject:@(messageUid) forKey:mediaContent.remoteUrl];
-
- //通知UI开始显示下载动画
- [[NSNotificationCenter defaultCenter] postNotificationName:kMediaMessageStartDownloading object:@(messageUid)];
-
-
- [self downloadFileWithURL:mediaContent.remoteUrl parameters:nil savedPath:savedPath downloadSuccess:^(NSURLResponse *response, NSURL *filePath) {
- NSLog(@"download message content of %lld success", messageUid);
- dispatch_async(dispatch_get_main_queue(), ^{
- [[WFCUMediaMessageDownloader sharedDownloader].downloadingMessages removeObjectForKey:mediaContent.remoteUrl];
- WFCCMessage *newMsg = msg;
- if (msg.conversation.type != Chatroom_Type) {
- newMsg = [[WFCCIMService sharedWFCIMService] getMessageByUid:messageUid];
- }
-
- if (!newMsg) {
- NSLog(@"Error, message %lld not exist", messageUid);
- errorBlock(msg.messageUid, -1);
- [[NSNotificationCenter defaultCenter] postNotificationName:kMediaMessageDownloadFinished object:@(messageUid) userInfo:@{@"result":@(NO)}];
- return;
- }
-
- if (![newMsg.content isKindOfClass:[WFCCMediaMessageContent class]]) {
- NSLog(@"Error, message %lld not media message", messageUid);
- errorBlock(msg.messageUid, -1);
- [[NSNotificationCenter defaultCenter] postNotificationName:kMediaMessageDownloadFinished object:@(messageUid) userInfo:@{@"result":@(NO)}];
- return;
- }
-
- WFCCMediaMessageContent *newContent = (WFCCMediaMessageContent *)newMsg.content;
- newContent.localPath = filePath.absoluteString;
- [[WFCCIMService sharedWFCIMService] updateMessage:newMsg.messageId content:newContent];
-
- mediaContent.localPath = filePath.absoluteString;
- successBlock(newMsg.messageUid, filePath.absoluteString);
-
- [[NSNotificationCenter defaultCenter] postNotificationName:kMediaMessageDownloadFinished object:@(messageUid) userInfo:@{@"result":@(YES), @"localPath":filePath.absoluteString}];
- });
- } downloadFailure:^(NSError *error) {
- dispatch_async(dispatch_get_main_queue(), ^{
- [[WFCUMediaMessageDownloader sharedDownloader].downloadingMessages removeObjectForKey:mediaContent.remoteUrl];
-
- errorBlock(msg.messageUid, -1);
-
- [[NSNotificationCenter defaultCenter] postNotificationName:kMediaMessageDownloadFinished object:@(messageUid) userInfo:@{@"result":@(NO)}];
- });
- NSLog(@"download message content of %lld failure with error %@", messageUid, error);
- } downloadProgress:^(NSProgress *downloadProgress) {
- NSLog(@"总大小:%lld,当前大小:%lld",downloadProgress.totalUnitCount,downloadProgress.completedUnitCount);
- }];
- return YES;
- }
- - (BOOL)tryDownload:(NSString *)mediaPath
- uid:(long long)uid
- mediaType:(DownloadMediaType)mediaType
- success:(void(^)(long long uid, NSString *localPath))successBlock
- error:(void(^)(long long uid, int error_code))errorBlock {
-
- if (!uid) {
- NSLog(@"Error, try download message have invalid uid");
- errorBlock(0, -2);
- return NO;
- }
-
- if (!mediaPath.length) {
- NSLog(@"Error, try download message with id %lld, but it's not media message", uid);
- errorBlock(uid, -1);
- return NO;
- }
-
- WFCCMessage *msg = [[WFCCIMService sharedWFCIMService] getMessageByUid:uid];
-
- NSString *cacheDir;
- if(msg) {
- WFCCMediaMessagePayload *payload = (WFCCMediaMessagePayload *)[msg.content encode];
- cacheDir = [[WFCUConfigManager globalManager] cachePathOf:msg.conversation mediaType:payload.mediaType];
-
- } else {
- NSFileManager *fileManager = [NSFileManager defaultManager];
- BOOL isDir;
- NSError *error = nil;
- NSString *downloadDir = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES).firstObject stringByAppendingString:@"/download"];
- if (![fileManager fileExistsAtPath:downloadDir isDirectory:&isDir]) {
- if(![fileManager createDirectoryAtPath:downloadDir withIntermediateDirectories:YES attributes:nil error:&error]) {
- errorBlock(uid, -1);
- NSLog(@"Error, create download folder error");
- return NO;
- }
- if (error) {
- errorBlock(uid, -1);
- NSLog(@"Error, create download folder error:%@", error);
- return NO;
- }
- }
- if (!isDir) {
- errorBlock(uid, -1);
- NSLog(@"Error, create download folder error");
- return NO;
- }
- cacheDir = downloadDir;
- }
-
-
- //通知UI开始显示下载动画
- [[NSNotificationCenter defaultCenter] postNotificationName:kMediaMessageStartDownloading object:@(uid)];
-
-
- if (self.downloadingMessages[mediaPath] != nil) {
- return NO;
- }
-
- NSString *savedPath = [cacheDir stringByAppendingPathComponent:[NSString stringWithFormat:@"media_%lld", uid]];
- switch (mediaType) {
- case DownloadMediaType_Image:
- savedPath = [NSString stringWithFormat:@"%@.jpg", savedPath];
- break;
-
- case DownloadMediaType_Voice:
- savedPath = [NSString stringWithFormat:@"%@.wav", savedPath];
- break;
-
- case DownloadMediaType_Video:
- savedPath = [NSString stringWithFormat:@"%@.mp4", savedPath];
- break;
-
- case DownloadMediaType_File:
- if(msg && [msg.content isKindOfClass:[WFCCFileMessageContent class]]) {
- WFCCFileMessageContent *fileContent = (WFCCFileMessageContent *)msg.content;
- savedPath = [cacheDir stringByAppendingPathComponent:fileContent.name];
- } else {
- savedPath = [cacheDir stringByAppendingPathComponent:[NSString stringWithFormat:@"file_%lld", uid]];
- }
- break;
- default:
- break;
- }
- savedPath = [WFCUUtilities getUnduplicatedPath:savedPath];
-
- NSFileManager *fileManager = [NSFileManager defaultManager];
- if ([fileManager fileExistsAtPath:savedPath]) {
- dispatch_async(dispatch_get_main_queue(), ^{
- successBlock(uid, savedPath);
- [[NSNotificationCenter defaultCenter] postNotificationName:kMediaMessageDownloadFinished object:@(uid) userInfo:@{@"result":@(YES), @"localPath":savedPath}];
- });
- return NO;
- }
-
- [self.downloadingMessages setObject:@(uid) forKey:mediaPath];
-
- [self downloadFileWithURL:mediaPath parameters:nil savedPath:savedPath downloadSuccess:^(NSURLResponse *response, NSURL *filePath) {
- NSLog(@"download message content of %lld success", uid);
- dispatch_async(dispatch_get_main_queue(), ^{
- [[WFCUMediaMessageDownloader sharedDownloader].downloadingMessages removeObjectForKey:mediaPath];
- successBlock(uid, filePath.absoluteString);
- [[NSNotificationCenter defaultCenter] postNotificationName:kMediaMessageDownloadFinished object:@(uid) userInfo:@{@"result":@(YES), @"localPath":filePath.absoluteString}];
- });
- } downloadFailure:^(NSError *error) {
- dispatch_async(dispatch_get_main_queue(), ^{
- [[WFCUMediaMessageDownloader sharedDownloader].downloadingMessages removeObjectForKey:mediaPath];
- errorBlock(uid, -1);
- [[NSNotificationCenter defaultCenter] postNotificationName:kMediaMessageDownloadFinished object:@(uid) userInfo:@{@"result":@(NO)}];
- });
- NSLog(@"download message content of %lld failure with error %@", uid, error);
- } downloadProgress:^(NSProgress *downloadProgress) {
- NSLog(@"总大小:%lld,当前大小:%lld",downloadProgress.totalUnitCount,downloadProgress.completedUnitCount);
- }];
- return YES;
- }
- - (void)dealloc {
- [[NSNotificationCenter defaultCenter] removeObserver:self];
- }
- @end
|