322 lines
11 KiB
Objective-C
Executable File
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
|