Dissect an iOS protocol programmatically, then invoke those methods? - ios

The question (reflection or something like it?)
Is it possible (in Swift) to extract all the method signatures of an iOS protocol programmatically, such as for UITextViewDelegate, whose methods are all optional, without having to instantiate a separate class that explicitly implements all the protocol's methods?

In this case, want to intervene as the delegate to intercept one of the methods and do some related operation to that activity, then daisy chain the delegate call forward. But unfortunately, becoming the delegate entails responsibility to forward all of the protocol the downstream consumer
If you're saying what I think you're saying, there actually is a very simple way to do this: implement forwardingTarget(for:), as I do here:
https://github.com/mattneub/Programming-iOS-Book-Examples/blob/master/bk2ch12p611tabBarMore/ch25p882tabBarMore/MyDataSource.swift
The idea is that I don't know what the table view's dataSource actually does, because the table view and its data source belong to Cocoa, but I want to act as a "man in the middle" between them and just tweak the behavior of one data source method if it is called. All other method calls just get passed along, without my even knowing what they are.

Related

how are protocol methods in iOS automatically invoked?

Im trying to understand the high level implementation of protocols without delegates in Apple frameworks. When a subClass conforms to and implements a protocol method, how is that method called? Lets consider the NSCoder protocol methods (encodeWithCoder: and initWithCoder:) for instance.
Without delegates, could you provide any uses cases for protocols (other than achieving polymorphism? I see that some methods could be abstracted away from base classes and grouped into an interfaces but without any implementation (as mixins for instance), what is the significant use?
First, protocol methods are not special in any way. They, like every other Objective-C method, gets called by a message sent to an object. There's nothing special about that part of things. Protocols are basically just a hint to the compiler, though you can query whether an object conforms to one at runtime and make decisions based on that.
You can verify this by implementing a protocol method (or the entire protocol) without declaring that fact in a classes' interface, and call the function on an instance of that object after casting it to be id<YourProtocol>, and it will work.
You can (and sometimes should) call NSCoding methods yourself -- you may decide that you want to persist objects to the disk, and that this is the best way to do it.
NSCoding is actually a great example of why protocols are still useful even though they do not provide any implementation -- the implementation of initWithCoder: and encodeWithCoder: will be different for every class that implements them -- there is no sense in providing an implementation.
Building on that, consider the datasource property of a UICollectionView; as there is no multiple inheritance in Objective-C, it would be undesirable for the datasource to be a class itself, as that would prevent you from using a UIViewController as the data source, and force you to make a whole new class for that express purpose.
Protocols can also be used to implement multiple inheritance in a type safe way without redeclaring the interface of the giver in the inheritor. If the entire interface of the class being inherited from is a protocol, then the inheritor can simply conform to that protocol as well.
Objective-C does provide mixins in the form of Categories, which can implement protocols on existing classes.
For a full throated defense of protocols (in Swift), see the Protocol-Oriented Programming WWWDC 2015 talk.
Taking the example of the NSCoding Protocol, the two required methods in the protocol, basically implement the steps an object should perform to encode itself to be archived. It also implements the initWithCoder to recreate the object from the archive.
Lets say you create a custom object, only your object knows which properties it needs to archive.
When you call a method to archive your custom object, the method call ultimately flow to your encodeWithCoder or initWithCoder to take action specific to your class.
***** Updated ****
Looking at this with an example :
Lets say our data structure looks like this
someArray = [String,CustomObject,aDictionary]
When we want to archive someArray, we call the archiveRootObject method on it. Now inorder for someArray to archive itself, it needs all its contained items to inturn archive themselves. The Array simply instructs the sub items to archiver themselves calling the encodeWithCoder method on them.
By adopting and conforming to the NSCoding protocol, you are just confirming to the root array that Yes, I know how to archive and unarchive myself.
Hope this helps.

I need to understand why delegation in Objective-C is so important, what makes it so special?

So I've read about delegate explanation and practices a lot, but I still seem to not get it, I have specific questions and I would love to have some insightful simple answers.
Why use delegate over instance method? In UIAlertView why not just make – alertView:clickedButtonAtIndex: an instance method that will be called on my UIAlertView instance?
What is the delegate property? why do I have to make delegate property and define it with that weird syntax #property (nonatomic, strong) id <ClassesDelegate> delegate
Is delegate and protocol are two faces for a coin?
When do I know I should implement delegate in my app instead of direct calling?
Is delegate used as much and as important in Swift?
What gets called first and why? The method in the class who made himself a delegate? or the delegate method itself in class where it is declared?
Thank you for taking the time to go through this, I am desperately looking for a clear and helpful answers to my questions, feel free to give example or cover some related topic!
The advantage of delegation is Dependency Inversion.
Usually code has a compile-time dependency in the same direction of the run-time calling dependency. If this was the case the UITableview class would have a compile-time dependence on our code since it calls our code. By using delegation this is inverted, our code has a compile-time dependency on the UITableview class but the UITableview class calls our code at run-time.
There is a cost involved: we need to set the delegate and UITableview has to check at run-time that the delegate method is implemented.
Note: When I say UITableview I am including UITableviewDelegate and UITableviewDatasource.
See: Dependency inversion principle and Clean Code, Episode 13.
Maybe a real life example can better describe what's different in the delegation design pattern.
Suppose you open a new business, and you have an accountant to take care of the bureaucratic stuffs.
Scenario #1
You go to his office, and give him the information he needs:
the company name
the company # number/id
the number of employees
the email address
the street address
etc.
Then the accountant will store the data somewhere, and will probably tell you "don't forget to call me if there's any change".
Tomorrow you hire a new employee, but forget to notify your accountant. He will still use the original outdated data you provided him.
Scenario #2
Using the delegation pattern, you go to your accountant, and you provide him your phone number (the delegate), and nothing else.
Later, he'll call you, asking: what's the business name?
Later, he'll call you, asking: how many employees do you have?
Later, he'll call you, asking: what's your company address?
The day after you hire a new employee.
2 days later, he'll call you asking: how many employee do you have?
In the delegation model (scenario #2), you see that your accountant will always have on demand up-to-date data, because he will call you every time he needs data. That's what "don't call me, I'll call you" means when talking of inversion of control (from the accountant perspective).
Transposing that in development, for example to populate a table you have 2 options:
instantiate a table control, pass all the data (list of items to display), then ask the table to render itself
instantiate a table control, give it a pointer to a delegate, and let it call the delegate when it needs to know:
the number of rows in the table
the data to display on row no. n
the height the row no. n should have
etc.
but also when:
the row no. n has been tapped
the header has been tapped
etc.
Firstly, don't feel bad that all if stuff isn't clear yet. This is a good example of something that seems tricky at first, but just takes time really click. That will happen before you know it :-). I'll try and answer each of your points above:
1) Think of it this way - the way UIAlertView works now, it allows Apple to “delegate” the implementation of the alertView:clickedButtonAtIndex: to you. If this was an instance method of UIAlertView, it would be the same implementation for everyone. To customize the implementation would then require subclassing - an often over relied upon design pattern. Apple tends to go with composition over inheritance in their frameworks and this is an example of that. You can read more on that concept here: http://en.wikipedia.org/wiki/Composition_over_inheritance
2) The delegate property is a reference to the object which implements the delegation methods and whichs should be used to “delegate” those tasks to. The weird syntax just means this - a property that holds a reference to an object that adheres to the protocol.
3) Not quite - delegation leverages protocols as a means for it’s implementation. In the example above, the is this the name of a protocol that an object which can be considered a delegate for that class must adhere to. It is inside that protocol that the methods for which a delegate of that class must implement are defined. You can also have optional protocol methods but that’s a different topic.
4) If I understand the question correctly, I think a good sign that you may want a delegate to be implemented instead of simply adding instance methods to your object is when you think that you may want the implementation of those methods to be easily swapped out or changed. When the implementation of those methods changes considerably based on where/how the functionality your building is being used
5) Absolutely! Objective-C and Swift are programming languages and the delegation pattern is an example of a design pattern. In general design patterns are hoziontal concepts that transcend across the verticals of programming languages.
6) I’m not sure I understand you exactly but I think there’s a bit of misunderstanding in the question - the method does not get called twice. The method declared in the delegate protocol is called once - typically from the class that contains the delegate property. The class calls the delegates implementation of that property via something like:
[self.delegate someMethodThatMyDelegateImplemented];
I hope some of this helped!
Sometimes you want your UIAlertView to work different in different contexts. If you set your custom UIAlertView to be delegate of itself it has to provide all those contexts (a lot of if/else statements). You can also set seperate delegate for each context.
This way you say to your compiler that every class (id) which implements protocol ClassesDelegate can be set to this property. As a side note it should usually be weak instead of strong to not introduce reference cycle (class A holds B, and B holds A)
Protocol (interface in other languages) is used to define set of methods which should be implemented by class. If class conforms to the protocol you can call this methods without knowledge of the specific class. Delegate is pattern in which class A delegates some work to class B (e.g. abstract printer delegates his work real printer)
When you need few different behaviours which depends on context (e.g. ContactsViewController needs to refresh his list when download is finished, but SingleContactViewController needs to reload image, labels etc.)
It is one of the most fundamental patterns in programming, so yes.
It's the same method
You can't just add a method to UIAlertView, because you don't have the source code. You'd have to subclass UIAlertView. But since you have more than one use of UIAlertView, You'd need several subclasses. That's very inconvenient.
Now let's say you use a library that subclasses UIAlertView, giving more functionality. That's trouble, because now you need to subclass this subclass instead of UIAlertView.
Now let's say that library uses different subclasses of UIAlertview, depending on whether you run on iOS 7 or 8, and UIAlertview unchanged on iOS 6. You're in trouble. Your subclassing pattern breaks down.
Instead, you create a delegate doing all the things specific to one UIAlertview. That delegate will work with the library just fine. Instead of subclassing a huge and complicated class, you write a very simple class. Most likely the code using the UIAlertview knows exactly what the delegate should be doing, so you can keep that code together.

