OSSManager.m 17 KB

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