AFHTTPClient - Parsing response object - objective-c

I just started using AFNetworking and I'm trying to learn how to do it correctly.
I subclass the AFHTTPClient and created my own MyAppClient with the right base URL.
I'm communicating with my server with HTTP POST request and server response with xml.
for sending a request I do:
[[MyAppClient sharedClient] postPath:somePath parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {
// need to parse the data here...
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
//
NSLog(#"%#", [error localizedDescription]);
}];
Few questions:
Why does the AFHTTPClient use operation if anyway it's using an asynchronous NSURLConnection that doesn't block the main thread?
After I'm getting the data I need to parse it, should I now create a new operation to parse the data?
It seems to me that it would be better to parse the data also in the operation and then return the parsed objects no?
At the same subject I have a custom generic XMLParser class that gets a NSData and parse it to NSDictionary, and I would like to use it for all of the responses, how can I integrate it in the AFHTTPClient AFHTTPRequestOperation so that the response will be already parsed?

Why does the AFHTTPClient use operation if anyway it's using an asynchronous NSURLConnection that doesn't block the main thread?
This is actually an excellent question.
In fact, a viable "HTTPRequestOperation" class is not all required to subclass from NSOperation. The design of AFHTTPRequestOperation is very likely based on the "original" design introduced by an Apple engineer, "Quinn", who invented the first "reference design" with his class QHTTPOperation and provided also a number of invaluable samples - which are still highly recommended and worth to take a look. This first design subclasses a NSOperation and encapsulates a NSURLConnection object.
This design has a number of advantages:
Since it's a subclasses of NSOperation, the network request then looks like an "asynchronous operation". That means basically, the network request then has the principal methods start and cancel and has a completion handler to signal the eventual result of the request. This generic API is important for an asynchronous network operation so that it becomes a more general asynchronous operation.
Since its a class, it encapsulates all related state variables for a request. For example, the request, the response, the response data, an error (if any), and a couple more relevant state variables. The "network request object" then becomes quite handy to use, unlike the delegate approach where it starts to become difficult when more than one request should be handled in the delegate methods in one delegate object.
An NSOperation object can be queued into a NSOperationQueue. This makes it possible to define the order of the requests, and specifically any other operation, and the number of simultaneous active operations (requests) if you have many.
With NSOperation one can define more or less complex dependencies among other operations, which lets you add some additional layer of "business logic". Occasionally, this becomes quite handy to solve more complex asynchronous problems.
So, the question why an already asynchronous NSURLConnection was encapsulated in a subclass of NSOperation are these aforementioned advantages. The reason was never to wrap it like a synchronous function into an NSOperation so that it can be executed in a NSOperationQueue.
In fact, there is a broad misconception about this. It appears, many people think the methods of the network request operation will be executed on the execution context of the NSOperation (for example when added to a NSOperationQueue). However, this is not the case (with possible small exceptions among the various other implementations). The execution context of the methods (mostly delegate methods of NSULRConnection) is a dedicated private thread which will be created by the NSOperation subclass. The lower level functions from the underlaying NSURLConnection also execute on their private execution context (one or more threads) anyway.
Only the start method will be executed on the operation's execution context, which returns quickly. That is, if there is a queue (say dispatch queue or an NSOperationQueue) where the operation has been dispatched, only the start method executes on the queue's execution context.
The NSOperation's isFinished state however, will be deferred up to the point where the network request indeed finished. This state has important meaning for other NSOperation objects and an NSOperationQueue: it signals the queue and other operations that this request has been finished.
So, the NSOperation is less a vehicle to define the execution context of the functions of a network request, but rather a means to organize and setup relations to other operations.
After I'm getting the data I need to parse it, should I now create a new operation to parse the data?
It seems to me that it would be better to parse the data also in the operation and then return the parsed objects no?
Well, you can do that. However, I wouldn't consider this a good design decision: an operation should only process a particular task. The network operation is the one, and the parse task _is another task, which can be an operation, too.
One reason for this is that operations can be "classified" regarding which system resources they mainly require: CPU, memory, IO, etc. Merging different "task types" makes it impossible to take advantage to associate them to dedicated queues in order to control utilization of system resources (see below).
Well, you can make a parse task an operation, of course. Whether this makes sense, depends, though:
The decision whether you want to make a particular task (or function) an NSOperation depends on the following considerations:
An "Operation" is justified, if that task may take a long time to finish (from a user's perspective) and thus you (as a developer) want the user give a chance to cancel the task: (you remember: an asynchronous operation has the principal method cancel)
Another reason would be to associate an operation to a particular execution context which itself is associated to a particular shared and limited system resource - like CPU, memory, IO etc. This lets you control for example the number of parallel executed operations which require a certain system resource. Say, you have a "Disk bound" task. In this case, you may create a NSOperationQueue whose number of concurrent operation is 1, and giving it a particular "role" and a suitable name, for example "DiskBoundQueue". The queue helps you control the creation and the start of operations, and forces a limit of the number of parallel executing operations so that the restricted system resource won't be exhausted. Then, one would add "disk-bound" operations only to the dedicated "DiskBoundQueue". Since a disk operates suboptimal when accessed from different tasks simultaneously, the number of concurrent operations is set to 1. That is, such dedicated queues help optimize utilization of system resources.
If you have dependencies between operations, say you want to start operation C only if operation A AND operation B has been finished successfully. NSOperation provide a means to establish such dependencies.
Yet another reason might be to control concurrent access to shared resources: if there are several operations which access a certain shared resource (an ivar for example) which are added to a serial NSOperationQueue, the access to the shared resource is serialized and thus "thread safe". However if concurrency is the only requirement, I would prefer to use the simpler approach utilizing dispatch queues and blocks.
So, and in order to be more precise regarding your question: no, an NSOperation would be likely oversized. You may be better of to use a dedicated dispatch queue, possibly a serial one which also solves concurrent access of shared resources.
At the same subject I have a custom generic XMLParser class that gets a NSData and parse it to NSDictionary, and I would like to use it for all of the responses, how can I integrate it in the AFHTTPClient AFHTTPRequestOperation so that the response will be already parsed?
A viable approach would just start the XML parser within the completion handler of a AFHTTPRequestOperation or the AFClient for example.
If you have another operation which is dependent on the XML parser's result, then one approach is to encapsulate the XML parser in an NSOperation, and then make the other operation dependent on the XML parser operation. (There are other and simpler solutions for such dependencies, though)

This doesn't immediately make sense. My guess is that using standard mechanisms provides the best performance. However, the success/failure-blocks are also executed in the operation.
I do all the parsing in the success-blocks of the operations. If you use JSON, you can also configure AFNetworking to do the de-/serialization automatically for you. You might want to convert those dictionaries and arrays into smarter classes, though.
Have a look at AFJSONRequestOperation. It might give you some hints.

1) In AFNetworking - Operation is the most granular level. You can either start it or enque them. AFHTTPClient is great if you are enqueuing requests. Look at enqueueOperation
2) AFNetworking keeps it modular. Essentially you are not tied to their parser. You can use any xml parser to parse data. Though I like (DCKeyValue)[https://github.com/dchohfi/KeyValueObjectMapping] to parse your data and directly converting them to objects.
3)You cannot automatically parse like RestKit but answer 2 should help you.

