509 lines
21 KiB
Mathematica
509 lines
21 KiB
Mathematica
|
|
//
|
|||
|
|
// PYHTTPManager.m
|
|||
|
|
// Food
|
|||
|
|
//
|
|||
|
|
// Created by ko1o, on 2019/7/27.
|
|||
|
|
// Copyright © 2019年 ko1o. All rights reserved.
|
|||
|
|
//
|
|||
|
|
|
|||
|
|
|
|||
|
|
#import <NSString+TUIUtil.h>
|
|||
|
|
#import "PYHTTPManager.h"
|
|||
|
|
#import "AFHTTPSessionManager.h"
|
|||
|
|
|
|||
|
|
//#import "PYAccountService.h"
|
|||
|
|
//#import "PYLoginViewController.h"
|
|||
|
|
//#import "PYNewLoginViewController.h"
|
|||
|
|
#import <AliyunOSSiOS/OSSService.h>
|
|||
|
|
#if IS_DEBUG
|
|||
|
|
static NSString * const salt = @"FFAsdaAoXidicS";
|
|||
|
|
#else
|
|||
|
|
static NSString * const salt = @"sdfsaAoXidiZs";
|
|||
|
|
#endif
|
|||
|
|
const NSInteger kNoLoginCode = 100;
|
|||
|
|
//static BOSClient *bosClient = nil;
|
|||
|
|
//static NSString *bucketname = nil;
|
|||
|
|
//static NSDictionary *typeConfigDic = nil;
|
|||
|
|
|
|||
|
|
static OSSClient *_aliOSSClient;
|
|||
|
|
static NSString *_expirationTimeInGMTFormat;
|
|||
|
|
|
|||
|
|
static NSString *kBucketName = nil;
|
|||
|
|
//static NSString *kAccessKeyId = @"LTAI4GJ3K5yB7xnatvAQdEi5";
|
|||
|
|
//static NSString *kAccessKeySecret = @"6dbahs8GFIZQtslSbQZa6xn2R1pdOA";
|
|||
|
|
//static NSString *kEndpoint = @"https://oss-cn-shenzhen.aliyuncs.com";
|
|||
|
|
|
|||
|
|
static NSString *kSSOCacheAvatarDir = @"avatar"; // 头像目录
|
|||
|
|
static NSString *kSSOCacheAvatarBgDir = @"cover"; // 头像背景目录
|
|||
|
|
static NSString *kSSOCacheReport = @"report"; // 举报
|
|||
|
|
static NSString *kSSOCacheProfilePhoto = @"profile_photo"; // 照片墙
|
|||
|
|
static NSString *kSSOCacheBottlePhoto = @"bottle_photo"; // 瓶子图片
|
|||
|
|
static NSString *kSSOCacheBottleVoice = @"bottle_voice"; // 瓶子语音
|
|||
|
|
static NSString *kSSOCacheiOSTestDir = @"iostest";
|
|||
|
|
|
|||
|
|
static dispatch_queue_t uploadQueue; // 上传队列
|
|||
|
|
|
|||
|
|
void runInMainThread(void(^action)(void)) {
|
|||
|
|
dispatch_async(dispatch_get_main_queue(), action);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
///网络状态改变通知Key
|
|||
|
|
#define NotificationName_ReachabilityStatusChange @"TH_ReachabilityStatusChange"
|
|||
|
|
|
|||
|
|
@implementation PYHTTPManager
|
|||
|
|
|
|||
|
|
static AFHTTPSessionManager *_manager;
|
|||
|
|
|
|||
|
|
+ (void)load {
|
|||
|
|
_manager = [[AFHTTPSessionManager alloc] initWithBaseURL:[NSURL URLWithString:PYHttpBaseUrl]];
|
|||
|
|
_manager.securityPolicy.allowInvalidCertificates =YES;
|
|||
|
|
_manager.requestSerializer = [AFJSONRequestSerializer serializer];
|
|||
|
|
|
|||
|
|
// _manager.responseSerializer = [AFJSONResponseSerializer serializer];
|
|||
|
|
_manager.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"application/json", @"text/json", @"text/javascript", @"text/html", nil];
|
|||
|
|
|
|||
|
|
AFSecurityPolicy *securityPolicy = [[AFSecurityPolicy alloc] init];
|
|||
|
|
//如果是需要验证自建证书,需要设置为YES
|
|||
|
|
[securityPolicy setAllowInvalidCertificates:NO];
|
|||
|
|
[_manager setSecurityPolicy:securityPolicy];
|
|||
|
|
|
|||
|
|
uploadQueue = dispatch_queue_create("com.youth.uploadfile", DISPATCH_QUEUE_SERIAL);
|
|||
|
|
// [self getSetupOSSClientWithCompletion:^(BOOL succeed) {
|
|||
|
|
//
|
|||
|
|
// }];
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
+ (void)showLoginPage
|
|||
|
|
{
|
|||
|
|
// UINavigationController *currectNav = [PYAppService currentNavigationController];
|
|||
|
|
// if ([currectNav.viewControllers.firstObject isKindOfClass:[PYNewLoginViewController class]]) {
|
|||
|
|
// return;
|
|||
|
|
// }
|
|||
|
|
// PYNavigationViewController *nav = [[PYNavigationViewController alloc] initWithRootViewController:[PYNewLoginViewController new]];
|
|||
|
|
// 取消所有请求
|
|||
|
|
[_manager.operationQueue cancelAllOperations];
|
|||
|
|
// [[PYAppService currentViewController] presentViewController:nav animated:YES completion:nil];
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
+ (void)setReachabilityStatusChangeBlock:(nullable void (^)(AFNetworkReachabilityStatus status))block
|
|||
|
|
{
|
|||
|
|
[_manager.reachabilityManager startMonitoring];
|
|||
|
|
[_manager.reachabilityManager setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) {
|
|||
|
|
|
|||
|
|
//发送网络状态修改通知, 可在全局调用一次就好
|
|||
|
|
[NSNotificationCenter.defaultCenter postNotificationName:NotificationName_ReachabilityStatusChange object:nil userInfo:@{NotificationName_ReachabilityStatusChange : @(status)}];
|
|||
|
|
|
|||
|
|
//兼容旧代码
|
|||
|
|
if (block) {
|
|||
|
|
block(status);
|
|||
|
|
}
|
|||
|
|
}];
|
|||
|
|
}
|
|||
|
|
///监听网络状态改变通知
|
|||
|
|
+ (void)addObserverForReachabilityStatusChange:(nullable void (^)(AFNetworkReachabilityStatus status))changeBlock {
|
|||
|
|
[NSNotificationCenter.defaultCenter addObserverForName:NotificationName_ReachabilityStatusChange object:nil queue:nil usingBlock:^(NSNotification * _Nonnull note) {
|
|||
|
|
if ([note.userInfo.allKeys containsObject:NotificationName_ReachabilityStatusChange]) {
|
|||
|
|
NSNumber *statusNum = [note.userInfo objectForKey:NotificationName_ReachabilityStatusChange];
|
|||
|
|
changeBlock(statusNum.integerValue);
|
|||
|
|
}
|
|||
|
|
}];
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
+ (BOOL)isNetReachable
|
|||
|
|
{
|
|||
|
|
return [_manager.reachabilityManager isReachable];
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// 直接显示后台返回的message 服务列表
|
|||
|
|
+ (NSArray *)showRspMessageServerNames
|
|||
|
|
{
|
|||
|
|
return @[
|
|||
|
|
@"activebm/",
|
|||
|
|
@"userwsub/",
|
|||
|
|
@"invoiceaddc/",
|
|||
|
|
@"invoiceadd/"
|
|||
|
|
];
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
+ (NSArray *)ignoreErrorMsg {
|
|||
|
|
return @[@""];
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
+ (NSArray *)handleErrorCodeWithPath:(NSString *)path {
|
|||
|
|
if ([path isEqualToString:@"learnroomdetail"]) {
|
|||
|
|
return @[@(1200), @(1201), @(1202)];
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return nil;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
+ (NSError *)errorWithPath:(NSString *)path forCode:(int)code userInfo:(NSDictionary *)userInfo {
|
|||
|
|
if ([[self handleErrorCodeWithPath:path] containsObject:@(code)]) {
|
|||
|
|
return [NSError errorWithDomain:NSCocoaErrorDomain code:code userInfo:userInfo];
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return nil;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
+ (NSDictionary *)headers {
|
|||
|
|
NSMutableDictionary *headersM = [NSMutableDictionary dictionary];
|
|||
|
|
if ([LoginService token]) {
|
|||
|
|
headersM[@"Authorization"] = [@"Bearer " stringByAppendingString:[LoginService token]];
|
|||
|
|
}
|
|||
|
|
return headersM;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
+ (NSMutableDictionary *)commonParamsM {
|
|||
|
|
NSMutableDictionary *commonParamsM = [NSMutableDictionary dictionary];
|
|||
|
|
// * post请求的统一基础参数,内含:
|
|||
|
|
// * device_brand: 手机厂商(系统 api 获取)
|
|||
|
|
// * device_model: 手机型号(系统 api 获取)
|
|||
|
|
// * app_version_name: 应用版本名,3个数字(4.1.12)
|
|||
|
|
// * app_version_code:应用开发版本号,客户端自己的 bundle id(1/123)
|
|||
|
|
// * interface_version: 请求的接口版本号(1.0)
|
|||
|
|
// * device_platform: 操作系统(iOS / Android)
|
|||
|
|
UIDevice *device = [UIDevice currentDevice];
|
|||
|
|
commonParamsM[@"device_brand"] = @"Apple";
|
|||
|
|
commonParamsM[@"device_model"] = device.model ?: @"Unknown";
|
|||
|
|
NSDictionary *infoDictionary = [[NSBundle mainBundle] infoDictionary];//获取app版本信息
|
|||
|
|
commonParamsM[@"app_version_name"] = infoDictionary[@"CFBundleShortVersionString"] ?: @"Unknown";
|
|||
|
|
NSInteger interVersionCode = (NSInteger)infoDictionary[@"CFBundleVersion"];
|
|||
|
|
NSString *versionCodeStr = [NSString stringWithFormat:@"%lu",interVersionCode];
|
|||
|
|
commonParamsM[@"app_version_code"] = versionCodeStr;
|
|||
|
|
// commonParamsM[@"app_version_code"] = infoDictionary[@"CFBundleVersion"] ?: @"Unknown";
|
|||
|
|
commonParamsM[@"interface_version"] = infoDictionary[@"CFBundleShortVersionString"] ?: @"Unknown";
|
|||
|
|
commonParamsM[@"device_platform"] = @"iOS";
|
|||
|
|
commonParamsM[@"os_version"] = [UIDevice currentDevice].systemVersion;
|
|||
|
|
|
|||
|
|
return commonParamsM;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
+ (NSString *)generateSignWithParams:(NSDictionary *)params {
|
|||
|
|
|
|||
|
|
NSArray *sortedKeys = [params.allKeys sortedArrayUsingComparator:^NSComparisonResult(id _Nonnull obj1, id _Nonnull obj2) {
|
|||
|
|
return obj1 > obj2;
|
|||
|
|
}];
|
|||
|
|
NSMutableString *signStrM = [NSMutableString stringWithFormat:@"%@,", salt];
|
|||
|
|
for (NSString *key in sortedKeys) {
|
|||
|
|
NSString *value = params[key];
|
|||
|
|
if (key && value) {
|
|||
|
|
[signStrM appendFormat:@"%@:%@,", key, value];
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
[signStrM appendString:salt];
|
|||
|
|
|
|||
|
|
return [signStrM md5];
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
+ (void)handleRsp:(id)responseObject path:(NSString *)path callback:(PYHTTPManagerCallback)callback {
|
|||
|
|
int code = [responseObject[@"code"] intValue];
|
|||
|
|
|
|||
|
|
// NSLog(@"code==%d",code);
|
|||
|
|
//9999封号
|
|||
|
|
if (code == 9998 || code == 9999) { // 接口认证失败,APP需要重新登录
|
|||
|
|
[SVProgressHUD dismiss];
|
|||
|
|
[PYAppService logout];
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
if (code == 10) { // 需要购买会员
|
|||
|
|
[SVProgressHUD dismiss];
|
|||
|
|
[PYAppService showVipAlertWithPath:path title:responseObject[@"title"] msg:responseObject[@"message"] source:nil];
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
NSError *handleError = [self errorWithPath:path forCode:code userInfo:responseObject];
|
|||
|
|
if (code != 0 && !handleError) {
|
|||
|
|
NSError *error = [NSError errorWithDomain:NSURLErrorDomain code:code userInfo:responseObject];
|
|||
|
|
if (![[self ignoreErrorMsg] containsObject:path]) {
|
|||
|
|
if (![responseObject[@"message"] isEqualToString:@"auth header is empty"]) {
|
|||
|
|
[SVProgressHUD showErrorWithStatus:responseObject[@"message"] ?: @"网络异常,请稍后再试~"];
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
if (callback) {
|
|||
|
|
callback(nil, error);
|
|||
|
|
}
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
id result = responseObject[@"data"];
|
|||
|
|
if ([result isKindOfClass:NSNull.class]) {
|
|||
|
|
result = nil;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (callback) {
|
|||
|
|
callback(result, handleError);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
+ (void)postWithPath:(NSString *)path params:(NSDictionary *)params callback:(PYHTTPManagerCallback)callback{
|
|||
|
|
|
|||
|
|
NSLog(@"path===%@,[self headers]%@",path,[self headers]);
|
|||
|
|
NSMutableDictionary *args = [self commonParamsM];
|
|||
|
|
[args addEntriesFromDictionary:params];
|
|||
|
|
args[@"sign"] = [self generateSignWithParams:args];
|
|||
|
|
[_manager POST:path parameters:args headers:[self headers] progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
|
|||
|
|
[self handleRsp:responseObject path:path callback:callback];
|
|||
|
|
|
|||
|
|
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
|
|||
|
|
if (callback) {
|
|||
|
|
if (error) {
|
|||
|
|
[SVProgressHUD showErrorWithStatus:error.localizedDescription ?: @"网络异常,请稍后再试~"];
|
|||
|
|
}
|
|||
|
|
callback(nil, error);
|
|||
|
|
}
|
|||
|
|
}];
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
+ (void)getWithPath:(NSString *)path params:(NSDictionary *)params callback:(PYHTTPManagerCallback)callback {
|
|||
|
|
NSMutableDictionary *args = [self commonParamsM];
|
|||
|
|
[args addEntriesFromDictionary:params];
|
|||
|
|
|
|||
|
|
[_manager GET:path parameters:args headers:[self headers] progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
|
|||
|
|
[self handleRsp:responseObject path:path callback:callback];
|
|||
|
|
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
|
|||
|
|
if (error.code == kNoLoginCode) {
|
|||
|
|
[self showLoginPage];
|
|||
|
|
return ;
|
|||
|
|
}
|
|||
|
|
if (callback) {
|
|||
|
|
if (error) {
|
|||
|
|
[SVProgressHUD showErrorWithStatus:error.localizedDescription ?: @"网络异常,请稍后再试~"];
|
|||
|
|
}
|
|||
|
|
callback(nil, error);
|
|||
|
|
}
|
|||
|
|
}];
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
+ (void)post:(NSString *)url params:(NSDictionary *)params imageses:(NSArray<NSArray<UIImage *> *> *)imageses imageNames:(NSArray<NSString *> *)imageNames callback:(PYHTTPManagerCallback)callback
|
|||
|
|
{
|
|||
|
|
AFHTTPSessionManager *manager = [[AFHTTPSessionManager alloc] initWithBaseURL:[NSURL URLWithString:PYHttpBaseUrl]];
|
|||
|
|
// [manager.requestSerializer setValue:@"multipart/form-data;charset=utf-8" forHTTPHeaderField:@"Content-Type"];
|
|||
|
|
manager.responseSerializer = [AFJSONResponseSerializer serializer];
|
|||
|
|
manager.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"text/plain", @"multipart/form-data", @"application/json", @"text/html", @"image/jpeg", @"image/png", @"application/octet-stream", @"text/json", nil];
|
|||
|
|
|
|||
|
|
NSMutableDictionary *args = [NSMutableDictionary dictionary];
|
|||
|
|
[args addEntriesFromDictionary:params];
|
|||
|
|
|
|||
|
|
// NSLog(@"PYHttpBaseUrl===%@",PYHttpBaseUrl);
|
|||
|
|
|
|||
|
|
[manager POST:url
|
|||
|
|
parameters:args
|
|||
|
|
headers:nil
|
|||
|
|
constructingBodyWithBlock:^(id<AFMultipartFormData> _Nonnull formData) {
|
|||
|
|
for (int j = 0; j < imageses.count; j++) {
|
|||
|
|
NSArray *images = imageses[j];
|
|||
|
|
NSString *imageName = imageNames[j];
|
|||
|
|
for (int i = 0 ;i < images.count; i++) {
|
|||
|
|
UIImage *image = images[i];
|
|||
|
|
NSData *data = UIImageJPEGRepresentation(image, 1.0);
|
|||
|
|
[formData appendPartWithFileData:data name:imageName fileName:[NSString stringWithFormat:@"%@.jpg", [[NSUUID UUID]UUIDString]] mimeType:@"image/jpeg"];
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
} progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
|
|||
|
|
if ([responseObject[@"code"] integerValue] != 200) {
|
|||
|
|
NSError *error = [NSError errorWithDomain:@"" code:[responseObject[@"code"] integerValue] userInfo:responseObject];
|
|||
|
|
callback(nil, error);
|
|||
|
|
[SVProgressHUD showErrorWithStatus:responseObject[@"message"]];
|
|||
|
|
} else {
|
|||
|
|
callback(responseObject[@"data"], nil);
|
|||
|
|
}
|
|||
|
|
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
|
|||
|
|
[SVProgressHUD showErrorWithStatus:[error localizedDescription]];
|
|||
|
|
callback(nil, error);
|
|||
|
|
}];
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
+ (NSString *)subfixForScene:(AliOSSUploadScene)scene
|
|||
|
|
{
|
|||
|
|
switch (scene) {
|
|||
|
|
case AliOSSUploadSceneAvatar:
|
|||
|
|
case AliOSSUploadSceneAvatarBg:
|
|||
|
|
case AliOSSUploadSceneReport:
|
|||
|
|
case AliOSSUploadSceneiOSTest:
|
|||
|
|
case AliOSSUploadSceneProfilePhoto:
|
|||
|
|
case AliOSSUploadSceneBottlePhoto:
|
|||
|
|
return @"jpg";
|
|||
|
|
case AliOSSUploadSceneBottleVoice:
|
|||
|
|
return @"m4a";
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return @"jpg";
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
+ (NSString *)cachePathForScene:(AliOSSUploadScene)scene
|
|||
|
|
{
|
|||
|
|
switch (scene) {
|
|||
|
|
case AliOSSUploadSceneAvatar :
|
|||
|
|
return kSSOCacheAvatarDir;
|
|||
|
|
case AliOSSUploadSceneAvatarBg:
|
|||
|
|
return kSSOCacheAvatarBgDir;
|
|||
|
|
case AliOSSUploadSceneReport:
|
|||
|
|
return kSSOCacheReport;
|
|||
|
|
case AliOSSUploadSceneProfilePhoto:
|
|||
|
|
return kSSOCacheProfilePhoto;
|
|||
|
|
case AliOSSUploadSceneBottlePhoto:
|
|||
|
|
return kSSOCacheBottlePhoto;
|
|||
|
|
case AliOSSUploadSceneBottleVoice:
|
|||
|
|
return kSSOCacheBottleVoice;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return kSSOCacheiOSTestDir;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
+ (void)getSetupOSSClientWithCompletion:(void(^)(BOOL succeed))completion {
|
|||
|
|
[self postWithPath:@"ossauth" params:nil callback:^(id _Nullable rsp, NSError * _Nullable error) {
|
|||
|
|
if (!error && rsp) {
|
|||
|
|
id<OSSCredentialProvider> credential = [[OSSFederationCredentialProvider alloc] initWithFederationTokenGetter:^OSSFederationToken * {
|
|||
|
|
// 您需要在此处实现获取一个FederationToken,并构造成OSSFederationToken对象返回。
|
|||
|
|
// 如果由于某种原因获取失败,直接返回nil。
|
|||
|
|
OSSFederationToken *token = [OSSFederationToken new];
|
|||
|
|
// 从STS服务获取的临时访问密钥(AccessKey ID和AccessKey Secret)。
|
|||
|
|
token.tAccessKey = rsp[@"access_key_id"];
|
|||
|
|
token.tSecretKey = rsp[@"access_key_secret"];
|
|||
|
|
// 从STS服务获取的安全令牌(SecurityToken)。
|
|||
|
|
token.tToken = rsp[@"security_token"];
|
|||
|
|
// 临时访问凭证的过期时间。
|
|||
|
|
token.expirationTimeInGMTFormat = rsp[@"expiration"];
|
|||
|
|
return token;
|
|||
|
|
}];
|
|||
|
|
|
|||
|
|
_expirationTimeInGMTFormat = rsp[@"expiration"];
|
|||
|
|
_aliOSSClient = [[OSSClient alloc] initWithEndpoint:rsp[@"end_point"] credentialProvider:credential];
|
|||
|
|
kBucketName = rsp[@"bucket_name"] ?: @"xidi-official-website";
|
|||
|
|
runInMainThread(^{
|
|||
|
|
if (completion) {
|
|||
|
|
completion(YES);
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
} else {
|
|||
|
|
runInMainThread(^{
|
|||
|
|
if (completion) {
|
|||
|
|
completion(NO);
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
}];
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
+ (void)uploadFileWithScene:(AliOSSUploadScene)scene
|
|||
|
|
data:(NSData *)data
|
|||
|
|
completion:(PYHTTPManagerCallback)completion
|
|||
|
|
{
|
|||
|
|
dispatch_async(uploadQueue, ^{
|
|||
|
|
@synchronized (self) {
|
|||
|
|
BOOL needNewOssClient = YES;
|
|||
|
|
if (_expirationTimeInGMTFormat != nil && _aliOSSClient != nil) {
|
|||
|
|
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
|
|||
|
|
dateFormatter.timeZone = [NSTimeZone timeZoneWithAbbreviation:@"GMT"];
|
|||
|
|
//2022-06-06T10:01:27Z
|
|||
|
|
[dateFormatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss'Z'"];
|
|||
|
|
NSDate *date = [dateFormatter dateFromString:_expirationTimeInGMTFormat];
|
|||
|
|
|
|||
|
|
if (date != nil && date.timeIntervalSinceNow > 60) {
|
|||
|
|
needNewOssClient = NO;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (needNewOssClient == YES || _aliOSSClient == nil) {
|
|||
|
|
dispatch_semaphore_t sema = dispatch_semaphore_create(0);
|
|||
|
|
[self getSetupOSSClientWithCompletion:^(BOOL succeed) {
|
|||
|
|
dispatch_semaphore_signal(sema);
|
|||
|
|
}];
|
|||
|
|
dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (!_aliOSSClient) {
|
|||
|
|
runInMainThread(^{
|
|||
|
|
[SVProgressHUD showErrorWithStatus:@"上传失败"];
|
|||
|
|
completion(nil, [NSError errorWithDomain:@"com.youth" code:-1 userInfo:nil]);
|
|||
|
|
});
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
OSSPutObjectRequest * put = [OSSPutObjectRequest new];
|
|||
|
|
put.bucketName = kBucketName;
|
|||
|
|
NSString *userID = [LoginService tokenInfo][@"id"] ?: [NSString stringWithFormat:@"random_%d", arc4random()];
|
|||
|
|
NSString *prefix = [NSString stringWithFormat:@"%@_%.0f", userID, [[NSDate date] timeIntervalSince1970] * 100000.0]; // 毫秒
|
|||
|
|
NSString *fileName = [NSString stringWithFormat:@"%@.%@", prefix, [self subfixForScene:scene]];
|
|||
|
|
//objectKey等同于objectName,表示上传文件到OSS时需要指定包含文件后缀在内的完整路径,例如abc/efg/123.jpg。
|
|||
|
|
NSString *cacheDir = [self cachePathForScene:scene];
|
|||
|
|
put.objectKey = [NSString stringWithFormat:@"%@/%@", cacheDir, fileName];
|
|||
|
|
// 直接上传NSData。
|
|||
|
|
put.uploadingData = data;
|
|||
|
|
// put.uploadProgress = ^(int64_t bytesSent, int64_t totalByteSent, int64_t totalBytesExpectedToSend) {
|
|||
|
|
// NSLog(@"%lld, %lld, %lld", bytesSent, totalByteSent, totalBytesExpectedToSend);
|
|||
|
|
// };
|
|||
|
|
// [SVProgressHUD showWithStatus:@"文件上传中..."];
|
|||
|
|
OSSTask * putTask = [_aliOSSClient putObject:put];
|
|||
|
|
[putTask continueWithBlock:^id(OSSTask *task) {
|
|||
|
|
if (completion) {
|
|||
|
|
if (!task.error) {
|
|||
|
|
// [SVProgressHUD dismiss];
|
|||
|
|
NSLog(@"upload object success!");
|
|||
|
|
// sign public url
|
|||
|
|
OSSTask *task = [_aliOSSClient presignPublicURLWithBucketName:kBucketName
|
|||
|
|
withObjectKey:put.objectKey];
|
|||
|
|
if (!task.error) {
|
|||
|
|
runInMainThread(^{
|
|||
|
|
completion(task.result, nil);
|
|||
|
|
});
|
|||
|
|
} else {
|
|||
|
|
NSLog(@"sign url error: %@", task.error);
|
|||
|
|
runInMainThread(^{
|
|||
|
|
completion(nil, task.error);
|
|||
|
|
[SVProgressHUD showErrorWithStatus:[NSString stringWithFormat:@"上传失败 sign %@", [task.error.userInfo objectForKey:@"message"]]];
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
} else {
|
|||
|
|
NSLog(@"upload object failed, error: %@" , task.error);
|
|||
|
|
runInMainThread(^{
|
|||
|
|
completion(nil, task.error);
|
|||
|
|
[SVProgressHUD showErrorWithStatus:[NSString stringWithFormat:@"上传失败%@", [task.error.userInfo objectForKey:@"message"]]];
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
return nil;
|
|||
|
|
}];
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
+ (void)uploadFileWithScene:(AliOSSUploadScene)scene
|
|||
|
|
datas:(NSArray<NSData *> *)datas
|
|||
|
|
completion:(PYHTTPManagerCallback)completion
|
|||
|
|
{
|
|||
|
|
NSInteger totalTaskCount = datas.count;
|
|||
|
|
__block NSInteger finishTaskCount = 0;
|
|||
|
|
NSMutableArray *fileUrls = [NSMutableArray array];
|
|||
|
|
for (NSData *data in datas) {
|
|||
|
|
[self uploadFileWithScene:scene data:data completion:^(id _Nullable rsp, NSError * _Nullable error) {
|
|||
|
|
@synchronized (self) {
|
|||
|
|
finishTaskCount++;
|
|||
|
|
if (rsp && !error && completion) {
|
|||
|
|
[fileUrls addObject:rsp];
|
|||
|
|
if (finishTaskCount >= totalTaskCount && fileUrls.count == finishTaskCount) {
|
|||
|
|
// 排序
|
|||
|
|
[fileUrls sortUsingComparator:^NSComparisonResult(NSString *url1, NSString *url2) {
|
|||
|
|
return [url1 compare:url2];
|
|||
|
|
}];
|
|||
|
|
runInMainThread(^{
|
|||
|
|
completion(fileUrls, nil);
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (error) {
|
|||
|
|
runInMainThread(^{
|
|||
|
|
completion(nil, error);
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}];
|
|||
|
|
|
|||
|
|
usleep(10000); // 10毫秒
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
@end
|