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

Read more posts by this author.