I want to use Twitter framework for iOS 5, but be able to run my app in older OS.
I added weak referenced framework (i.e. set "optional" flag) in Xcode 4.2 Target settings. Base SDK is iOS 5, iOS deployment Target is iOS 3.2.
Next, I try to use Twitter framework:
#import <Twitter/Twitter.h>
...
Class twClass = NSClassFromString(@"TWTweetComposeViewController");
if (!twClass) // Framework not available, older iOS
{
[self shareWithTwitterPriorIOS5];
return;
}
if ([TWTweetComposeViewController canSendTweet]) // Check if twitter is setup and reachable
{
TWTweetComposeViewController* twc = [[TWTweetComposeViewController alloc] init];
// [twc addURL:[NSURL URLWithString:@"http://mail.ru"]];
// [twc addImage:[UIImage imageNamed:@"Some image.png"]]
[twc setInitialText:textToShare];
[viewController presentViewController:twc animated:YES completion:^{
// Optional
}];
[twc release];
// Assume twc is ARC released or call [twc release];
}
else
{
// Twitter account not configured, inform the user
}
It run well on iOS 5 simulator. As soon as I try to use simulator or real device with older OS version, I get error "Twitter/Twitter.h" file not found (in compile time). If I remove "#import" directive, I get a couple of errors TWTweetComposeViewController class not found.
If I comment all twitter-related code, I get linker error: "ld: framework not found Twitter". Ld command caused error:
Ld /Users/mikhailkeskinov/Library/Developer/Xcode/DerivedData/Dictionary-eiyrziajmltuglfzgtnjxffkojwi/Build/Products/Debug-iphoneos/Dictionary.app/Dictionary normal armv6
cd /Developer/WorkShop/XDictionary/trunk
setenv IPHONEOS_DEPLOYMENT_TARGET 3.2
setenv PATH "/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin:/Developer/usr/bin:/usr/bin:/bin:/usr/sbin:/sbin"
/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/clang -arch armv6 -isysroot /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS3.2.sdk -L/Users/mikhailkeskinov/Library/Developer/Xcode/DerivedData/Dictionary-eiyrziajmltuglfzgtnjxffkojwi/Build/Products/Debug-iphoneos "-L/Developer/WorkShop/XDictionary/trunk/Dictionary/Twitter+OAuth/Libraries & Headers" -F/Users/mikhailkeskinov/Library/Developer/Xcode/DerivedData/Dictionary-eiyrziajmltuglfzgtnjxffkojwi/Build/Products/Debug-iphoneos -filelist /Users/mikhailkeskinov/Library/Developer/Xcode/DerivedData/Dictionary-eiyrziajmltuglfzgtnjxffkojwi/Build/Intermediates/Dictionary.build/Debug-iphoneos/Dictionary.build/Objects-normal/armv6/Dictionary.LinkFileList -dead_strip -miphoneos-version-min=3.2 -lxml2 -framework AVFoundation -framework UIKit -framework Foundation -framework CoreGraphics -lOAuth -weak_framework Twitter -o /Users/mikhailkeskinov/Library/Developer/Xcode/DerivedData/Dictionary-eiyrziajmltuglfzgtnjxffkojwi/Build/Products/Debug-iphoneos/Dictionary.app/Dictionary
What is wrong in here?
After 5 hours, tons silly documentation reader, changing all target & project settings etc. I at least come to solution. Turns out it is pretty easy, when you know it. Probably, my answer will save somebody's day.
As you can see, real device destination ("mkeskinov's iPod") doubled. I never pay attention at this fact. It looks like it just doubled by some mistake, but it is not. If you select "Product\Edit Schemes" & open Destination list (on the top of window), you can clearly see the difference:
What I need to do to successfully compile app for real device - just select second option. It will compile for iOS 5 and then run on real device with OS 4. First option means that it will be compile for iOS 4, and if you have any references to Frameworks, which is not presented in iOS 4 (never mind, weak references or strong) - you get compile time error.
Your code is probably fine.
You absolutely want to build your app against the iOS5 SDK. The binary you produce will run on older iOS versions (provided your target SDK is an older version, as you have indicated).
Your code is correctly checking for iOS5 capabilities and doing the right thing, and you are correctly weak linking to the Twitter framework. It is these techniques that allows your app (built against the latest SDK) to run without crashing on older iOS versions.
Add this to your header file .h:
#import <Twitter/TWTweetComposeViewController.h>
Here is what I have used for my app:
if ([TWTweetComposeViewController class])
{
//can tweet
} else
{
//can't tweet
}
Instead of using import, you should reference the TWTweetComposeViewController class using the Class object you got from NSClassFromString(), e.g. [twClass canSendTweet] instead of [TWTweetComposeViewController canSendTweet].
来源:https://stackoverflow.com/questions/8580775/how-to-access-weak-linked-framework-in-ios