i am created Universal application, in that i used UIModalPresentationFull, for displaying MFMailComposerSheet in iPad, which helps me to show the full screen of a MailComposer view in landscape view of ipad. When i run the application in ipad simulator i works well. If i set it to iPhone simulator 3.0 or 3.1.3 it shows the error like "error: 'UIModalPresentationFullScreen' undeclared (first use in this function)" when i comment it and run in iPhone simulator it works what would be the solution for this error or, else is that any method replaces "UIModalPresentationFull" works in both ipad and iphone?
Thanks and regards
Venkat
UIModalPresentationFullScreen is only available in the 3.2 (and above) SDK so you can't compile it with a SDK lower than that.
However, you don't need to for a universal application - you compile it against the highest SDK you are going to run on and then you have to check at run-time if the methods / classes you are using are available. You set this in your build settings : Base SDK should be set to the highest SDK you are using (probably 3.2 for the iPad) and iPhone OS Deployment Target should be set to 3.0 - the lowest SDK on which your code can run.
You should be doing this each time you use a 3.2 only bit of code :
if ([controller respondsToSelector:#selector(setModalPresentationStyle:)])
[controller setModalPresentationStyle:UIModalPresentationFullScreen];
Then, even though you have compiled against the 3.2 SDK, when you run it on lower SDK devices, this method will not be run.
I test this on an iphone that still has 3.0 SDK on it. I don't know exactly how you would test in the simulator with a lower SDK sorry.
enter code here
Using conditional compilation block we can isolate the process for iPhone and iPad
" #if __IPHONE_OS_VERSION_MAX_ALLOWED >= 30200 "
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
{
// The device is an iPad running iPhone 3.2 or later.
if ([picker respondsToSelector:#selector(setModalPresentationStyle:)])
{
//picker.modalPresentationStyle = UIModalPresentationFullScreen;
[picker setModalPresentationStyle:UIModalPresentationFullScreen];
}
}
" #endif "
Please remove the quotes and use that if and else part too...(i.e)conditional compilation block
Related
Recently submitted iPhone and iPod Touch application to app store successfully, but later came to know that is not working on iPad 3.2 but works on iPad with high iOS like 4 in scaled version.
Reason: setOrientation property of Movie player.
Actual Query: In order to make it work on iPad 3.2 in MAC Desktop I used
if(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
{
player.view.frame = CGRectMake(0, 0, 768, 1024);
[self.view addSubview:player.view];
[player play];
}
else {
#ifdef __IPHONE_4_0
player.controlStyle = MPMovieControlStyleNone;
#else
[player setOrientation:UIDeviceOrientationPortrait animated:NO];
}
when i run the same code on my MAC BOOK with iOS 3.0 this code is throwing the error...not supported.
So
If i build the above code on MAC DESKTOP(with iOS 4) will that work
on iPhone device with iOS 3.0 ? ..in reference to Event Kit Frame
Work(which throws error in iOS 3.0..but required in iOS 4).
I need to go for separate iPad app instead of Universal?
Is there any difference in iPhone with iOS 3.2 and iPad with iOS 3.2 in terms of
properties used?
I don't think you should hardcode it like that at compile time. Instead you should test if a particular class or method/property on a class exists and then do the appropriate thing. Like using [NSObject respondstoSelector:] to test whether your object understands a particular method.
Okay, first of all it does not matter if you use the Mac desktop or the MacBook to compile. It looks like you may be confusing the "minimum iOS" value and the "base SDK".
Base SDK: Refers to the code library that the complier will use to check your code, but does not determine which OS's your app will actually run on. You can have a base SDK of 5.0 and your app may still work fine on a 3.0 system. The catch is that if you are using code that is compatable with your Base SDK and not older OS's, the compiler will not catch it.
Minimum OS: This value does determine which OS's your app will run on.
If you are using code for higher OS's but want to run on lower OS's you need to test in the code for which OS you are running on and then run the appropriate code for that platform.
I'm diving into iOS development and I created a universal app that turned into an iPhone-only app. When it runs on the iPad, it just loads a white screen since there's no iPad code written yet. What I'd like is for it to run in "iPhone" mode on the iPad, if it somehow ends up on an iPad. I have the "Targeted Device Family" property set to "iPhone", so that should prevent it from showing up in the App Store as an iPad app, but if anyone owns both an iPad and an iPhone, then the app could end up synced to the iPad, at which point it will just load the white screen because it will try to run the app in iPad mode, which it doesn't have any code to support. In this situation, I prefer that it actually ran on the iPad, but in iPhone mode.
My questions are...
When an iPad runs a universal app, how does it know to run it in "iPhone mode" or execute the iPad specific code?
In a universal app, how does it know which code is iPhone and which code is iPad?
How can I prevent the iPad from trying to run the iPad code and, instead, run the iPhone code?
I apologize if I sound like a total noob, but I am. Thanks so much for your wisdom!
The iPad looks into the application's Info.plist, for the UIDeviceFamily key, which is an array. The value '1' indicates iPhone/iPod Touch, '2' indicates 'iPad'. If there's a '1' but no '2' then you get the simulated iPhone environment. This value is written to the Info.plist automatically as a result of your 'Targeted Device Family'. If you think you've set it to iPhone but are still getting an iPad build, check you didn't just set it for one build configuration. Check the Info.plist within your produced app bundle if you want to be really confident.
There's only one binary, which you write to launch correctly on either device.
Just don't target the iPad.
I'm assuming what you actually want is to remove the "universal" capability, and just make it an iPhone app.
In Xcode, go to Project => Edit Project Settings => Build.
Search for universal, or 'Targeted Device Family'.
Pick iPhone.
Goodbye iPad.
When an iPad runs a universal app, how does it know to run it in "iPhone mode" or execute the iPad specific code?
The iPad looks for the Targeted Device Family, if the iPad is not present, then it knows it must run the app in iPhone mode.
In a universal app, how does it know which code is iPhone and which code is iPad?
When you write the code for the app, you must specify what device you are targeting if there are specific things you need to do per device. (see the code example below)
How can I prevent the iPad from trying to run the iPad code and, instead, run the iPhone code?
Do not support iPad in your Targeted Device Family. Second, in your code, do not specify that specific code needs a specific device, for example:
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
{
/* run something specific for the iPad */
}
else
{
/* run something specific for the iPhone */
}
If you build an universal app, it will use your iPad code. It is not possible to run a universal app in "iPhone Mode". Apple will check that you have followed the iPad design specifications.
In a universal app, there are two app-delegates: AppDelegate_iPhone.h and AppDelegate_iPad.h
You can add your iPhone code in the AppDelegate_iPad, but Apple will not be pleased.
You should NOT add this to your Info.plist file. Instead, add it to your build settings per Apple's suggestion. Specifically, use the TARGETED_DEVICE_FAMILY build setting.
If you are using storyboards, you also want to remove the UIMainStoryboardFile~ipad key from your Info.plist as it will be used regardless of your TARGETED_DEVICE_FAMILY setting.
Good luck!
I think there is an entry in the info.plist file for each of the devices that says which main window to load.
Maybe a quick and dirty solution would be to set both MainWindow-iPhone and MainWindow-iPad to the same -iPhone- main window.
Another way to do it (with code) is:
In your App's AppDelegate (if your App was created as an Universal App) you can find the following code:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Override point for customization after application launch.
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) {
//iPad...
} else {
//iPhone and iPod Touch...
}
return YES;
}
There you can customize what view to show.
Since Xcode 5, you can chose your development target devices from the Project:
From the devices section within Development Info, now you can choose:
1-iPhone 2- iPad 3- Universal
I think that something is wrong with your configuration, because if you target the code for iPhone only Device, the app will bu runnable on an iPad with the screen that was designed for iPhone (so, reduced, with the possibility to x2).
the proposals from the AppStore (iPhone/iPad/both) depend on the user's preferences
you can experiment it with the Simulator (and choose iPad as the Device)
the code is the same for iPad/iPhone ! ... unless you use [[UIDevice currentDevice] userInterfaceIdiom] mentioned supra...
I have an opengl application that renders better in RetinaDisplay mode (double scale factor) and I noticed the iPad emulates an iPhone app with a low resolution screen (normal scale factor).
I want to double the scale factor when my iPhone app is run on an iPad, in order to benefit from Retina Display graphics. But it seems the iPad really well fakes being an iPhone (which would be perfect if only it was a Retina Display one...)
When I force the double scale, it works very well (at least in simulator, I do not have an iPad to test).
So I need a way to know if I am run on an iPad despite many things telling me it to be an old iPhone.
Or maybe I should not try to do that ?
If the app is an iPhone app running in the emulator mode on an iPad, it will have a userInterfaceIdiom of Phone, but a model type of iPad. You can check this with the following code:
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone &&
[[[UIDevice currentDevice] model] hasPrefix:#"iPad"]) {
// This app is an iPhone app running on an iPad
}
If you are looking to make custom code (most likely custom UI related methods) for the iPad only then you can use (as Apple directs) the UI_USER_INTERFACE_IDIOM() method that exists in iOS 3.2 and later
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
{
// The device is an iPad running iPhone 3.2 or later.
}
else
{
// The device is an iPhone or iPod touch.
}
You can read more here http://developer.apple.com/library/ios/#documentation/iphone/conceptual/iphoneosprogrammingguide/BuildTimeConfiguration/BuildTimeConfiguration.html
This is the Apple recommended method
Look up in the documentation, UIDevice:
For instance something like:
NSString *system = [[UIDevice currentDevice] systemName];
Then by using [system isEqualToString:#"iPad"] whether its an ipad or not.
UIDevice is a very nice class, it also has stuff like multiTaskingSupported, systemVersion etc. gotta love UIKit ;)
i think it is that:
// Set hello to "Hello, <device or simulator>"!
if TARGET_IPHONE_SIMULATOR
NSString *hello = #"Hello, iOS Simulator!";
else
NSString *hello = #"Hello, iOS device!";
endif
the link apple doc
about
This actually will only tell you if
the app is being run in a simulated
environment, or on an actual device,
and has no influence on whether the
platform is iPad or iPhone.
In fact it says at compile time the target of the platform you are compiling for, thus before run you know and do the necessary for take care of something specific.
For example I have diferent URL for developing (running on simulator) and for production usage, so I do some like
#if TARGET_IPHONE_SIMULATOR
#define URL #"http://192.x.x.x/request"
#else
#define URL #"http://example.com/request"
#endif
you shouldn't be able to tell the difference, if its an iPhone app, then as far as it can tell it is running on an iPhone. if you want to target an iPad, then you need to build it for an iPad target.
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
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:
How should I approach building a Universal iOS app that will include iOS 4 features, even though the iPad doesn't yet run iOS 4?
(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
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];
}
after i complied my app on IOS4 my app stopped working on ipod touches. it is a first generation ipod touch, with os 3 on it. So i assume application for OS4 are not working on old ipodtouches ? but there was no warring from the app store and it is even listed for download for ipod touch too. any ideas ?
base SDK is iphone device 4 and development target is iphone os 3. i works on iphone's with os 3 but when i try it on my ipod touch with os 3.1.3 it crashed. and i am getting this error mi_cmd_stack_list_frames: Not enough frames in stack. I added a break on main.m and the app crashes even before getting to first line in main.m .. the debug is ok it crashes when i try to run it on the device. it works fine in simulator.
One more thing, this is a universal app, and i am using uisplitview controller.. so i think when it runs on os 3 it breaks.. is there anyway to fix this ?
Apps built for iOS 4.0 will not run on devices with 3.0. Note that in the App Store, there is a section under "Requirements:" that says "Requires iOS 4.0 or later." in cases like this.
Ok!!! I assumed my main.m will do the job and point the right appdelegate but apparently i still needed to check if the classes exist. so here is the answer
Class splitVCClass = NSClassFromString(#"UISplitViewController");
if (splitVCClass)
{
//UISplitViewController* mySplitViewController = [[splitVCClass alloc] init];
UISplitViewController* _splitViewController = [[splitVCClass alloc]init];
[_splitViewController setViewControllers:[NSArray arrayWithObjects:_rootNavigationController,_navigationController,nil]];
}
happy ending.