-->

Background Upload With Stream Request Using NSUrlS

2019-02-20 08:34发布

问题:

Previously in iOS7 when we try to upload with stream request in background we get following exception

Terminating app due to uncaught exception 'NSGenericException', reason: 'Upload tasks in background sessions must be from a file'

But in iOS8 there is no exception when we try to upload with stream in background.

Now my question is

1) Is backgourd upload with uploadTaskWithStreamedRequest: allowed in iOS8?

2) In iOS8 i am using background NSURLConfiguration with uploadTaskWithStreamedRequest. I am using -(void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task needNewBodyStream:(void (^)(NSInputStream *))completionHandler to provide stream to NSUrlSession. When app is in foreground it is working fine and uploading my file to the server. But as soon as the app igoes in background the stream ends and NSURLSession completes with following error

Error Domain=NSURLErrorDomain Code=-997 "Lost connection to background transfer service"

I think when app goes in background my stream ends. Now my question is that in which runloop should I should I schedule my Stream or let me know if there is any mistake in my understanding.

-(void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task needNewBodyStream:(void (^)(NSInputStream *))completionHandler
{
    // Open producer/consumer streams.  We open the producerStream straight
    // away.  We leave the consumerStream alone; NSURLConnection will deal
    // with it.
    NSLog(@"%@", [NSThread currentThread]);
    NSInputStream *consStream;
    NSOutputStream *prodStream;
    [NSStream createBoundInputStream:&consStream outputStream:&prodStream bufferSize:SFAMaxBufferLength];
    assert(consStream != nil);
    assert(prodStream != nil);
    self.consumerStream = consStream;
    self.producerStream = prodStream;
    self.producerStream.delegate = self;
    [self.producerStream scheduleInRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
    [self.producerStream open];
    // Set up our state to send the body prefix first.
    self.buffer = [self.bodyPrefixData bytes];
    self.bufferLimit = [self.bodyPrefixData length];
    completionHandler(self.consumerStream);
}

回答1:

You can't upload streamed tasks using Background Configuration. I successfully upload data only in two cases:

  1. Download task with data stored in request body.
  2. Upload task from file. In that case you will not receive response body.


回答2:

You can upload a multipart file in background - just that this is not straight forward. Refer: AFNetworking error in uploadTaskWithStreamedRequest