6

I introduced Printing via AirPrint recently, but wanted to not drop support for pre 4.2 versions (obviously). Done it before for things like Game Center, etc. What I found particularly odd in this case was I had to weak link UIKit. Printing was not contained in its own framework allowing me to be more granular.

This just didn't feel right, although it solves my problem allowing the app to run properly on all versions.

In Apple's SDK Compatibility Guide they state:

When using a framework that is available in your deployment target, you should require that framework (and not weakly link it).

UIKit is available, just not classes such as UIPrintInfo, UIPrintInteractionController, etc.

Am I right that it seems odd to weakly link such a core framework? Is there a better way?

MarkPowell
  • 16,482
  • 7
  • 61
  • 77
  • did you find an answer to this yet? It seems that using NS_CLASS_AVAILABLE is fine if you have not yet declared the type of the class and test for it first. having worked off these 2 links: http://goo.gl/6yH4U and http://goo.gl/FiOd9 I still haven't found a suitable solution. – John Wang Jan 30 '11 at 09:39

1 Answers1

2

There is a better way. iOS 4.2 introduced NS_CLASS_AVAILABLE for this purpose, but there are some restrictions on using it. All the details are listed in the documentation linked to below:

http://developer.apple.com/library/ios/#documentation/DeveloperTools/Conceptual/cross_development/Using/using.html

Steven Kramer
  • 8,473
  • 2
  • 37
  • 43
  • To make this more specific: test at run-time using [UIPrintInfo class], if this returns nil you're on an older system and should skip/disable your printing functions. – Steven Kramer Jan 07 '11 at 14:36
  • @Steven Kramer: I have the same issue. I use -(BOOL)canPrint { BOOL result = NO; Class printClass = (NSClassFromString(@"UIPrintInteractionController")); if (printClass != nil) { result = [UIPrintInteractionController isPrintingAvailable]; } return result; }. Then I test [self print] to enable/disable the print functionality, but it doesn't work. I tried it on ipod touch with ios 3.1.3. I tried also with NSClassFromString(@"UIPrintInfo"), but nothing. Do you any suggestion? – Sefran2 May 30 '11 at 15:01
  • What do you mean by "doesn't work" ? Linking errors? Dynamic linking errors? Or is the test just returning `NO` where it should return `YES` or vice-versa? – Steven Kramer May 30 '11 at 16:38
  • @Steven Kramer: When I run the app, the crash report says:"Dyld Error Message: Symbol not found: _OBJC_CLASS_$_UIPrintInfo Referenced from: /var/mobile/Applications/403A2A5D-2DAC-4DFC-83B5-5800A25890AB/MyApp.app/MyApp Expected in: /System/Library/Frameworks/UIKit.framework/UIKit in /var/mobile/Applications/403A2A5D-2DAC-4DFC-83B5-5800A25890AB/MyApp.app/MyApp Dyld Version: 149". I don't link weakly the uikit framework 'cause the apple doc says: "When using a framework that is available in your deployment target, you should require that framework (and not weakly link it)." – Sefran2 May 30 '11 at 17:12
  • 1
    Did you do all the build setting configuration listed in that document, such as the compiler to use, etc.? – Steven Kramer May 30 '11 at 20:56
  • BTW, you could always weak-link UIKit, if push came to shove. – Steven Kramer May 30 '11 at 20:57
  • @Steven Kramer: Now, I've changed the compiler to LLVM-GCC 4.2 and it works. But I don't understand if I misread the docs or docs contain some errors... I mean... I'm using NSClassFromString and not [UIPrintInteractionController class]. However, thanks. Now, I have to understand if this compiler changing could affect the performance or not. – Sefran2 May 30 '11 at 21:15
  • 1
    Fran, the standard GCC simply doesn't support weak-linking, simple as that! The compiler needs to specifically mark some symbols as weakly-linked and standard GCC won't do it. Good luck with your project. – Steven Kramer May 31 '11 at 09:46