iosobjective-cuiviewcontrollermfmessagecomposeviewcontroller

Refactoring ViewController(repetitive logic)


In my app, every ViewController has the same logic. I want to extract it into one class.

Here's my case.

Every ViewController has a variety logic to send an iMessage. The total number of view controllers is about 50.

This is first VC.

@interface FirstViewController : UIViewController <MFMessageComposeViewControllerDelegate>
....
- (void)sendMessage {
    MFMessageComposeViewController *mfvc = [[MFMessageComposeViewController alloc] init];
    .....
    [self presentViewController:mfvc animated:YES completion:^{}];
}

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

This is second VC.

@interface SecondViewController : UIViewController <MFMessageComposeViewControllerDelegate>
....
- (void)sendMessage {
    MFMessageComposeViewController *mfvc = [[MFMessageComposeViewController alloc] init];
    .....
    [self presentViewController:mfvc animated:YES completion:^{}];
}

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

There are about 50 such view controllers.

So, I want to change this as follows.

@interface SendMessageHelper : XXX <MFMessageComposeViewControllerDelegate>
....
- (void)sendMessage:(NSString *messageBody) {
    // All the code that sends the iMessage include "presentViewController"
}

// Delegate
- (void)messageComposeViewController:(MFMessageComposeViewController *)controller 
                 didFinishWithResult:(MessageComposeResult)result {
    // Dismiss iMessage ViewController
}

///////////////////////////////////////////////////////////////////

@interface FirstViewController : UIViewController 
....
- (void)sendMessage {
    // Just call SendMessageHelper's sendMessage:
}

@interface SecondViewController : UIViewController 
....
- (void)sendMessage {
    // Just call SendMessageHelper's sendMessage:
}

....

@interface FiftiethViewController : UIViewController 
....
- (void)sendMessage {
    // Just call SendMessageHelper's sendMessage:
}

Is it possible to handle all MFMessageComposeViewController related logic and delegates in separate classes? How can I implement it?

If it is not possible, please advise a better way.


Solution

  • You have several options. You can create a subclass of UIViewController that implements your methods and make all of your 50 view controllers be subclasses of this custom subclass.

    It might be better in this case to create a category on UIViewController with these methods added:

    The header:

    @interface UIViewController (Messages);
      // Delegate
      - (void)messageComposeViewController:(MFMessageComposeViewController *) controller 
        didFinishWithResult:(MessageComposeResult)result;
    @end
    

    The .m file:

    @implementation UIViewController (Messages) {
      - (void)sendMessage {
          MFMessageComposeViewController *mfvc =[[MFMessageComposeViewController alloc] init];
          .....
          [self presentViewController:mfvc animated:YES completion:^{}];
      }
    
      // Delegate
      - (void)messageComposeViewController:(MFMessageComposeViewController *)controller 
        didFinishWithResult:(MessageComposeResult)result {
          [self dismissViewControllerAnimated:YES completion:^{}];
      }
    @end
    

    Then if you #import the header file those methods will become available.