Related

what is nsoperation?how to use it?

I am implementing the contact module basically adding,deleting,searching and listing the contacts.
Here i used file to persist the data like storing all the contacts in file(json format) and deserializing back to the object.
Now my target is to perform serialization and deserialization functions in background thread using nsoperation.And how one class extends nsopertions and what to do in that class.
I am new to mac os.And i cant understand what exactly nsoperation means?how to use it in my module.how to make them run concurrently.I had seen lot of tutorials but still it is very clumsy for me.I am really in need of help.Thanks in advance.
We have lot of answer to your question
What is NSOperation?
First Apple Reference Says
The NSOperation class is an abstract class you use to encapsulate the
code and data associated with a single task. Because it is abstract,
you do not use this class directly but instead subclass or use one of
the system-defined subclasses (NSInvocationOperation or
BlockOperation) to perform the actual task. Despite being abstract,
the base implementation of NSOperation does include significant logic
to coordinate the safe execution of your task. The presence of this
built-in logic allows you to focus on the actual implementation of
your task, rather than on the glue code needed to ensure it works
correctly with other system objects.
Then Simple meaning of NSOperation
NSOperation represents a single unit of work. It’s an abstract class
that offers a useful, thread-safe structure for modeling state,
priority, dependencies, and management.
Do you need to run it concurrently?
What is Concurrency?
Doing multiple things at the same time.
Taking advantage of number of cores available in multicore CPUs.
Running multiple programs in parallel.
Why NSOperationQueue?
For situations where NSOperation doesn’t make sense to build out a
custom NSOperation subclass, Foundation provides the concrete
implementations NSBlockOperation and NSInvocationOperation.
Examples of tasks that lend themselves well to NSOperation include
network requests, image resizing, text processing, or any other
repeatable, structured, long-running task that produces associated
state or data.
But simply wrapping computation into an object doesn’t do much without
a little oversight. That’s where NSOperationQueue comes in
What is NSOperationQueue?
NSOperationQueue regulates the concurrent execution of operations. It
acts as a priority queue, such that operations are executed in a
roughly First-In-First-Out manner, with higher-priority
(NSOperation.queuePriority) ones getting to jump ahead of
lower-priority ones. NSOperationQueue can also limit the maximum
number of concurrent operations to be executed at any given moment,
using the maxConcurrentOperationCount property.
NSOperationQueue itself is backed by a Grand Central Dispatch queue,
though that’s a private implementation detail.
To kick off an NSOperation, either call start, or add it to an
NSOperationQueue, to have it start once it reaches the front of the
queue. Since so much of the benefit of NSOperation is derived from
NSOperationQueue, it’s almost always preferable to add an operation to
a queue rather than invoke start directly.
Also
Operation queues usually provide the threads used to run their
operations. In OS X v10.6 and later, operation queues use the
libdispatch library (also known as Grand Central Dispatch) to initiate
the execution of their operations. As a result, operations are always
executed on a separate thread, regardless of whether they are
designated as concurrent or non-concurrent operations
So your code should be
NSOperationQueue *backgroundQueue = [[NSOperationQueue alloc] init];
[backgroundQueue addOperationWithBlock:^{
//Your Background Work kHere
.....
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
//Your Main Thread(UI) Work Here
....
}];
}];

