add .gitignore

This commit is contained in:
JoyWayer
2023-12-27 20:38:37 +08:00
parent b106a628a5
commit f6343426d6
515 changed files with 104217 additions and 199 deletions

View File

@@ -0,0 +1,33 @@
#import <Foundation/Foundation.h>
@class QNResponseInfo;
typedef void (^QNInternalProgressBlock)(long long totalBytesWritten, long long totalBytesExpectedToWrite);
typedef void (^QNCompleteBlock)(QNResponseInfo *info, NSDictionary *resp);
typedef BOOL (^QNCancelBlock)(void);
/**
* Http 客户端接口
*/
@protocol QNHttpDelegate <NSObject>
- (void)multipartPost:(NSString *)url
withData:(NSData *)data
withParams:(NSDictionary *)params
withFileName:(NSString *)key
withMimeType:(NSString *)mime
withCompleteBlock:(QNCompleteBlock)completeBlock
withProgressBlock:(QNInternalProgressBlock)progressBlock
withCancelBlock:(QNCancelBlock)cancelBlock
withAccess:(NSString *)access;
- (void)post:(NSString *)url
withData:(NSData *)data
withParams:(NSDictionary *)params
withHeaders:(NSDictionary *)headers
withCompleteBlock:(QNCompleteBlock)completeBlock
withProgressBlock:(QNInternalProgressBlock)progressBlock
withCancelBlock:(QNCancelBlock)cancelBlock
withAccess:(NSString *)access;
@end

View File

@@ -0,0 +1,206 @@
//
// QNResponseInfo.h
// QiniuSDK
//
// Created by bailong on 14/10/2.
// Copyright (c) 2014年 Qiniu. All rights reserved.
//
#import <Foundation/Foundation.h>
/**
* 中途取消的状态码
*/
extern const int kQNRequestCancelled;
/**
* 网络错误状态码
*/
extern const int kQNNetworkError;
/**
* 错误参数状态码
*/
extern const int kQNInvalidArgument;
/**
* 0 字节文件或数据
*/
extern const int kQNZeroDataSize;
/**
* 错误token状态码
*/
extern const int kQNInvalidToken;
/**
* 读取文件错误状态码
*/
extern const int kQNFileError;
/**
* 上传完成后返回的状态信息
*/
@interface QNResponseInfo : NSObject
/**
* 状态码
*/
@property (readonly) int statusCode;
/**
* 七牛服务器生成的请求ID用来跟踪请求信息如果使用过程中出现问题请反馈此ID
*/
@property (nonatomic, copy, readonly) NSString *reqId;
/**
* 七牛服务器内部跟踪记录
*/
@property (nonatomic, copy, readonly) NSString *xlog;
/**
* cdn服务器内部跟踪记录
*/
@property (nonatomic, copy, readonly) NSString *xvia;
/**
* 错误信息,出错时请反馈此记录
*/
@property (nonatomic, copy, readonly) NSError *error;
/**
* 服务器域名
*/
@property (nonatomic, copy, readonly) NSString *host;
/**
* 请求消耗的时间,单位 秒
*/
@property (nonatomic, readonly) double duration;
/**
* 服务器IP
*/
@property (nonatomic, readonly) NSString *serverIp;
/**
* 客户端id
*/
@property (nonatomic, readonly) NSString *id;
/**
* 时间戳
*/
@property (readonly) UInt64 timeStamp;
/**
* 网络类型
*/
//@property (nonatomic, readonly) NSString *networkType;
/**
* 是否取消
*/
@property (nonatomic, readonly, getter=isCancelled) BOOL canceled;
/**
* 成功的请求
*/
@property (nonatomic, readonly, getter=isOK) BOOL ok;
/**
* 是否网络错误
*/
@property (nonatomic, readonly, getter=isConnectionBroken) BOOL broken;
/**
* 是否需要重试,内部使用
*/
@property (nonatomic, readonly) BOOL couldRetry;
/**
* 是否需要换备用server内部使用
*/
@property (nonatomic, readonly) BOOL needSwitchServer;
/**
* 是否为 七牛响应
*/
@property (nonatomic, readonly, getter=isNotQiniu) BOOL notQiniu;
/**
* 工厂函数,内部使用
*
* @return 取消的实例
*/
+ (instancetype)cancel;
/**
* 工厂函数,内部使用
*
* @param desc 错误参数描述
*
* @return 错误参数实例
*/
+ (instancetype)responseInfoWithInvalidArgument:(NSString *)desc;
/**
* 工厂函数,内部使用
*
* @param desc 错误token描述
*
* @return 错误token实例
*/
+ (instancetype)responseInfoWithInvalidToken:(NSString *)desc;
/**
* 工厂函数,内部使用
*
* @param error 错误信息
* @param host 服务器域名
* @param duration 请求完成时间,单位秒
*
* @return 网络错误实例
*/
+ (instancetype)responseInfoWithNetError:(NSError *)error
host:(NSString *)host
duration:(double)duration;
/**
* 工厂函数,内部使用
*
* @param error 错误信息
*
* @return 文件错误实例
*/
+ (instancetype)responseInfoWithFileError:(NSError *)error;
/**
* 工厂函数,内部使用
*
* @return 文件错误实例
*/
+ (instancetype)responseInfoOfZeroData:(NSString *)path;
/**
* 构造函数
*
* @param status 状态码
* @param reqId 七牛服务器请求id
* @param xlog 七牛服务器记录
* @param body 服务器返回内容
* @param host 服务器域名
* @param duration 请求完成时间,单位秒
*
* @return 实例
*/
- (instancetype)init:(int)status
withReqId:(NSString *)reqId
withXLog:(NSString *)xlog
withXVia:(NSString *)xvia
withHost:(NSString *)host
withIp:(NSString *)ip
withDuration:(double)duration
withBody:(NSData *)body;
@end

