1

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.

user3569109
  • 191
  • 8

1 Answers1

1

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.

Duncan C
  • 128,072
  • 22
  • 173
  • 272
  • Thank you very much!! You saved me!! I wrote the code like your answer and solved the problem. In your answer there is a saying like "You have several options." If you can, I will ask you for additional answers to other implementations. – user3569109 Feb 10 '17 at 15:36