NSURLSession 委托跨类拆分 - NSURLSession、NSURLUploadTask、NSURLDownloadTask
Posted
技术标签:
【中文标题】NSURLSession 委托跨类拆分 - NSURLSession、NSURLUploadTask、NSURLDownloadTask【英文标题】:NSURLSession Delegates split across classes - NSURLSession, NSURLUploadTask, NSURLDownloadTask 【发布时间】:2015-09-04 03:46:29 【问题描述】:我正在为我的应用创建上传/下载媒体功能。我的上传队列工作正常,但是当我添加下载和必要的下载委托时,上传委托被称为事件,尽管任务是下载。 我最初的类结构是一个单例 QueueController,它具有 NSURLSession 和委托(但不下载)以及可以保存上传或下载的 TransferModel。 当我尝试添加下载时,回调无法正常工作,因此我将与传输相关的委托放在两个子类 TransferUploadModel 和 TransferDownloadModel 中,但现在我的委托没有触发。
这是我的方法签名的样子: 队列控制器:
@interface QueueController : NSObject<NSURLSessionDelegate>
@property(nonatomic, weak) NSObject<QueueControllerDelegate>* delegate;
@property(atomic, strong) NSURLSession* session;
@property(nonatomic) NSURLSessionConfiguration* configuration;
+ (QueueController*)sharedInstance;
@end
@implementation QueueController
- (void)application:(UIApplication *)application
handleEventsForBackgroundURLSession:(NSString *)identifier
completionHandler:(void (^)(void))completionHandler
//...
TransferUploadModel:
@interface TransferUploadModel : TransferModel <NSURLSessionTaskDelegate,
NSURLSessionDataDelegate>
//...
@end
//Note TransferModel is a subclass of NSOperation
@implementation TransferUploadModel
- (id)initWithMedia:(MediaItem*)mediaItem_
withTransferType:(TransferType)transferType_
andWiths3Path:s3Path_
andWiths3file_name:s3file_name_
andWithNSURLSession:session
- (void)main
//NSOperation override
//
// Transfer upload started
//
- (void)uploadMedia
/**
* Fetch signed URL
*/
AWSS3GetPreSignedURLRequest *getPreSignedURLRequest = [AWSS3GetPreSignedURLRequest new];
getPreSignedURLRequest.bucket = BUCKET_NAME;
getPreSignedURLRequest.key = @"mypic.jpeg";
getPreSignedURLRequest.HTTPMethod = AWSHTTPMethodPUT;
getPreSignedURLRequest.expires = [NSDate dateWithTimeIntervalSinceNow:3600];
// Important: must set contentType for PUT request
getPreSignedURLRequest.contentType = self.content_type;
NSLog(@"headers: %@", getPreSignedURLRequest);
/**
* Upload the file
*/
[[[AWSS3PreSignedURLBuilder defaultS3PreSignedURLBuilder] getPreSignedURL:getPreSignedURLRequest] continueWithBlock:^id(AWSTask *task)
if (task.error)
NSLog(@"Error: %@", task.error);
else
NSURL* presignedURL = task.result;
NSLog(@"upload presignedURL is: \n%@", presignedURL);
NSMutableURLRequest* request = [NSMutableURLRequest requestWithURL:presignedURL];
request.cachePolicy = NSURLRequestReloadIgnoringLocalCacheData;
[request setHTTPMethod:@"PUT"];
[request setValue:self.content_type forHTTPHeaderField:@"Content-Type"];
@try
self.nsurlSessionUploadTask = [self.nsurlSession uploadTaskWithRequest:request
fromFile:self.mediaCopyURL];
[self.nsurlSessionUploadTask resume];
//
// Delegates don't fire after this...
//
@catch (NSException* exception)
NSLog(@"exception creating upload task: %@", exception);
return nil;
];
//
// NSURLSessionDataDelegate : didReceiveData
//
- (void)URLSession:(NSURLSession *)session
dataTask:(NSURLSessionDataTask *)dataTask
didReceiveData:(NSData *)data
NSLog(@"...");
//
// Initial response from server with headers
//
- (void)URLSession:(NSURLSession *)session
dataTask:(NSURLSessionDataTask *)dataTask
didReceiveResponse:(NSURLResponse *)response
completionHandler:
(void (^)(NSURLSessionResponseDisposition disposition))completionHandler
NSLog(@"response.description:%@", response.description);
completionHandler(NSURLSessionResponseAllow);
//
// Upload transfer in progress
//
- (void)URLSession:(NSURLSession *)session
task:(NSURLSessionUploadTask *)task
didSendBodyData:(int64_t)bytesSent
totalBytesSent:(int64_t)totalBytesSent
totalBytesExpectedToSend:(int64_t)totalBytesExpectedToSend
@try
NSLog(@"...");
@catch (NSException *exception)
NSLog(@"%s exception: %@", __PRETTY_FUNCTION__, exception);
//
// Upload transfer completed
//
- (void)URLSession:(NSURLSession *)session
task:(NSURLSessionTask *)task
didCompleteWithError:(NSError *)error
NSLog(@"...");
// end URLSession:session:task:error
@end
非常感谢任何帮助。
谢谢, J
【问题讨论】:
【参考方案1】:好的,我发现如果我将 NSURLSession 移动到 TransferUploadModel 和 TransferDownloadModel 中,那么代表会被调用。由于这些模型在队列中很多,我这样初始化:
@implementation TransferUploadModel
static NSURLSession *session = nil;
static dispatch_once_t onceToken;
- (id) init
self = [super init];
dispatch_once(&onceToken, ^
NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:@"transferUploadQueue"];
configuration.sessionSendsLaunchEvents = YES;
configuration.discretionary = YES;
session = [NSURLSession sessionWithConfiguration:configuration delegate:self delegateQueue:nil];
);
self.session = session;
//...
@end
谢谢, 约翰
【讨论】:
以上是关于NSURLSession 委托跨类拆分 - NSURLSession、NSURLUploadTask、NSURLDownloadTask的主要内容,如果未能解决你的问题,请参考以下文章
Xcode 7.3:NSURLSession/NSURLConnection HTTP 加载失败(kCFStreamErrorDomainSSL,-9802)