Is ther any way to perform a runtime check for the iPhone device at runtime?
It has to be able to differenciate iPhone 4 from other iPhone/iPod touch models.
Any workaround that does the same thing is OK too.
I use some code like this for the same purpose:
if([[UIScreen mainScreen] respondsToSelector:#selector(scale)])
return [[UIScreen mainScreen] scale] == 2.0 ? YES : NO;
return NO;
Only iOS 4.x+ devices support the UIScreen scale instance method. And since iPhone4's don't run iOS 3, we can rule those out right away. Next, we check if the scale factor is 2.0, if so we know it has a retina display.
While this isn't definitive (apple could release another retina device tomorrow), it does test 'model' where it's important -- i.e., you could be fetching images from a web service that provides #2x images and standard images, which is what I'm doing, which means you need to write the scaling image support manually, you don't get it for free as with UIImage's -imageNamed: for local files.
You can get the exact model through the UIDevice class:
[[UIDevice currentDevice] model]
This, and some other methods are documented here: http://developer.apple.com/iphone/library/documentation/uikit/reference/UIDevice_Class/Reference/UIDevice.html
Be careful, though, to not confuse hardware model with iOS version. If you want to provide extra/different functionality for devices that support them, it's better to check if that specific interface is available, using the respondsToSelector: method, or the NSClassFromString function.
Be careful with using the NSClassFromString function, though, since some classes exists as a part of the private API in the earlier SDK:s, with a completely different interface.
Related
I wrote my application for iPhone in xcode 5.0 and it supports only 7 ios.
How can I make it available for ios 6?
Also interested in how to prevent applications load on ipad?
First question: Make sure your deployment target is 6.0, don't use API's that are iOS 7 only, or check by using
if ([someObject respondsToSelector:#selector(ios7onlymethod)] {
// do your iOS 7 only stuff
} else {
// Fall back to iOS 6-supported ways
}
Or use
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0f) {
// do your iOS 7 only stuff
} else {
// Fall back to iOS 6-supported ways
}
New frameworks you want to use should be marked as optional in Xcode; to do that select your target, click general, and scroll to the "Linked Frameworks and Libraries" section.
What's really cool is that classes in frameworks marked as optional are replaced with nil on versions of iOS that don't have them. So suppose you write some code like this, using a class from the Sprite Kit framework, new in iOS 7:
SKSpriteNode *spriteNode = [SKSpriteNode spriteWithImageNamed:#"mySprite"];
On iOS 6, when the linker, which "links" frameworks to apps (apps don't copy frameworks, they just get them from the system), sees SKSpriteNode in your code, and the framework is marked as optional, that line of code will be replaced by this:
... = [nil spriteWithImageNamed:#"mySprite"];
Sending messages to nil in Objective-C does absolutely nothing, so the above code doesn't crash. No problem. So instead of lingering your code with if-statements checking for the existence of a class, you can just go with the flow and let the dynamic linker do the work.
Further reading:
iOS 7 UI Transition Guide: Supporting iOS 6
Supporting Multiple iOS Versions and Devices
Second question: There is no way to say that you want your app to only run on iPhones and iPod touches. You can require things that are specifical to the iPhone and iPod touch (like a certain processor architecture or the M7 motion coprocessor) but Apple won't like it if you require the M7 chip to exclude a certain device when you don't even need it. You should probably think about why you don't want your app to run on iPads.
I am just started write app for ios.
I have 2 questions.
I know there are some codes which work fine in ios4.3 but don't work in ios5 and the opposite is also true.I want to know,which is the best practice for writing app both for ios4.3 and ios5?Is it acceptable run-time to check the version for specific parts of code??
I am also should write same app for ipad. So, I want to know which is the best practice for writing app for iphone which works also on ipad??
Thanks
iOS 5 or iOS 4
Another way to detect the version is to use the respondsToSelector: message on objects. The advantage compared to the version method is that you don't need to know what the next versions of iOS are gonna be to maintain your application. (What if, for instance, a new 5.0.2 version shows up? Your app should know that the "5.0.2" string is newer than "5.0"? I agree it would not be complicated to code, but using respondsToSelector: is much more convenient)
iPhone/iPod Touch or iPad
My usual way to code universal app (ie iPhone and iPad) is to define a basic implementation of my custom UIViewController classes, and then implement an HD version of it, inheriting the default behavior but customizing it for the iPad (overriding methods works well but the delegate pattern might be better: you get compilation warnings if you forget to implement methods).
If you use a different .xib file from the beginning of your application lifecycle (that's what you get by universal Xcode-provided templates), you may end up defining classes just from Interface Builder, and won't need to implement any runtime test in your code to know if you're running on an iPhone or an iPad.
You can get the version using:
[[UIDevice currentDevice] systemVersion];
The systemVersion returns a string, like "5.0". You can then compare the strings using string comparison. For example:
NSString *requiredVersion = #"5.0";
NSString *currentVersion = [[UIDevice currentDevice] systemVersion];
if ([currentVersion compare:requiredVersion options:NSNumericSearch] != NSOrderedAscending)
isItSupported = TRUE;
The documentation indicates that you can use the following to determine if you have an iPhone or iPad:
[[UIDevice currentDevice] model];
I've not used this though.
See the documentation.
I am developing a Cocoa Touch application for Apple's App store and I want to do some tweaking in the code depending on what device it's running on. How can I tell?
I've used this in a Universal app to determine if the code is running on an iPad
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
{
// Do iPad only stuff here
}
Check out the documentation for UIDevice
Look at UIDevice and it's properties. There is a systemVersion string that will work for what you want.
Is this the proper way to detect which device a user is running?
NSString *currentModel = [[UIDevice currentDevice] model];
if ([currentModel isEqualToString:#"iPhone"]) {
// The user is running on iPhone so allow Call, Camera, etc.
} else {
// The user is running on a different device (iPod / iPad / iPhone Simulator) disallow Call.
}
It is not a general solution but Apple in many cases provides API calls to check wether specific feature is supported or not. Examples could be:
+isSourceTypeAvailable: and +availableMediaTypesForSourceType: in UIImagePickerController allowing you to check if camera is available for the current device.
+canSendMail in MFMailComposeViewController to check if device is configured to send mail.
-canOpenURL in UIApplication class to check if URL can be opened. For example it can be used to check if it is possible to make a phone call:
if (![[UIApplication sharedApplication] canOpenURL:
[NSURL URLWithString:#"tel://"]])
//We cannot make a call - hide call button here
If such API calls are available for your purpose I would use them rather then rely on hardcoded string identifiers.
I'm not sure I'd want to generalize that much (ie, there may eventually be an iPod with a camera, and I don't know that the iPhone will ALWAYS be called "iPhone"), but yes, this is the accepted way.
Does anyone know the recommended way to check whether the device supports specific capabilities, for example the camera. I know I can detect the device the app is on with UIDevice but I was wondering if there is a way to enumerate the device's capabilities?
I'm not sure if there is a way to enumerate all of the device's capabilities. Usually, this check is done on a capability by capability basis.
So, to use your example, if you would like to know if the device you are running on has the capability to take a picture, you would:
[UIImagePickerController isSourceTypeAvailable:
UIImagePickerControllerSourceTypeCamera];
This would return true (YES) for any iPhone, and false (NO) for any iPod Touch (at least at the time of this writing).