View File

@@ -0,0 +1,210 @@
//
// QNResponseInfo.m
// QiniuSDK
//
// Created by bailong on 14/10/2.
// Copyright (c) 2014 Qiniu. All rights reserved.
//
#import "QNResponseInfo.h"
#import "QNUserAgent.h"
#import "QNVersion.h"
const int kQNZeroDataSize = -6;
const int kQNInvalidToken = -5;
const int kQNFileError = -4;
const int kQNInvalidArgument = -3;
const int kQNRequestCancelled = -2;
const int kQNNetworkError = -1;
/**
https://developer.apple.com/library/ios/documentation/Cocoa/Reference/Foundation/Miscellaneous/Foundation_Constants/index.html#//apple_ref/doc/constant_group/URL_Loading_System_Error_Codes
NSURLErrorUnknown = -1,
NSURLErrorCancelled = -999,
NSURLErrorBadURL = -1000,
NSURLErrorTimedOut = -1001,
NSURLErrorUnsupportedURL = -1002,
NSURLErrorCannotFindHost = -1003,
NSURLErrorCannotConnectToHost = -1004,
NSURLErrorDataLengthExceedsMaximum = -1103,
NSURLErrorNetworkConnectionLost = -1005,
NSURLErrorDNSLookupFailed = -1006,
NSURLErrorHTTPTooManyRedirects = -1007,
NSURLErrorResourceUnavailable = -1008,
NSURLErrorNotConnectedToInternet = -1009,
NSURLErrorRedirectToNonExistentLocation = -1010,
NSURLErrorBadServerResponse = -1011,
NSURLErrorUserCancelledAuthentication = -1012,
NSURLErrorUserAuthenticationRequired = -1013,
NSURLErrorZeroByteResource = -1014,
NSURLErrorCannotDecodeRawData = -1015,
NSURLErrorCannotDecodeContentData = -1016,
NSURLErrorCannotParseResponse = -1017,
NSURLErrorInternationalRoamingOff = -1018,
NSURLErrorCallIsActive = -1019,
NSURLErrorDataNotAllowed = -1020,
NSURLErrorRequestBodyStreamExhausted = -1021,
NSURLErrorFileDoesNotExist = -1100,
NSURLErrorFileIsDirectory = -1101,
NSURLErrorNoPermissionsToReadFile = -1102,
NSURLErrorSecureConnectionFailed = -1200,
NSURLErrorServerCertificateHasBadDate = -1201,
NSURLErrorServerCertificateUntrusted = -1202,
NSURLErrorServerCertificateHasUnknownRoot = -1203,
NSURLErrorServerCertificateNotYetValid = -1204,
NSURLErrorClientCertificateRejected = -1205,
NSURLErrorClientCertificateRequired = -1206,
NSURLErrorCannotLoadFromNetwork = -2000,
NSURLErrorCannotCreateFile = -3000,
NSURLErrorCannotOpenFile = -3001,
NSURLErrorCannotCloseFile = -3002,
NSURLErrorCannotWriteToFile = -3003,
NSURLErrorCannotRemoveFile = -3004,
NSURLErrorCannotMoveFile = -3005,
NSURLErrorDownloadDecodingFailedMidStream = -3006,
NSURLErrorDownloadDecodingFailedToComplete = -3007
*/
static QNResponseInfo *cancelledInfo = nil;
static NSString *domain = @"qiniu.com";
@implementation QNResponseInfo
+ (instancetype)cancel {
return [[QNResponseInfo alloc] initWithCancelled];
}
+ (instancetype)responseInfoWithInvalidArgument:(NSString *)text {
return [[QNResponseInfo alloc] initWithStatus:kQNInvalidArgument errorDescription:text];
}
+ (instancetype)responseInfoWithInvalidToken:(NSString *)text {
return [[QNResponseInfo alloc] initWithStatus:kQNInvalidToken errorDescription:text];
}
+ (instancetype)responseInfoWithNetError:(NSError *)error host:(NSString *)host duration:(double)duration {
int code = kQNNetworkError;
if (error != nil) {
code = (int)error.code;
}
return [[QNResponseInfo alloc] initWithStatus:code error:error host:host duration:duration];
}
+ (instancetype)responseInfoWithFileError:(NSError *)error {
return [[QNResponseInfo alloc] initWithStatus:kQNFileError error:error];
}
+ (instancetype)responseInfoOfZeroData:(NSString *)path {
NSString *desc;
if (path == nil) {
desc = @"data size is 0";
} else {
desc = [[NSString alloc] initWithFormat:@"file %@ size is 0", path];
}
return [[QNResponseInfo alloc] initWithStatus:kQNZeroDataSize errorDescription:desc];
}
- (instancetype)initWithCancelled {
return [self initWithStatus:kQNRequestCancelled errorDescription:@"cancelled by user"];
}
- (instancetype)initWithStatus:(int)status
error:(NSError *)error {
return [self initWithStatus:status error:error host:nil duration:0];
}
- (instancetype)initWithStatus:(int)status
error:(NSError *)error
host:(NSString *)host
duration:(double)duration {
if (self = [super init]) {
_statusCode = status;
_error = error;
_host = host;
_duration = duration;
_id = [QNUserAgent sharedInstance].id;
_timeStamp = [[NSDate date] timeIntervalSince1970];
}
return self;
}
- (instancetype)initWithStatus:(int)status
errorDescription:(NSString *)text {
NSError *error = [[NSError alloc] initWithDomain:domain code:status userInfo:@{ @"error" : text }];
return [self initWithStatus:status error:error];
}
- (instancetype)init:(int)status
withReqId:(NSString *)reqId
withXLog:(NSString *)xlog
withXVia:(NSString *)xvia
withHost:(NSString *)host
withIp:(NSString *)ip
withDuration:(double)duration
withBody:(NSData *)body {
if (self = [super init]) {
_statusCode = status;
_reqId = [reqId copy];
_xlog = [xlog copy];
_xvia = [xvia copy];
_host = [host copy];
_duration = duration;
_serverIp = ip;
_id = [QNUserAgent sharedInstance].id;
_timeStamp = [[NSDate date] timeIntervalSince1970];
if (status != 200) {
if (body == nil) {
_error = [[NSError alloc] initWithDomain:domain code:_statusCode userInfo:nil];
} else {
NSError *tmp;
NSDictionary *uInfo = [NSJSONSerialization JSONObjectWithData:body options:NSJSONReadingMutableLeaves error:&tmp];
if (tmp != nil) {
// UTF8nil
NSString *str = [[NSString alloc] initWithData:body encoding:NSUTF8StringEncoding];
if (str == nil) {
str = @"";
}
uInfo = @{ @"error" : str };
}
_error = [[NSError alloc] initWithDomain:domain code:_statusCode userInfo:uInfo];
}
} else if (body == nil || body.length == 0) {
NSDictionary *uInfo = @{ @"error" : @"no response json" };
_error = [[NSError alloc] initWithDomain:domain code:_statusCode userInfo:uInfo];
}
}
return self;
}
- (NSString *)description {
return [NSString stringWithFormat:@"<%@= id: %@, ver: %@, status: %d, requestId: %@, xlog: %@, xvia: %@, host: %@ ip: %@ duration: %f s time: %llu error: %@>", NSStringFromClass([self class]), _id, kQiniuVersion, _statusCode, _reqId, _xlog, _xvia, _host, _serverIp, _duration, _timeStamp, _error];
}
- (BOOL)isCancelled {
return _statusCode == kQNRequestCancelled || _statusCode == -999;
}
- (BOOL)isNotQiniu {
return (_statusCode >= 200 && _statusCode < 500) && _reqId == nil;
}
- (BOOL)isOK {
return _statusCode == 200 && _error == nil && _reqId != nil;
}
- (BOOL)isConnectionBroken {
// reqId is nill means the server is not qiniu
return _statusCode == kQNNetworkError || (_statusCode < -1000 && _statusCode != -1003);
}
- (BOOL)needSwitchServer {
return _statusCode == kQNNetworkError || (_statusCode < -1000 && _statusCode != -1003) || (_statusCode / 100 == 5 && _statusCode != 579);
}
- (BOOL)couldRetry {
return (_statusCode >= 500 && _statusCode < 600 && _statusCode != 579) || _statusCode == kQNNetworkError || _statusCode == 996 || _statusCode == 406 || (_statusCode == 200 && _error != nil) || _statusCode < -1000 || self.isNotQiniu;
}
@end

