When tasks are created on a concurrent queue, incorrect completionHandlers can get called. #2093
Comments
Would it make sense for AFNetworking to manage its own internal serial queue, and dispatch all task creation calls into that? |
Yeah, that would certainly work. I'll update this task if my radar gets closed.
|
…asks to prevent bug where NSURLSession creates tasks with non-unique identifiers (see radr://5871104061079552)
Implemented the aforementioned serial queue solution in a563ca0. Let me know if you see any problems or have any suggestions on how to improve it. Thanks! |
Just FYI, this bug is fixed in iOS 8. |
@matt, we know that bug fixed in iOS 8+, should we support creation_queue in iOS 8+ versions?
|
We could potentially go down that route. If you wanted to work up a PR on the 3.0.0 branch, I'd be happy to review it! |
@kcharwood, it's a good idea, i'll try to deliver this fix on this weekend! |
…f iOS 7 version with additional logic of fixing Apple bug in NSURLSession. More about: Open Radar: http://openradar.appspot.com/radar?id=5871104061079552 (status: Fixed in iOS8) Issue: AFNetworking#2093
Static Analyzer raised a warning that `uploadTaskWithRequest:fromFile:progress:completionHandler:` can return `nil` although its return type is not nullable. The method `url_session_manager_create_task_safely` is receiving a block that runs the uploading task under the conditions: if iOS == 7.x: create synchronously task on serial creation_queue. if iOS >= 8.x: just create the task. in order to overcome another iOS 7 bug: AFNetworking#2093 However the workaround attempts that should overcome another bug: AFNetworking#1675 are not inside the safely method.
`uploadTaskWithRequest:fromFile:progress:completionHandler:` can return `nil` although its return type is declared to be nonnull. Inside `uploadTaskWithRequest:fromFile:progress:completionHandler:` the creation of the upload task is done using the method `url_session_manager_create_task_safely` passing it a block that creates the task. This function is used to workaround a bug in iOS 7.x (AFNetworking#2093), where task creation must be performed on a single thread. However there's another bug in iOS < 8.0 that causes `NSURLSession` to sometimes return `nil` when creating a file upload task (AFNetworking#1675). This bug has another workaround that retry to create the task few more times. However these retry attempts are not executed via the safety function mentioned above, potentially reinstating the other iOS 7 bug. This commit moves the task creation retry attempts to inside the block that is sent to `url_session_manager_create_task_safely` and thus ensuring retry attempts if needed, will also run on the designated queue.
Static analyzer raises a warning that `uploadTaskWithRequest:fromFile:progress:completionHandler:` can return `nil` although its return type is declared to be nonnull. Inside `uploadTaskWithRequest:fromFile:progress:completionHandler:` the creation of the upload task is done using the method `url_session_manager_create_task_safely` passing it a block that creates the task. This function is used to workaround a bug in iOS 7.x (AFNetworking#2093), where task creation must be performed on a single thread. However there's another bug in iOS < 8.0 that causes `NSURLSession` to sometimes return `nil` when creating a file upload task (AFNetworking#1675). This bug has another workaround that retry to create the task few more times. However these retry attempts are not executed via the safety function mentioned above, potentially reinstating the other iOS 7 bug. This commit moves the task creation retry attempts to inside the block that is sent to `url_session_manager_create_task_safely` and thus ensuring retry attempts if needed, will also run on the designated queue.
Due to this bug: http://openradar.appspot.com/radar?id=5871104061079552 in NSURLSessionTask, creating tasks on a concurrent queue can cause incorrect completionHandlers to get called.
When a duplicate taskIdentifier is returned by the task, the previous completionHandler gets cleared out and replaced with the new one. If the data for the first request comes back before the second request's data, the first response is then called against the second completionHandler.
I'm not sure what AFNetworking should do here — it could enforce creating tasks on a serial queue or it could just advise people to do so. We could also add a test to assert that the taskIdentifier is not a duplicate?
The text was updated successfully, but these errors were encountered: