Files
peko-ios/YuMi/Tools/File/UploadFile.m
2024-05-17 16:57:28 +08:00

325 lines
15 KiB
Objective-C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//
// UploadFile.m
// xplan-ios
//
// Created by GreenLand on 2022/2/23.
//
#import <QCloudCOSXML/QCloudCOSXML.h>
#import "UploadFile.h"
#import <AFNetworking.h>
#import "Api+Mine.h"
#import "UploadFileModel.h"
static UploadFile* manager;
@interface UploadFile()<QCloudSignatureProvider,QCloudCredentailFenceQueueDelegate>
// 一个脚手架实例
@property (nonatomic) QCloudCredentailFenceQueue* credentialFenceQueue;
@property(nonatomic,strong) UploadFileModel *fileModel;
@end
@implementation UploadFile
+ (instancetype)share {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
manager = [[UploadFile alloc] init];
});
return manager;
}
-(void)initQCloud{
[Api getQCloudInfo:^(BaseModel * _Nullable data, NSInteger code, NSString * _Nullable msg) {
if (code == 200){
UploadFileModel *fileModel = [UploadFileModel modelWithDictionary:data.data];
self.fileModel = fileModel;
QCloudServiceConfiguration* configuration = [QCloudServiceConfiguration new];
configuration.appID = fileModel.appId;
QCloudCOSXMLEndPoint* endpoint = [[QCloudCOSXMLEndPoint alloc] init];
endpoint.regionName = fileModel.region;
// 使用 HTTPS
endpoint.useHTTPS = YES;
configuration.endpoint = endpoint;
// 密钥提供者为自己
configuration.signatureProvider = self;
// 初始化 COS 服务示例
[QCloudCOSXMLService registerDefaultCOSXMLWithConfiguration:configuration];
[QCloudCOSTransferMangerService registerDefaultCOSTransferMangerWithConfiguration:
configuration];
self.credentialFenceQueue = [QCloudCredentailFenceQueue new];
self.credentialFenceQueue.delegate = self;
}
}];
}
#pragma mark- QCloudSignatureProvider
- (void) signatureWithFields:(QCloudSignatureFields*)fileds
request:(QCloudBizHTTPRequest*)request
urlRequest:(NSMutableURLRequest*)urlRequst
compelete:(QCloudHTTPAuthentationContinueBlock)continueBlock
{
[Api getQCloudInfo:^(BaseModel * _Nullable data, NSInteger code, NSString * _Nullable msg) {
if (code == 200){
UploadFileModel *fileModel = [UploadFileModel modelWithDictionary:data.data];
QCloudCredential* credential = [QCloudCredential new];
// 临时密钥 SecretId
credential.secretID = fileModel.secretId;
// 临时密钥 SecretKey
credential.secretKey = fileModel.secretKey;
// 临时密钥 Token
credential.token = fileModel.sessionToken;
/** 强烈建议返回服务器时间作为签名的开始时间, 用来避免由于用户手机本地时间偏差过大导致的签名不正确(参数startTime和expiredTime单位为秒)
*/
credential.startDate = [NSDate dateWithTimeIntervalSince1970:fileModel.startTime]; // 单位是秒
credential.expirationDate = [NSDate dateWithTimeIntervalSince1970:fileModel.expireTime];// 单位是秒
QCloudAuthentationV5Creator* creator = [[QCloudAuthentationV5Creator alloc]
initWithCredential:credential];
// 注意 这里不要对urlRequst 进行copy以及mutableCopy操作
QCloudSignature *signature = [creator signatureForData:urlRequst];
continueBlock(signature, nil);
}
}
];
}
#pragma mark - QCloudCredentailFenceQueueDelegate
- (void) fenceQueue:(QCloudCredentailFenceQueue * )queue requestCreatorWithContinue:(QCloudCredentailFenceQueueContinue)continueBlock
{
//这里同步从◊后台服务器获取临时密钥,强烈建议将获取临时密钥的逻辑放在这里,最大程度上保证密钥的可用性
//...
[Api getQCloudInfo:^(BaseModel * _Nullable data, NSInteger code, NSString * _Nullable msg) {
if (code == 200){
UploadFileModel *fileModel = [UploadFileModel modelWithDictionary:data.data];
QCloudCredential* credential = [QCloudCredential new];
// 临时密钥 SecretId
credential.secretID = fileModel.secretId;
// 临时密钥 SecretKey
credential.secretKey = fileModel.secretKey;
// 临时密钥 Token
credential.token = fileModel.sessionToken;
/** 强烈建议返回服务器时间作为签名的开始时间, 用来避免由于用户手机本地时间偏差过大导致的签名不正确(参数startTime和expiredTime单位为秒)
*/
credential.startDate = [NSDate dateWithTimeIntervalSince1970:fileModel.startTime]; // 单位是秒
credential.expirationDate = [NSDate dateWithTimeIntervalSince1970:fileModel.expireTime];// 单位是秒
QCloudAuthentationV5Creator* creator = [[QCloudAuthentationV5Creator alloc]
initWithCredential:credential];
continueBlock(creator, nil);
}
}];
}
/// 上传一个文件
/// @param filePath 文件地址
/// @param fileName 文件的名字
/// @param success 成功
/// @param failure 失败
- (void)QCloudUploadFile:(NSString *)filePath
named:(NSString *)fileName
success:(void (^)(NSString *key, NSDictionary *resp))success
failure:(void (^)(NSNumber *resCode, NSString *message))failure {
QCloudCOSXMLUploadObjectRequest* put = [QCloudCOSXMLUploadObjectRequest new];
// 本地文件路径
NSURL* url = [NSURL fileURLWithPath:filePath];
// 存储桶名称由BucketName-Appid 组成可以在COS控制台查看 https://console.cloud.tencent.com/cos5/bucket
put.bucket = self.fileModel.bucket;
// 对象键,是对象在 COS 上的完整路径,如果带目录的话,格式为 "video/xxx/movie.mp4"
put.object = fileName;
//需要上传的对象内容。可以传入NSData*或者NSURL*类型的变量
put.body = url;
//监听上传进度
[put setSendProcessBlock:^(int64_t bytesSent,
int64_t totalBytesSent,
int64_t totalBytesExpectedToSend) {
// bytesSent 本次要发送的字节数(一个大文件可能要分多次发送)
// totalBytesSent 已发送的字节数
// totalBytesExpectedToSend 本次上传要发送的总字节数(即一个文件大小)
}];
//监听上传结果
[put setFinishBlock:^(id outputObject, NSError *error) {
//可以从 outputObject 中获取 response 中 etag 或者自定义头部等信息
if (error) {
failure(@(error.code),error.localizedDescription);
return;
}
QCloudUploadObjectResult * result = (QCloudUploadObjectResult *)outputObject;
NSArray *urlList = [result.location componentsSeparatedByString:@".com/"];
if (urlList.count == 2){
NSString *url = [NSString stringWithFormat:@"%@/%@",self.fileModel.customDomain,urlList[1]];
success(url,nil);
return;
}
success(result.location,nil);
}];
[[QCloudCOSTransferMangerService defaultCOSTransferManager] UploadObject:put];
}
/// 上传一个Image
/// @param image 图片
/// @param imageName 图片的名字
/// @param success 成功
/// @param failure 失败
- (void)QCloudUploadImage:(NSData *)data
named:(NSString *)name
success:(void (^)(NSString *key, NSDictionary *resp))success
failure:(void (^)(NSNumber *resCode, NSString *message))failure{
QCloudCOSXMLUploadObjectRequest* put = [QCloudCOSXMLUploadObjectRequest new];
put.bucket = self.fileModel.bucket;
// 对象键,是对象在 COS 上的完整路径,如果带目录的话,格式为 "video/xxx/movie.mp4"
put.object = name;
//需要上传的对象内容。可以传入NSData*或者NSURL*类型的变量
put.body = data;
//监听上传进度
[put setSendProcessBlock:^(int64_t bytesSent,
int64_t totalBytesSent,
int64_t totalBytesExpectedToSend) {
// bytesSent 本次要发送的字节数(一个大文件可能要分多次发送)
// totalBytesSent 已发送的字节数
// totalBytesExpectedToSend 本次上传要发送的总字节数(即一个文件大小)
}];
//监听上传结果
[put setFinishBlock:^(id outputObject, NSError *error) {
if (error) {
failure(@(error.code),error.localizedDescription);
return;
}
QCloudUploadObjectResult * result = (QCloudUploadObjectResult *)outputObject;
NSArray *urlList = [result.location componentsSeparatedByString:@".com/"];
if (urlList.count == 2){
NSString *url = [NSString stringWithFormat:@"%@/%@",self.fileModel.customDomain,urlList[1]];
success(url,nil);
return;
}
success(result.location,nil);
}];
[[QCloudCOSTransferMangerService defaultCOSTransferManager] UploadObject:put];
}
-(void)downloadAnimationFileName:(NSString *)fileName localPath:(NSString *)localPath completion:(void (^) (BOOL isSuccess, NSString *editAudioPath))completion{
QCloudCOSXMLDownloadObjectRequest * request = [QCloudCOSXMLDownloadObjectRequest new];
// 存储桶名称由BucketName-Appid 组成可以在COS控制台查看 https://console.cloud.tencent.com/cos5/bucket
request.bucket = self.fileModel.bucket;
NSArray *urlList = [fileName componentsSeparatedByString:@".com/"];
// 对象键,是对象在 COS 上的完整路径,如果带目录的话,格式为 "video/xxx/movie.mp4"
request.object = [urlList safeObjectAtIndex1:1];
// 设置下载的路径 URL如果设置了文件将会被下载到指定路径中
request.downloadingURL = [NSURL fileURLWithPath:localPath];
// 监听下载结果
[request setFinishBlock:^(id outputObject, NSError *error) {
// outputObject 包含所有的响应 http 头部
NSDictionary* info = (NSDictionary *) outputObject;
NSLog(@"%@",info);
}];
// 监听下载进度
[request setDownProcessBlock:^(int64_t bytesDownload,
int64_t totalBytesDownload,
int64_t totalBytesExpectedToDownload) {
// bytesDownload 新增字节数
// totalBytesDownload 本次下载接收的总字节数
// totalBytesExpectedToDownload 本次下载的目标字节数
}];
[[QCloudCOSTransferMangerService defaultCOSTransferManager] DownloadObject:request];
}
+(void)downloadAudioWithFileName:(NSString *)fileName musicUrl:(NSString *)musicUrl mainFileName:(NSString *)mainFileName completion:(void (^) (BOOL isSuccess, NSString *editAudioPath))completion {
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
NSURL *url = [NSURL URLWithString:[musicUrl stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]]];
NSURLRequest *request = [NSURLRequest requestWithURL :url];
NSURLSessionDownloadTask *download = [manager downloadTaskWithRequest:request progress:^(NSProgress * _Nonnull downloadProgress) {
} destination:^NSURL * _Nonnull(NSURL * _Nonnull targetPath, NSURLResponse * _Nonnull response) {
NSString *filePath = [[[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) safeObjectAtIndex1:0] stringByAppendingPathComponent:mainFileName] stringByAppendingPathComponent:fileName];
return [NSURL fileURLWithPath:filePath];
} completionHandler:^(NSURLResponse * _Nonnull response, NSURL * _Nullable filePath, NSError * _Nullable error) {
if (!error) {
completion(YES, filePath.path);
} else {
completion(NO, nil);
}
}];
[download resume];
}
+(void)downloadGiftDynamicEffectWithList:(NSSet *)list completion:(void (^) (BOOL isSuccess, NSMutableArray *editAudioPath))completion{
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
manager.operationQueue.maxConcurrentOperationCount = 20; // 控制并发数量
dispatch_group_t requestGroup = dispatch_group_create();
NSMutableArray *failList = [NSMutableArray array];
for (NSString *giftUrl in list) {
NSString *encodingUrl = [giftUrl stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet characterSetWithCharactersInString:@"`#%^{}\"[]|\\<> "].invertedSet];
NSString *fileName = [[encodingUrl componentsSeparatedByString:@"/"] lastObject];
NSString *filePath = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) safeObjectAtIndex1:0] stringByAppendingPathComponent:@"GiftDynamicEffectList"];
NSString *fullPath = [filePath stringByAppendingPathComponent:fileName];
if ([[NSFileManager defaultManager] fileExistsAtPath:fullPath]) {
continue;
}
NSFileManager *fileMgr = [[NSFileManager alloc] init];
[fileMgr createDirectoryAtPath:filePath withIntermediateDirectories:YES attributes:nil error:nil];
dispatch_group_enter(requestGroup);
NSURL *url = [NSURL URLWithString:[encodingUrl stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]]];
NSURLRequest *request = [NSURLRequest requestWithURL :url];
NSURLSessionDownloadTask *download = [manager downloadTaskWithRequest:request progress:^(NSProgress * _Nonnull downloadProgress) {
} destination:^NSURL * _Nonnull(NSURL * _Nonnull targetPath, NSURLResponse * _Nonnull response) {
return [NSURL fileURLWithPath:fullPath];
} completionHandler:^(NSURLResponse * _Nonnull response, NSURL * _Nullable filePath, NSError * _Nullable error) {
dispatch_group_leave(requestGroup);
if (!error) {
NSLog(@"下载完成");
} else {
NSLog(@"下载失败");
[failList addObject:encodingUrl];
}
}];
[download resume];
}
dispatch_group_notify(requestGroup, dispatch_get_main_queue(), ^{
if(failList.count > 0){
completion(NO,failList);
NSLog(@"下载有失败");
}else{
NSLog(@"下载全部完成");
completion(NO,nil);
}
});
}
@end