Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

iPhone - Architecture for viewController and network requests

So, I have 2 types of data, some needs to be persisted and some doesn't.

I'm thinking about where to put all my network related code, inside my UIViewControllers, where all the network request start from, or in a another layer.

What I had in mind is this:

Have a layer called NetworkManager. NetworkManager is singerlton to all my web service calls.

For data that needs to be persistent and can be presented in a list, I would have network manager issues the request, save the response in my local core data DB, and have my UIViewController listen to that data using FetchResultsController.

But, there's many other types of requests. For example : login request, user info request, friendsNearBy, and so on… some don't have to be persistent in my db, and some don't fit the FRC architecture.

For these type of request, as far as I see, there are 2 ways of handling it:

1. Have another layer that separates between the ViewControllers and the NetworkManager. Let's call it Mediator. The Mediator gets the dictionary(JSON) request from the networkManager, decides according to the app logic if there's anything else needs to be done with it, and then post a notification with appropriate name and data. If the mediator saves the UIViewController who issued the request, it can delegate the response directly to him instead of posting a notification.

The Flow would be like this:

MyUiViewController - > Mediator -> NetworkManger->Mediator-> PostNotification (or directly back to MyUiViewController)

Pros:
Decoupling
Nice structure and separation of concerns

Cons:
Harder to code
Sometimes harder to understand and debug.

2. Not having this 3 layered architecture, but instead having MyUiViewControllers, issue a network request with blocks. Meaning instead of the Mediator intercepting the response before MyUiViewController, just let MyUiViewController handle the response using blocks as he is the one that issues it.

Pros:
Simple and quick to code
Easy to understand

Cons:
Coupling of network code inside your controllers

I was hoping to get suggestions and comments about what's best from people's experience, or other/better way of doing this.

like image 851
Idan Avatar asked Mar 31 '12 10:03

Idan


2 Answers

Have you got whats the best method already?

Here's what i do generally,

Have a NetworkManager which is not Singleton. Define a protocol with method OnSuccess,OnError. Implement this in your ViewController which initiates the network connection. Set the delegate on NetworkManager and let delegate be called when Asynchronous request is executed.

Use delegates instead of blocks as its easy to maintain.

This may not be best solution, but hopefully it gives you some pointers.

like image 98
suresh Avatar answered Nov 10 '22 00:11

suresh


I recommend option 2 with a little bit of what you listed for option 1. In my apps I tend to have two distinct modes of operation that operate concurrently.

Automatic downloads: App essential data is downloaded and saved directly to the database. It's initiated each time the app becomes active. As each request completes an NSNotification is sent out for any visible view controllers that may need to know about the new data.

For example, if I save player data I'll send a notification like "PlayerDataUpdated". When a view controller is visible it listens for notifications. When it's not visible it doesn't listen for notifications since any changes in to the database will be discovered during viewWillAppear.

User Initiated downloads: For user-initiated network requests, such as pull to refresh, you should call the appropriate method on NetworkManager from the view controller that needs the updated data.

like image 36
Sigma4Life Avatar answered Nov 10 '22 01:11

Sigma4Life