Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NSURLSession Delegate Queue

This seems weird. I can't seem to seem to successfully set an NSURLSession's delegateQueue on creation.

- (void)viewDidLoad
{
    [super viewDidLoad];

    NSOperationQueue *queue = [[NSOperationQueue alloc] init];
    queue.maxConcurrentOperationCount = 5;

    NSLog(@"The queue before: %@", queue);
    NSLog(@"Max op Count before: %i", queue.maxConcurrentOperationCount);

    NSURLSession *session = [NSURLSession sessionWithConfiguration:nil
                                                          delegate:self
                                                     delegateQueue:queue];

    NSLog(@"The queue after: %@", session.delegateQueue);
    NSLog(@"Max op Count after : %i", session.delegateQueue.maxConcurrentOperationCount);
}

This results in the following output.

The queue before: <NSOperationQueue:   0x16d99160>{name = 'NSOperationQueue 0x16d99160'}
Max op Count before: 5
The queue after: <NSOperationQueue: 0x16d77a50>{name = 'NSOperationQueue 0x16d77a50'}
Max op Count after : 1

It looks like my delegateQueue is being ignored. I've tried on the device as well as on the simulator. I've haven't found any documentation which would explain this. Does anyone have any insight?

like image 696
Drewsmits Avatar asked Sep 29 '13 04:09

Drewsmits


People also ask

What is delegate queue?

A protocol that defines methods that URL session instances call on their delegates to handle task-level events.

What is Nsurl session?

In iOS 7 and later, NSUrlSession and related classes are the preferred way to transfer larger files to and from the Web. NSUrlSession downloads can work when the application is in the background.

What is Nsurl session WebSocket?

NSURLSessionWebSocketTask is a concrete subclass of NSURLSessionTask that provides a message-oriented transport protocol over TCP and TLS in the form of WebSocket framing. It follows the WebSocket Protocol defined in RFC 6455. You create a NSURLSessionWebSocketTask with either a ws: or wss: URL.


2 Answers

It looks like, despite what the getter for delegateQueue says, the NSURLSession is indeed using your NSOperationQueue. I added KVO for the "operations" property on the queue:

[queue addObserver:self forKeyPath:@"operations" options:NSKeyValueObservingOptionNew context:NULL];

And added the following method:

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
    NSLog(@"%@%@", object, change);
    NSOperationQueue *queue = (NSOperationQueue *)object;

    NSLog(@"The queue in KVO: %@", queue);
    NSLog(@"Max op Count in KVO: %i", queue.maxConcurrentOperationCount);

    NSLog(@"%@", self.session.delegateQueue);

}

And it prints:

2013-09-29 07:45:13.751 sotest1[17214:1403] <NSOperationQueue: 0x895e0c0>{name = 'NSOperationQueue 0x895e0c0'}
2013-09-29 07:45:13.757 sotest1[17214:4207] <NSOperationQueue: 0x98a0940>{name = 'NSOperationQueue 0x98a0940'}{
    kind = 1;
    new =     (
        "<NSBlockOperation: 0x9a52370>"
    );
}
2013-09-29 07:45:13.757 sotest1[17214:4207] The queue in KVO: <NSOperationQueue: 0x98a0940>{name = 'NSOperationQueue 0x98a0940'}
2013-09-29 07:45:13.757 sotest1[17214:4207] Max op Count in KVO: 5

So you can see the delegate does indeed get processed by your queue, despite the fact that the getter says otherwise. Weird.

Btw, the way you're doing it is also exactly AFNetworking does it, which is generally a good sign: https://github.com/AFNetworking/AFNetworking/blob/master/AFNetworking/AFURLSessionManager.m#L287

like image 168
ksimons Avatar answered Nov 23 '22 06:11

ksimons


I confirm the problem on my side I tried to set a queue of 1 element as you did using the maxConcurrentOperationCount=1 on the session I see several tasks running in the same time as described by the logged below in the (URLSession:didWriteData:totalBytesWritten):

NSLog(@"Download %.2f%% task=%d - operationInQueue=%d maxOperation=%d ", result, [downloadTask taskIdentifier], [self.bkgQueue operationCount],[self.bckQueue maxConcurrentOperationCount]);

Download 1.80% task=2 - operationInQueue=2 maxOperation=1 
Download 1.15% task=1 - operationInQueue=1 maxOperation=1 
Download 1.49% task=1 - operationInQueue=1 maxOperation=1 
Download 1.51% task=1 - operationInQueue=1 maxOperation=1 
Download 1.14% task=0 - operationInQueue=1 maxOperation=1 
Download 3.90% task=2 - operationInQueue=2 maxOperation=1 
Download 1.14% task=0 - operationInQueue=1 maxOperation=1 
Download 1.85% task=1 - operationInQueue=1 maxOperation=1 
Download 1.87% task=1 - operationInQueue=1 maxOperation=1 

I also tried to increase this number and a count on my queue=1. It seems it is managing by himself the queue.

like image 25
Nicolas Lauquin Avatar answered Nov 23 '22 06:11

Nicolas Lauquin