Adding an NSOperationQueue to an NSOperation

Is it safe to add an NSOperationQueue to an NSOperation, and then add this operation to another NSOperationQueue?
Here is some code to visualize what I am trying to do.
NSOperationQueue *mainQueue = [NSOperationQueue alloc] init];
// Here I declare some NSBlockOperation's, i.e. parseOperation1-2-3
// and also another operation called zipOperation, which includes
// an NSOperationQueue itself. This queue takes the processed (parsed) files
// and write them to a single zip file. Each operation's job is to write the data
// stream and add it to the zip file. After all operations are done,
// it closes the zip.
[zipOperation addDependency:parseOperation1];
[zipOperation addDependency:parseOperation2];
[zipOperation addDependency:parseOperation3];
[mainQueue addOperation:parseOperation1];
[mainQueue addOperation:parseOperation2];
[mainQueue addOperation:parseOperation3];
[mainQueue addOperation:zipOperation];
I have used this approach and have it running in live code deployed on the App Store. I haven't experienced any issues during development or in the last 2 months since the code has been live.
In my case I had a high level series of operations, some of which contained a set of sub operations. Rather than expose the detail of each sub operation into the high level code, I created NSOperations which themselves contained NSOperationQueues and enqueued their own sub operations. The code I ended up with was much cleaner and easier to maintain.
I read extensively into NSOperation and have not seen any commentary that warns against this approach. I reviewed a lot of information online, the Apple documentation, and WWDC videos.
The only possible "drawback" might be the added complexity of understanding and implementing a Concurrent operation. Embedding an NSOperationQueue in an NSOperation means that operation becomes Concurrent.
So that's a 'YES' from me.
Additional details about concurrent operations:
An NSOperationQueue calls the start method on a normal (non-concurrent) NSOperation and expects the operation to be finished by the time the start call returns. For instance some piece of code you supplied to NSBlockOperation is complete at the end of the block.
If the work will not be finished by the time the start call returns then you configure the NSOperation as a Concurrent operation, so the NSOperationQueue knows that it has to wait until you tell it that the operation is finished at some later point in time.
For example, concurrent operations are often used to run asynchronous network calls; the start method only starts the network call, which then runs in the background, and calls back to the operation when its finished. You then change the isFinished property of the NSOperation to flag that the work is now complete.
So.... Normally when you add operations to an NSOperationQueue that queue runs those operations in the background. So if you put an NSOperationQueue inside an NSOperation then that operations work will be done in the background. Therefore the operation is concurrent and you need to flag when the internal NSOperationQueue has finished processing all it's operations.
Alternatively there are some methods on NSOperationQueue such as waitUntilAllOperationsAreFinished which could be used to ensure all the work was done before the start call returns, however these involve blocking threads and I avoided them, you may feel more comfortable with that approach, and making sure you don't have any side effects from blocking threads.
In my case I was already familiar with Concurrent operations so it was straightforward just to set it up as a Concurrent operation.
Some documentation about concurrent operations:
Concurrency Programming Guide: Configuring Operations for Concurrent Execution
In this example they are detaching a thread to perform work in the background, in our case we would be starting the NSOperationQueue here.

NSOperationQueue designated thread

