shopify analytics

Refactor repetitive logic in View Controllers using Category

Say you have some repetitive logic handling delegate and similar method across multiple view controllers, like this :

FirstViewController.m

@interface FirstViewController : UIViewController <MFMessageComposeViewControllerDelegate>
//....
@end

@implementation
- (void)sendMessage {
    MFMessageComposeViewController *mfmvc = [[MFMessageComposeViewController alloc] init];
    //.....
    [self presentViewController:mfmvc animated:YES completion:^{}];
}

// Delegate
- (void)messageComposeViewController:(MFMessageComposeViewController *)controller didFinishWithResult:(MessageComposeResult)result {
    //...
    [self dismissViewControllerAnimated:YES completion:^{}];
}
@end



SecondViewController.m

@interface SecondViewController : UIViewController <MFMessageComposeViewControllerDelegate>
//....
@end

@implementation
- (void)sendMessage {
    MFMessageComposeViewController *mfmvc = [[MFMessageComposeViewController alloc] init];
    //.....
    [self presentViewController:mfmvc animated:YES completion:^{}];
}

// Delegate
- (void)messageComposeViewController:(MFMessageComposeViewController *)controller didFinishWithResult:(MessageComposeResult)result {
    //...
    [self dismissViewControllerAnimated:YES completion:^{}];
}
@end


Grouping with Category

You can place the repeating method into a Category of UIViewController

Right click on your Xcode project and create a new file.

Select 'New File'

Select Objective-C File (or Swift File if you are using Swift)
Select 'Objective-C File'



For the File Type select Category, for the Class select UIViewController, then type in the name you want.
File type select 'Category'

This will create two file UIViewController+Messaging.h and UIViewController+Messaging.m .

Move the repeating logic to UIViewController+Messaging.m file and add method declaration in UIViewController+Messaging.h for non-delegate method which will be called.



UIViewController+Messaging.h

#import <UIKit/UIKit.h>

@interface UIViewController (Messaging)
- (void)sendMessage;
@end



UIViewController+Messaging.m

#import "UIViewController+Messaging.h"

@implementation UIViewController (Messaging)

- (void)sendMessage {
    MFMessageComposeViewController *mfmvc = [[MFMessageComposeViewController alloc] init];
    //.....
    [self presentViewController:mfmvc animated:YES completion:^{}];
}

// Delegate
- (void)messageComposeViewController:(MFMessageComposeViewController *)controller didFinishWithResult:(MessageComposeResult)result {
    //...
    [self dismissViewControllerAnimated:YES completion:^{}];
}

@end



And then import this category in the view controllers mentioned previously.



FirstViewController.m

#import "UIViewController+Messaging.h"
@interface FirstViewController : UIViewController <MFMessageComposeViewControllerDelegate>
//....
@end

@implementation

@end



SecondViewController.m

#import "UIViewController+Messaging.h"
@interface SecondViewController : UIViewController <MFMessageComposeViewControllerDelegate>
//....
@end

@implementation

@end



This will reduce code repetition and make it easier to edit on a single file. You can import the category easily to another view controller should it need these method in the future.

Note : The convention is to add a prefix using a unique name before the method (non-delegate) in Category to prevent clash with other category.

Axel Kee

Heya! I am Axel, I like to draw, code and occasionally write

Kuala Lumpur