Signed-off-by: Dan Thorpe firstname.lastname@example.org
Provides a userInfo to AFURLConnectionOperation objects.
Signed-off-by: Dan Thorpe <email@example.com>
Hi, thanks for your pull request. Could you explain what use case you were designing with this addition?
Hey Matt. Firstly: love the code.
I often need to have a dependent NSBlockOperation which does processing after an AFHTTPRequestOperation completes (usually save an NSManagedObjectContext), or when a group of related operations complete. And in some cases I need to trigger additional networking requests while processing responses of previous ones. So, I need a way to add these additional request operations as dependencies of the NSBlockOperation. So, I'm setting that NSBlockOperation in the request's userInfo dictionary.
If there is another way to do that, then, I'd love to hear your thoughts.
Oh, in that case, I'd like to point you to a feature I've been working on recently: batched operations. If I'm understanding your needs correctly, I think this would cut down considerably on the amount and complexity of your code.
As for saving and processing managed object contexts, my preferred approach is to use dispatch queues rather than block operations. That's what we did in Gowalla 4, and I know that MagicalRecord takes a similar approach.
I just refactored my code from dispatch groups/queues to NSOperations and I actually much prefer it. Previously, I was solving this particular problem by passing around dispatch_group_t objects, and while that wasn't really a problem, I was having some annoying edge case issues. I'll checkout your batched operations branch tomorrow and see how it changes things.
The userInfo dictionary is a simple addition that made the batching of existing, and new operations quite easy. But I can see how it could get abused, and why you might be reluctant to add it.
So, I had a look at your batched operations branch. The way I've done this in my own class, sort of an HTTPClient class, is pass in a block, which returns an NSArray of AFHTTPRequestOperations, and a MOC, and a completion block. This allows me to have completion blocks for each individual request operation, and a completion for the group. The only thing I don't get is the progress counts.
However, that's not really why I need a userInfo dictionary. The problem is that I perform work in the completion handlers of each request operation. And this work can in some cases trigger another operation. So, I need a way of adding this operation as an additional dependency of the overall completion block. And there is no way to get to that object, unless I pass it along in a userInfo dictionary with each request operation... Essentially it greedily consumes a webservice. It works quite well.
I'll have a look at what they do in Magical Record...
While I'm not completely clear about the limitations of batching in your particular implementation, I trust your understanding that determined that userInfo was the correct solution for your needs.
That said, and like you mentioned earlier, I'm hesitant to add this into core, for fear of it being misunderstood / abused. In most cases, passing userInfo is a symptom of an underlying crack in an API's design. Until that breaking use case is shown to be something that a lot of people are encountering, I'll leave it as an exercise to the end-user.
Thanks again for submitting your patch, Daniel.
[Issue #686][Issue #168] Adding userInfo @property /cc @tewha