Is there another way of launching the Messages app in iOS? (for donations)

You can set the body as well, but you have to escape the string.

NSString *sms = @"sms://+1234567890&body=This is the body.";

NSString *url = [sms stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:url]];

Yes and No.

On a basic level: NO. I have had a look through the docs and you (rather frustratingly) cannot set a body for your message when calling the Messages app externally.

You can only:

  1. Open the messages app

    [[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"sms:"]];
    
  2. Input a number to message to

    [[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"sms:+1234567890"]];
    

More Complex: YES. Here is the method and code to send an SMS with body. It presents a view exactly like the messages app as a ModalView. And for reference you can read the docs here.

  1. Import the MessageUI Framework to your project

  2. Add these to the .h of the view that the action to send a message is on (in my case a simple view with a single button).

    #import <MessageUI/MessageUI.h>
    #import <MessageUI/MFMessageComposeViewController.h>
    
  3. The important code to send the message should be similar to:

    -(IBAction)sendSMS:(id)sender {
    
        if([MFMessageComposeViewController canSendText]) {
            MFMessageComposeViewController *controller = [[MFMessageComposeViewController alloc] init];
            controller.body = @"Hello";
            controller.recipients = [NSArray arrayWithObjects:@"+1234567890", nil];
            controller.messageComposeDelegate = self;
            [self presentViewController:controller animated:YES completion:nil];
        }
    }
    

The above code will not send texts or cancel the view as we have not implemented the messageComposeViewController:didFinishWithResult: method - the docs for this can be read here. This will look like the following:

- (void)messageComposeViewController:(MFMessageComposeViewController *)controller 
                 didFinishWithResult:(MessageComposeResult)result {
    switch(result) {
        case MessageComposeResultCancelled:
            // user canceled sms
            [self dismissViewControllerAnimated:YES completion:nil];
            break;
        case MessageComposeResultSent:
            // user sent sms
            //perhaps put an alert here and dismiss the view on one of the alerts buttons
            break;
        case MessageComposeResultFailed:
            // sms send failed
            //perhaps put an alert here and dismiss the view when the alert is canceled
            break;
        default:
            break;
    }
}

In each case you can you can present alerts, dismiss the view (as in case 1), or anything your app requires.

I am sure this second method should be approved or Apple should remove it from their documentation. The key thing though is the canSendText if statement. If this (or the case switch for didFinishWithResult) is not implemented Apple will certainly reject the app.