View File

@@ -0,0 +1,40 @@
#import "QNHttpDelegate.h"
#import <Foundation/Foundation.h>
#import "QNConfiguration.h"
#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)
@interface QNSessionManager : NSObject <QNHttpDelegate>
- (instancetype)initWithProxy:(NSDictionary *)proxyDict
timeout:(UInt32)timeout
urlConverter:(QNUrlConvert)converter
dns:(QNDnsManager *)dns;
- (void)multipartPost:(NSString *)url
withData:(NSData *)data
withParams:(NSDictionary *)params
withFileName:(NSString *)key
withMimeType:(NSString *)mime
withCompleteBlock:(QNCompleteBlock)completeBlock
withProgressBlock:(QNInternalProgressBlock)progressBlock
withCancelBlock:(QNCancelBlock)cancelBlock
withAccess:(NSString *)access;
- (void)post:(NSString *)url
withData:(NSData *)data
withParams:(NSDictionary *)params
withHeaders:(NSDictionary *)headers
withCompleteBlock:(QNCompleteBlock)completeBlock
withProgressBlock:(QNInternalProgressBlock)progressBlock
withCancelBlock:(QNCancelBlock)cancelBlock
withAccess:(NSString *)access;
- (void)get:(NSString *)url
withHeaders:(NSDictionary *)headers
withCompleteBlock:(QNCompleteBlock)completeBlock;
@end
#endif

