问题
In order to support iPhone OS 3.x and 4.0 I programmatically control MFMessageComposeViewController functionality like this (use it only if the OS version is 4.0 or above):
// if iPhone OS version >= 4.0
if (os_version_num >= 4) {
MFMessageComposeViewController *controller = [[MFMessageComposeViewController alloc] init];
if([MFMessageComposeViewController canSendText])
{
controller.body = text;
controller.recipients = [NSArray arrayWithObjects: nil];
controller.messageComposeDelegate = self;
[self presentModalViewController:controller animated:YES];
[controller release];
}
}
But, when I try to run it on iPhone 3.1.3 device, I immediately get the following error (even before application gets loaded):
dyld: Symbol not found: _OBJC_CLASS_$_MFMessageComposeViewController
Referenced from: /var/mobile/Applications/7232C474-FAD5-4E28-ABC5-8520F62300B0/TextMe.app/TextMe
Expected in: /System/Library/Frameworks/MessageUI.framework/MessageUI
Data Formatters temporarily unavailable, will re-try after a 'continue'. (Not safe to call dlopen at this time.)
What am I doing wrong?
回答1:
You need to make sure you're doing a few things:
In your target's build settings:
- set Base SDK to iPhone Device 4.0
- set iPhone OS Deployment Target to iPhone OS 3.1.3 (or lower)
In your target's general settings, under Linked Libraries, change the "Type" next to MessageUI.framework to Weak.
Don't import <MessageUI/MFMessageComposeViewController.h>
or it will crash on launch in 3.x. Just import <MessageUI/MessageUI.h>
I don't know what os_version_num is, but here's the code I use to test for the availability of MFMessageComposeViewController:
Class smsClass = (NSClassFromString(@"MFMessageComposeViewController"));
if (smsClass != nil && [MFMessageComposeViewController canSendText]) {
MFMessageComposeViewController *controller = [[MFMessageComposeViewController alloc] init];
controller.body = text;
controller.recipients = [NSArray arrayWithObjects: nil];
controller.messageComposeDelegate = self;
[self presentModalViewController:controller animated:YES];
[controller release];
}
回答2:
Class theClass = NSClassFromString(@"MFMessageComposeViewController");
MFMessageComposeViewController *controller = theClass ? [[theClass alloc] init] : nil;
You can use the type MFMessageComposeViewController as in:
MFMessageComposeViewController *controller;
But you cannot use the global object MFMessageComposeViewController as in:
[MFMessageComposeViewController alloc];
Instead use the class lookup so you are not dependent on the linker:
[NSClassFromString(@"MFMessageComposeViewController") alloc];
回答3:
In your target parameters, simply set messageUI.framework to type 'weak'
回答4:
If you import <MessageUI/MessageUI.h>
and set weak reference to MessageUI framework, you can directly call:
if ([MFMessageComposeViewController canSendText]) {
controller.body = body;
controller.recipients = [NSArray arrayWithObjects:number, nil];
controller.messageComposeDelegate = self;
[self presentModalViewController:controller animated:YES];
[controller release];
} else {
[[UIApplication sharedApplication] openURL: [NSURL URLWithString:[NSString stringWithFormat:@"sms:%@",number]]];
}
On iOS 3.1.2 you will get nil in the if clause and old method will be launched.
回答5:
I was having the same problem, and solved it a different way:
On the Left hand-side of your XCode window,
If you scroll down to the Bulls Eye with "Targets" and expand that
Expand your
< control > + < click > on "Link Binary With Libraries"
Choose "Add" --> "Existing Frameworks"
Choose "MessageUI.framework" and click on "Add"
That should add the Message UI to your app, tell me if it works.
回答6:
What about if you have functions that you only want to include conditionally.
- (void)messageComposeViewController:(MFMessageComposeViewController *)controller
didFinishWithResult:(MessageComposeResult)result {
[self dismissModalViewControllerAnimated:YES];
}
For example, if the function definition contained MFMessageViewController
, how do you make this part conditional (that is, not cause a problem with OS 3.x). Or is it not a problem at all?
来源:https://stackoverflow.com/questions/3149813/programmatically-control-iphone-os-versions-to-enable-functions-for-both-os-3-x