dyld: Symbol not found error while building SMS iPhone application

Question: I am building an iPhone/iPad universal application that must be run on 3.1+ devices. I inserted an SMS sending option into the app. After the code was built without errors or warnings, and has been deployed to the test devices of iPod Touch or iPad, I get an error at the bottom of the Xcode’s screen: Error from Debugger: mi_cmd_stack_list_frames: Not enough frames in stack. The log file contains another error message: dyld: Symbol not found: _OBJC_CLASS_$_MFMessageComposeViewController Referenced from:… What did I miss? I use Xcode iOS SDK 4.2 and the error occurs when iOS Deployment Target is set to iPhone OS 3.1.3 or 3.2 and I attach these devices. Answer: When a code wants to “use” a 4.0+ framework object or reference while running on a 3.1.3 machine, it crashes. Framework APIs that are unavailable in earlier versions should be weak-linked. In your code you have to check for null function pointers before calling these newer APIs. You must programmatically control MFMessageComposeViewController class like this:
// self = view controller, phonenumber=addressee, text=message
// DO NOT use this: MFMessageComposeViewController *controller =[[MFMessageComposeViewController alloc] init];

MFMessageComposeViewController *controller = [NSClassFromString(@"MFMessageComposeViewController") alloc];
if( controller ){
    controller.messageComposeDelegate = self;
    controller.recipients = [NSArray arrayWithObject: phoneNumber]; // With the new MessageUI SMS controller, you can send SMS to multiple people at the same time.
    controller.body = [NSString stringWithString: text];
    [self presentModalViewController:controller animated:YES];
    [controller release];
1. In the Xcode at your application target’s general settings, change the “Type” Required to Weak (see target -> Get Info -> General -> Linked Libraries -> MessageUI.framework -> Type column). 2. Remove the import of MessageUI/MFMessageComposeViewController.h from your header file. 3. Test the iOS version and the device if it is capable of running your code without invoking 4.0+ frameworks. See what this hyper safe code does:
+ (BOOL) isSMSAvailable
    @synchronized(self) {
        @try {
            Class smsClass = (NSClassFromString(@"MFMessageComposeViewController"));
            if (smsClass && [smsClass canSendText] ){   // when smsClass is not nil, canSendText must be available
                return YES;
        @catch (NSException * e) {
            NSLOG(@"isSMSAvailable exception: %@", e.reason );
        return NO;
Notes: 1. I know that iOS4 is running at a snail’s pace on an iPhone 3G, but try to convince your business partners and do not support iOS older than 3.2 for new codes. We must tranditionally support previous versions only “for a while”. 2. No, not a typo. We use NSLOG as …
#define NSLOG(format,...)   NSLog(@"<%@ line=%d> %@", [[NSString stringWithUTF8String:__FILE__]lastPathComponent], __LINE__, [NSString stringWithFormat:(format), ##__VA_ARGS__])
3. For better and universal solution, use SMS gateway API-s to send SMS (ie. text) from both iPhone and iPad/iPod applications.