OSSManager.m 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519
  1. //
  2. // OSSManager.m
  3. // AliyunOSSSDK-iOS-Example
  4. //
  5. // Created by huaixu on 2018/10/23.
  6. // Copyright © 2018 aliyun. All rights reserved.
  7. //
  8. #import "OSSManager.h"
  9. #import "OssNetApi.h"
  10. #import <AliyunOSSiOS/OSSService.h>
  11. #import "ChatsStore.h"
  12. #import "GDBManager.h"
  13. #import "GWebSocket.h"
  14. // yourEndpoint填写Bucket所在地域对应的Endpoint。以华东1(杭州)为例,Endpoint填写为https://oss-cn-hangzhou.aliyuncs.com。
  15. #define endpoint @"https://oss-ap-southeast-1.aliyuncs.com"//生产服务器
  16. @interface OSSManager ()
  17. @property (nonatomic, strong) OSSPutObjectRequest *normalUploadRequest;
  18. @property (nonatomic, strong) OSSGetObjectRequest *normalDloadRequest;
  19. @property (nonatomic, strong) NSDateFormatter *formatter;
  20. @property (nonatomic, copy) NSString *month;
  21. @property (nonatomic, strong) NSMutableDictionary<NSString *, NSNumber *> *taskDict;
  22. @end
  23. @implementation OSSManager
  24. + (instancetype)sharedManager {
  25. static OSSManager *_manager = nil;
  26. static dispatch_once_t onceToken;
  27. dispatch_once(&onceToken, ^{
  28. _manager = [[OSSManager alloc] init];
  29. });
  30. return _manager;
  31. }
  32. - (instancetype)init {
  33. if (self = [super init]) {
  34. _uploadTanck = [NSMutableArray new];
  35. _taskDict = [NSMutableDictionary dictionary];
  36. }
  37. return self;
  38. }
  39. -(void)getOSSInfo:(void (^_Nullable)(bool))success{
  40. if (!_uploadTanck) {
  41. _uploadTanck = [NSMutableArray new];
  42. }
  43. [OssNetApi getOSSInfo:nil succ:^(int code, NSDictionary * res) {
  44. NSLog(@"res:%@",res);
  45. NSString *codeV =res[@"code"];
  46. if(codeV.intValue==200){
  47. self.OSSInfo = res[@"data"];
  48. if(self.OSSInfo){
  49. [UDManager.shareInstance setDDManager:self.OSSInfo key:nkOSSinfo];
  50. success(true);
  51. }
  52. }
  53. else{
  54. success(false);
  55. }
  56. } fail:^(NSError * _Nonnull error) {
  57. success(false);
  58. }];
  59. }
  60. -(void)initmyAliyunOSS{
  61. if(self.OSSInfo){
  62. // yourEndpoint填写Bucket所在地域对应的Endpoint。以华东1(杭州)为例,Endpoint填写为https://oss-cn-hangzhou.aliyuncs.com。
  63. //NSString *endpoint = @"https://oss-ap-southeast-1.aliyuncs.com";
  64. // 旧版本图片服务的endpoint
  65. // NSString *oldimgendpoint = @"http://img-ap-southeast-1.aliyuncs.com";
  66. // 从STS服务获取的临时访问密钥(AccessKey ID和AccessKey Secret)。
  67. NSString *accessKeyId = self.OSSInfo[@"accessKeyId"];
  68. NSString *accessKeySecret = self.OSSInfo[@"accessKeySecret"];
  69. // 从STS服务获取的安全令牌(SecurityToken)。
  70. NSString *securityToken = self.OSSInfo[@"securityToken"];
  71. // NSString *expiration = self.OSSInfo[@"expiration"];
  72. id<OSSCredentialProvider> credentialProvider = [[OSSStsTokenCredentialProvider alloc] initWithAccessKeyId:accessKeyId secretKeyId:accessKeySecret securityToken:securityToken];
  73. OSSClientConfiguration *cfg = [[OSSClientConfiguration alloc] init];
  74. cfg.maxRetryCount = 5;
  75. cfg.timeoutIntervalForRequest = 15;
  76. cfg.isHttpdnsEnable = NO;
  77. cfg.crc64Verifiable = YES;
  78. OSSClient *defaultClient = [[OSSClient alloc] initWithEndpoint:endpoint credentialProvider:credentialProvider clientConfiguration:cfg];
  79. [OSSManager sharedManager].defaultClient = defaultClient;
  80. NSDate *now = [NSDate date];
  81. NSTimeInterval trt = [now timeIntervalSince1970];
  82. self.initIme = trt;
  83. //旧的图片服务
  84. // OSSClient *defaultImgClient = [[OSSClient alloc] initWithEndpoint:oldimgendpoint credentialProvider:credentialProvider clientConfiguration:cfg];
  85. // [OSSManager sharedManager].imageClient = defaultImgClient;
  86. }
  87. }
  88. //普通上传
  89. - (void)asyncPutFile:(NSString *)objectKey localFilePath:(NSString *)filePath thrid:(NSString *)strtime{
  90. if([self chectToken]){
  91. if([OSSManager sharedManager].defaultClient==nil){
  92. [self getOSSInfo:^(bool code){
  93. if(code){
  94. [self initmyAliyunOSS];
  95. [self prasyncPutFile:objectKey localFilePath:filePath thrid:strtime];
  96. }
  97. else{
  98. [MBProgressHUD showWithText:@"OSS文件服务初始化失败!請重試"];
  99. }
  100. }];
  101. }
  102. else{
  103. [self prasyncPutFile:objectKey localFilePath:filePath thrid:strtime];
  104. }
  105. }
  106. else{
  107. [self getOSSInfo:^(bool code){
  108. if(code){
  109. [self initmyAliyunOSS];
  110. [self prasyncPutFile:objectKey localFilePath:filePath thrid:strtime];
  111. }
  112. else{
  113. [MBProgressHUD showWithText:@"OSS文件服务初始化失败!請重試"];
  114. }
  115. }];
  116. }
  117. }
  118. -(void)prasyncPutFile:(NSString *)objectKey localFilePath:(NSString *)filePath thrid:(NSString *)strtime{
  119. if (![objectKey oss_isNotEmpty]) {
  120. if(self.delegate){
  121. NSDictionary *dic=@{
  122. @"state":@"3",
  123. @"pcent":@"",
  124. @"thrid":strtime
  125. };
  126. [self.delegate stateChange:dic];
  127. }
  128. return;
  129. }
  130. NSLog(@"objectKey:%@",objectKey);
  131. _normalUploadRequest = [OSSPutObjectRequest new];
  132. _normalUploadRequest.bucketName = self.OSSInfo[@"bucket"];
  133. _normalUploadRequest.objectKey = [self formatObjectKeyWith:objectKey];
  134. _normalUploadRequest.uploadingFileURL = [NSURL fileURLWithPath:filePath];
  135. _normalUploadRequest.isAuthenticationRequired = YES;
  136. weakSelf(self);
  137. _normalUploadRequest.uploadProgress = ^(int64_t bytesSent, int64_t totalByteSent, int64_t totalBytesExpectedToSend) {
  138. CGFloat progress = 1.f * totalByteSent / totalBytesExpectedToSend;
  139. // NSLog(@"上传文件进度: %f", progress);
  140. NSInteger pcent =progress*100;
  141. if(weakself.delegate){
  142. NSDictionary *dic=@{
  143. @"state":@"1",
  144. @"pcent":[NSString stringWithFormat:@"%ld",(long)pcent],
  145. @"thrid":strtime
  146. };
  147. [weakself.delegate stateChange:dic];
  148. }
  149. };
  150. dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
  151. OSSTask * task = [[OSSManager sharedManager].defaultClient putObject:self->_normalUploadRequest];
  152. [task continueWithBlock:^id(OSSTask *task) {
  153. dispatch_async(dispatch_get_main_queue(), ^{
  154. if (task.error) {
  155. [self updataFileMsg:strtime state:@"1"];
  156. if(self.delegate){
  157. NSDictionary *dic=@{
  158. @"state":@"3",
  159. @"pcent":@"",
  160. @"thrid":strtime
  161. };
  162. [self.delegate stateChange:dic];
  163. }
  164. } else {
  165. NSLog(@"上传文件完成");
  166. [self updataFileMsg:strtime state:@"2"];
  167. if(self.delegate){
  168. NSDictionary *dic=@{
  169. @"state":@"2",
  170. @"pcent":@"",
  171. @"thrid":strtime
  172. };
  173. [self.delegate stateChange:dic];
  174. }
  175. }
  176. });
  177. return nil;
  178. }];
  179. });
  180. }
  181. //断点续传
  182. - (void)asyncResumableUploadFile:(NSString *)objectKey localFilePath:(NSString *)filePath thrid:(NSString *)strtime{
  183. if([self chectToken]){
  184. if([OSSManager sharedManager].defaultClient==nil){
  185. [self getOSSInfo:^(bool code){
  186. if(code){
  187. [self initmyAliyunOSS];
  188. [self PrasyncResumableUploadFile:objectKey localFilePath:filePath thrid:strtime];
  189. }
  190. else{
  191. [MBProgressHUD showWithText:@"OSS文件服务初始化失败!請重試"];
  192. }
  193. }];
  194. }
  195. else{
  196. [self PrasyncResumableUploadFile:objectKey localFilePath:filePath thrid:strtime];
  197. }
  198. }
  199. else{
  200. [self getOSSInfo:^(bool code){
  201. if(code){
  202. [self initmyAliyunOSS];
  203. [self PrasyncResumableUploadFile:objectKey localFilePath:filePath thrid:strtime];
  204. }
  205. else{
  206. [MBProgressHUD showWithText:@"OSS文件服务初始化失败!請重試"];
  207. }
  208. }];
  209. }
  210. }
  211. -(void)PrasyncResumableUploadFile:(NSString *)objectKey localFilePath:(NSString *)filePath thrid:(NSString *)strtime{
  212. NSLog(@"PrasyncResumableUploadFile objectKey: %@ filePath: %@", objectKey, filePath);
  213. NSURL *documentsDirectoryURL = [[NSFileManager defaultManager] URLForDirectory:NSDocumentDirectory inDomain:NSUserDomainMask appropriateForURL:nil create:NO error:nil];
  214. NSString *fileName = [NSURL fileURLWithPath:filePath].lastPathComponent;
  215. NSString *path = [documentsDirectoryURL URLByAppendingPathComponent:fileName].path;
  216. if (![[NSFileManager defaultManager] fileExistsAtPath:path]){
  217. NSLog(@"PrasyncResumableUploadFile error: %@", path);
  218. return;
  219. }
  220. NSString *fileKey = [self fileMessageKeyWith:strtime];
  221. // 获取UploadId上传文件。
  222. OSSResumableUploadRequest * resumableUpload = [OSSResumableUploadRequest new];
  223. resumableUpload.bucketName = self.OSSInfo[@"bucket"];
  224. // objectKey等同于objectName,表示断点上传文件到OSS时需要指定包含文件后缀在内的完整路径,例如abc/efg/123.jpg
  225. resumableUpload.objectKey = [self formatObjectKeyWith:objectKey];
  226. resumableUpload.partSize = 1024 * 1024;
  227. resumableUpload.uploadProgress = ^(int64_t bytesSent, int64_t totalByteSent, int64_t totalBytesExpectedToSend) {
  228. // NSLog(@"%lld, %lld, %lld", bytesSent, totalByteSent, totalBytesExpectedToSend);
  229. CGFloat progress = 1.f * totalByteSent / totalBytesExpectedToSend;
  230. // NSLog(@"上传文件进度: %f", progress);
  231. NSInteger pcent =progress*100;
  232. if(self.delegate){
  233. NSDictionary *dic=@{
  234. @"state":@"1",
  235. @"pcent":[NSString stringWithFormat:@"%ld",(long)pcent],
  236. @"thrid":strtime
  237. };
  238. [self.delegate stateChange:dic];
  239. }
  240. dispatch_main_async_safe(^{
  241. [self.taskDict setValue:@(pcent) forKey:fileKey];
  242. })
  243. // dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
  244. // prgress(pcent,strtime);
  245. // });
  246. };
  247. NSString *cachesDir = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) firstObject];
  248. // 设置断点记录保存路径。
  249. resumableUpload.recordDirectoryPath = cachesDir;
  250. // 将参数deleteUploadIdOnCancelling设置为NO,表示不删除断点记录文件,上传失败后将从断点记录处继续上传直到文件上传完成。如果不设置此参数,即保留默认值YES,表示删除断点记录文件,下次再上传同一文件时则重新上传。
  251. resumableUpload.deleteUploadIdOnCancelling = NO;
  252. resumableUpload.uploadingFileURL = [NSURL URLWithString:path];
  253. OSSTask * resumeTask = [[OSSManager sharedManager].defaultClient resumableUpload:resumableUpload];
  254. [self addUploadTanckobj:resumeTask thrid:strtime];
  255. [resumeTask continueWithBlock:^id(OSSTask *task) {
  256. if (task.error) {
  257. NSLog(@"error: %@", task.error);
  258. if ([task.error.domain isEqualToString:OSSClientErrorDomain] && task.error.code == OSSClientErrorCodeCannotResumeUpload) {
  259. // 此任务无法续传,需获取新的uploadId重新上传。
  260. }
  261. dispatch_main_async_safe(^{
  262. [[NSUserDefaults standardUserDefaults] setValue:@(-1) forKey:fileKey];
  263. })
  264. [self updataFileMsg:strtime state:@"3"];
  265. // if(self.delegate){
  266. // NSDictionary *dic=@{
  267. // @"state":@"3",
  268. // @"pcent":@"",
  269. // @"thrid":strtime
  270. // };
  271. // [self.delegate stateChange:dic];
  272. // }
  273. } else {
  274. NSLog(@"Upload file success");
  275. dispatch_main_async_safe(^{
  276. [[NSUserDefaults standardUserDefaults] setValue:@(100) forKey:fileKey];
  277. })
  278. [self updataFileMsg:strtime state:@"2"];
  279. // if(self.delegate){
  280. // NSDictionary *dic=@{
  281. // @"state":@"2",
  282. // @"pcent":@"",
  283. // @"thrid":strtime
  284. // };
  285. // [self.delegate stateChange:dic];
  286. // }
  287. }
  288. return nil;
  289. }];
  290. // [resumeTask waitUntilFinished];
  291. // [resumableUpload cancel];
  292. }
  293. -(void)addUploadTanckobj:(OSSTask *)task thrid:(NSString *)thrid{
  294. NSDictionary *item = @{
  295. @"task":task,
  296. @"thrid":thrid
  297. };
  298. [_uploadTanck addObject:item];
  299. }
  300. -(BOOL)isuploadTanck:(NSString *)thrid{
  301. // NSLog(@"stopUploadTanck-------------2");
  302. if(_uploadTanck.count>0){
  303. for (NSDictionary *item in _uploadTanck) {
  304. NSString *th = item[@"thrid"];
  305. NSLog(@"stopUploadTanck-------------3");
  306. if([th isEqualToString:thrid]){
  307. NSLog(@"stopUploadTanck-------------4");
  308. return true;
  309. }
  310. }
  311. }
  312. return false;
  313. }
  314. -(void)removeUploadTanckobj:(NSString *)thrid{
  315. if(_uploadTanck.count>0){
  316. for (NSDictionary *item in _uploadTanck) {
  317. NSString *th = item[@"thrid"];
  318. if([th isEqualToString:thrid]){
  319. [_uploadTanck removeObject:item];
  320. return;
  321. }
  322. }
  323. }
  324. }
  325. -(void)stopUploadTanck:(NSString *)thrid{
  326. NSLog(@"stopUploadTanck-------------2");
  327. if(_uploadTanck.count>0){
  328. for (NSDictionary *item in _uploadTanck) {
  329. NSString *th = item[@"thrid"];
  330. NSLog(@"stopUploadTanck-------------3");
  331. if([th isEqualToString:thrid]){
  332. OSSTask *task = item[@"task"];
  333. NSLog(@"stopUploadTanck-------------4");
  334. //[task cancel];取消传输
  335. return;
  336. }
  337. }
  338. }
  339. }
  340. -(void)updataFileMsg:(NSString *)thrid state:(NSString *)state{
  341. [GDBManager.shareInstance selectLocalmsgWithLocaltime:thrid succ:^(NSArray * _Nullable array) {
  342. NSLog(@"selectLocalmsgWithLocaltime:%@",array);
  343. if(array){
  344. if(array.count>0){
  345. NSDictionary *msg =array[0];
  346. NSString *msgtype = msg[@"messageType"];
  347. if (([msgtype isEqualToString:MessageType_Del]||[msgtype isEqualToString:MessageType_CallBack2])) {
  348. return;
  349. }
  350. NSDictionary *extend=msg[@"extend"];
  351. NSMutableDictionary *mextend = [extend mutableCopy];
  352. NSMutableDictionary *mmsg = [msg mutableCopy];
  353. if([state isEqualToString:@"2"]){
  354. NSString *localPath =extend[@"localurl"];
  355. NSURL *loaclUrl = [NSURL URLWithString:localPath];
  356. NSString *url = [self fullUploadURLByAppendPath:loaclUrl.lastPathComponent];
  357. [mextend setObject:url forKey:@"url"];
  358. [mextend setObject:[NSNumber numberWithInt:0] forKey:@"fileError"];
  359. [mmsg setObject:mextend forKey:@"extend"];
  360. [mmsg setObject:@"" forKey:@"id"];
  361. }
  362. else if([state isEqualToString:@"3"]){
  363. [mextend setObject:@"" forKey:@"url"];
  364. // [mextend setObject:@"" forKey:@"fileName"];
  365. [mextend setObject:[NSNumber numberWithInt:1] forKey:@"fileError"];
  366. [mmsg setObject:mextend forKey:@"extend"];
  367. [mmsg setObject:@"" forKey:@"id"];
  368. [ChatsStore.shareInstance reciveMsg:mmsg];
  369. return;
  370. }
  371. NSDictionary *sendInfo = @{
  372. @"code":@"2",
  373. @"message":mmsg,
  374. };
  375. NSError *error;
  376. NSData *jsonData = [NSJSONSerialization dataWithJSONObject:sendInfo options:0 error:&error];
  377. if (!jsonData) {
  378. NSLog(@"Got an error: %@", error);
  379. } else {
  380. NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
  381. // NSLog(@"%@", jsonString);
  382. NSLog(@"----发送文件消息2----");
  383. [GWebSocket.shareInstance sendMsg:jsonString];
  384. }
  385. }
  386. }
  387. } fail:^(NSString * _Nullable error) {
  388. ;
  389. }];
  390. }
  391. -(BOOL)chectToken{
  392. if(self.initIme>0){
  393. NSDate *now = [NSDate date];
  394. NSTimeInterval trt = [now timeIntervalSince1970];
  395. NSInteger time = trt;
  396. time =time-self.initIme;
  397. NSLog(@"chectToken------:%ld",(long)time);
  398. if(time>2000){
  399. return false;
  400. }
  401. else{
  402. return true;
  403. }
  404. }
  405. else{
  406. return false;
  407. }
  408. return false;
  409. }
  410. - (NSString *)fullUploadURLByAppendPath:(NSString *)path {
  411. return [NSString stringWithFormat:@"http://oss.abtim-my.com/%@/%@", self.month, path];
  412. }
  413. - (NSDateFormatter *)formatter {
  414. if (!_formatter) {
  415. _formatter = [[NSDateFormatter alloc] init];
  416. [_formatter setDateFormat:@"yyyy-MM"]; // 设置你想要的日期格式
  417. }
  418. return _formatter;
  419. }
  420. - (NSString *)month {
  421. if (!_month) {
  422. _month = [self.formatter stringFromDate:[NSDate date]];
  423. }
  424. return _month;
  425. }
  426. - (NSString *)formatObjectKeyWith:(NSString *)objectKey {
  427. return [NSString stringWithFormat:@"%@/%@", self.month, objectKey];;
  428. }
  429. - (void)applicationWillTerminate {
  430. NSLog(@"applicationWillTerminate: %@", self.taskDict);
  431. for (NSString *key in self.taskDict.allKeys) {
  432. NSInteger progress = [self.taskDict[key] integerValue];
  433. if (progress < 100) {
  434. [[NSUserDefaults standardUserDefaults] setValue:@(-1) forKey:key];
  435. }
  436. }
  437. }
  438. - (NSString *)fileMessageKeyWith:(NSString *)strtime {
  439. return [NSString stringWithFormat:@"k_oss_file_%@", strtime];
  440. }
  441. @end