NSNotification-based iOS App - ios

I am currently thinking about the data-model for my iOS App. The app does only receive Information from a server and therefore, the "model" itself generally does all the web-requests, ...
However, these network requests have to be performed in the background - I mean another task, not the iOS background state - and after the request has finished, the information in the Application has to be updated.
Would it make more sense to write a delegate to inform the controller or could I also use NSNotificationCenter? I think an NSNotification-based solution could make the model more universal, e.g. in a desktop application.
And maybe, I should add: the model (since it saves some session Information) is a singleton, so a regular delegate based method would not work...

I don't think that it would be a good idea to use a separate thread to handle the communication. Apart from being complex, it is not necessary since NSURLConnection/NSURLRequest do allow you to handle communication asynchronously, i.e., without blocking.
In detail, you can create an NSURLRequest executing:
NSURLRequest* yourReq = [NSURLRequest requestWithURL:yourURL];
then create an NSURLConnection with:
NSURLConnection* yourConnection = [NSURLConnection connectionWithRequest:yourReq delegate:yourDelegate];
and start it with:
[yourConnection start];
When the data is ready, one of the methods for your delegate (connectionDidFinishLoading:, or connection:didFailWithError:) will be called so that you can update your UI.
All this without blocking.
An even better alternative to using NSURLConnection/NSURLRequest, is using ASIHTTPRequest, which seems to be more resilient as to memory management and also offers a great caching mechanism.
EDIT: if your concern is that being your model a singleton, you cannot have a delegate, let me suggest that you look further into the matter.
Your model may be a singleton and the delegate to your request may have nothing to do with the model, apart from knowing how to access it (which is pretty trivial being the model a singleton).
This is possible by several mechanisms with NSURLConnection, but if you use ASIHTTPRequest, it will become really easy, because each ASIHTTRequest can have its own delegate.

A delegate solution does work and is recommended. It looks something like:
[[DataLayer sharedInstance] fetchDataWithDelegate:self];
That method can spawn a background thread and respond to the delegate on the main thread.

Related

Good practice using NSURLConnection and its callbacks? Objective-C

I don't have a current problem really, but rather a question that I can't seem to find a satisfying answer to.
What is good practice to use when handling callbacks and invokations of NSURLConnection in objective-c? Let's look at some examples.
Let's say I have 3 different ViewControllers, and I've created a class that does the network calls with NSURLConnection in order to obtain a JSON from some site. All 3 VC's will be doing different kinds of network calls. How would one go about doing this without having to repeat code or have the network handling all spread out? And what if I need to make more network calls depending on the result of a previous call?
I use the normal NSURLConnection delegates, such as didReceiveResponse, didReceiveData, connectionDidFinishLoading etc. So what I do is I store the statusCode in didReceiveResponse and in connectionDidFinishLoading I call a function I name handleResponse which checks the statusCode and if the statusCode states that the call was successful I translate the NSData* object that I've stored the data I received from didReceiveData delegate. This is all fine, but the data I translate I want to be sent to the correct viewController.
There are several options to do this:
I let the delegate for the NSURLConnection calls be the
ViewController itself. This sucks, since I have to duplicate the
NSURLConnection code in every VC I want to make a network call,
obviously.
Or I could handle all the data in the Network class that performs
the NSURLConnection calls. This sucks since I get logic code in a
network class, and I don't really want that? This also requires that the Network Class knows about classes and data structures that it probably shouldn't. It's a network class and should not do anything but networking stuff.
My final approach, which I try for the first time now, is to let the
ViewController tell the network class that it wants to make a
NSURLConnection call, and sets a NSNotification message which the
Network class should invoke in the handleResponse method I
mentioned earlier. The Network class sends the data it received
through that NSNotification and the logic for handling that data
falls on the VC that asked for instead. To me this is most logical
and feels like a somewhat good way of doing things.
The problem with solution 3 is that I have to have different Notification methods to handle different kinds of data, which could result in quite a few such methods. If different VC's also use the same kind of data handling as another NSNotification method, then I have to duplicate that code as well. I'm also fairly new to using NSNotification in general and not very knowledgeable about its drawbacks.
Final question, let's say I want to make 4 different NSURLConnection calls, one after the other has been confirmed finished and successful. How would you go about that? I've done this a few times, but it ends up as a counter in the form of an enum to keep track of which network call was just made and which one should be next, which results in switch-statements executing certain code depending on which was just performed. I'm thinking about maybe implementing some sort of queue which goes through all calls in a sequence instead.
I appreciate any kind of input!
Most if not all of these problems are solved by AFNetworking. Specially the problems concerning having to duplicate requests or connections.
For the final question, for example you can do it with blocks AFNetworking provides such a structure, so you can specifically coordinate multiple calls.
AFNetworking
There are a lot of tutorials out there and the brief documentation of the library github site provides short, concise and easy to understand examples. Getting to use it takes a few minutes.

