// // YBStorageObj.m // YBVideo // // Created by YB007 on 2019/11/22. // Copyright © 2019 cat. All rights reserved. // #import "YBStorageObj.h" #import "StorageConfig.h" #import #import #import #import typedef NS_ENUM(NSInteger,StorageType) { StorageType_Image, //图片 StorageType_File, //音、视频 }; @interface YBStorageObj() @end @implementation YBStorageObj static YBStorageObj *storageManeger = nil; +(instancetype)storageManeger { static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ storageManeger = [[super allocWithZone:NULL]init]; }); return storageManeger; } +(instancetype)allocWithZone:(struct _NSZone *)zone { return [self storageManeger]; } #pragma mark - 第一步:获取存储类型(tx 、qiniu) -(void)getCOSType:(YBStorageTypeBlock)complete { NSDate *oldDate = [StorageConfig getResTime] ? [StorageConfig getResTime] : [NSDate date]; NSDate *curDate = [NSDate date]; NSTimeInterval timeInterval = [curDate timeIntervalSinceDate:oldDate]; [MBProgressHUD showMessage:@""]; YBWeakSelf; //这里过期时间默认 10 分钟,不建议改特别大的值(七牛存储token有过期时间,这个时间一定要小于七牛的过期时间) if (![StorageConfig getResTime] || timeInterval > 600) { //说明没有存储过或者超过10分钟、获取存储类型(如果是七牛顺带获取token) [YBNetworking postWithUrl:@"Video.getCosInfo" Dic:@{} Suc:^(int code, id info, NSString *msg) { // [MBProgressHUD hideHUD]; if (code == 0) { NSDictionary *infoDic = [info firstObject]; //保留存储时间、存储类型 [StorageConfig saveResTime:[NSDate date]]; NSString *cloudType = minstr([infoDic valueForKey:@"cloudtype"]); [StorageConfig saveStorageType:minstr([infoDic valueForKey:@"cloudtype"])]; //【七牛基本信息】 NSDictionary *qnInfo = @{}; if ([[infoDic valueForKey:@"qiniuInfo"] isKindOfClass:[NSDictionary class]]) { qnInfo = [infoDic valueForKey:@"qiniuInfo"]; [StorageConfig saveQNToken:minstr([qnInfo valueForKey:@"qiniuToken"])]; [StorageConfig saveQNDomain:minstr([qnInfo valueForKey:@"qiniu_domain"])]; [StorageConfig saveQNZone:minstr([qnInfo valueForKey:@"qiniu_zone"])]; } //【亚马逊基本信息】 NSDictionary *awsInfo = @{}; if ([[infoDic valueForKey:@"awsInfo"] isKindOfClass:[NSDictionary class]]) { awsInfo = [infoDic valueForKey:@"awsInfo"]; [StorageConfig saveAwsBucket:minstr([awsInfo valueForKey:@"aws_bucket"])]; [StorageConfig saveAwsRegion:minstr([awsInfo valueForKey:@"aws_region"])]; [StorageConfig saveAwsIdentityPoolid:minstr([awsInfo valueForKey:@"aws_identitypoolid"])]; } if ([[infoDic valueForKey:@"txCloudInfo"] isKindOfClass:[NSDictionary class]]) { NSDictionary *txInfo = [infoDic valueForKey:@"txCloudInfo"]; [StorageConfig saveTXRegion:minstr([txInfo valueForKey:@"region"])]; [StorageConfig saveTXBucket:minstr([txInfo valueForKey:@"bucket"])]; [StorageConfig saveTXAppID:minstr([txInfo valueForKey:@"appid"])]; } //基本信息验证 if ([cloudType isEqual:@"aws"]) { //亚马逊 if ([PublicObj checkNull:minstr([awsInfo valueForKey:@"aws_bucket"])] || [PublicObj checkNull:minstr([awsInfo valueForKey:@"aws_region"])] || [PublicObj checkNull:minstr([awsInfo valueForKey:@"aws_identitypoolid"])]) { if (complete) { complete(-1); } [MBProgressHUD showError:YZMsg(@"亚马逊存储配置有误")]; }else { [weakSelf yb_awsInitialization]; if (complete) { complete(0); } } }else if ([cloudType isEqual:@"tx"]) { if (complete) { [weakSelf txInit]; complete(0); } } else{ //七牛 if ([PublicObj checkNull:minstr([qnInfo valueForKey:@"qiniuToken"])] || [PublicObj checkNull:minstr([qnInfo valueForKey:@"qiniu_zone"])]) { if (complete) { complete(-1); } [MBProgressHUD showError:YZMsg(@"七牛存储配置有误")]; }else { if (complete) { complete(0); } } } }else { if (complete) { complete(-1); } [MBProgressHUD hideHUD]; [MBProgressHUD showPop:msg]; } } Fail:^(id fail) { [MBProgressHUD hideHUD]; if (complete) { complete(-2); } }]; }else { //10分钟内不请求接口,使用本地存贮的值 [MBProgressHUD hideHUD]; if (complete) { [weakSelf txInit]; complete(0); } } } #pragma mark - 第二步:开始上传(tx 、qiniu) //图片 -(void)yb_storageImg:(UIImage *)img andName:(NSString *)imgName progress:(YBStoragePercentBlock)ybprogress complete:(YBStorageFinishaBlock)complete{ NSString *cloudType = minstr([StorageConfig getStorageType]); NSData *thumbData = UIImagePNGRepresentation(img); if ([cloudType isEqual:@"aws"]) { //亚马逊 AWSS3TransferUtilityUploadCompletionHandlerBlock completionHandler = ^(AWSS3TransferUtilityUploadTask *task, NSError *error) { if (error) { NSLog(@"uploadfail:%@",error); if (complete) { complete(-1,@""); } } else { NSLog(@"uploadSur:%@",task.key); if (complete) { NSString *taskey = [NSString stringWithFormat:@"%@",task.key]; complete(0,taskey); } } }; AWSS3TransferUtilityUploadExpression *expression = [AWSS3TransferUtilityUploadExpression new]; expression.progressBlock = ^(AWSS3TransferUtilityTask *task, NSProgress *progress) { if (ybprogress) { ybprogress(progress.fractionCompleted); } NSLog(@"pro:%f",progress.fractionCompleted); }; AWSS3TransferUtility *transferUtility = [AWSS3TransferUtility defaultS3TransferUtility]; [[transferUtility uploadData:thumbData bucket:[StorageConfig getAwsBucket] key:imgName contentType:@"image/png" expression:expression completionHandler:completionHandler] continueWithBlock:^id _Nullable(AWSTask * _Nonnull t) { if (t.error) { NSLog(@"Error: %@", t.error); if (complete) { complete(-1,@""); } } if (t.result) { AWSS3TransferUtilityUploadTask *uploadTask = t.result; // Do something with uploadTask. NSLog(@"restult:%@",uploadTask); } return nil; }]; }else if ([cloudType isEqual:@"tx"]) { //腾讯 QCloudCOSXMLUploadObjectRequest* put = [QCloudCOSXMLUploadObjectRequest new]; put.object = imgName;//[NSString stringWithFormat:@"dspdemo/%@",imgName]; put.bucket = minstr([StorageConfig getTXBucket]); put.body = thumbData; [put setSendProcessBlock:^(int64_t bytesSent, int64_t totalBytesSent, int64_t totalBytesExpectedToSend) { //NSLog(@"rk;;upload %lld totalSend %lld aim %lld", bytesSent, totalBytesSent, totalBytesExpectedToSend); if (ybprogress) { ybprogress((CGFloat)totalBytesSent/totalBytesExpectedToSend); } }]; [put setFinishBlock:^(id outputObject, NSError* error) { QCloudUploadObjectResult *rst = outputObject; NSLog(@"rk;;111111:\nlocation:%@\n%@",rst.location,rst.key); if (error) { //失败 if (complete) { complete(-1,@""); } }else{ //成功 if (complete) { complete(0,rst.key); } } }]; [[QCloudCOSTransferMangerService defaultCOSTransferManager] UploadObject:put]; }else { //七牛 QNConfiguration *config = [QNConfiguration build:^(QNConfigurationBuilder *builder) { builder.zone = [self getQNZone]; }]; QNUploadOption *option = [[QNUploadOption alloc]initWithMime:nil progressHandler:^(NSString *key, float percent) { //NSLog(@"=====%@9999:%f",imgName,percent); if (ybprogress) { ybprogress(percent); } } params:nil checkCrc:NO cancellationSignal:nil]; QNUploadManager *upManager = [[QNUploadManager alloc] initWithConfiguration:config]; [upManager putData:thumbData key:imgName token:minstr([StorageConfig getQNToken]) complete:^(QNResponseInfo *info, NSString *key, NSDictionary *resp) { NSLog(@"info ===== %@ \n resp ===== %@", info,resp); if (info.ok) { //成功 if (complete) { complete(0,key); } }else { //失败 if (complete) { complete(-1,@""); } } } option:option]; } } //音、视频 -(void)yb_storageVideoOrVoice:(NSString *)filePath andName:(NSString *)fileName progress:(YBStoragePercentBlock)ybprogress complete:(YBStorageFinishaBlock)complete{ NSString *cloudType = minstr([StorageConfig getStorageType]); if ([cloudType isEqual:@"aws"]) { //亚马逊 NSString *mineType = @"video/mp4"; if ([filePath hasSuffix:@".m4a"]) { mineType = @"audio/x-m4a"; }else if ([filePath hasSuffix:@".wav"]){ mineType = @"audio/wav"; } AWSS3TransferUtilityUploadCompletionHandlerBlock completionHandler = ^(AWSS3TransferUtilityUploadTask *task, NSError *error) { if (error) { NSLog(@"uploadfail:%@",error); if (complete) { complete(-1,@""); } } else { NSLog(@"uploadSur:%@",task.key); if (complete) { NSString *taskey = [NSString stringWithFormat:@"%@",task.key]; complete(0,taskey);//task.key } } }; AWSS3TransferUtilityUploadExpression *expression = [AWSS3TransferUtilityUploadExpression new]; expression.progressBlock = ^(AWSS3TransferUtilityTask *task, NSProgress *progress) { if (ybprogress) { ybprogress(progress.fractionCompleted); } NSLog(@"pro:%f",progress.fractionCompleted); }; AWSS3TransferUtility *transferUtility = [AWSS3TransferUtility defaultS3TransferUtility]; [[transferUtility uploadFile:[NSURL URLWithString:filePath] bucket:[StorageConfig getAwsBucket] key:fileName contentType:mineType expression:expression completionHandler:completionHandler] continueWithBlock:^id _Nullable(AWSTask * _Nonnull t) { if (t.error) { NSLog(@"Error: %@", t.error); if (complete) { complete(-1,@""); } } if (t.result) { AWSS3TransferUtilityUploadTask *uploadTask = t.result; // Do something with uploadTask. NSLog(@"restult:%@",uploadTask); } return nil; }]; }else if ([cloudType isEqual:@"tx"]) { //腾讯 QCloudCOSXMLUploadObjectRequest* put = [QCloudCOSXMLUploadObjectRequest new]; NSURL* pathUrl = [NSURL fileURLWithPath:filePath]; put.object = fileName; put.bucket = minstr([StorageConfig getTXBucket]); put.body = pathUrl; [put setSendProcessBlock:^(int64_t bytesSent, int64_t totalBytesSent, int64_t totalBytesExpectedToSend) { //NSLog(@"%@rk;;upload %lld totalSend %lld aim %lld",fileName, bytesSent, totalBytesSent, totalBytesExpectedToSend); if (ybprogress) { ybprogress((CGFloat)totalBytesSent/totalBytesExpectedToSend); } }]; [put setFinishBlock:^(id outputObject, NSError* error) { QCloudUploadObjectResult *rst = outputObject; NSLog(@"rk;;111111:\nlocation:%@\n%@",rst.location,rst.key); if (error) { //失败 if (complete) { complete(-1,@""); } }else{ //成功 if (complete) { complete(0,rst.key); } } }]; [[QCloudCOSTransferMangerService defaultCOSTransferManager] UploadObject:put]; }else { //七牛 QNConfiguration *config = [QNConfiguration build:^(QNConfigurationBuilder *builder) { builder.zone = [self getQNZone]; }]; QNUploadOption *option = [[QNUploadOption alloc]initWithMime:nil progressHandler:^(NSString *key, float percent) { //NSLog(@"=====%@9999:%f",fileName,percent); if (ybprogress) { ybprogress(percent); } } params:nil checkCrc:NO cancellationSignal:nil]; QNUploadManager *upManager = [[QNUploadManager alloc] initWithConfiguration:config]; [upManager putFile:filePath key:fileName token:minstr([StorageConfig getQNToken]) complete:^(QNResponseInfo *info, NSString *key, NSDictionary *resp) { NSLog(@"info ===== %@ \n resp ===== %@", info,resp); if (info.ok) { //成功 if (complete) { complete(0,key); } }else { //失败 if (complete) { complete(-1,@""); } } } option:option]; } } #pragma mark - 腾讯初始化、验证开始 -(void)txInit { if (![[StorageConfig getStorageType] isEqual:@"tx"]) { return; } if ([PublicObj checkNull:[StorageConfig getTXAppID]] || [PublicObj checkNull:[StorageConfig getTXBucket]] ||[PublicObj checkNull:[StorageConfig getTXRegion]]) { dispatch_async(dispatch_get_main_queue(), ^{ [MBProgressHUD showPop:YZMsg(@"腾讯云存储信息不完整")]; }); return; } QCloudServiceConfiguration* configuration = [QCloudServiceConfiguration new]; configuration.appID = minstr([StorageConfig getTXAppID]);//@"1258210369"; configuration.signatureProvider = self; QCloudCOSXMLEndPoint* endpoint = [[QCloudCOSXMLEndPoint alloc] init]; endpoint.regionName = minstr([StorageConfig getTXRegion]);//@"ap-shanghai"; configuration.endpoint = endpoint; [QCloudCOSXMLService registerDefaultCOSXMLWithConfiguration:configuration]; [QCloudCOSTransferMangerService registerDefaultCOSTransferMangerWithConfiguration:configuration]; } //腾讯验签 - (void)signatureWithFields:(QCloudSignatureFields*)fileds request:(QCloudBizHTTPRequest*)request urlRequest:(NSMutableURLRequest*)urlRequst compelete:(QCloudHTTPAuthentationContinueBlock)continueBlock { //此接口代替原来的 8088 端口请求 [YBNetworking postWithUrl:@"Video.getTxCosFederationToken" Dic:@{} Suc:^(int code, id info, NSString *msg) { if (code == 0) { NSDictionary *infoDic = [info firstObject]; QCloudCredential* credential = [QCloudCredential new]; credential.secretID = [NSString stringWithFormat:@"%@",[infoDic valueForKey:@"tmpSecretId"]]; credential.secretKey = [NSString stringWithFormat:@"%@",[infoDic valueForKey:@"tmpSecretKey"]]; credential.token = [NSString stringWithFormat:@"%@",[infoDic valueForKey:@"sessionToken"]]; QCloudAuthentationV5Creator* creator = [[QCloudAuthentationV5Creator alloc] initWithCredential:credential]; QCloudSignature* signature = [creator signatureForData:urlRequst]; continueBlock(signature, nil); }else { dispatch_async(dispatch_get_main_queue(), ^{ [MBProgressHUD showPop:msg]; }); } } Fail:nil]; } #pragma mark - 腾讯初始化、验证结束 #pragma makr - 七牛划分区域开始 -(QNZone *)getQNZone{ //华东:qiniu_hd 华北:qiniu_hb 华南:qiniu_hn 北美:qiniu_bm 新加坡:qiniu_xjp NSString *qnStr = minstr([StorageConfig getQNZone]); //华东 QNZone *zone = [QNFixedZone zone0]; if ([qnStr isEqual:@"qiniu_hb"]) { //华北 zone = [QNFixedZone zone1]; }else if ([qnStr isEqual:@"qiniu_hn"]){ //华南 zone = [QNFixedZone zone2]; }else if ([qnStr isEqual:@"qiniu_bm"]){ //北美 zone = [QNFixedZone zoneNa0]; }else if ([qnStr isEqual:@"qiniu_xjp"]){ //新加坡 zone = [QNFixedZone zoneAs0]; } return zone; } #pragma makr - 七牛划分区域结束 #pragma mark - 亚马逊扩展配置开始 -(void)yb_awsInitialization { NSDictionary *infoDic = [NSBundle mainBundle].infoDictionary; NSDictionary *awsDic = @{@"CredentialsProvider":@{@"CognitoIdentity":@{@"Default":@{ @"PoolId":[StorageConfig getAwsIdentityPoolid], @"Region":[StorageConfig getAwsRegion], } } }, @"S3TransferUtility":@{@"Default":@{@"Region":[StorageConfig getAwsRegion]}} }; [infoDic setValue:awsDic forKey:@"AWS"]; NSLog(@"==info:%@",infoDic); //identityPoolId格式: @"ap-southeast-1:f972XXXX-cc7d-431a-80c6-581266daXXXX" AWSCognitoCredentialsProvider *credentialsProvider = [[AWSCognitoCredentialsProvider alloc] initWithRegionType:[self getAwsRegion] identityPoolId:[StorageConfig getAwsIdentityPoolid]]; AWSServiceConfiguration *configuration = [[AWSServiceConfiguration alloc] initWithRegion:[self getAwsRegion] credentialsProvider:credentialsProvider]; AWSServiceManager.defaultServiceManager.defaultServiceConfiguration = configuration; } -(void)yb_awsTransferOfBackgroundWithApplication:(UIApplication *)application andIdentifier:(NSString *)identifier completion:(void (^)(void))completionHandler{ [AWSS3TransferUtility interceptApplication:application handleEventsForBackgroundURLSession:identifier completionHandler:completionHandler]; } -(AWSRegionType)getAwsRegion { NSString *awsStr = minstr([StorageConfig getAwsRegion]); if ([awsStr isEqual:@"AWSRegionUSEast1"] || [awsStr isEqual:@"USEast1"] || [awsStr isEqual:@"us-east-1"]) { return AWSRegionUSEast1; } if ([awsStr isEqual:@"AWSRegionUSEast2"] || [awsStr isEqual:@"USEast2"] || [awsStr isEqual:@"us-east-2"]) { return AWSRegionUSEast2; } if ([awsStr isEqual:@"AWSRegionUSWest1"] || [awsStr isEqual:@"USWest1"] || [awsStr isEqual:@"us-west-1"]) { return AWSRegionUSWest1; } if ([awsStr isEqual:@"AWSRegionUSWest2"] || [awsStr isEqual:@"USWest2"] || [awsStr isEqual:@"us-west-2"]) { return AWSRegionUSWest2; } if ([awsStr isEqual:@"AWSRegionEUWest1"] || [awsStr isEqual:@"EUWest1"] || [awsStr isEqual:@"eu-west-1"]) { return AWSRegionEUWest1; } if ([awsStr isEqual:@"AWSRegionEUWest2"] || [awsStr isEqual:@"EUWest2"] || [awsStr isEqual:@"eu-west-2"]) { return AWSRegionEUWest2; } if ([awsStr isEqual:@"AWSRegionEUCentral1"] || [awsStr isEqual:@"EUCentral1"] || [awsStr isEqual:@"eu-central-1"]) { return AWSRegionEUCentral1; } if ([awsStr isEqual:@"AWSRegionAPNortheast1"] || [awsStr isEqual:@"APNortheast1"] || [awsStr isEqual:@"ap-northeast-1"]) { return AWSRegionAPNortheast1; } if ([awsStr isEqual:@"AWSRegionAPNortheast2"] || [awsStr isEqual:@"APNortheast2"] || [awsStr isEqual:@"ap-northeast-2"]) { return AWSRegionAPNortheast2; } if ([awsStr isEqual:@"AWSRegionAPSoutheast1"] || [awsStr isEqual:@"APSoutheast1"] || [awsStr isEqual:@"ap-southeast-1"]) { return AWSRegionAPSoutheast1; } if ([awsStr isEqual:@"AWSRegionAPSoutheast2"] || [awsStr isEqual:@"APSoutheast2"] || [awsStr isEqual:@"ap-southeast-2"]) { return AWSRegionAPSoutheast2; } if ([awsStr isEqual:@"AWSRegionAPSouth1"] || [awsStr isEqual:@"APSouth1"] || [awsStr isEqual:@"ap-south-1"]) { return AWSRegionAPSouth1; } if ([awsStr isEqual:@"AWSRegionSAEast1"] || [awsStr isEqual:@"SAEast1"] || [awsStr isEqual:@"sa-east-1"]) { return AWSRegionSAEast1; } if ([awsStr isEqual:@"AWSRegionCACentral1"] || [awsStr isEqual:@"CACentral1"] || [awsStr isEqual:@"ca-central-1"]) { return AWSRegionCACentral1; } if ([awsStr isEqual:@"AWSRegionUSGovWest1"] || [awsStr isEqual:@"USGovWest1"] || [awsStr isEqual:@"us-gov-west-1"]) { return AWSRegionUSGovWest1; } if ([awsStr isEqual:@"AWSRegionCNNorth1"] || [awsStr isEqual:@"CNNorth1"] || [awsStr isEqual:@"cn-north-1"]) { return AWSRegionCNNorth1; } if ([awsStr isEqual:@"AWSRegionCNNorthWest1"] || [awsStr isEqual:@"CNNorthWest1"] || [awsStr isEqual:@"cn-northwest-1"]) { return AWSRegionCNNorthWest1; } if ([awsStr isEqual:@"AWSRegionEUWest3"] || [awsStr isEqual:@"EUWest3"] || [awsStr isEqual:@"eu-west-3"]) { return AWSRegionEUWest3; } if ([awsStr isEqual:@"AWSRegionUSGovEast1"] || [awsStr isEqual:@"USGovEast1"] || [awsStr isEqual:@"us-gov-east-1"]) { return AWSRegionUSGovEast1; } if ([awsStr isEqual:@"AWSRegionEUNorth1"] || [awsStr isEqual:@"EUNorth1"] || [awsStr isEqual:@"eu-north-1"]) { return AWSRegionEUNorth1; } if ([awsStr isEqual:@"AWSRegionAPEast1"] || [awsStr isEqual:@"APEast1"] || [awsStr isEqual:@"ap-east-1"]) { return AWSRegionAPEast1; } if ([awsStr isEqual:@"AWSRegionMESouth1"] || [awsStr isEqual:@"MESouth1"] || [awsStr isEqual:@"me-south-1"]) { return AWSRegionMESouth1; } if ([awsStr isEqual:@"AWSRegionAFSouth1"] || [awsStr isEqual:@"AFSouth1"] || [awsStr isEqual:@"af-south-1"]) { return AWSRegionAFSouth1; } if ([awsStr isEqual:@"AWSRegionEUSouth1"] || [awsStr isEqual:@"EUSouth1"] || [awsStr isEqual:@"eu-south-1"]) { return AWSRegionEUSouth1; } return AWSRegionUnknown; } #pragma mark - 亚马逊扩展配置结束 @end