4

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?

Mike Keskinov
  • 11,614
  • 6
  • 59
  • 87

4 Answers4

5

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.

enter image description here

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:

enter image description here

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.

Mike Keskinov
  • 11,614
  • 6
  • 59
  • 87
  • 1
    Yes, you saved me from your fate! In my case there was no difference between the two items in the scheme editor, but switching did the trick. I may have triggered this by installing an older iOS SDK in a newer Xcode. Documenting/sharing your self-answer is always a good thing. Thanks. – Paul Collins Aug 05 '12 at 03:03
  • Apple fixed this problem in XCode 4.3. The answer above for XCODE v. 4.2 – Mike Keskinov Aug 06 '12 at 15:03
4

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.

Mark Granoff
  • 16,878
  • 2
  • 59
  • 61
  • But **how** can I run my code on **real device with older OS**? I expected, that setting Base SDK = 5.0 should cause Xcode to build always against iOS5 SDK. – Mike Keskinov Dec 21 '11 at 13:28
  • You need to have a device with an older version. :-) You can test this with the simulator though. Just use the 4.3 simulator, and your app should run (built against the iOS5 SDK) just fine. All the iOS5-specific features that you are checking exist, will not, of courtse, under the 4.3 simulator, but your app should run just fine. – Mark Granoff Dec 21 '11 at 15:16
  • Finally, I found how to compile against iOS 5. It is pretty easy, when you know (I posted my own answer). – Mike Keskinov Dec 21 '11 at 15:24
1

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
} 
user523234
  • 14,323
  • 10
  • 62
  • 102
  • And you use #import at the top of .m file, right? This #import cause compile-time error for some reason. – Mike Keskinov Dec 20 '11 at 20:30
  • So. Can you connect device with older OS version to you MAC and run you app on this device using Xcode 4? If your answer is YES, please let me know, how you do it. I get compile error every time I try use older OS version. – Mike Keskinov Dec 21 '11 at 13:31
  • Glad to see you solved the problem. I got sidetracked a little so did not see your question. – user523234 Dec 24 '11 at 15:52
0

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].

krill
  • 199
  • 5
  • If I do so, I'll get a couple of warrings like "Class method +canSendTweet not found" or "Instance method -setInitialText: not found". Don't like it. And the biggest problem - I still can't run my code under older OS, because of linked error (see edited question above). – Mike Keskinov Dec 20 '11 at 20:26