NSURLConnection (initWithRequest vs sendAsyncRequest)

If both initWithRequest and sendAsyncRequest are Asynchronous ways of connections then whats the major difference ?
Other than completion Handler and Queue concept in sendAsyncReq what else ?
Which 1 is more advantageous ??
The sendAsynchronousRequest is simpler and easier to use, saving you from implementing NSURLConnectionDataDelegate and NSURLConnectionDelegate methods. But if you need richness of delegate approach (e.g. challenge-based authentication, need cancelable requests, etc.), then sendAsynchronousRequest is not up to the job.
If targeting iOS 7 and later, consider NSURLSession, instead, too. You can enjoy simplicity of block-based networking and still enjoy delegate methods if and when needed. Also requests are always cancelable. It also opens new opportunities (e.g. background sessions that continue operating even if your app is no longer active).

NSURLConnection and different ways of making asynchronous requests

I need to communicate with RESTful services either through HTTP and HTTPS. I am reading some examples about performing asynchronous requests by means of the NSURLConnection class, and some of them use the sendAsynchronousRequest:queue:completionHandler: method, and other use the connectionWithRequest:delegate: method and implements the NSURLConnectionDelegate methods. I'm not able to make clear what implications each of these approaches has, if difference is only in implementation but performance and results are the same, or if one of the approaches is better or more correct than the other...
Thanks!
There are two differences that are usually key.
First, the return type of both methods. [NSURLConnection
sendAsynchronousRequest:queue:completionHandler:] has a return type
of void which means you cannot capture the NSURLConnection e.g. in
a property, so you lose quite some control over it, i.e. you can not
[NSURLConnection cancel] it. On the other hand, [NSURLConnection connectionWithRequest:delegate:] does return the connection back to you, so you retain full control.
Second, if you are downloading a large file, the block based method
will load the data into memory and 'deliver' it when the block
executes. Presuming a small RESTful answer, this might be ok for you.
However if you are downloading a large file you might want to write
the incoming data directly into a file handle to reduce memory
consumption. For this you need the delegate method
[NSURLConnectionDataDelegate connection:didReceiveData:]. Sadly the
NSURLConnectionDataDelegate documentation is not readily linked in the current Apple documentation.
If you set yourself to be the delegate of the NSURLConnection, those
methods will be called.
Hope this helps.

What is the best networking solution for a complex multithreaded app?

