【问题标题】:NSURLSession Delegates split across classes - NSURLSession, NSURLUploadTask, NSURLDownloadTaskNSURLSession 委托跨类拆分 - 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

【问题讨论】:

    标签: nsurlsession nsurlsessiondownloadtask nsurlsessionuploadtask


    【解决方案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
    

    谢谢, 约翰

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-02-07
      • 1970-01-01
      • 2016-06-04
      • 1970-01-01
      相关资源
      最近更新 更多