Obj-C, conditionally run code only if iOS5 is available? - iphone

How can I check and conditionally only compile / run code if iOS5 is available ?

You can either check the systemVersion property of UIDevice like so:
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 5.0f) {
// Do something
}
But personally I don't like that method as I don't like the parsing of the string returned from systemVersion and the comparison done like that.
The best way is to check that whatever class / method it is that you want to use, exists. For example:
If you want to use TWRequest from the Twitter framework:
Class twRequestClass = NSClassFromString(#"TWRequest");
if (twRequestClass != nil) {
// The class exists, so we can use it
} else {
// The class doesn't exist
}
Or if you want to use startMonitoringForRegion: from CLLocationManager which was brought in in iOS 5.0:
CLLocationManager *locationManager = [[CLLocationManager alloc] init];
...
if ([locationManager respondsToSelector:#selector(startMonitoringForRegion:)]) {
// Yep, it responds
} else {
// Nope, doesn't respond
}
In general it's better to do checks like that than to look at the system version.

Try out this code:
if([[[UIDevice currentDevice] systemVersion] floatValue] >= 5.0)
{
//Do stuff for iOS 5.0
}
Hope this helps you.

Related

How to build app with iOS 5.0 methods for iOS 4.3?

I'm finishing iCloud feature for my app and can't solve one problem:
Since I'm using some new 5.0 features like NSFileCoordinator, I can't build my app for 4.3 because of "dyld: Symbol not found: _OBJC_CLASS_$_NSFileCoordinator".
How can I "untarget" some files (which have iCloud methods) for building 4.3 version?
Thanks in advance!
Have a look at this.
Class cls = NSClassFromString (#"NSFileCoordinator");
if (cls) {
// Create an instance of the class and use it.
} else {
// Alternate code path to follow when the
// class is not available.
}
Also check this answer to see why
you should avoid relying on the version string as an indication of device or OS capabilities.
To just take them out of the source copilation:
Click on your project file.
Go to "Build Phases".
Expand "Compile Sources".
Select the file you dont want, and press the "-" button at the
bottom of the section.
Or you can delete it from the project (just remove the reference rather than deleting the file), and it will remove it from this section as well.
Or you could create preprocessor macros to check to see if the user can run the functions
// System Versioning Preprocessor Macros
#define SYSTEM_VERSION_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedSame)
#define SYSTEM_VERSION_GREATER_THAN(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedDescending)
#define SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedAscending)
#define SYSTEM_VERSION_LESS_THAN(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedAscending)
#define SYSTEM_VERSION_LESS_THAN_OR_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedDescending)
/* Usage
if (SYSTEM_VERSION_LESS_THAN(#"4.0")) {
...
}
if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(#"3.1.1")) {
...
}*/
With this, you can check to see what systen version the user is using and only build for 5.0, but put in functioning code for if it is a version less than 5.0.
I think it's better to turn off iCloud feature for 4.3 builds altogether. You can do that by check iOS version at runtime. In your particular case you could check for presence of NSFileCoordinator class with NSClassFromString() function, but I'm pretty sure there are more decent ways on the internet of accomplishing this.
You could make a new build target and set a compiler preprocessing Macro like NO_CLOUD and then use
#ifdef NO_CLOUD
... code here ...#else
... cloud code here ... #endif
You have to weak link to the framwork's (when you add a framework to the project just set it as optional not required).
In the h file you have to import only if you have ios 5
#if defined(__IPHONE_5_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_5_0
#import <Twitter/Twitter.h>
#import <Accounts/Accounts.h>
#endif
and in the m file you have to try to create class from string and test to see if you have the class. And also test top see if the class responds to selectors.
Class TWTweetComposeViewControllerClass = NSClassFromString(#"TWTweetComposeViewController");
if (TWTweetComposeViewControllerClass != nil) {
if([TWTweetComposeViewControllerClass respondsToSelector:#selector(canSendTweet)]) {
UIViewController *twitterViewController = [[TWTweetComposeViewControllerClass alloc] init];
[twitterViewController performSelector:#selector(setInitialText:)
withObject:NSLocalizedString(#"TwitterMessage", #"")];
[twitterViewController performSelector:#selector(addURL:)
withObject:url];
[twitterViewController performSelector:#selector(addImage:)
withObject:[UIImage imageNamed:#"yourImage.png"]];
[self.navigationController presentModalViewController:twitterViewController animated:YES];
[twitterViewController release];
}
} else {
//do something else
}
My example is based on twitter engine you have to adapt it to your classes.
Build it with latest SDK (5.0). It will tun both 4.3 and 5.0
And you can check IOS version
if ([[UIDevice currentDevice] systemVersion] floatValue] >= 5.0f) {
// iCloud
} else {
// iCloudless
}

How can we programmatically detect which iOS version is device running on? [duplicate]

This question already has answers here:
How to check iOS version?
(36 answers)
Closed 9 years ago.
I want to check if the user is running the app on iOS less than 5.0 and display a label in the app.
How do I detect which iOS is running on user's device programmatically?
Thanks!
Best current version, without need to deal with numeric search within NSString is to define macros (See original answer: Check iPhone iOS Version)
Those macros do exist in github, see: https://github.com/carlj/CJAMacros/blob/master/CJAMacros/CJAMacros.h
Like this:
#define SYSTEM_VERSION_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedSame)
#define SYSTEM_VERSION_GREATER_THAN(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedDescending)
#define SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedAscending)
#define SYSTEM_VERSION_LESS_THAN(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedAscending)
#define SYSTEM_VERSION_LESS_THAN_OR_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedDescending)
and use them like this:
if (SYSTEM_VERSION_LESS_THAN(#"5.0")) {
// code here
}
if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(#"6.0")) {
// code here
}
Outdated version below
to get OS version:
[[UIDevice currentDevice] systemVersion]
returns string, which can be turned into int/float via
-[NSString floatValue]
-[NSString intValue]
like this
Both values (floatValue, intValue) will be stripped due to its type, 5.0.1 will become 5.0 or 5 (float or int), for comparing precisely, you will have to separate it to array of INTs
check accepted answer here: Check iPhone iOS Version
NSString *ver = [[UIDevice currentDevice] systemVersion];
int ver_int = [ver intValue];
float ver_float = [ver floatValue];
and compare like this
NSLog(#"System Version is %#",[[UIDevice currentDevice] systemVersion]);
NSString *ver = [[UIDevice currentDevice] systemVersion];
float ver_float = [ver floatValue];
if (ver_float < 5.0) return false;
For Swift 4.0 syntax
below example is just checking if the device is of iOS11 or greater version.
let systemVersion = UIDevice.current.systemVersion
if systemVersion.cgFloatValue >= 11.0 {
//"for ios 11"
}
else{
//"ios below 11")
}
Update
From iOS 8 we can use the new isOperatingSystemAtLeastVersion method on NSProcessInfo
NSOperatingSystemVersion ios8_0_1 = (NSOperatingSystemVersion){8, 0, 1};
if ([[NSProcessInfo processInfo] isOperatingSystemAtLeastVersion:ios8_0_1]) {
// iOS 8.0.1 and above logic
} else {
// iOS 8.0.0 and below logic
}
Beware that this will crash on iOS 7, as the API didn't exist prior to iOS 8. If you're supporting iOS 7 and below, you can safely perform the check with
if ([NSProcessInfo instancesRespondToSelector:#selector(isOperatingSystemAtLeastVersion:)]) {
// conditionally check for any version >= iOS 8 using 'isOperatingSystemAtLeastVersion'
} else {
// we're on iOS 7 or below
}
Original answer iOS < 8
For the sake of completeness, here's an alternative approach proposed by Apple itself in the iOS 7 UI Transition Guide, which involves checking the Foundation Framework version.
if (floor(NSFoundationVersionNumber) <= NSFoundationVersionNumber_iOS_6_1) {
// Load resources for iOS 6.1 or earlier
} else {
// Load resources for iOS 7 or later
}
I know I am too late to answer this question. I am not sure does my method still working on low iOS versions (< 5.0):
NSString *platform = [UIDevice currentDevice].model;
NSLog(#"[UIDevice currentDevice].model: %#",platform);
NSLog(#"[UIDevice currentDevice].description: %#",[UIDevice currentDevice].description);
NSLog(#"[UIDevice currentDevice].localizedModel: %#",[UIDevice currentDevice].localizedModel);
NSLog(#"[UIDevice currentDevice].name: %#",[UIDevice currentDevice].name);
NSLog(#"[UIDevice currentDevice].systemVersion: %#",[UIDevice currentDevice].systemVersion);
NSLog(#"[UIDevice currentDevice].systemName: %#",[UIDevice currentDevice].systemName);
You can get these results:
[UIDevice currentDevice].model: iPhone
[UIDevice currentDevice].description: <UIDevice: 0x1cd75c70>
[UIDevice currentDevice].localizedModel: iPhone
[UIDevice currentDevice].name: Someones-iPhone002
[UIDevice currentDevice].systemVersion: 6.1.3
[UIDevice currentDevice].systemName: iPhone OS
[[UIDevice currentDevice] systemVersion]
[[UIDevice currentDevice] systemVersion];
or check the version like
You can get the below Macros from here.
if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(IOS_VERSION_3_2_0))
{
UIImageView *background = [[[UIImageView alloc] initWithImage:[UIImage imageNamed:#"cs_lines_back.png"]] autorelease];
theTableView.backgroundView = background;
}
Hope this helps
[[[UIDevice currentDevice] systemVersion] floatValue]
Marek Sebera's is great most of the time, but if you're like me and find that you need to check the iOS version frequently, you don't want to constantly run a macro in memory because you'll experience a very slight slowdown, especially on older devices.
Instead, you want to compute the iOS version as a float once and store it somewhere. In my case, I have a GlobalVariables singleton class that I use to check the iOS version in my code using code like this:
if ([GlobalVariables sharedVariables].iOSVersion >= 6.0f) {
// do something if iOS is 6.0 or greater
}
To enable this functionality in your app, use this code (for iOS 5+ using ARC):
GlobalVariables.h:
#interface GlobalVariables : NSObject
#property (nonatomic) CGFloat iOSVersion;
+ (GlobalVariables *)sharedVariables;
#end
GlobalVariables.m:
#implementation GlobalVariables
#synthesize iOSVersion;
+ (GlobalVariables *)sharedVariables {
// set up the global variables as a static object
static GlobalVariables *globalVariables = nil;
// check if global variables exist
if (globalVariables == nil) {
// if no, create the global variables class
globalVariables = [[GlobalVariables alloc] init];
// get system version
NSString *systemVersion = [[UIDevice currentDevice] systemVersion];
// separate system version by periods
NSArray *systemVersionComponents = [systemVersion componentsSeparatedByString:#"."];
// set ios version
globalVariables.iOSVersion = [[NSString stringWithFormat:#"%01d.%02d%02d", \
systemVersionComponents.count < 1 ? 0 : \
[[systemVersionComponents objectAtIndex:0] integerValue], \
systemVersionComponents.count < 2 ? 0 : \
[[systemVersionComponents objectAtIndex:1] integerValue], \
systemVersionComponents.count < 3 ? 0 : \
[[systemVersionComponents objectAtIndex:2] integerValue] \
] floatValue];
}
// return singleton instance
return globalVariables;
}
#end
Now you're able to easily check the iOS version without running macros constantly. Note in particular how I converted the [[UIDevice currentDevice] systemVersion] NSString to a CGFloat that is constantly accessible without using any of the improper methods many have already pointed out on this page. My approach assumes the version string is in the format n.nn.nn (allowing for later bits to be missing) and works for iOS5+. In testing, this approach runs much faster than constantly running the macro.
Hope this helps anyone experiencing the issue I had!
In MonoTouch:
To get the Major version use:
UIDevice.CurrentDevice.SystemVersion.Split('.')[0]
For minor version use:
UIDevice.CurrentDevice.SystemVersion.Split('.')[1]
To get more specific version number information with major and minor versions separated:
NSString* versionString = [UIDevice currentDevice].systemVersion;
NSArray* vN = [versionString componentsSeparatedByString:#"."];
The array vN will contain the major and minor versions as strings, but if you want to do comparisons, version numbers should be stored as numbers (ints). You can add this code to store them in the C-array* versionNumbers:
int versionNumbers[vN.count];
for (int i = 0; i < sizeof(versionNumbers)/sizeof(versionNumbers[0]); i++)
versionNumbers[i] = [[vN objectAtIndex:i] integerValue];
* C-arrays used here for more concise syntax.
A simple check for iOS version less than 5 (all versions):
if([[[UIDevice currentDevice] systemVersion] integerValue] < 5){
// do something
};

RespondsToSelector returning a false-negative?

I'm currently using -respondsToSelector: like so:
if (![moviePlayer respondsToSelector:#selector(currentPlaybackTime)]) {
NSLog(#"Cannot get current playbackTime on %#", moviePlayer);
return;
}
where moviePlayer is an instantiated MPMoviePlayerController object. I do a lot of other similar selector checks, so I know that pretty much everything else is working fine, but for some reason, this respondsToSelector check returns false, even though if I do something like time = [moviePlayer currentPlaybackTime], it works fine. This is on 4.0+ iOS, so there's no reason for it to return false.
Any reasons why this would happen?
According to the iOS class reference, currentPlaybackTime is a property of MPMusicPlayerController, not MPMoviePlayerController.
MPMusicPlayerController:
http://developer.apple.com/library/ios/#documentation/MediaPlayer/Reference/MPMusicPlayerController_ClassReference/Reference/Reference.html
MPMoviePlayerController:
http://developer.apple.com/library/ios/#documentation/MediaPlayer/Reference/MPMoviePlayerController_Class/MPMoviePlayerController/MPMoviePlayerController.html
It may be a private property of MPMoviePlayerController that does not have an accessor.
EDIT (see comments)
Determine OS version:
float iPhoneOSVersion = [[[UIDevice currentDevice] systemVersion] floatValue];
if ( iPhoneOSVersion < 3.2 )
{
}
else
{
}

Check iOS version at runtime?

This is sort of a follow on from my last question. I am using beginAnimations:context: to setup an animation block to animate some UITextLabels. However I noticed in the docs that is says: "Use of this method is discouraged in iOS 4.0 and later. You should use the block-based animation methods instead."
My question is I would love to use animateWithDuration:animations: (available in iOS 4.0 and later) but do not want to exclude folks using iOS 3.0. Is there a way to check to iOS version of a device at runtime so that I can make a decision as to which statement to use?
Simpler solution for anyone who'll need help in the future:
NSArray *versionCompatibility = [[UIDevice currentDevice].systemVersion componentsSeparatedByString:#"."];
if ( 5 == [[versionCompatibility objectAtIndex:0] intValue] ) { /// iOS5 is installed
// Put iOS-5 code here
} else { /// iOS4 is installed
// Put iOS-4 code here
}
In many cases you do not need to check iOS version directly, instead of that you can check whether particular method is present in runtime or not.
In your case you can do the following:
if ([[UIView class] respondsToSelector:#selector(animateWithDuration:animations:)]){
// animate using blocks
}
else {
// animate the "old way"
}
to conform to version specified in system defines
//#define __IPHONE_2_0 20000
//#define __IPHONE_2_1 20100
//#define __IPHONE_2_2 20200
//#define __IPHONE_3_0 30000
//#define __IPHONE_3_1 30100
//#define __IPHONE_3_2 30200
//#define __IPHONE_4_0 40000
You can write function like this
( you should probably store this version somewhere rather than calculate it each time ):
+ (NSInteger) getSystemVersionAsAnInteger{
int index = 0;
NSInteger version = 0;
NSArray* digits = [[UIDevice currentDevice].systemVersion componentsSeparatedByString:#"."];
NSEnumerator* enumer = [digits objectEnumerator];
NSString* number;
while (number = [enumer nextObject]) {
if (index>2) {
break;
}
NSInteger multipler = powf(100, 2-index);
version += [number intValue]*multipler;
index++;
}
return version;
}
Then you can use this as follows:
if([Toolbox getSystemVersionAsAnInteger] >= __IPHONE_4_0)
{
//blocks
} else
{
//oldstyle
}
Xcode 7 added the available syntax making this relatively more simple:
Swift:
if #available(iOS 9, *) {
// iOS 9 only code
}
else {
// Fallback on earlier versions
}
Xcode 9 also added this syntax to Objective-C
Objective-C:
if (#available(iOS 9.0, *)) {
// iOS 9 only code
} else {
// Fallback on earlier versions
}
Most of these solutions on here are so overkill. All you need to do is [[UIDevice currentDevice].systemVersion intValue]. This automatically removes the decimal, so there is no need to split the string.
So you can just check it like:
if ([[UIDevice currentDevice].systemVersion intValue] >= 8) {
// iOS 8.0 and above
} else {
// Anything less than iOS 8.0
}
You can also define a macro with this code:
#define IOS_VERSION [[UIDevice currentDevice].systemVersion intValue];
or even include your check:
#define IOS_8PLUS ([[UIDevice currentDevice].systemVersion intValue] >= 8)
Then you just need to do:
if (IOS_8PLUS) {
// iOS 8.0 and above
} else {
// Anything less than iOS 8.0
}
Discouraged is not the same as deprecated.
If you need to support earlier versions of iOS that do not have the block based methods, there is nothing wrong with using the older methods (as long as they haven't been removed, of course).
You can use the version of the Foundation framework to determine the current system version.
if (floor(NSFoundationVersionNumber) <= NSFoundationVersionNumber_iOS_6_1){
//for earlier versions
} else {
//for iOS 7
}
For my purposes I've written a tiny library that abstracts away the underlying C calls and presents an Objective-C interface.
GBDeviceDetails deviceDetails = [GBDeviceInfo deviceDetails];
if (deviceDetails.iOSVersion >= 6) {
NSLog(#"It's running at least iOS 6"); //It's running at least iOS 6
}
Apart from getting the current iOS version, it also detects the hardware of the underlying device, and gets info about the screen size; all at runtime.
It's on github: GBDeviceInfo. Licensed under Apache 2.
Put this in your Prefix.pch file
#define IOS_VERSION [[[[[UIDevice currentDevice] systemVersion] componentsSeparatedByString:#"."] firstObject] intValue]
And then you can check iOS versions like:
if(IOS_VERSION == 8)
{
// Hello 8!
}
else
{
// Hello some other version!
}
Off course if you can use feature detection (and it makes sense for your use case) you should do that.
In MonoTouch:
To get the Major version use:
UIDevice.CurrentDevice.SystemVersion.Split('.')[0]
For minor version use:
UIDevice.CurrentDevice.SystemVersion.Split('.')[1]
A bit nicer and more efficient adaptation to the above solutions:
-(CGPoint)getOsVersion
{
static CGPoint rc = {-1,-1};
if (rc.x == -1) {
NSArray *versionCompatibility = [[UIDevice currentDevice].systemVersion componentsSeparatedByString:#"."];
rc.x = [versionCompatibility[0] intValue];
rc.y = [versionCompatibility[1] intValue];
}
return rc;
}
now you can
if ([self getOsVersion].x < 7) {
}
HTH

Best way to programmatically detect iPad/iPhone hardware

The reason I need to find out is that on an iPad, a UIPickerView has the same height in landscape orientation as it does in portrait. On an iPhone it is different. The iPad programming guide introduces an "idiom" value to UIDevice:
UIDevice* thisDevice = [UIDevice currentDevice];
if(thisDevice.userInterfaceIdiom == UIUserInterfaceIdiomPad)
{
// iPad
}
else
{
// iPhone
}
which works OK while you're in iPad (3.2) but not iPhone (3.1.3) - so it looks like there also needs to be an ifdef to conditionally compile that check, like:
#if __IPHONE_OS_VERSION_MIN_REQUIRED >= 30200
UIDevice* thisDevice = [UIDevice currentDevice];
if(thisDevice.userInterfaceIdiom == UIUserInterfaceIdiomPad)
{
// etc.
}
#endif
To me that's starting to look very clumsy. What's a better way?
Checking at runtime (your first way) is completely different from #if at compile time. The preprocessor directives won't give you a universal app.
The preferred way is to use Apple's Macro:
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.
}
Use 3.2 as the base SDK (because the macro is not defined pre 3.2), you can target prior OS versions to get it running on the iPhone.
I'm answering this now (and at this late date) because many of the existing answers are quite old, and the most Up Voted actually appears to be wrong according to Apples current docs (iOS 8.1, 2015)!
To prove my point, this is the comment from Apples header file (always look at the Apple source and headers):
/*The UI_USER_INTERFACE_IDIOM() macro is provided for use when
deploying to a version of the iOS less than 3.2. If the earliest
version of iPhone/iOS that you will be deploying for is 3.2 or
greater, you may use -[UIDevice userInterfaceIdiom] directly.*/
Therefore, the currently APPLE recommended way to detect iPhone vs. iPad, is as follows:
1) (DEPRECATED as of iOS 13) On versions of iOS PRIOR to 3.2, use the Apple provided macro:
// for iPhone use UIUserInterfaceIdiomPhone
if(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
2) On versions of iOS 3.2 or later, use the property on [UIDevice currentDevice]:
// for iPhone use UIUserInterfaceIdiomPhone
if([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad)
I like my isPad() function. Same code but keep it out of sight and in only one place.
My solution (works on 3.2+):
#define IS_IPHONE (!IS_IPAD)
#define IS_IPAD (UI_USER_INTERFACE_IDIOM() != UIUserInterfaceIdiomPhone)
then,
if (IS_IPAD)
// do something
or
if (IS_IPHONE)
// do something else
In Swift use userInterfaceIdiom instance property as-
if UIDevice.current.userInterfaceIdiom == .phone {
print("iPhone")
}
& For other devices -
switch UIDevice.current.userInterfaceIdiom {
case .pad:
print("iPad")
case .phone:
print("iPhone")
case .tv:
print("TV")
case .carPlay:
print("carPlay")
default: break;
}
Put this method in your App Delegate so that you can call it anywhere using [[[UIApplication sharedApplication] delegate] isPad]
-(BOOL)isPad
{
BOOL isPad;
NSRange range = [[[UIDevice currentDevice] model] rangeOfString:#"iPad"];
if(range.location==NSNotFound)
{
isPad=NO;
}
else {
isPad=YES;
}
return isPad;
}
If you are using features that are not backwards compatible, I found the best way for me is to create a #define in the pre-compiled header. Example:
#if __IPHONE_OS_VERSION_MAX_ALLOWED > __IPHONE_3_2
#define USING_4_X
#endif
Then in your code, you can do this:
BOOL exists = NO;
#ifdef USING_4_X
exists = [SomeObject someMethod:[url lastPathComponent]];
#else
exists = [SomeObject someMethod:[[url path] lastPathComponent]];
#endif
If
1- you already have the app installed into your device,
2- you change its build settings to be a 'Universal' app,
3- install the app to your device on top of the pre-existing app (without deleting the previous one)
You might find that the solutions provided here to detect iPhone/iPad do not work. First, delete the app that was 'only' for iPad/iPhone and install it fresh to your device.
BOOL isIpad()
{
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
return YES;
}
return NO;
}
extension UIDevice {
var isIPad: Bool {
return UIDevice.current.userInterfaceIdiom == .pad
}
}