Multiple Delegates in iOS

I am making an object that goes to download stuff for all of my view controllers. The object is singleton instance and has a callback method with received data once the download is completed. It also has a delegate property so that it knows which object to call back to after the download is done.
There are multiple controllers that use this shared instance, and my question is how to call back to the correct view controller that requested the download.
My approach is to use delegation, but the problem is that since other view controllers are also its delegate, the download object could call back to every object and this will be hard to track.
I've worked on projects where people have attempted to use multiple delegates and it's basically a bad idea. The delegate pattern is about a 1 to 1 relationship between a class and it's delegate. Whilst it is possible to achieve some level of multiple delegation through switching the delegates in and out, it's more likely to lead to unpredictable behaviour and bugs.
My recommendation would be to change how you are thinking about this. You have two options as I see it:
Switch to an Observer pattern where you can register multiple observers which your main class can interact with. This is useful where your observers all implement the same protocol and where your main class wants to be aware of the observers and interaction with them.
Broadcast NSNotifications to indicate state changes and events. Here is a more decoupled approach because the main class does not need to know who is listening and does not directly interact with them. Other can start and stop being notified at their leisure. It also has the advantage that you do not need to create or implement a separate protocol. Instead you register the classes that need to know about changes with the NSNotificationCenter which in turns handles all the routing of notifications for you.
It actually sounds like the delegate pattern might not be the best approach here.
I would look into NSNotificationCenter instead.
The basic idea is that your singleton doing the net connection posts a notification (with something like postNotificationName:object:userInfo:) , saying that new data is available. Within this notification, you can pass a dictionary object (userInfo) that holds the data you've fetched, or info on what parts of your Model contain updated data.
Then, your other view controllers can register themselves to 'observe' these notifications by calling addObserver:selector:name:object:. Generally speaking, when a vc becomes visible I call addObserver, and removeObserver when it's being hidden or transitioned out.
Good luck!
Delegation doesn't seem like the right solution to this problem. How about requiring the requesting view controller to provide an object (its self) and a selector for you to call as a completion notification? Of course, you'll need a place to store that object and selector until the download completes. Hopefully you have (or could create) an object for this.
i recommend to use one of these ways
observer:
when use data that you want to inform other object are near to primitive ones.for example when you are using 'NSMutableArray' you can not inform the change in one of object by the standard implemented pattern at least you need to implement one for your self that is not reusable that much
Notification
when your interaction with destination object (those need to be inform) is in one-way.it means you don't need any acknowledge or other data back from them.
delegate
when there is one object to inform at each time step.
note:block use for success and fail is not a pattern to broadcast data its about to queue task when you don't know when they are finishing or failing like network operations
EDIT:
how to create notification | multi delegate issues and implementation
While I agree with most of the answers here, if you did actually want to achieve multiple delegates you could potentially declare an array of delegates and send messages to all delegates within that array. If your protocol has optional delegate methods you safely check using responds(to aSelector: Selector!) -> Bool before invoking (being mindful of memory management, as those delegates would be strongly referenced in the array). Again I do agree that multiple delegates is likely a bad architectural idea and using blocks or notification center would suit your needs better.
One approach, which works for me if you only have one other object to forward messages to is to create a forwardingDelegate This does not end up with issues of hard to debug ordering of delegates and it does not unnecessarily create a dependency on the other object. Keep in mind, if you have many objects then this might not be the best approach, it is mainly for one additional object but this could be extended to support an array of objects so long as there is one that receives the SDK and forwards it to the other objects [1]. Note that every method that is needed for the forwarded object needs to pass it along, even if it is not used by the forwarding object.
For example, if I need to forward the messages coming from the mapView delegate:
- (void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated
{
// handle this object here.
if ([self.forwardingDelegate respondsToSelector:#selector(mapView:regionDidChangeAnimated:)])
{
[self.forwardingDelegate mapView:mapView regionDidChangeAnimated:animated];
}
// or handle this object here.
}
[self.forwardingDelegate mapView:mapView regionDidChangeAnimated:animated];
The forwarding property would be declared like this.
#property (nonatomic) id<MKMapViewDelegate> forwardingDelegate;
And the other object would adopt the protocol as if it were receiving the original message.
[1] The array approach for multiple delegates may get tricky because then you don't have as much control over what order the delegates get called, as was mentioned in other posts.

Why only one delegate?

I've read that an object can only have one delegate at once.
But is that really true?
Let's say I make an object with a protocol and from that object I want to gather a lot of data from several other objects. I add every object that conforms to my protocol to an array. Then I just loop through it and call my methods on every delegate.
NSMutableArray *collectFromDelegates = [NSMutableArray alloc]init];
//in delegateArray I keep pointers to every delegate.
for(id delegate in delegateArray){
[collectFromDelegates addObject:[delegate someProtocolMethod]];
}
Is this wrong?
That's not really delegation.
Delegation is a simple and powerful pattern in which one object in a program acts on behalf of, or in coordination with, another object. The delegating object keeps a reference to the other object—the delegate—and at the appropriate time sends a message to it. The message informs the delegate of an event that the delegating object is about to handle or has just handled.
It doesn't make much sense to have more than one object handle an event for you, since it has already been handled. The only reason I could see to have multiple delegates is that if the first fails to handle an event, it can be passed to the next, continuing until some object handles it.
In your example, the objects are acting as data sources. This makes more sense than multiple delegates, but could easily be implemented by having a single data source combine data from multiple objects, which means the object asking for the data doesn't have to worry about how to combine it.
The other case where you would often want multiple objects is receiving notifications of an event. This is not delegation because the objects are not working for the object, just acting on something that happened to the object. This is better implemented using notifications or observing.
Apple's convention is to only have one "delegate" object. But you can set up your own class to have an array of delegates if that's what you need. You might want to call them something else for clarity.
In your example, calling them "dataSources" might be more appropriate.
A class only really needs one delegate, if you have more than one you are solving a different problem. The delegate pattern is used to modify the behaviour of a class. Say for instance we have a Dog class which can bark, but different types of dogs bark in different way. A delegate would be one way of changing the barking behaviour.
If you need more than one you are probably more interested in OBSERVING what your class is doing, it needs to NOTIFY others of current EVENTS. As several other classes might be interested in the behaviour of one you would need an array. In iOS SDK this is already done for you with notifications. This is called the Observer pattern.
Different use cases...
I've read that an object can only have one delegate at once. But it's that really true?
Where did you read that? No, it's not true. For instance, UITableView has two delegates, one to supply the data, the other to handle actions.
A delegate is just an abstract concept - you can have as many delegates as you want. However, this is rarely required and often a poor pattern.
Apple make good use of a source and delegate pattern. Source ivars (a form of delegate) provide data, while delegate ivars are invoked for logical responses. Perhaps this is a better solution?
Alternatively you can use NSNotification to inform many listeners of a single event.
Hope this helps!
Generally, when you want to message multiple classes that are interested in what you class does, you would use NSNotifications. That will however not allow them to return data unless you allow them to send a message to the object of the notification. I'm not sure if that would be a cleaner solution though.
One approach beside the mentioned Notifications could be, that your delegate implementation holds an array of objects conforming to the protocol and calls the protocols method on this as a wrapper.

What is the purpose of an iOS delegate?

I understand what a delegate does in iOS, and I've looked at sample code, but I'm just wondering about the advantages of this type of encapsulation (as opposed to including delegate methods in the primary object).
The advantage of the delegate design pattern is loose coupling. It enables class A (the delegate) to depend on class B (the delegating class) without class B having to have any knowledge of class A. This ensures that the dependency relationship is one-way only, rather than being circular.
It also forms the foundation (lower case "f") of Apple's frameworks because it allows them to invoke your code as appropriate when functionality specific to your application is required. For example, responding to a button tap or telling a table view how many sections there should be.
Delegation is a design pattern not only used in iOS but many other languages. It enables you to hand values and messages over in your class hierarchy.
In iOS, delegation requires the "delegate" class to implement a protocol which contain methods that the "delegating" knows about. Still following?
The delegating class's implementation will call these protocol methods, but the delegate class will implement these methods in their class.
This keeps your Classes clean.
In reality, you don't really need delegation if you can add new methods to a single class. But for UIKIT's UIView class, Apple will not allow you to add new implementations to their class.
correct me if I'm wrong.
The most common use of a delegate in iOS is to establish communication within modules that are unrelated or partially related to each other. For example, passing data forward in a UINavigationController is very easy, we can just use segue. However, sending data backwards is little tricky. In this case, we can use delegate to send the data backward.
Let's call, the class, associated with the first Controller ClassA and the class, associated with the second Controller ClassB. The first Controller is connected to the second controller with a forward segue. We can pass data from ClassA to ClassB through this segue. Now, we need to pass some data to ClassA from ClassB for which we can use delegates.
The sender class(ClassB) needs to have a protocol in its header file(.h) and also a reference of it as delegate inside the block, #interface ClassB .... #end. This reference let's the ClassB know that it has a delegate. Any class that wants to use this ClassB will have to implement all of this protocol's required methods(if any). So, the receiver class,ClassA will implement the method but the call will be made by the sender class, ClassB.
This way, receiver class doesn't need to worry about the sender class' internal structure, and can receive the required information.
Delegation as I understand it is when an object will pass the responsibility of handeling an event to another object thus "delegating" the responsibility to that object.
For example if you have an NSButton in iOs you generally assign the Delegate to be the parent view controller. This means instead of handeling touchUp events in the definition of the button it is instead handled in the view controller.
The main advantage of delegation over simply implementing methods in the "primary object" (by which I assume you mean the object doing the delegating) is that delegation takes advantage of dynamic binding. At compile time, the class of the delegate object does not need to be known. For example, you might have a class that delegates the windowDidMove: method. In this class, you'd probably see some bit of code like
if([[self delegate] respondsToSelector:#selector(windowDidMove:)]) {
[[self delegate] windowDidMove:notification];
}
Here, the delegating class is checking at runtime whether its delegate responds to the given method selector. This illustrates a powerful concept: the delegating class doesn't need to know anything about the delegate other than whether it responds to certain methods. This is a powerful form of encapsulation, and it is arguably more flexible than the superclass-subclass relationship, since the delegator and the delegate are so loosely coupled. It is also preferable to simply implementing methods in the "primary object" (delegating object), since it allows runtime alteration of the method's implementation. It's also arguable that this dynamic runtime makes code inherently more dangerous.
Delegate is an important design pattern for iOS app.All apps directly or behind the hood use this delegate pattern.
Delegate design pattern allows an object to act on behalf of another.
If we are working with tableview then there are "tableViewDelegate" and "tableViewDataSource". But what this means
Suppose you have a tableview.
now some major concern for this.
1.what is the datasource(the data that will appear in table view) for this tableview?
2.How many row for table view etc.
delegate design pattern solve these question using another object as the provider or the solver of these question.
An object mark himself to the table view and ensure the table view that "Yes i am the man who can assist you" by marking himself as the delegate to the table view .Thanks
The class marked as delegate takes the responsibilities to handle the callbacks sent while some event occurs. For example, in case of UITextField, there are some methods called when some events occurs like editing started, editing ended, character typed etc. These methods will already be defined in the protocol. We will have to assign delegate for that i.e. which class is going to handle these events.
With the help of a delegate, two-way communication can be achieved. A delegate might be used to make an object reusable, to provide a flexible way to send messages, or to implement customization.
In iOS ecosystem especially UIKit Framework which consists of UIApplication, UITableView, UICollectionView, UITextfield & so on uses delegate & datasource design pattern intensively to communicate data to and fro.
Delegate design pattern is used to pass/communicate data from FirstVC(Delegator) to SecondVC(Delegate) to complete a task.
Here, SecondVC(Delegate) conforms to a protocol delegate & implements all its requirements like methods by providing body to complete that task given by FirstVC(Delegator).
Also, FirstVC(Delegator) object will be having a optional property of protocol delegate type i.e delegate which must be assigned by SecondVC(Delegate).
Now, FirstVC(Delegator) can call that method residing in SecondVC(Delegate) by passing data from its delegate property.
EX: CEO(FirstVC) which passes data i.e "confidential data" to Secretary(SecondVC) to do further processes using that data.
Datasource design pattern is part of Delegate pattern which is used to pass/communicate data from SecondVC(Delegate) to FirstVC(Delegator) when a task is assigned to SecondVC(Delegate).
Here, SecondVC(Delegate) conforms to a protocol datasource & implements all its requirements like methods with return type by providing body to talk back to FirstVC(Delegator) after the task is given by FirstVC(Delegator).
Also, FirstVC(Delegator) object will be having an optional property of protocol dataSource type i.e dataSource which must be assigned by SecondVC(Delegate).
Now, FirstVC(Delegator) can call that method with a return type residing in SecondVC(Delegate) by passing data from its dataSource property.
EX: Secretary(SecondVC) replies back with a data i.e "Sir, I am already having too much work to do. Please, can you assign that data to others" to CEO(FirstVC). Now, CEO(FirstVC) will analyse that data to do further processes.
Delegation means one object passes behaviour to another object..

Resources