I have been trying to figure out why and how to use performSelector.
I did come across Apple Docs. However, I am not able to fully understand it.
Would anyone be able to help me out in explaining this?
From Apple's documentation:
the performSelector: method allows you to send messages that aren’t
determined until runtime
Longer story:
You can send messages to objects without prior knowledge of whether the object implements this particular method. For example:
NSString *astring = #"test";
[test dance]; // Doesn't compile
[test performSelector:#selector(dance)]; // Doesn't make sense but compiles
AFAIK, using the selector is a way to declare the callback method as what we did on Java, C#, ... Suppose that you develop library A, which do an asynchronous calculate and return result whenever it done. At development time, you don't know what call back method you should call whenever the calculating done. So you can make the library get an selector as input parameter and use performSelector later to invoke callback methods.
Hope this helps.
Related
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.
I'm very new on iOS application development so please explain me about delegate and call back. When we use use call back and delegate?
Call backs are used to allow an API or service to provide information to your code when certain events occur (e.g. when a task has completed). This is useful in asynchronous programming, e.g. when you want your current thread to get on with something else, or to allow the user to continue using the UI. (i.e. a call back is a function or lambda you have written, which is passed as a parameter to another method)
A delegate is the 'signature' (the 'type definition' of a method, including parameters) that a method (such as a call back) must provide in order for it to be useable as callback or event handler.
Edit Just to be complete, Delegation is also a design pattern, whereby the responsibility of control or action is delegated from one object to another.
Big piece about delegates here on the dev centre:
http://developer.apple.com/library/ios/#DOCUMENTATION/Cocoa/Conceptual/CocoaFundamentals/CommunicatingWithObjects/CommunicateWithObjects.html
There is a tutorial app using callback/delegate
http://brandontreb.com/objective-c-programming-tutorial-creating-a-twitter-client-part-1/
I think this should be simple, but im having a real hard time finding information about this topic. I have made a static library and have no problem getting the basics to work. But im having a hard time figuring out how to make a call back from the static library to the main APP.
I would like my static library to only use one header as front, this header should contain functions like:
requestImage:(NSString *)path;
requestLikstOfSomething:(NSSting *)guid;
and so on..
These functions should do the necessary work and start a async NSURLConnection, and call back to the main application when the call have finished. How do you guys do this, what are the best ways to callback from a static library when a async method is finished? should i do this with delegates (is this possible), notifications, key/value observers. I really want to know how you guys have solved this, and what you regard as the best practices.
Im going to have 20-25 different calls so i want the static library header file to be as simple as possible preferable only with a list of the 20-25 functions.
UPDATE:
My question is not how to use delegate pattern, but witch way is the best to do callbacks from static librarys. I would like to use delegates but i dont want to have 20-25 protocol declarations in the public header file. I would prefer to have only one function for each request.
Solution choosen:
i choose the solution from erkanyildiz with the help of a target parameter, i know its pretty low tech, but it was for me the cleanest solution. My goal was to keep the header file as small as possible. Thanks to everybody for they input, i will for sure look more into borrrdens solution with grand central dispatch when i get the time. user1055604 solution with a couple of "standard" delegates for replys is also one i like. So again thank you all for inputs.
Thanks in advance.
Best regards
Morten
Delegation pattern is a good way to do it.
You can check these pages:
http://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/CocoaFundamentals/CommunicatingWithObjects/CommunicateWithObjects.html#//apple_ref/doc/uid/TP40002974-CH7-SW18
http://en.wikipedia.org/wiki/Delegation_pattern#Objective-C_example
As another approach, you can use a target parameter in every method you have.
And schedule callbacks on those targets, checking if they are responding to your callbacks using respondsToSelector
Look here for an example with delegates: How to perform Callbacks in Objective-C.
It shouldn't matter that the callback is executing from within a static library.
Static libraries are a compile/link time phenomenon. As such, calls to and from within static libraries are transparent to the application at runtime.
If you would rather not have one callback protocol declaration for each function in your static library, start with looking at what each callback would return if you did, forcefully, implement it as a callback.
From there on, find what's in common between them and bind the common elements together in a class which will serve as an interface for the responses. You may need more that one such class.
As an example, look at NSURLResponse:
NSURLResponse declares the programmatic interface for an object that accesses the response returned by an NSURLRequest instance.
NSURLResponse encapsulates the metadata associated with a URL load in a manner independent of protocol and URL scheme.
This class is used by NSURLConnection in its didReceiveResponse delegate method. In the worse case, you will end up with a couple of callbacks instead of a noisy header file. Happy coding. :-)
Try making your function calls using Grand Central Dispatch. It's quite simple, and very powerful. Here is a sample of how to make an async call with a callback:
http://pastebin.com/xDUKm6wh
This paste bin is complaining about errors, but take note of the pattern. It should work just fine.
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.
I noticed that when I do this :
[myParser setDelegate:self];
it works :D (even if I didn't add the code in the header file ... you know, the
<delegateStuff, delegateOtherStuff>
in the interface declaration)
When are you supposed to modify the header file to make your delegate work ? Is the setDelegate method enough to make it work ?
Cheers for any help ;)
Gauthier
In short, the <NSXMLParserDelegate> in your interface declaration is not required, it's there for error checking at compile time. Calling the setDelegate: method is required if you want to receive delegate messages.
The <delegateStuff> you refer to are protocol declarations. A Protocol in Objective-C is like an Interface in Java: it defines a list of messages (methods) that the class responds to. Unlike Java, however, Objective-C is dynamically typed, meaning any message can be sent to any object and you can only be sure if it will respond to it at run time.
The upshot of this is that if a method like setDelegate: asks for a parameter of type id, you can give it any object whatsoever. The code in NSXMLParser can check if it is able to respond to a specific message before sending it. That way you can implement whatever delegate methods you want. (Because Java has more strict type checking, you must implement all the methods in an interface, whether you need them all or not.)
If setDelegate: instead act for a type id <NSXMLParserDelegate> it is now saying that it wants an object that implements the NSXMLParserDelegate protocol. This is only checked at compile time to help you catch errors, though. If you use a typecast you can send any object in there and, as long as it responds to the required messages, your program will run fine. (Again, in Java, you could use a typecast to compile, but the typecast itself would throw an exception if the object wasn't of the correct type, even if it had the same methods.)
By the way, are you subclassing NSXMLParser? (I assume so, since you are passing self to setDelegate:. That is not the way it is meant to be used! The Cocoa frameworks usually prefer delegates over subclasses. Your delegate class should be a separate class extending NSObject (or something else if you want).
When it's required, the compiler will let you know with a warning.
I've noticed that when you add the to the header file, Xcode is able to autocomplete any delegate methods you might want to use. I do it every time just for this reason.
The compiler now warns if is missing under iPhone SDK 4.0
A "delegate" will always work as long as it implements the selectors that are called at runtime. Declaring a matching delegate protocol is not required, but you can get a compiler warning if the delegate is typed to more than just "id" (e.g., id [SomeDelegateProtocol] delegate).
However... if you declare that a class meets the spec of a particular protocol, then (a) that protocol must exist and (b) your class will be checked for the protocols selectors. The NSXMLParserDelegate that is now included with iPhone SDK 4 will cause older apps to throw a warning; if you add the protocol and then try to backward compile to 3.x you will get a compile error because the protocol does not exist prior to 4 (at least you are unlikely to have included a framework with that protocol in it). I just encountered this as I'm beginning to migrate current apps from 3 to 4. I hate warnings that I cannot easily eliminate.