// // OSSManager.m // AliyunOSSSDK-iOS-Example // // Created by huaixu on 2018/10/23. // Copyright © 2018 aliyun. All rights reserved. // #import "OSSManager.h" #import "OssNetApi.h" #import #import "ChatsStore.h" #import "GDBManager.h" #import "GWebSocket.h" // yourEndpoint填写Bucket所在地域对应的Endpoint。以华东1(杭州)为例,Endpoint填写为https://oss-cn-hangzhou.aliyuncs.com。 #define endpoint @"https://oss-ap-southeast-1.aliyuncs.com"//生产服务器 @interface OSSManager () @property (nonatomic, strong) OSSPutObjectRequest *normalUploadRequest; @property (nonatomic, strong) OSSGetObjectRequest *normalDloadRequest; @property (nonatomic, strong) NSDateFormatter *formatter; @property (nonatomic, copy) NSString *month; @property (nonatomic, strong) NSMutableDictionary *taskDict; @end @implementation OSSManager + (instancetype)sharedManager { static OSSManager *_manager = nil; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ _manager = [[OSSManager alloc] init]; }); return _manager; } - (instancetype)init { if (self = [super init]) { _uploadTanck = [NSMutableArray new]; _taskDict = [NSMutableDictionary dictionary]; } return self; } -(void)getOSSInfo:(void (^_Nullable)(bool))success{ if (!_uploadTanck) { _uploadTanck = [NSMutableArray new]; } [OssNetApi getOSSInfo:nil succ:^(int code, NSDictionary * res) { NSLog(@"res:%@",res); NSString *codeV =res[@"code"]; if(codeV.intValue==200){ self.OSSInfo = res[@"data"]; if(self.OSSInfo){ [UDManager.shareInstance setDDManager:self.OSSInfo key:nkOSSinfo]; success(true); } } else{ success(false); } } fail:^(NSError * _Nonnull error) { success(false); }]; } -(void)initmyAliyunOSS{ if(self.OSSInfo){ // yourEndpoint填写Bucket所在地域对应的Endpoint。以华东1(杭州)为例,Endpoint填写为https://oss-cn-hangzhou.aliyuncs.com。 //NSString *endpoint = @"https://oss-ap-southeast-1.aliyuncs.com"; // 旧版本图片服务的endpoint // NSString *oldimgendpoint = @"http://img-ap-southeast-1.aliyuncs.com"; // 从STS服务获取的临时访问密钥(AccessKey ID和AccessKey Secret)。 NSString *accessKeyId = self.OSSInfo[@"accessKeyId"]; NSString *accessKeySecret = self.OSSInfo[@"accessKeySecret"]; // 从STS服务获取的安全令牌(SecurityToken)。 NSString *securityToken = self.OSSInfo[@"securityToken"]; // NSString *expiration = self.OSSInfo[@"expiration"]; id credentialProvider = [[OSSStsTokenCredentialProvider alloc] initWithAccessKeyId:accessKeyId secretKeyId:accessKeySecret securityToken:securityToken]; OSSClientConfiguration *cfg = [[OSSClientConfiguration alloc] init]; cfg.maxRetryCount = 5; cfg.timeoutIntervalForRequest = 15; cfg.isHttpdnsEnable = NO; cfg.crc64Verifiable = YES; OSSClient *defaultClient = [[OSSClient alloc] initWithEndpoint:endpoint credentialProvider:credentialProvider clientConfiguration:cfg]; [OSSManager sharedManager].defaultClient = defaultClient; NSDate *now = [NSDate date]; NSTimeInterval trt = [now timeIntervalSince1970]; self.initIme = trt; //旧的图片服务 // OSSClient *defaultImgClient = [[OSSClient alloc] initWithEndpoint:oldimgendpoint credentialProvider:credentialProvider clientConfiguration:cfg]; // [OSSManager sharedManager].imageClient = defaultImgClient; } } //普通上传 - (void)asyncPutFile:(NSString *)objectKey localFilePath:(NSString *)filePath thrid:(NSString *)strtime{ if([self chectToken]){ if([OSSManager sharedManager].defaultClient==nil){ [self getOSSInfo:^(bool code){ if(code){ [self initmyAliyunOSS]; [self prasyncPutFile:objectKey localFilePath:filePath thrid:strtime]; } else{ [MBProgressHUD showWithText:@"OSS文件服务初始化失败!請重試"]; } }]; } else{ [self prasyncPutFile:objectKey localFilePath:filePath thrid:strtime]; } } else{ [self getOSSInfo:^(bool code){ if(code){ [self initmyAliyunOSS]; [self prasyncPutFile:objectKey localFilePath:filePath thrid:strtime]; } else{ [MBProgressHUD showWithText:@"OSS文件服务初始化失败!請重試"]; } }]; } } -(void)prasyncPutFile:(NSString *)objectKey localFilePath:(NSString *)filePath thrid:(NSString *)strtime{ if (![objectKey oss_isNotEmpty]) { if(self.delegate){ NSDictionary *dic=@{ @"state":@"3", @"pcent":@"", @"thrid":strtime }; [self.delegate stateChange:dic]; } return; } NSLog(@"objectKey:%@",objectKey); _normalUploadRequest = [OSSPutObjectRequest new]; _normalUploadRequest.bucketName = self.OSSInfo[@"bucket"]; _normalUploadRequest.objectKey = [self formatObjectKeyWith:objectKey]; _normalUploadRequest.uploadingFileURL = [NSURL fileURLWithPath:filePath]; _normalUploadRequest.isAuthenticationRequired = YES; weakSelf(self); _normalUploadRequest.uploadProgress = ^(int64_t bytesSent, int64_t totalByteSent, int64_t totalBytesExpectedToSend) { CGFloat progress = 1.f * totalByteSent / totalBytesExpectedToSend; // NSLog(@"上传文件进度: %f", progress); NSInteger pcent =progress*100; if(weakself.delegate){ NSDictionary *dic=@{ @"state":@"1", @"pcent":[NSString stringWithFormat:@"%ld",(long)pcent], @"thrid":strtime }; [weakself.delegate stateChange:dic]; } }; dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ OSSTask * task = [[OSSManager sharedManager].defaultClient putObject:self->_normalUploadRequest]; [task continueWithBlock:^id(OSSTask *task) { dispatch_async(dispatch_get_main_queue(), ^{ if (task.error) { [self updataFileMsg:strtime state:@"1"]; if(self.delegate){ NSDictionary *dic=@{ @"state":@"3", @"pcent":@"", @"thrid":strtime }; [self.delegate stateChange:dic]; } } else { NSLog(@"上传文件完成"); [self updataFileMsg:strtime state:@"2"]; if(self.delegate){ NSDictionary *dic=@{ @"state":@"2", @"pcent":@"", @"thrid":strtime }; [self.delegate stateChange:dic]; } } }); return nil; }]; }); } //断点续传 - (void)asyncResumableUploadFile:(NSString *)objectKey localFilePath:(NSString *)filePath thrid:(NSString *)strtime{ if([self chectToken]){ if([OSSManager sharedManager].defaultClient==nil){ [self getOSSInfo:^(bool code){ if(code){ [self initmyAliyunOSS]; [self PrasyncResumableUploadFile:objectKey localFilePath:filePath thrid:strtime]; } else{ [MBProgressHUD showWithText:@"OSS文件服务初始化失败!請重試"]; } }]; } else{ [self PrasyncResumableUploadFile:objectKey localFilePath:filePath thrid:strtime]; } } else{ [self getOSSInfo:^(bool code){ if(code){ [self initmyAliyunOSS]; [self PrasyncResumableUploadFile:objectKey localFilePath:filePath thrid:strtime]; } else{ [MBProgressHUD showWithText:@"OSS文件服务初始化失败!請重試"]; } }]; } } -(void)PrasyncResumableUploadFile:(NSString *)objectKey localFilePath:(NSString *)filePath thrid:(NSString *)strtime{ NSLog(@"PrasyncResumableUploadFile objectKey: %@ filePath: %@", objectKey, filePath); NSURL *documentsDirectoryURL = [[NSFileManager defaultManager] URLForDirectory:NSDocumentDirectory inDomain:NSUserDomainMask appropriateForURL:nil create:NO error:nil]; NSString *fileName = [NSURL fileURLWithPath:filePath].lastPathComponent; NSString *path = [documentsDirectoryURL URLByAppendingPathComponent:fileName].path; if (![[NSFileManager defaultManager] fileExistsAtPath:path]){ NSLog(@"PrasyncResumableUploadFile error: %@", path); return; } NSString *fileKey = [self fileMessageKeyWith:strtime]; // 获取UploadId上传文件。 OSSResumableUploadRequest * resumableUpload = [OSSResumableUploadRequest new]; resumableUpload.bucketName = self.OSSInfo[@"bucket"]; // objectKey等同于objectName,表示断点上传文件到OSS时需要指定包含文件后缀在内的完整路径,例如abc/efg/123.jpg resumableUpload.objectKey = [self formatObjectKeyWith:objectKey]; resumableUpload.partSize = 1024 * 1024; resumableUpload.uploadProgress = ^(int64_t bytesSent, int64_t totalByteSent, int64_t totalBytesExpectedToSend) { // NSLog(@"%lld, %lld, %lld", bytesSent, totalByteSent, totalBytesExpectedToSend); CGFloat progress = 1.f * totalByteSent / totalBytesExpectedToSend; // NSLog(@"上传文件进度: %f", progress); NSInteger pcent =progress*100; if(self.delegate){ NSDictionary *dic=@{ @"state":@"1", @"pcent":[NSString stringWithFormat:@"%ld",(long)pcent], @"thrid":strtime }; [self.delegate stateChange:dic]; } dispatch_main_async_safe(^{ [self.taskDict setValue:@(pcent) forKey:fileKey]; }) // dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ // prgress(pcent,strtime); // }); }; NSString *cachesDir = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) firstObject]; // 设置断点记录保存路径。 resumableUpload.recordDirectoryPath = cachesDir; // 将参数deleteUploadIdOnCancelling设置为NO,表示不删除断点记录文件,上传失败后将从断点记录处继续上传直到文件上传完成。如果不设置此参数,即保留默认值YES,表示删除断点记录文件,下次再上传同一文件时则重新上传。 resumableUpload.deleteUploadIdOnCancelling = NO; resumableUpload.uploadingFileURL = [NSURL URLWithString:path]; OSSTask * resumeTask = [[OSSManager sharedManager].defaultClient resumableUpload:resumableUpload]; [self addUploadTanckobj:resumeTask thrid:strtime]; [resumeTask continueWithBlock:^id(OSSTask *task) { if (task.error) { NSLog(@"error: %@", task.error); if ([task.error.domain isEqualToString:OSSClientErrorDomain] && task.error.code == OSSClientErrorCodeCannotResumeUpload) { // 此任务无法续传,需获取新的uploadId重新上传。 } dispatch_main_async_safe(^{ [[NSUserDefaults standardUserDefaults] setValue:@(-1) forKey:fileKey]; }) [self updataFileMsg:strtime state:@"3"]; // if(self.delegate){ // NSDictionary *dic=@{ // @"state":@"3", // @"pcent":@"", // @"thrid":strtime // }; // [self.delegate stateChange:dic]; // } } else { NSLog(@"Upload file success"); dispatch_main_async_safe(^{ [[NSUserDefaults standardUserDefaults] setValue:@(100) forKey:fileKey]; }) [self updataFileMsg:strtime state:@"2"]; // if(self.delegate){ // NSDictionary *dic=@{ // @"state":@"2", // @"pcent":@"", // @"thrid":strtime // }; // [self.delegate stateChange:dic]; // } } return nil; }]; // [resumeTask waitUntilFinished]; // [resumableUpload cancel]; } -(void)addUploadTanckobj:(OSSTask *)task thrid:(NSString *)thrid{ NSDictionary *item = @{ @"task":task, @"thrid":thrid }; [_uploadTanck addObject:item]; } -(BOOL)isuploadTanck:(NSString *)thrid{ // NSLog(@"stopUploadTanck-------------2"); if(_uploadTanck.count>0){ for (NSDictionary *item in _uploadTanck) { NSString *th = item[@"thrid"]; NSLog(@"stopUploadTanck-------------3"); if([th isEqualToString:thrid]){ NSLog(@"stopUploadTanck-------------4"); return true; } } } return false; } -(void)removeUploadTanckobj:(NSString *)thrid{ if(_uploadTanck.count>0){ for (NSDictionary *item in _uploadTanck) { NSString *th = item[@"thrid"]; if([th isEqualToString:thrid]){ [_uploadTanck removeObject:item]; return; } } } } -(void)stopUploadTanck:(NSString *)thrid{ NSLog(@"stopUploadTanck-------------2"); if(_uploadTanck.count>0){ for (NSDictionary *item in _uploadTanck) { NSString *th = item[@"thrid"]; NSLog(@"stopUploadTanck-------------3"); if([th isEqualToString:thrid]){ OSSTask *task = item[@"task"]; NSLog(@"stopUploadTanck-------------4"); //[task cancel];取消传输 return; } } } } -(void)updataFileMsg:(NSString *)thrid state:(NSString *)state{ [GDBManager.shareInstance selectLocalmsgWithLocaltime:thrid succ:^(NSArray * _Nullable array) { NSLog(@"selectLocalmsgWithLocaltime:%@",array); if(array){ if(array.count>0){ NSDictionary *msg =array[0]; NSString *msgtype = msg[@"messageType"]; if (([msgtype isEqualToString:MessageType_Del]||[msgtype isEqualToString:MessageType_CallBack2])) { return; } NSDictionary *extend=msg[@"extend"]; NSMutableDictionary *mextend = [extend mutableCopy]; NSMutableDictionary *mmsg = [msg mutableCopy]; if([state isEqualToString:@"2"]){ NSString *localPath =extend[@"localurl"]; NSURL *loaclUrl = [NSURL URLWithString:localPath]; NSString *url = [self fullUploadURLByAppendPath:loaclUrl.lastPathComponent]; [mextend setObject:url forKey:@"url"]; [mextend setObject:[NSNumber numberWithInt:0] forKey:@"fileError"]; [mmsg setObject:mextend forKey:@"extend"]; [mmsg setObject:@"" forKey:@"id"]; } else if([state isEqualToString:@"3"]){ [mextend setObject:@"" forKey:@"url"]; // [mextend setObject:@"" forKey:@"fileName"]; [mextend setObject:[NSNumber numberWithInt:1] forKey:@"fileError"]; [mmsg setObject:mextend forKey:@"extend"]; [mmsg setObject:@"" forKey:@"id"]; [ChatsStore.shareInstance reciveMsg:mmsg]; return; } NSDictionary *sendInfo = @{ @"code":@"2", @"message":mmsg, }; NSError *error; NSData *jsonData = [NSJSONSerialization dataWithJSONObject:sendInfo options:0 error:&error]; if (!jsonData) { NSLog(@"Got an error: %@", error); } else { NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding]; // NSLog(@"%@", jsonString); NSLog(@"----发送文件消息2----"); [GWebSocket.shareInstance sendMsg:jsonString]; } } } } fail:^(NSString * _Nullable error) { ; }]; } -(BOOL)chectToken{ if(self.initIme>0){ NSDate *now = [NSDate date]; NSTimeInterval trt = [now timeIntervalSince1970]; NSInteger time = trt; time =time-self.initIme; NSLog(@"chectToken------:%ld",(long)time); if(time>2000){ return false; } else{ return true; } } else{ return false; } return false; } - (NSString *)fullUploadURLByAppendPath:(NSString *)path { return [NSString stringWithFormat:@"http://oss.abtim-my.com/%@/%@", self.month, path]; } - (NSDateFormatter *)formatter { if (!_formatter) { _formatter = [[NSDateFormatter alloc] init]; [_formatter setDateFormat:@"yyyy-MM"]; // 设置你想要的日期格式 } return _formatter; } - (NSString *)month { if (!_month) { _month = [self.formatter stringFromDate:[NSDate date]]; } return _month; } - (NSString *)formatObjectKeyWith:(NSString *)objectKey { return [NSString stringWithFormat:@"%@/%@", self.month, objectKey];; } - (void)applicationWillTerminate { NSLog(@"applicationWillTerminate: %@", self.taskDict); for (NSString *key in self.taskDict.allKeys) { NSInteger progress = [self.taskDict[key] integerValue]; if (progress < 100) { [[NSUserDefaults standardUserDefaults] setValue:@(-1) forKey:key]; } } } - (NSString *)fileMessageKeyWith:(NSString *)strtime { return [NSString stringWithFormat:@"k_oss_file_%@", strtime]; } @end