iOS – Subclassing to avoid code duplication and protocols - objective-c

I need all my view controllers to be able to show the Message compose view controller (MFMessageComposeViewController) and also handle MFMessageComposeViewControllerDelegate method to see whether a message was sent/cancelled/failed. So my idea was to subclass UIViewController impement these methods in this view controller. And then have all my view controllers that need to be able to send messages subclass the above view controller.
So like BaseMessageViewController : UIViewController
And then ViewController1 : BaseMessageViewController, ViewController2 : BaseMessageViewController and so on...
So when I was at it, I thought I would create a protocol like this:
#protocol MessageProcessing
#required
- (void)presentMessageCompose;
- (void)processMessageCancelled;
- (void)processMessageSent;
- (void)processMessageFailed;
#end
But I'm not sure if BaseMessageViewController should conform to this protocol or if my "concrete" view controllers should conform to it?
One thought was that if my BaseMessageViewController conforms to it then my concrete view controllers would automatically conform to it because of class inheritance? But I'm not seeing any warnings in my concrete view controllers that they are not implementing a required method.
Can someone please give me a helping hand here :)

If these are messages that BaseMessageViewController sends to self, there's no reason to define a protocol. Just declare the methods in BaseMessageViewController, and comment the declarations to describe when they are sent.
You will also need to provide implementations of the methods in BaseMessageViewController to suppress a compiler warning. If you want every subclass to implement the methods, you can define the methods in BaseMessageViewController using this pattern:
- (void)processMessageCancelled {
[self doesNotRecognizeSelector:_cmd];
abort();
}

This is a classic example of the Abstract Base Class vs protocol question.
Use an Abstract Base Class (in Cocoa these are called Class Clusters) when you'd like to define a framework, with some common concerns encapsulated by the framework and some specific concerns to be handled by sub-classes. An example could be a message parsing framework.
Use a Protocol to define a common contract for classes that need their own object hierarchy. An example might be a media player, where 'play' and 'stop' are completely different depending on the type of media.
Alternatively, for something in-between, Justin Spahr-summers defines the 'concrete protocol' in libextobjc. . . https://github.com/jspahrsummers/libextobjc (similar to concrete interfaces in Java 8).

Related

Why does Xcode "does not conform to protocol fix-it" adds many methods

Xcode has a new "fix-it" feature for automatically implementing protocol methods. Here is an example:
MFMessageComposeViewControllerDelegate has only a single method. However, when I click "fix" button, Xcode creates MANY irrelevant method stubs:
I haven't added any new other protocols, it's just as follows:
#interface TUDiscoverInviteViewController ()<CNContactPickerDelegate, MFMessageComposeViewControllerDelegate>
#end
My view controller only derives from UITableViewController. Where are those method stubs coming from and how can I prevent this behavior?
I'm on Xcode 9.2.
UITableViewController conforms to UITableViewDataSource and UITableViewDelegate, so you get those method stubs too.
I don't see a way to get Xcode to only generate stubs for one protocol, except by temporarily removing the other protocols and changing your base class.
If you use AppCode, then you can use AppCode's Code > Generate > Implement Methods interface to select which members you want stubs for:

why must i inherit NSobject instead of NSapplication to implement delegate method on GNUSTEP?

I've seen several Obj-C tutorials. The delegate classes all inherit from NSObject. For example, the applicationDidFinishLaunching delegate method, in some tutorials, it inherited from NSObject but NSApplication to implement it. The reason I don't think it should inherited from NSObject is that I didn't find any delegate protocol declaration in it, but I found that delegate protocol declaration in NSApplication. My Objective-C toy environment is GnuSep.
Here is some code:
#interface browserController : NSObject //here. inheriting from NSObject,but NSObject don'have any protocols declaration about applicationDidFinishLaunching.
{
NSBrowser *browser;
}
#end
#implementation browserController
- (void)menuAction:menuItem
{
..............................
}
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
NSWindow *win;
ActiveBrowserDelegate * abd;
WindowDelegate *wd;
NSRect wf = {{100, 100}, {600, 500}};
NSRect bf = {{10, 10}, {580, 350}};
.............................
}
It is called informal protocol (though GNUstep declared it anyway as GSAppDelegateProtocol for documentation purpose) NSApplication will simply check it at runtime if your delegate object will respond to the message, (using -respondsToSelector:) A delegate can be a view, a string, a proxy, anything as long as you make it responds to the selector. You don't need to make your delegate implement every method in such protocol since all verifications would be done at runtime. To make it looks cleaner you could just redeclare -applicationDidFinishLaunching: in #interface though you don't really need to, just make one in the #implementaiton is enough.
A delegate may inherit from anything appropriate. It is usually supposed to implement a certain protocol.
A protocol is a way of implementing a formal communication interface between two classes.
However, it is most unlikly that a delegate will inherit from its communication partner class.
With other words: Protocols are often used to overcome the unavailability of multiple inheritance. (Pretty much like interfaces in Java)
Example: A UIViewController subclass' instance controls a view that contains a UITableView. Rather than subclassing the UITableView for the implementation of its look or data, there are two delegates assigned to the table view object. One delegate serves as provider for custom layout (provides items such as the header view) and another (?) delegate provides the data that is being displayed.
Now, this delegate could be any object, inheriting from NSObject and implementing the two protocols. This object cold then be instanciated by the view controller and assigned to the table.
However, it is common practice that the view controller itself serves as delgate for the table(s) that it controls. That is a good pattern but strictly spoken not required. It could be any object.
Now the custom view contoller inherits from UITableViewController (which already implements the protocols and inherits from ViewController) and serves as delgate for the table view. The table view itself could be any subclass of UITableView. (Although this is a bad example here because subclassing UITableView is normally not advisable)
If the delegate does not need to inherit from any class and just implements the protocol, then it shold at least inherit from the cocoa base class NSObject. That ensures that it inherits all the usual capabilites and behaviour of any object. (init method, copy method, description method etc.) That may be required to work properly with other classes of the framework such as beeing used as an object within an NSArray, NSLog etc.