I want to use an NSOperationQueue to dispatch CoreData operations. However, operation queue behavior is not always the same (e.g. it dispatches using libdispatch on iOS 4.0/OS 10.6 which uses thread pools) and a queue might not always use the same thread (as NSManagedObjectContext requires).
Can I force a serial NSOperationQueue to execute on a single thread?
Or do I have to create my own simple queuing mechanism for that?
Can I force a serial NSOperationQueue to execute on a single thread?
Or do I have to create my own simple queuing mechanism for that?
You shouldn't need to do either of those. What Core Data really requires is that you don't have two pieces of code making changes to a managed object context at the same time. There's even a note on this at the very beginning of Concurrency with Core Data:
Note: You can use threads, serial operation queues, or dispatch queues for concurrency.
For the sake of conciseness, this article uses “thread” throughout to refer to any of these.
What's really required is that you serialize operations on a given context. That happens naturally if you use a single thread, but NSOperationQueue also serializes its operations if you set maxConcurrentOperationCount to 1, so you don't have to worry about ensuring that all operations take place on the same thread.
Apple decided to bind managed objects to real Threads.. it isnt that safe anymore to access a context on different threads - a context without any objects MIGHT be safe but its objects are not

iOS, Objective C - NSURLConnection and asynchronious examples, default behavior and best practices?

I have been working with a few applications that deal with NSURLConnections. While researching best practices I have noticed a lot of examples online showing how to use NSOperation and NSOperationQueue to deal with this.
I have also noticed on stackoverflow a few examples that show initializing the connection as synchronous and asynchronous using the class methods of NSURLConnection: sendAsynchronousRequest and sendSynchronousRequest.
Currently I am doing my initialization as follows:
[[NSURLConnection alloc] initWithRequest:request delegate:self];
While doing this I have monitored the main thread and the calls to the delegate methods:
connectionDidFinishLoading, connectionDidReceiveResponse, connectionDidReceiveData and connectionDidFailWithError
Everything I have read in Apples documentation and my tests prove to me that this is asynchronous by default behavior.
I would like to know from more experienced Objective C programmers when the other options would be used for either a best practice, or just be more correct than what I see as the most simplistic way to get async behavior?
This is my first question I have posted on here, if more information is needed please ask.
Synchronous is bad bad bad. Try to avoid it. That will block up your main thread if the data transfer is large, thus resulting in an unresponsive UI.
Yes, it is possible to dispatch a synchronous call onto a different thread, but then you have to access any UI elements back on the main thread and it is a mess.
Normally I just use the delegate methods you have described - it is straightforward, and NSURLConnection already handles the asynchronous call for you away from the main thread. All you need to do is implement the simple delegate methods! It's a little more code, but you always want to go asynchronous. Always. And when it is finished loading, use the information you get to update the UI from the finishedLoading delegate method.
You also have the option of using blocks now, but I can't speak for how well those work or even how to use them well. I'm sure there's a tutorial somewhere - the delegate methods are just so easy to implement.
The method you list are the traditional means of asynchronous transfer and an app that uses them will be efficient in processor (and hence power) use.
The sendAsynchronousRequest method is a relatively new addition, arriving in iOS 5. In terms of best practice there's little other than style to differentiate between it and the data delegate methods other than that a request created with the latter can be cancelled and a request created with the former can't. However the tidiness and hence the readability and greater improbability of bugs of the block-based sendAsynchronousRequest arguably give it an edge if you know you're not going to want to cancel your connections.
As a matter of best practice, sendSynchronousRequest should always be avoided. If you use it on the main thread then you'll block the user interface. If you use it on any other thread or queue that you've created for a more general purpose then you'll block that. If you create a special queue or thread for it, or post it to an NSOperationQueue then you'll get no real advantages over a normal asynchronous post and your app will be less power efficient per Apple's standard WWDC comments.
References to sendSynchronousRequest are probably remnants of pre-iOS 5 patterns. Anywhere you see a sendSynchronousRequest, a sendAsynchronousRequest could be implemented just as easily and so as to perform more efficiently. I'd guess it was included originally because sometimes you're adapting code that needs to flow in a straight line and because there were no blocks and hence no 'essentially a straight line' way to implement an asynchronous call. I really can't think of any good reason to use it now.

iPhone use of mutexes with asynchronous URL requests

