2

我正在使用 NSURLSessionUploadTask 上传多个文件。我想在后台运行相同的进程,它适用于当前文件。在当前文件成功上传之前,应用程序不会暂停。现在,当第二个文件上传时,它不会开始上传过程,直到我再次启动或应用程序变得活跃。上传不会介于两者之间,这很好。第一次完成时有什么方法可以开始下一个上传过程。第二次上传也在后台开始,但从应用程序进入后台最多可以工作 3 分钟。这里我展示了我的代码:

AppDelegate.h
@property (nonatomic, copy) void(^backgroundTransferCompletionHandler)();

AppDelegate.m
- (void)applicationDidEnterBackground:(UIApplication *)application{
    __block UIBackgroundTaskIdentifier backgroundTaskIdentifier = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{

    NSLog(@"Background Time:%f",[[UIApplication sharedApplication] backgroundTimeRemaining]);

    [[UIApplication sharedApplication] endBackgroundTask:backgroundTaskIdentifier];
    backgroundTaskIdentifier = backgroundTaskIdentifier;
    `enter code here`}];
    }

-(void)application:(UIApplication *)application handleEventsForBackgroundURLSession:(NSString *)identifier completionHandler:(void (^)())completionHandler{
    self.backgroundTransferCompletionHandler = completionHandler;
    NSLog(@"handleEventsForBackgroundURLSession called");
}

- (void)URLSessionDidFinishEventsForBackgroundURLSession:(NSURLSession *)session{
    AppDelegate *appDelegate2 = (AppDelegate *)[[UIApplication sharedApplication] delegate];
    NSLog(@"URLSessionDidFinishEventsForBackgroundURLSession call in app delegate");
    [session getTasksWithCompletionHandler:^(NSArray *dataTasks, NSArray *uploadTasks, NSArray *downloadTasks) {
        NSLog(@"uploadTasks: %@",uploadTasks);
        if ([uploadTasks count] == 0) {
            if (appDelegate2.backgroundTransferCompletionHandler != nil) {
                // Copy locally the completion handler.
                void(^completionHandler)() = appDelegate2.backgroundTransferCompletionHandler;

                // Make nil the backgroundTransferCompletionHandler.
                appDelegate2.backgroundTransferCompletionHandler = nil;

                [[NSOperationQueue mainQueue] addOperationWithBlock:^{
                // Call the completion handler to tell the system that there are no other background transfers.
                completionHandler();
                NSLog(@"All tasks are finished");
            }];
        }
    }
    else{

    }
}];
}


UploadView.m
- (NSURLSession *)backgroundSession {
    static NSURLSession *session = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
    NSInteger randomNumber = arc4random() % 1000000;
    //        NSURLSessionConfiguration *sessionConfiguration = [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:[NSString stringWithFormat:@"com.example.apple-samplecode.SimpleBackgroundTransfer.BackgroundSession%d",(int)randomNumber]];
    NSURLSessionConfiguration *sessionConfiguration = [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:[NSString stringWithFormat:@"com.upload.myapp.BackgroundSession%d",(int)randomNumber]];

    sessionConfiguration.sessionSendsLaunchEvents = YES;
    sessionConfiguration.HTTPMaximumConnectionsPerHost = 1;
    // Define the Upload task
    [sessionConfiguration setHTTPAdditionalHeaders: @{@"Accept": @"text/html"}];
    sessionConfiguration.timeoutIntervalForRequest = 600.0;
//        sessionConfiguration.networkServiceType = NSURLNetworkServiceTypeBackground;
//        sessionConfiguration.discretionary = YES;
    sessionConfiguration.allowsCellularAccess = YES;
    session = [NSURLSession sessionWithConfiguration:sessionConfiguration delegate:self delegateQueue:[NSOperationQueue mainQueue]];
});
return session;
}

ViewDidLoad(){
....
self.uploadSession = [self backgroundSession];
....}


-UploadStart(){//here i am calling this function in loop. When first file got uploaded, control comes here for second task and then upload should continue.
    self.uploadTask = [self.uploadSession uploadTaskWithRequest:requestUpload fromFile:[NSURL fileURLWithPath:tmpfile]]; // self.uploadTask is an object of NSURLSessionUploadTask
}

- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didSendBodyData:(int64_t)bytesSent totalBytesSent:(int64_t)totalBytesSent totalBytesExpectedToSend:(int64_t)totalBytesExpectedToSend {
}

- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data
{
    NSLog(@"didReceiveData Task: %@ upload complete", dataTask);
    NSHTTPURLResponse *httpResp = (NSHTTPURLResponse*) self.uploadTask.response;
    if (httpResp.statusCode == 200) {
         uploadedFiles++; //an int value
         if(uploadedFiles==arrUpload.count){
             //all files uploaded here
         }
         else{
             //upload next file from here
         }
    }
}

- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error {

}

- (void)URLSessionDidFinishEventsForBackgroundURLSession:(NSURLSession *)session{
    NSLog(@"URLSessionDidFinishEventsForBackgroundURLSession called");
    AppDelegate *appDelegate2 = (AppDelegate *)[[UIApplication sharedApplication] delegate];
    if (appDelegate2.backgroundTransferCompletionHandler != nil) {
        // Copy locally the completion handler.
        void(^completionHandler)() = appDelegate2.backgroundTransferCompletionHandler;

        // Make nil the backgroundTransferCompletionHandler.
        appDelegate2.backgroundTransferCompletionHandler = nil;

        [[NSOperationQueue mainQueue] addOperationWithBlock:^{
            // Call the completion handler to tell the system that there are no other background transfers.
            completionHandler();
            NSLog(@"All tasks are finished");
        }];
    }
}

上面的代码完全可以工作,但是在 App 后台模式 3 分钟后,下一个文件没有开始在后台上传。

任何帮助将不胜感激。在此先感谢...有关更多说明,请与我联系。

4

0 回答 0