OSSManager.m 17 KB

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