views:

83

answers:

2

I am building a universal for iphone/ipad and I already set the deployment target to 3.0. It can run well on iPad 3.2 and iphone 4.1. However, when I build and run it on my iPod 3.1.3, the runtime automatically picks the iPad code path and tell me that it cannot find UIPopOverController and UIMenuItem. In my iPhone path code, I don't use anything like that.

It builds successfully and only when trying to run, it says error and cannot find:

dyld: Symbol not found: _OBJC_CLASS_$_UIPopoverController
  Referenced from: /var/mobile/Applications/My_APP
  Expected in: /System/Library/Frameworks/UIKit.framework/UIKit

Editted :

If I remove all of my iPad classes and set the App.info Main nib bundle to be iphone only. Then, it works well. I think the problem is that it runs the iPad code. I don't know what's wrong with my iPod or my project

+1  A: 

You need to make runtime tests for the classes that are not present on 3.1.3. You cannot have any code like [UIPopoverControler alloc], and you must weaklink to the frameworks.

See answers to this question:

http://stackoverflow.com/questions/3320355/how-should-i-approach-building-a-universal-ios-app-that-will-include-ios-4-featur

(The question is different to yours, but the root problem is the same one.)

Or this article:

http://cocoawithlove.com/2010/07/tips-tricks-for-conditional-ios3-ios32.html

JosephH
+1 for sharing the link. But I think that is not my problem. I already tried to do checking for iOS4 attributes, I think my problem is that Xcode auto detects my iPod as an iPad device and run the iPad code for it
vodkhang
Can you update your question to show how you are deciding whether to run the ipad code or the iphone code? xcode doesn't take care of that for you, you have to manually check and load the correct nib, etc, eg using [[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad)
JosephH
Did you ever try with universal app? It determines in the Info.plist fie by specifying the first window. I just specified MainWidow_iPhone.xib for iPhone and MainWindow_iPad.xib for iPad. I tested in iPhone 4.0 and iPad 3.2, it works well, only problem with iPod 3.1.3
vodkhang
Yes, I've written universal apps. I think the problem is you're not doing one of the above things that I've pointed out in my answer. You need to weak link the assemblies, you need to call the classes indirectly. It will work on the iphone 4 because the UIPopoverController is present on the iphone 4, so your code will link fine. On the ipod, you're failing to link, so you must be doing one of the above wrong. The linker doesn't care about code paths, it just tries to link everything your code references (regardless whether that code will be run), so you must weak link and call indirectly.
JosephH
Hum, that sounds correct. I will double check that. Thanks for your answer
vodkhang
+1  A: 

If you simply want to get around the compile time problems since that device will never the code in question then you can just call the popover etc classes this way:

Class infopopclass = NSClassFromString(@"UIPopoverController");
if(infopopclass) {
    id infopop = [[infopopclass alloc] initWithContentViewController:myPopViewController];
    [infopop presentPopoverFromRect:CGRectMake(20, 70, 10, 10) inView:self.view permittedArrowDirections:4 animated:YES];
}
Ben