My iPhone client has a lot of involvement with asynchronous requests, a lot of the time consistently modifying static collections of dictionaries or arrays. As a result, it's common for me to see larger data structures which take longer to retrieve from a server with the following errors:
*** Terminating app due to uncaught exception 'NSGenericException', reason: '*** Collection <NSCFArray: 0x3777c0> was mutated while being enumerated.'
This typically means that two requests to the server come back with data which are trying to modify the same collection. What I'm looking for is a tutorial/example/understanding of how to properly structure my code to avoid this detrimental error. I do believe the correct answer is mutexes, but I've never personally used them yet.
This is the result of making asynchronous HTTP requests with NSURLConnection and then using NSNotification Center as a means of delegation once requests are complete. When firing off requests that mutate the same collection sets, we get these collisions.
There are several ways to do this. The simplest in your case would probably be to use the #synchronized directive. This will allow you to create a mutex on the fly using an arbitrary object as the lock.
#synchronized(sStaticData) {
// Do something with sStaticData
}
Another way would be to use the NSLock class. Create the lock you want to use, and then you will have a bit more flexibility when it comes to acquiring the mutex (with respect to blocking if the lock is unavailable, etc).
NSLock *lock = [[NSLock alloc] init];
// ... later ...
[lock lock];
// Do something with shared data
[lock unlock];
// Much later
[lock release], lock = nil;
If you decide to take either of these approaches it will be necessary to acquire the lock for both reads and writes since you are using NSMutableArray/Set/whatever as a data store. As you've seen NSFastEnumeration prohibits the mutation of the object being enumerated.
But I think another issue here is the choice of data structures in a multi-threaded environment. Is it strictly necessary to access your dictionaries/arrays from multiple threads? Or could the background threads coalesce the data they receive and then pass it to the main thread which would be the only thread allowed to access the data?
If it's possible that any data (including classes) will be accessed from two threads simultaneously you must take steps to keep these synchronized.
Fortunately Objective-C makes it ridiculously easy to do this using the synchronized keyword. This keywords takes as an argument any Objective-C object. Any other threads that specify the same object in a synchronized section will halt until the first finishes.
-(void) doSomethingWith:(NSArray*)someArray
{
// the synchronized keyword prevents two threads ever using the same variable
#synchronized(someArray)
{
// modify array
}
}
If you need to protect more than just one variable you should consider using a semaphore that represents access to that set of data.
// Get the semaphore.
id groupSemaphore = [Group semaphore];
#synchronized(groupSemaphore)
{
// Critical group code.
}
In response to the sStaticData and NSLock answer (comments are limited to 600 chars), don't you need to be very careful about creating the sStaticData and the NSLock objects in a thread safe way (to avoid the very unlikely scenario of multiple locks being created by different threads)?
I think there are two workarounds:
1) You can mandate those objects get created at the start of day in the single root thread.
2) Define a static object that is automatically created at the start of day to use as the lock, e.g. a static NSString can be created inline:
static NSString *sMyLock1 = #"Lock1";
Then I think you can safely use
#synchronized(sMyLock1)
{
// Stuff
}
Otherwise I think you'll always end up in a 'chicken and egg' situation with creating your locks in a thread safe way?
Of course, you are very unlikely to hit any of these problems as most iPhone apps run in a single thread.
I don't know about the [Group semaphore] suggestion earlier, that might also be a solution.
N.B. If you are using synchronisation don't forget to add -fobjc-exceptions to your GCC flags:
Objective-C provides support for
thread synchronization and exception
handling, which are explained in this
article and “Exception Handling.” To
turn on support for these features,
use the -fobjc-exceptions switch of
the GNU Compiler Collection (GCC)
version 3.3 and later.
http://developer.apple.com/library/ios/#documentation/cocoa/Conceptual/ObjectiveC/Articles/ocThreading.html
Use a copy of the object to modify it. Since you are trying to modify the reference of an array (collection), while someone else might also modify it (multiple access), creating a copy will work for you. Create a copy and then enumerate over that copy.
NSMutableArray *originalArray = #[#"A", #"B", #"C"];
NSMutableArray *arrayToEnumerate = [originalArray copy];
Now modify the arrayToEnumerate. Since it's not referenced to originalArray, but is a copy of the originalArray, it won't cause an issue.
There are other ways if you don't want the overhead of Locking as it has its cost. Instead of using a lock to protect on shared resource (in your case it might be dictionary or array), you can create a queue to serialise the task that is accessing your critical section code.
Queue doesn't take same amount of penalty as locks as it doesn't require trapping into the kernel to acquire mutex.
simply put
dispatch_async(serial_queue, ^{
<#critical code#>
})
In case if you want current execution to wait until task complete, you can use
dispatch_sync(serial_queue Or concurrent, ^{
<#critical code#>
})
Generally if execution doest need not to wait, asynchronous is a preferred way of doing.