View File

@@ -0,0 +1,333 @@
//
// QNHttpManager.m
// QiniuSDK
//
// Created by bailong on 14/10/1.
// Copyright (c) 2014 Qiniu. All rights reserved.
//
#import "AFNetworking.h"
#import "HappyDNS.h"
#import "QNAsyncRun.h"
#import "QNConfiguration.h"
#import "QNResponseInfo.h"
#import "QNSessionManager.h"
#include "QNSystem.h"
#import "QNUserAgent.h"
#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)
@interface QNProgessDelegate : NSObject
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context;
@property (nonatomic, strong) QNInternalProgressBlock progressBlock;
@property (nonatomic, strong) NSProgress *progress;
@property (nonatomic, strong) NSURLSessionUploadTask *task;
@property (nonatomic, strong) QNCancelBlock cancelBlock;
- (instancetype)initWithProgress:(QNInternalProgressBlock)progressBlock;
@end
static NSURL *buildUrl(NSString *host, NSNumber *port, NSString *path) {
port = port == nil ? [NSNumber numberWithInt:80] : port;
NSString *p = [[NSString alloc] initWithFormat:@"http://%@:%@%@", host, port, path];
return [[NSURL alloc] initWithString:p];
}
static BOOL needRetry(NSHTTPURLResponse *httpResponse, NSError *error) {
if (error != nil) {
return error.code < -1000;
}
if (httpResponse == nil) {
return YES;
}
int status = (int)httpResponse.statusCode;
return status >= 500 && status < 600 && status != 579;
}
@implementation QNProgessDelegate
- (instancetype)initWithProgress:(QNInternalProgressBlock)progressBlock {
if (self = [super init]) {
_progressBlock = progressBlock;
_progress = nil;
}
return self;
}
- (void)valueChange:(NSProgress *)uploadProgress {
_progressBlock(uploadProgress.completedUnitCount, uploadProgress.totalUnitCount);
if (_cancelBlock && _cancelBlock()) {
[_task cancel];
}
}
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context;
{
if (context == nil || object == nil) {
return;
}
NSProgress *progress = (NSProgress *)object;
void *p = (__bridge void *)(self);
if (p == context) {
_progressBlock(progress.completedUnitCount, progress.totalUnitCount);
if (_cancelBlock && _cancelBlock()) {
[_task cancel];
}
} else {
[super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
}
}
@end
@interface QNSessionManager ()
@property (nonatomic) AFHTTPSessionManager *httpManager;
@property UInt32 timeout;
@property (nonatomic, strong) QNUrlConvert converter;
@property bool noProxy;
@property (nonatomic) QNDnsManager *dns;
@end
@implementation QNSessionManager
- (instancetype)initWithProxy:(NSDictionary *)proxyDict
timeout:(UInt32)timeout
urlConverter:(QNUrlConvert)converter
dns:(QNDnsManager *)dns {
if (self = [super init]) {
if (proxyDict != nil) {
_noProxy = NO;
} else {
_noProxy = YES;
}
_httpManager = [QNSessionManager httpManagerWithProxy:proxyDict];
_timeout = timeout;
_converter = converter;
_dns = dns;
}
return self;
}
+ (AFHTTPSessionManager *)httpManagerWithProxy:(NSDictionary *)proxyDict {
NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
if (proxyDict != nil) {
configuration.connectionProxyDictionary = proxyDict;
}
AFHTTPSessionManager *httpManager = [[AFHTTPSessionManager alloc] initWithSessionConfiguration:configuration];
httpManager.responseSerializer = [AFHTTPResponseSerializer serializer];
return httpManager;
}
- (instancetype)init {
return [self initWithProxy:nil timeout:60 urlConverter:nil dns:nil];
}
+ (QNResponseInfo *)buildResponseInfo:(NSHTTPURLResponse *)response
withError:(NSError *)error
withDuration:(double)duration
withResponse:(NSData *)body
withHost:(NSString *)host
withIp:(NSString *)ip {
QNResponseInfo *info;
if (response) {
int status = (int)[response statusCode];
NSDictionary *headers = [response allHeaderFields];
NSString *reqId = headers[@"X-Reqid"];
NSString *xlog = headers[@"X-Log"];
NSString *xvia = headers[@"X-Via"];
if (xvia == nil) {
xvia = headers[@"X-Px"];
}
if (xvia == nil) {
xvia = headers[@"Fw-Via"];
}
info = [[QNResponseInfo alloc] init:status withReqId:reqId withXLog:xlog withXVia:xvia withHost:host withIp:ip withDuration:duration withBody:body];
} else {
info = [QNResponseInfo responseInfoWithNetError:error host:host duration:duration];
}
return info;
}
- (void)sendRequest:(NSMutableURLRequest *)request
withCompleteBlock:(QNCompleteBlock)completeBlock
withProgressBlock:(QNInternalProgressBlock)progressBlock
withCancelBlock:(QNCancelBlock)cancelBlock
withAccess:(NSString *)access {
__block NSDate *startTime = [NSDate date];
NSString *domain = request.URL.host;
NSString *u = request.URL.absoluteString;
NSURL *url = request.URL;
NSArray *ips = nil;
if (_converter != nil) {
url = [[NSURL alloc] initWithString:_converter(u)];
request.URL = url;
domain = url.host;
} else if (_noProxy && _dns != nil && [url.scheme isEqualToString:@"http"]) {
if (isIpV6FullySupported() || ![QNIP isV6]) {
ips = [_dns queryWithDomain:[[QNDomain alloc] init:domain hostsFirst:NO hasCname:YES maxTtl:1000]];
double duration = [[NSDate date] timeIntervalSinceDate:startTime];
if (ips == nil || ips.count == 0) {
NSError *error = [[NSError alloc] initWithDomain:domain code:-1003 userInfo:@{ @"error" : @"unkonwn host" }];
QNResponseInfo *info = [QNResponseInfo responseInfoWithNetError:error host:domain duration:duration];
NSLog(@"failure %@", info);
completeBlock(info, nil);
return;
}
}
}
[self sendRequest2:request withCompleteBlock:completeBlock withProgressBlock:progressBlock withCancelBlock:cancelBlock withIpArray:ips withIndex:0 withDomain:domain withRetryTimes:3 withStartTime:startTime withAccess:access];
}
- (void)sendRequest2:(NSMutableURLRequest *)request
withCompleteBlock:(QNCompleteBlock)completeBlock
withProgressBlock:(QNInternalProgressBlock)progressBlock
withCancelBlock:(QNCancelBlock)cancelBlock
withIpArray:(NSArray *)ips
withIndex:(int)index
withDomain:(NSString *)domain
withRetryTimes:(int)times
withStartTime:(NSDate *)startTime
withAccess:(NSString *)access {
NSURL *url = request.URL;
__block NSString *ip = nil;
if (ips != nil) {
ip = [ips objectAtIndex:(index % ips.count)];
NSString *path = url.path;
if (path == nil || [@"" isEqualToString:path]) {
path = @"/";
}
url = buildUrl(ip, url.port, path);
[request setValue:domain forHTTPHeaderField:@"Host"];
}
request.URL = url;
[request setTimeoutInterval:_timeout];
[request setValue:[[QNUserAgent sharedInstance] getUserAgent:access] forHTTPHeaderField:@"User-Agent"];
[request setValue:nil forHTTPHeaderField:@"Accept-Language"];
if (progressBlock == nil) {
progressBlock = ^(long long totalBytesWritten, long long totalBytesExpectedToWrite) {
};
}
QNInternalProgressBlock progressBlock2 = ^(long long totalBytesWritten, long long totalBytesExpectedToWrite) {
progressBlock(totalBytesWritten, totalBytesExpectedToWrite);
};
__block QNProgessDelegate *delegate = [[QNProgessDelegate alloc] initWithProgress:progressBlock2];
NSURLSessionUploadTask *uploadTask = [_httpManager uploadTaskWithRequest:request fromData:nil progress:^(NSProgress *_Nonnull uploadProgress) {
[delegate valueChange:uploadProgress];
}
completionHandler:^(NSURLResponse *response, id responseObject, NSError *error) {
NSData *data = responseObject;
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;
double duration = [[NSDate date] timeIntervalSinceDate:startTime];
QNResponseInfo *info;
NSDictionary *resp = nil;
if (_converter != nil && _noProxy && (index + 1 < ips.count || times > 0) && needRetry(httpResponse, error)) {
[self sendRequest2:request withCompleteBlock:completeBlock withProgressBlock:progressBlock withCancelBlock:cancelBlock withIpArray:ips withIndex:index + 1 withDomain:domain withRetryTimes:times - 1 withStartTime:startTime withAccess:access];
return;
}
if (error == nil) {
info = [QNSessionManager buildResponseInfo:httpResponse withError:nil withDuration:duration withResponse:data withHost:domain withIp:ip];
if (info.isOK) {
NSError *tmp;
resp = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableLeaves error:&tmp];
}
} else {
info = [QNSessionManager buildResponseInfo:httpResponse withError:error withDuration:duration withResponse:data withHost:domain withIp:ip];
}
completeBlock(info, resp);
}];
delegate.task = uploadTask;
delegate.cancelBlock = cancelBlock;
[uploadTask resume];
}
- (void)multipartPost:(NSString *)url
withData:(NSData *)data
withParams:(NSDictionary *)params
withFileName:(NSString *)key
withMimeType:(NSString *)mime
withCompleteBlock:(QNCompleteBlock)completeBlock
withProgressBlock:(QNInternalProgressBlock)progressBlock
withCancelBlock:(QNCancelBlock)cancelBlock
withAccess:(NSString *)access {
NSMutableURLRequest *request = [_httpManager.requestSerializer multipartFormRequestWithMethod:@"POST"
URLString:url
parameters:params
constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
[formData appendPartWithFileData:data name:@"file" fileName:key mimeType:mime];
}
error:nil];
[self sendRequest:request withCompleteBlock:completeBlock withProgressBlock:progressBlock withCancelBlock:cancelBlock
withAccess:access];
}
- (void)post:(NSString *)url
withData:(NSData *)data
withParams:(NSDictionary *)params
withHeaders:(NSDictionary *)headers
withCompleteBlock:(QNCompleteBlock)completeBlock
withProgressBlock:(QNInternalProgressBlock)progressBlock
withCancelBlock:(QNCancelBlock)cancelBlock
withAccess:(NSString *)access {
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[[NSURL alloc] initWithString:url]];
if (headers) {
[request setAllHTTPHeaderFields:headers];
}
[request setHTTPMethod:@"POST"];
if (params) {
[request setValuesForKeysWithDictionary:params];
}
[request setHTTPBody:data];
QNAsyncRun(^{
[self sendRequest:request
withCompleteBlock:completeBlock
withProgressBlock:progressBlock
withCancelBlock:cancelBlock
withAccess:access];
});
}
- (void)get:(NSString *)url
withHeaders:(NSDictionary *)headers
withCompleteBlock:(QNCompleteBlock)completeBlock {
QNAsyncRun(^{
NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:configuration];
NSURL *URL = [NSURL URLWithString:url];
NSURLRequest *request = [NSURLRequest requestWithURL:URL];
NSURLSessionDataTask *dataTask = [manager dataTaskWithRequest:request completionHandler:^(NSURLResponse *response, id responseObject, NSError *error) {
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;
NSData *s = [@"{}" dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary *resp = nil;
QNResponseInfo *info;
if (error == nil) {
info = [QNSessionManager buildResponseInfo:httpResponse withError:nil withDuration:0 withResponse:s withHost:@"" withIp:@""];
if (info.isOK) {
resp = responseObject;
}
} else {
info = [QNSessionManager buildResponseInfo:httpResponse withError:error withDuration:0 withResponse:s withHost:@"" withIp:@""];
}
completeBlock(info, resp);
}];
[dataTask resume];
});
}
@end
#endif

