// // UploadFile.m // xplan-ios // // Created by GreenLand on 2022/2/23. // #import #import "UploadFile.h" #import #import "Api+Mine.h" #import "YinUploadFileModel.h" static UploadFile* manager; @interface UploadFile() // 一个脚手架实例 @property (nonatomic) QCloudCredentailFenceQueue* credentialFenceQueue; @property(nonatomic,strong) YinUploadFileModel *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){ YinUploadFileModel *fileModel = [YinUploadFileModel 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){ YinUploadFileModel *fileModel = [YinUploadFileModel 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){ YinUploadFileModel *fileModel = [YinUploadFileModel 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]; } /// 上传一个文件 /// @param data 文件 /// @param fileName 文件的名字 /// @param success 成功 /// @param failure 失败 - (void)QCloudUploadFileWithData:(NSData *)data named:(NSString *)fileName success:(void (^)(NSString *key, NSDictionary *resp))success failure:(void (^)(NSNumber *resCode, NSString *message))failure { QCloudCOSXMLUploadObjectRequest* put = [QCloudCOSXMLUploadObjectRequest new]; \ // 存储桶名称,由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 = data; //监听上传进度 [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)downloadAudioWithFileName:(NSString *)fileName musicUrl:(NSString *)musicUrl mainFileName:(NSString *)mainFileName completion:(void (^) (BOOL isSuccess, NSString *editAudioPath))completion { AFHTTPSessionManager *manager = [AFHTTPSessionManager manager]; NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:musicUrl]]; 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]; } @end