What's the benefits of conforming to a protocol and do I need to declare it so if a superclass does?

I'm writing a quick simple table view app. I've declared the view I'm creating the table view in to be a subclass of UITableViewController. UITableViewController conforms to the UITableViewDelegate and UITableViewDataSource protocols.
My question is, does my view which is the subclass of UITableViewController, also need to state it conforms to these protocols?
Also what is the advantage on conforming to a protocol, meaning putting after the subclass? The code I write works provided the methods are there regardless of the protocol being mentioned in the header.
Does it make a difference if I added a UITableView into a UIViewController subclass?
Since you inherit from a class that conforms to those protocols, no, you do not need to state that you conform to them in your subclass.
The advantage to stating that you conform to your protocol is that some delegate properties will require an instance of a class that explicitly states it conforms to them. Also, it's just a good idea to state that you conform to a protocol if you, in fact, do.

ios & obj-c methods that do not need declaration in header

I was checking some video at Lynda.com about iphone development.
The guy was adding custom data to a picker, but to add the data he was not declaring the methods in the header file. He was checking which nethods he needed on the documentation and copying pasting those methods declarations in his controller class.
For exampe this method
-(int) numberOfComponentsInPickerView: (UIPickerView *) pickerView
Why doesn't we need to declare those methods on the header file?
If those methods pertain to the picker class, why do we declare them in the controller class instead of simply calling them in the picker IBOutlet instance?
TIA
When you declare in your header that you follow a certain protocol, you are essentially saying that you agree to implement the methods defined in the protocol.
I'll bet he added something like this to the header:
<UIPickerViewDataSource>
That means that he is implementing the UIPickerViewDataSource protocol.
So, by implementing the UIPickerViewDataSource protocol, you are implying those methods, therefore, they do not need to be prototyped.
If those methods pertain to the picker class, why do we declare them in the controller class instead of simply calling them in the picker IBOutlet instance?
The method you quoted does not belong to the UIPickerView class, but rather to the UIPickerViewDataSource protocol. Your controller acts as a "helper" for the picker, so the picker is calling your controller if it needs to figure out how many components it should display. You are usually not calling this method yourself.
As another answer pointed out, by declaring that you implement the protocol, the methods of that protocol are implicitly declared. By adding <UIPickerViewDataSource> to your interface, you're basically saying "I can act as a data source for a picker view and I'm ready for any picker that wants to call the methods that are declared in the protocol".

Objective C protocol as an equal to Java Interface?

The question is not only regarding the headline, but more of a "how will I achieve this, without trying to force a Java/Flash design into an Objective C (iPhone)program".
I have 6 views that extends UIView, these views all have different behavior but share certain methods, like -(void) update and -(void) changeState:(NSInteger)state.
A viewController, whose job is it to update, instantiate and display these views has a switch block to do this. So switch(4) {...} instantiates UIView4, but as I need a reference to the currently instantiated view (to do update and changeState:), I have a UIView property on my ViewController called self.currentView. As the instantiated UIView4 extends UIView I can easily go [self.currentView addSubview:UIView4instance] and then release the UIView4instance.
Now how will I call the [UIView4instance update] method on the view? or the [UIView5instance changeState] etc. etc.
Since I added it to self.currentView which is of type UIView it no longer has any reason to believe it has an update or changeState: method, meaning I cannot iterate the views and send them these messages.
This approach brings on a ton of other problems, I would need to test and typeCast my views each time I needed to do any operations on them.
If I were doing something like this Composite Pattern approach in, say, Java. I would either write an interface that all the views (UIView1, UIview2.... UIViewN) would implement. Or maybe an abstract class that all the views inherited the changeState: and update methods from.
This way I could have self.currentView just know that I'm adding objects to your view and they all conform to these methods.
The two solutions I can think of, with my very small Objective-C experience is:
doing it with delegation or categories, but this seems overkill in every way :/
I guess I could also extend UIView and then extend my class extending UIView again, but there is probably a reason Objective-C does not directly support abstract classes...
Hope someone could point me in the right direction regarding these issues.
Thanks:)
Yes it is equal. You can declare a protocol
#protocol MyViewProtocol
-(void)update;
-(void)changeState:(NSInteger)state;
#end
and declare your subclasses like
#interface MyUIView3 : UIView<MyViewProtocol> {
....
}
....
#end
Then, the declaration
UIView<MyViewProtocol>* view=[[MyUIView3 alloc] init];
means that view is an instance (of a subclass of) UIView which also conforms to MyViewProtocol.
Just the way it works in Java, I think. See the apple doc on protocols.
One thing to be aware of is that while defining a protocol like this is a convenience and certainly makes things clearer, it is by no means necessary to make your solution work. Objective-C binds methods at runtime, and so all you really need to do is to make sure all your view classes implement the methods you care about and call them.
You will get a complier warning for this, but it will work.
Now, in general it's probably preferable to define a protocol like this and it's what I generally do. But it's also important to remember that runtime binding is there and can be incredibly powerful.