hi i am developing a sms App for my client. so far i have put down this plan in place.
1)The app keeps polling the server with an asynchronous request so that it does not interfere with the user interface.
2) for sending sms i am currently using synchronous request , depending on the reply from server i have do various things. i am showing the spinning circle and make the user wait until i get the response from server.
my client has problem with point 2.
The client says as soon as the send sms button is clicked it has to go back to the homescreen and should be able to navigate to any screen and do all other things that the app offers. i could have used async request , but i am not sure how to handle the responses from the server when i am on different view controller other than the one request is called from.
Can somebody help me on this.
Thank You.
The classic way of handling the response of an asynchronous action is either using delegation or notifications. Do not use a singleton. This breaks modularity and decoupling of different view controllers.
Roadmap of how to handle asynchronous actions
Register for the response of the asynchronous actions. This can be setting the delegate of the requesting object e.g. NSURLConnection to the view controller, which is typically self in this context. The othe possibility is that you register for the notification which is fired by the requesting object if things have happend e.g. when a download is finished or an error occurred.
Implement the delegate methods or the notifications to update your model and/or your user interface. Be aware that updating the UI has to happen on your main thread.
Start the asynchronous action. What happens in the background is that a separate thread is spawned or an operation is dispatched using GCD. These are implementation details and do not bother you.
Wait for the answer, which will result in one of your implemented methods to be executed which you then use to update what has changed.
Difference between notifications and delegates
The two differences between delegates and notifications is that delegate is a one-to-one connection between the delegate and the delegating object. Notifications are posted application wide and can be observed by as many objects as needed creating a one-to-many connection. Think about this as a broadcast. The second main difference is that delegation can be used to transfer information back from the delegate to the delegating object. Meaning that the delegating object asks the delegate for certain information. Typical example would be the data source of an UITableView. Notifications however are a one way street. The information flows from the posting object to the observing objects. This makes sense because think about the situation where you would have more than one observer and each would give feedback to the posting objects. Which one would be the right one?
In your case you would have to look up the delegate methods of the asynchronous HTTP request object and implement them accordingly.
Maybe you can try ASIHTTpRequest , It has Sync an Async request
If you using Async request , you can do anything after you press a button to do a request .
Check this
The solution depends on the response processing.... if you are just showing user that the sms sending is failed/successful than you can do it in any general utility class that shows alert.. but for this you have to create the singletone instance of your connection class so delegate(class itself) don't die when the response comes back.......
For this we need to keep track of currentViewController ....... we can do this by creating a reference ........ id currentViewController in appDelegate(with setter/getters).......... so it could be accessible in everywhere application........
its referred object should be changed each time when user changes the viewController.... that will help us to know on which viewController user is currently working.
than when the singeltone class of connection finished its response loading we can use this currentViewController with your desired viewController.
I am not sure how you are using different view controller....... pushing it/ presenting it or adding its view.....
Related
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.
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.
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.
I'm wondering how to deal with this particular issue:
I'm creating a place object, which gets initialized with a geographical lat-long pair. Then I use the iOS geocoder to get an address for that coordinate. I want to set that address to one of my instance variables. However, this asynchronous call doesn't get completed in time, so when I instantiate my object and try to display the address, it hasn't been done yet. What are some strategies to deal with this and similar problems?
Thanks! Merry Christmas!
I don't feel like creating an extensive answer on Christmas Eve so I'll give a brief answer here for now, and edit it later if you've got questions and/or want more details.
Asynchronous requests all have delegate/protocol methods that let you know when the request has failed or succeeded. You should use the NSNotification API and register any object that needs the address for a notification that's triggered when the object completes the request. When the object receives the notification, it can then configure its views or whatever it needs to do. In the requestDidFinish (or whatever) method, you should send the notification.
Check out this article for details (as well as some cool stuff about threading!): http://www.raywenderlich.com/4295/multithreading-and-grand-central-dispatch-on-ios-for-beginners-tutorial
I'm developing a project for iDevice. I'll explain the architecture of my project, and I would like some feedback.
My project is a typical iPhone application : list of item --> detail.
STEPS:
I made a singleton to store information .
I send an asynchronous request to receive list of items (not detailed), when the request finishes loading, I store the result in a string in singleton and I post a notification ("loading terminated").
In other object I "catch" this notification, parse the result stored in singleton, store the parse result in an array in singleton and I post notification ("parse terminated").
In other object, I "catch" the notification and I display result in a table view.
When a cell is selected, I do the same thing (with other name of notification and other variable in the singleton for detailed item)
I use this architecture because my project needs to be generic and extensible.
It is a good idea to do it in this way? Are there better options?
Sounds a bit like a Model View Controller http://maniacdev.com/2009/10/a-quick-explanation-of-mvc/
I don't know if you need another object to do step 3. The data is just going into the singleton anyway. Might be best to have a response processor handle getting the results from 2 and then do the processing from 3 and then send it to the singleton.
Essentially:
- make the synch request and set a delegate to handle the response
- perform all the processing and formatting of the response and save to singleton
- singleton notifies it's delegates of a change
- objects subscribed as a delegate to the singleton perform their action, in this case, display data
check out the link and read up a bit on MVC
Background:
I am in the early stages of an an iPhone App and REST WebService product. Basically, I have a database on the a server and have written some REST APIs to access this database. I have a companion iphone app that will consume these REST APIs.
Questions:
What is the best approach to place the code for accessing the REST Apis? Should I create a separate subclass of NSObject and place the interface and implementation details there? I would like to reduce the amount of code duplication throughout the application in the various ViewControllers that would interact with the REST API.
For Example:
My app would start up and make a REST API call to determine the current state of local information on the device by comparing the value returned from the API vs local. Then I would initiate an update request from the API to refresh the local datastore.
Now if I have all of this logic in the start-up ViewController I have multiple calls using NSURLConnection which only has on delegate. I don't know how to make these separate calls in the same ViewController.
What are some approaches to solving this problem?
I generally create custom objects which use ASIHTTPRequest (using composition, not subclassing) which can be initialised with any required parameters, and use that to manage requests to the RESTful service. The custom object will provide a delegate protocol for handling success, failure and other custom notifications so that I can use this feedback to update the application UI while the request is performed asynchronously.
If you need to parse large amount of data returned from a request, make sure you launch a separate thread to do this, rather than doing it in your HTTP request success callback, otherwise this will keep the network activity spinner active longer than it actually should be.
If you need to manage multiple requests of the same type, you could add a "tag" property to your custom request, so that when your success/failure delegate response is called, you can easily identify which request it belongs to without having to keep an instance variable to the original request.
I'm working on a largely navigation-based iPhone app that communicates with a REST API using OAuth, and I'd like to know how my classes should best communicate with each other. I've got multiple UITableViews, multiple UITableViewDataSources, an API class, and a view controller that handles authentication in a web view.
Here's how I have things structured now:
My UIApplicationDelegate owns an instance of the class that knows how to communicate with the REST API
I can ask the API class to call a REST method, and it returns with the data (it wraps ASIHTTPRequests to handle OAuth transparently, so it doesn't currently know which object asked for the data)
If the user isn't authenticated, I can ask the API class to initiate the OAuth process
The OAuth dialog can be presented, and the application granted access to the API on the user's behalf
The trouble I'm running into is that my UITableViewDataSources need to communicate with the API class to fetch their data, but authentication might need to happen first, which involves a modal authentication view presented by a view controller.
Would it be better to have each UITableViewDataSource model own its own instance of the API class, or should the API class be a singleton?
If each model owns an instance of the API class, how should it communicate to the view controller that authentication needs to happen?
If the API class is a singleton, how should it interact with multiple models and view controllers to present the authentication dialog? Delegates for each? Post NSNotifications?
Some other way I haven't thought of?
Really, I think the core of the problem is that I have one class that's primarily used for data fetching purposes, but it might need user interaction to do so successfully.
I typically use a singleton exactly in the way you describe and it works well. Here is how I would answer your questions.
Singleton
N/A. Use a singleton.
Notifications work well, but I tend to prefer to pass a delegate with each request and then keep a hold of it inside the singleton until the request has finished at which point I just call back to the delegate with a success or failure message. Notifications can get pretty messy if you have multiple view controllers that are live in your navigation stack all potentially listening and responding depending. I've seen that introduce some really weird bugs. If you're careful, notifications work just fine, but passing a delegate allows you to associate a specific delegate, typically the current view controller, with a specific request which is often ideal.
I think you're on the right track.