View File

@@ -0,0 +1,37 @@
//
// QNUserAgent.h
// QiniuSDK
//
// Created by bailong on 14-9-29.
// Copyright (c) 2014年 Qiniu. All rights reserved.
//
#import <Foundation/Foundation.h>
/**
* UserAgent
*
*/
@interface QNUserAgent : NSObject
/**
* 用户id
*/
@property (copy, nonatomic, readonly) NSString *id;
/**
* UserAgent 字串
*/
- (NSString *)description;
/**
* UserAgent + AK 字串
*/
- (NSString *)getUserAgent:(NSString *)access;
/**
* 单例
*/
+ (instancetype)sharedInstance;
@end

View File

@@ -0,0 +1,86 @@
//
// QNUserAgent.m
// QiniuSDK
//
// Created by bailong on 14-9-29.
// Copyright (c) 2014 Qiniu. All rights reserved.
//
#import <Foundation/Foundation.h>
#if __IPHONE_OS_VERSION_MIN_REQUIRED
#import <MobileCoreServices/MobileCoreServices.h>
#import <UIKit/UIKit.h>
#else
#import <CoreServices/CoreServices.h>
#endif
#import "QNUserAgent.h"
#import "QNVersion.h"
static NSString *qn_clientId(void) {
#if __IPHONE_OS_VERSION_MIN_REQUIRED
NSString *s = [[[UIDevice currentDevice] identifierForVendor] UUIDString];
if (s == nil) {
s = @"simulator";
}
return s;
#else
long long now_timestamp = [[NSDate date] timeIntervalSince1970] * 1000;
int r = arc4random() % 1000;
return [NSString stringWithFormat:@"%lld%u", now_timestamp, r];
#endif
}
static NSString *qn_userAgent(NSString *id, NSString *ak) {
#if __IPHONE_OS_VERSION_MIN_REQUIRED
return [NSString stringWithFormat:@"QiniuObject-C/%@ (%@; iOS %@; %@; %@)", kQiniuVersion, [[UIDevice currentDevice] model], [[UIDevice currentDevice] systemVersion], id, ak];
#else
return [NSString stringWithFormat:@"QiniuObject-C/%@ (Mac OS X %@; %@; %@)", kQiniuVersion, [[NSProcessInfo processInfo] operatingSystemVersionString], id, ak];
#endif
}
@interface QNUserAgent ()
@property (nonatomic) NSString *ua;
@end
@implementation QNUserAgent
- (NSString *)description {
return _ua;
}
- (instancetype)init {
if (self = [super init]) {
_id = qn_clientId();
}
return self;
}
/**
* UserAgent
*/
- (NSString *)getUserAgent:(NSString *)access {
NSString *ak;
if (access == nil || access.length == 0) {
ak = @"-";
} else {
ak = access;
}
return qn_userAgent(_id, ak);
}
/**
*
*/
+ (instancetype)sharedInstance {
static QNUserAgent *sharedInstance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedInstance = [[self alloc] init];
});
return sharedInstance;
}
@end