iPhone Objective-C service handlers - iphone

I am a as3 developer, I am used to use handlers everytime I launch an event and I am wondering which is the best way / practice to do that in Objective C.
Let's say I want to call a diferent services from my backend.
In as3 would be something like this to listent to the finish event:
service.addEventListener( Event.COMPLETE, handler_serviceDidFinished )
service2.addEventListener( Event.COMPLETE, handler_serviceDidFinished2 )
But how can I do the same in Objective C?
The problem is I already created the protocols and delegates, but how can I separate each response from the server?
For example:
-(void)callService:( NSString * )methodName withParameters:(NSMutableDictionary *) parameters
{
...
if (self.delegate != NULL && [self.delegate respondsToSelector:#selector(serviceDidFinishSuccessfully:)]) {
[delegate serviceDidFinishSuccessfully:data];
}
}
Well I'm trying to create a generic delegate here, so how can I separate each response for every service?
My first idea is that maybe I should return the name of the service method in the delegate call to identify each service. Maybe I should create a UID for each service and pass it the same way...
Any idea?

You might be interested in Objective-C notifications. Basically, these allow you to use a "notification center" to which you "post" different messages; then, all the callback/delegate classes can "register" for certain notifications, so that they know when to do things. This way, all your backend has to do is post the notification, and not worry about whether certain delegates respond to selectors, etc. See Cocoa Core Competencies: Notifications (as well as the NSNotificationCenter and NSNotification class references) for more.

Look at the NSURLConnection delegate - the common pattern is to pass back the object calling you as the first parameter, exactly so you can distinguish among several objects you are a delegate for.
Notifications are a useful thing to indicate task completion, but not really good for handlers that need to affect the processing flow of the object.

Related

Chain of POST requests in Objective C (iPhone)

I need to send a server a set of requests with some data. The data in the subsequent requests will be determined based on the server response in the earlier requests. I do not want to use synchronous approach with NSURLConnection class, as it is very limiting (for one of the requests, for instance, i need to prevent redirects. According to Apple Dev documentation this can only be done with Delegate implementation).
Depending on which request in the chain it is, i need to be doing different things (send different messages to various classes).
The way i see it now, is that i have to either create n delegates for each of my requests, or create a delegate which would initWithFlag and then create the instances of that delegate with different flags, or i need to use something like a factory pattern which would be pretty similar solution to the second one.
I do not WANT to implement a delegate at all, i want to send requests with the least bit of coding possible.
I am also not looking at any frameworks (ASIHTTPRequest etc), i would like to do it with the native classes.
What would be the best approach?
I know you said you don't want to use third party frameworks, but I'd really suggest AFNetworking. With that said, you do not NEED AFNetworking or any third party library, it will just make your life easier IMHO.
So, what I have done in a similar scenario is essentially use the Command Pattern. When I want to send off one of these complicated "requests" I initialize a command object, set all of the necessary parameters and then call execute. My command object has completion and failure handlers/blocks and execute is an asynchronous call.
Within the command I have different 'steps' that are effectively synchronous and depend on each other. Let's say request A depends on B and B depends on C, the first step of the command is to execute A on it's own queue (I am using GCD with a private queue) and wait for it to finish. Once A finishes (successfully) I continue on to B and pass in any results I need from A into B. Likewise for B->C. If any of the intermediate requests fail throughout the process I can execute the failure block and handle it from where I executed the command (consumer end). If all finish successfully I execute the success block.
I prefer the encapsulation of this approach as it is very easy to re-use throughout the project, all of the intricacies are tucked away in the command's implementation.
Oh and the fact that I use callbacks/blocks I did not need to implement any delegates. In your case using the NSURL classes your command object would be the delegate of any of those instances.
I have settled on implementing the delegate after all.
The key things that tripped me were:
Do NOT declare the delegate methods in .h file. They won't work like that. Simply add them to implementation.
A delegate can be init'ed within the NSURLConnection initWithRequest method or it can be held as a property of the parent class, there is no difference.
The best way to handle multiple requests is the suggested initWithFlag. Therefore, it is best to create a delegate when initialising connection. The delegate lives long enough to perform full data transfer under ARC.
The most convenient way to cancel the redirect comes from Apple's Developer Library:
-(NSURLRequest *)connection:(NSURLConnection *)connection
willSendRequest:(NSURLRequest *)request
redirectResponse:(NSURLResponse *)redirectResponse
{
NSURLRequest *newRequest = request;
if (redirectResponse)
{
newRequest = nil;
}
return newRequest;
}
Please note that this message is sent several times during the life of the connection for undisclosed reasons. However, if the response is not an actual redirect, the redirectResponse will be nil.
Setting the request to nil will cancel the redirect, but NSURLConnection will finish processing the original data (that is, connectionDidFinishLoading message will be sent).
You can cancel this behaviour by sending this message:
[connection cancel];
I found NSNotifications to be the best way to pass results to the parent class.

asynchronous request objective c

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.....

Using multiple NSURLConnections at the same time - best practices

In my iPhone app, I've been able to use NSURLConnection properly to download data from a URL. I simply set the delegate to my UIView, and make sure that I set up the UIView to answer for the proper delegate functions such as -connection:didReceiveResponse:. However, if I have a number of NSURLConnections (either for a similar type of request, or multiple kinds of requests), it gets messy because the delegate functions, such as didReceiveRequest, don't differentiate between the different requests. The advantage of asynchronous requests is that you are supposed to be able to multiple at once, without blocking the main thread. What's the best practice for how to use multiple NSURLConnection requests at the same time?
I prefer to wrap them in a higher-level object (like ImageDownloader or SomeWebServiceCall) that has all the per-connection/call state information. I usually create a delegate these objects so that the caller gets a more specific callback when the operation has succeeded or failed.
Perhaps look into ASIHTTPRequest, instead of NSURLConnection. ASIHTTPRequest makes a lot of this work trivially easy.
In this case, I'd say NSOperation is your best bet. ASIHTTPRequest is based on NSOperation and allows you to handle each request as an operation, which serves as the delegate for its own NSURLConnection.
You'll have to be careful here though, because by default NSOperations are run on separate threads, but some APIs, like this one, are required to be executed on the main thread. If you inspect the source code to ASIHTTPRequest you'll notice they've got some infrastructure to ensure delegate methods are called on the main thread.
Create an instance variable for each NSURLConnection and NSMutableData. All of your delegate methods have the NSURLConnection object as an argument, so you can match them as such:
-(void)connectionDidFinishLoading:(NSURLConnection *)connection {
if (connection == aConnection) {
// Do something with the data for aConnection
} else if (connection == otherConnection) {
// Do something with the data for otherConnection
}
}
This still limits you to one connection per instance variable, so it's not suitable for, for instance, a table view with images on each row that need to be loaded.

What is NSNotification?

Can anybody explain the importance of NSNotificationCenter?
Where to use them?
What is the difference between NSNotificationCenter vs. AppDelegate?
Apple has provided an Observer Pattern in the Cocoa library called the NSNotificationCenter.
The basic idea is that a listener registers with a broadcaster using some predefined protocol. At some later point, the broadcaster is told to notify all of its listeners, where it calls some function on each of its listeners and passes certain arguments along. This allows for asynchronous message passing between two different objects that don't have to know about one-another, they just have to know about the broadcaster.
You can find more details about it here: http://numbergrinder.com/node/32
The Application Delegate is an object which receives notifications when the UIApplication object reaches certain states. In many respects, it is a specialized one-to-one Observer pattern.
You can read more about it here: What is the AppDelegate for and how do I know when to use it?
If you come from an Actionscript background then NSNotification is like adding listeners to objects I guess.
NSNotification is like notifying the other class about the changes that will happen if some action takes place in another class.

How can I listen for didRegisterForRemoteNotificationsWithDeviceToken outside the app delegate

I would like to my object to receive notification with the DeviceToken becomes available. Is there a way to delegate only certain functions from the UIApplication to my class?
Update:
I'm not so much interested in accessing it from the application delegate, I already have an application delegate, but want to respond to the event via call back or some observer method if it's possible.
Despite not being marked as such in the documentation, all UIApplicationDelegate methods are optional, so you can simply implement the ones you require, and ignore the ones you don't.
However, you'll probably want to implement all three of the APS methods, rather than just the one indicating registration success!