Files
youle_app_ios/msext/QiniuSDK/Storage/QNUploadManager.m
2023-12-27 20:38:37 +08:00

322 lines
11 KiB
Objective-C
Executable File

//
// QNUploader.h
// QiniuSDK
//
// Created by bailong on 14-9-28.
// Copyright (c) 2014年 Qiniu. All rights reserved.
//
#import <Foundation/Foundation.h>
#if __IPHONE_OS_VERSION_MIN_REQUIRED
#import "QNALAssetFile.h"
#import <AssetsLibrary/AssetsLibrary.h>
#import <MobileCoreServices/MobileCoreServices.h>
#import <UIKit/UIKit.h>
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 80000
#import "QNPHAssetFile.h"
#import <Photos/Photos.h>
#endif
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 90100
#import "QNPHAssetResource.h"
#endif
#else
#import <CoreServices/CoreServices.h>
#endif
#import "QNAsyncRun.h"
#import "QNConfiguration.h"
#import "QNCrc32.h"
#import "QNFile.h"
#import "QNFormUpload.h"
#import "QNResponseInfo.h"
#import "QNResumeUpload.h"
#import "QNSessionManager.h"
#import "QNSystem.h"
#import "QNUpToken.h"
#import "QNUploadManager.h"
#import "QNUploadOption+Private.h"
@interface QNUploadManager ()
@property (nonatomic) id<QNHttpDelegate> httpManager;
@property (nonatomic) QNConfiguration *config;
@end
@implementation QNUploadManager
- (instancetype)init {
return [self initWithConfiguration:nil];
}
- (instancetype)initWithRecorder:(id<QNRecorderDelegate>)recorder {
return [self initWithRecorder:recorder recorderKeyGenerator:nil];
}
- (instancetype)initWithRecorder:(id<QNRecorderDelegate>)recorder
recorderKeyGenerator:(QNRecorderKeyGenerator)recorderKeyGenerator {
QNConfiguration *config = [QNConfiguration build:^(QNConfigurationBuilder *builder) {
builder.recorder = recorder;
builder.recorderKeyGen = recorderKeyGenerator;
}];
return [self initWithConfiguration:config];
}
- (instancetype)initWithConfiguration:(QNConfiguration *)config {
if (self = [super init]) {
if (config == nil) {
config = [QNConfiguration build:^(QNConfigurationBuilder *builder){
}];
}
_config = config;
#if (defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 70000) || (defined(__MAC_OS_X_VERSION_MAX_ALLOWED) && __MAC_OS_X_VERSION_MAX_ALLOWED >= 1090)
_httpManager = [[QNSessionManager alloc] initWithProxy:config.proxy timeout:config.timeoutInterval urlConverter:config.converter dns:config.dns];
#endif
}
return self;
}
+ (instancetype)sharedInstanceWithConfiguration:(QNConfiguration *)config {
static QNUploadManager *sharedInstance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedInstance = [[self alloc] initWithConfiguration:config];
});
return sharedInstance;
}
+ (BOOL)checkAndNotifyError:(NSString *)key
token:(NSString *)token
input:(NSObject *)input
complete:(QNUpCompletionHandler)completionHandler {
NSString *desc = nil;
if (completionHandler == nil) {
@throw [NSException exceptionWithName:NSInvalidArgumentException
reason:@"no completionHandler"
userInfo:nil];
return YES;
}
if (input == nil) {
desc = @"no input data";
} else if (token == nil || [token isEqualToString:@""]) {
desc = @"no token";
}
if (desc != nil) {
QNAsyncRunInMain(^{
completionHandler([QNResponseInfo responseInfoWithInvalidArgument:desc], key, nil);
});
return YES;
}
return NO;
}
- (void)putData:(NSData *)data
key:(NSString *)key
token:(NSString *)token
complete:(QNUpCompletionHandler)completionHandler
option:(QNUploadOption *)option {
if ([QNUploadManager checkAndNotifyError:key token:token input:data complete:completionHandler]) {
return;
}
QNUpToken *t = [QNUpToken parse:token];
if (t == nil) {
QNAsyncRunInMain(^{
completionHandler([QNResponseInfo responseInfoWithInvalidToken:@"invalid token"], key, nil);
});
return;
}
[_config.zone preQuery:t on:^(int code) {
if (code != 0) {
QNAsyncRunInMain(^{
completionHandler([QNResponseInfo responseInfoWithInvalidToken:@"get zone failed"], key, nil);
});
return;
}
if ([data length] == 0) {
QNAsyncRunInMain(^{
completionHandler([QNResponseInfo responseInfoOfZeroData:nil], key, nil);
});
return;
}
QNUpCompletionHandler complete = ^(QNResponseInfo *info, NSString *key, NSDictionary *resp) {
QNAsyncRunInMain(^{
completionHandler(info, key, resp);
});
};
QNFormUpload *up = [[QNFormUpload alloc]
initWithData:data
withKey:key
withToken:t
withCompletionHandler:complete
withOption:option
withHttpManager:_httpManager
withConfiguration:_config];
QNAsyncRun(^{
[up put];
});
}];
}
- (void)putFileInternal:(id<QNFileDelegate>)file
key:(NSString *)key
token:(NSString *)token
complete:(QNUpCompletionHandler)completionHandler
option:(QNUploadOption *)option {
@autoreleasepool {
QNUpToken *t = [QNUpToken parse:token];
if (t == nil) {
QNAsyncRunInMain(^{
completionHandler([QNResponseInfo responseInfoWithInvalidToken:@"invalid token"], key, nil);
});
return;
}
[_config.zone preQuery:t on:^(int code) {
if (code != 0) {
QNAsyncRunInMain(^{
completionHandler([QNResponseInfo responseInfoWithInvalidToken:@"get zone failed"], key, nil);
});
return;
}
QNUpCompletionHandler complete = ^(QNResponseInfo *info, NSString *key, NSDictionary *resp) {
[file close];
QNAsyncRunInMain(^{
completionHandler(info, key, resp);
});
};
if ([file size] <= _config.putThreshold) {
NSData *data = [file readAll];
[self putData:data key:key token:token complete:complete option:option];
return;
}
NSString *recorderKey = key;
if (_config.recorder != nil && _config.recorderKeyGen != nil) {
recorderKey = _config.recorderKeyGen(key, [file path]);
}
NSLog(@"recorder %@", _config.recorder);
QNResumeUpload *up = [[QNResumeUpload alloc]
initWithFile:file
withKey:key
withToken:t
withCompletionHandler:complete
withOption:option
withRecorder:_config.recorder
withRecorderKey:recorderKey
withHttpManager:_httpManager
withConfiguration:_config];
QNAsyncRun(^{
[up run];
});
}];
}
}
- (void)putFile:(NSString *)filePath
key:(NSString *)key
token:(NSString *)token
complete:(QNUpCompletionHandler)completionHandler
option:(QNUploadOption *)option {
if ([QNUploadManager checkAndNotifyError:key token:token input:filePath complete:completionHandler]) {
return;
}
@autoreleasepool {
NSError *error = nil;
__block QNFile *file = [[QNFile alloc] init:filePath error:&error];
if (error) {
QNAsyncRunInMain(^{
QNResponseInfo *info = [QNResponseInfo responseInfoWithFileError:error];
completionHandler(info, key, nil);
});
return;
}
[self putFileInternal:file key:key token:token complete:completionHandler option:option];
}
}
- (void)putALAsset:(ALAsset *)asset
key:(NSString *)key
token:(NSString *)token
complete:(QNUpCompletionHandler)completionHandler
option:(QNUploadOption *)option {
#if __IPHONE_OS_VERSION_MIN_REQUIRED
if ([QNUploadManager checkAndNotifyError:key token:token input:asset complete:completionHandler]) {
return;
}
@autoreleasepool {
NSError *error = nil;
__block QNALAssetFile *file = [[QNALAssetFile alloc] init:asset error:&error];
if (error) {
QNAsyncRunInMain(^{
QNResponseInfo *info = [QNResponseInfo responseInfoWithFileError:error];
completionHandler(info, key, nil);
});
return;
}
[self putFileInternal:file key:key token:token complete:completionHandler option:option];
}
#endif
}
- (void)putPHAsset:(PHAsset *)asset
key:(NSString *)key
token:(NSString *)token
complete:(QNUpCompletionHandler)completionHandler
option:(QNUploadOption *)option {
#if (defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 80000)
if ([QNUploadManager checkAndNotifyError:key token:token input:asset complete:completionHandler]) {
return;
}
@autoreleasepool {
NSError *error = nil;
__block QNPHAssetFile *file = [[QNPHAssetFile alloc] init:asset error:&error];
if (error) {
QNAsyncRunInMain(^{
QNResponseInfo *info = [QNResponseInfo responseInfoWithFileError:error];
completionHandler(info, key, nil);
});
return;
}
[self putFileInternal:file key:key token:token complete:completionHandler option:option];
}
#endif
}
- (void)putPHAssetResource:(PHAssetResource *)assetResource
key:(NSString *)key
token:(NSString *)token
complete:(QNUpCompletionHandler)completionHandler
option:(QNUploadOption *)option {
#if (defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 90100)
if ([QNUploadManager checkAndNotifyError:key token:token input:assetResource complete:completionHandler]) {
return;
}
@autoreleasepool {
NSError *error = nil;
__block QNPHAssetResource *file = [[QNPHAssetResource alloc] init:assetResource error:&error];
if (error) {
QNAsyncRunInMain(^{
QNResponseInfo *info = [QNResponseInfo responseInfoWithFileError:error];
completionHandler(info, key, nil);
});
return;
}
[self putFileInternal:file key:key token:token complete:completionHandler option:option];
}
#endif
}
@end