I have a streaming iOS app that captures video to Wowza servers.
It's a beast, and it's really finicky.
I'm grabbing configuration settings from a php script that shoots out JSON.
Now that I've implemented that, I've run into some strange threading issues. My app connects to the host, says its streaming, but never actually sends packets.
Getting rid of the remote configuration NSURLConnection (which I've made sure is properly formatted) delegate fixes the problem. So I'm thinking either some data is getting misconstrued across threads or something like that.
What will help me is knowing:
Are NSURLConnection delegate methods called on the main thread?
Will nonatomic data be vulnerable in a delegate method?
When dealing with a complex threaded app, what are the best practices for grabbing data from the web?
Have you looked at AFNetworking?
http://www.raywenderlich.com/30445/afnetworking-crash-course
https://github.com/AFNetworking/AFNetworking
It's quite robust and helps immensely with the threading, and there are several good tutorials.
Are NSURLConnection delegate methods called on the main thread?
Yes, on request completion it gives a call back on the main thread if you started it on the main thread.
Will nonatomic data be vulnerable in a delegate method?
Generally collection values (like array) are vulnerable with multiple threads; the rest shouldn't create anything other than a race problem.
When dealing with a complex threaded app, what are the best practices for grabbing data from the web?
I feel it's better to use GCD for handling your threads, and asynchronous retrieval using NSURLConnection should be helpful. There are few network libraries available to do the boilerplate code for you, such as AFNetworking, and ASIHTTPRequest (although that is a bit old).
Are NSURLConnection delegate methods called on the main thread?
Delegate methods can be executed on a NSOperationQueue or a thread. If you not explicitly schedule the connection, it will use the thread where it receives the start message. This can be the main thread, but it can also any other secondary thread which shall also have a run loop.
You can set the thread (indirectly) with method
- (void)scheduleInRunLoop:(NSRunLoop *)aRunLoop forMode:(NSString *)mode
which sets the run loop which you retrieved from the current thread. A run loop is associated to a thread in a 1:1 relation. That is, in order to set a certain thread where the delegate methods shall be executed, you need to execute on this thread, retrieve the Run Loop from the current thread and send scheduleInRunLoop:forMode: to the connection.
Setting up a dedicated secondary thread requires, that this thread will have a Run Loop. Ensuring this is not always straight forward and requires a "hack".
Alternatively, you can use method
- (void)setDelegateQueue:(NSOperationQueue *)queue
in order to set the queue where the delegate methods will be executed. Which thread will be actually used for executing the delegates is then undetermined.
You must not use both methods - so schedule on a thread OR a queue. Please consult the documentation for more information.
Will nonatomic data be vulnerable in a delegate method?
You should always synchronize access to shared resources - even for integers. On certain multiprocessor systems it is not even guaranteed that accesses to a shared integer is safe. You will have to use memory barriers on both threads in order to guarantee that.
You might utilize serial queues (either NSOperationQueue or dispatch queue) to guarantee safe access to shared resources.
When dealing with a complex threaded app, what are the best practices for grabbing data from the web?
Utilize queues, as mentioned, then you don't have to deal with threads. "Grabbing data" is not only a threading problem ;)
If you prefer a more specific answer you would need to describe your problem in more detail.
To answer your first question: The delegate methods are called on the thread that started the asynchronous load operation for the associated NSURLConnection object.

Do you need to consider thread-safety using NSURLConnection? - iOS

I've just been wondering for a while now how exactly asynchrounous requests work with NSURLConnection.
For example, suppose you have several upload processes running in your application, all initialized using different instances of NSURLConnection. As uploading processes, your wrapper objects gets the NSURLConnection delegate methods called, like:
-(void)connectionDidFinishLoading:(NSURLConnection*)connection;
Suppose that in all your NSURLConnection wrapper objects share the same delegate object which have a list of all active uploads in an array, and that when the connectionDidFinishLoading gets called for all your connections, they go in and remove themself from that list in the shared delegate object.
The question then is, do you have to worry about thread-safety when those connection objects can access the same array? Or does all those delegate methods go back to the main-thread in such a way that you are not supposed to worry about thread-safety?
The trick is that the delegate methods are called on the thread on which you created your NSURLConnection, which unless you specifically change it will be the main thread. The OS uses one of the threading Queueing APIs to call the delegate method over and over on that thread in the order each connection finishes.
With NSURLConnection its only really the transfer that needs to be threaded. If the transfer happened on the main thread then during the transfer the User wouldn't be able to interact with your iOS application. Doing stuff with the result takes a relatively short time, but if it takes a long time whether you choose to do that processing in the background (on a different thread) or not is then up to you.

Resources