This question already has answers here:
iOS detect if user is on an iPad
(17 answers)
Closed 8 years ago.
Is there an API for checking at runtime whether you are running on an iPhone or an iPad?
One way I can think of would be to use:
[[UIDevice currentDevice] model];
And detect the existence of the string #"iPad" - which seems a bit fragile.
In the 3.2 SDK, I see that UIDevice also has a property which is really what I'm looking for, but doesn't work for pre-3.2 (obviously):
[[UIDevice currentDevice] userInterfaceIdiom];
Are there other ways than checking for the existence of #"iPad" for a universal app?
Checkout UI_USER_INTERFACE_IDIOM.
Returns the interface idiom supported by the current device.
Return Value
UIUserInterfaceIdiomPhone if the device is an iPhone or iPod touch or UIUserInterfaceIdiomPad if the device is an iPad.
UIUserInterfaceIdiom
The type of interface that should be used on the current device
typedef enum {
UIUserInterfaceIdiomPhone,
UIUserInterfaceIdiomPad,
} UIUserInterfaceIdiom;
Just for my reference:
#property (nonatomic, readonly) BOOL isPhone;
-(BOOL)isPhone {
return (UI_USER_INTERFACE_IDIOM()==UIUserInterfaceIdiomPhone);
}
or use a #define
#define IS_PHONE (UI_USER_INTERFACE_IDIOM()==UIUserInterfaceIdiomPhone)
However, if you're using isPhone all over your code, that's generally bad practice. Use the factory pattern and polymorphism to keep your if statements contained, so you get objects created for phone or for iPad and then work with those.
Added
I'm using this solution all over my code now. It adds a standard factory pattern into the alloc.
#define ALLOC_PER_DEVICE() id retVal = nil; \
NSString *className = NSStringFromClass(self);\
if (IS_PHONE && ![className hasSuffix:#"Phone"]) {\
className = [NSString stringWithFormat:#"%#Phone", className];\
Class newClass = NSClassFromString(className);\
retVal = [newClass alloc];\
}\
if (!retVal)\
retVal = [super alloc];\
assert(retVal != nil);\
return retVal\
Then my allocs look like this:
+alloc { ALLOC_PER_DEVICE(); }
And I add a subclass called TheClassPhone for the phone version.
Note: Since there's no multiple inheritance in Objective-C, using inheritance to solve your problems is a bit overrated (i.e., it doesn't work if you have subclasses of subclasses). Nothing like a good if when you need it.
Use NSClassFromString and an iPad-specific class. Read more here:
http://developer.apple.com/iphone/library/documentation/General/Conceptual/iPadProgrammingGuide/StartingYourProject/StartingYourProject.html#//apple_ref/doc/uid/TP40009370-CH9-SW3
Check for the presence of the userInterfaceIdiom property, usings respondsToSelector:. If it doesn't exist, we are on a pre-3.2 device, thus not an iPad.
If userInterfaceIdiom exists, use it.
Edit: ... which is obviously exactly what the UI_USER_INTERFACE_IDIOM() macro does, so use that instead. :)
You can check if you run the app on iPhone or iPad by using the following code:
- (NSString *)deviceModel
{
struct utsname systemInfo;
uname(&systemInfo);
return [NSString stringWithCString:systemInfo.machine encoding:NSUTF8StringEncoding];
}
- (NSString *) platformString
{
NSString *platform = [self deviceModel];
if ([platform isEqualToString:#"iPhone1,1"]) return #"iPhone_2G";
else if ([platform isEqualToString:#"iPhone1,2"]) return #"iPhone_3G";
else if ([platform isEqualToString:#"iPhone2,1"]) return #"iPhone_3GS";
else if ([platform isEqualToString:#"iPhone3,1"]) return #"iPhone_4";
else if ([platform isEqualToString:#"iPhone3,3"]) return #"Verizon_iPhone_4";
else if ([platform isEqualToString:#"iPhone4,1"]) return #"iPhone_4S";
else if ([platform isEqualToString:#"iPhone5,1"]) return #"iPhone_5";
else if ([platform isEqualToString:#"iPhone5,2"]) return #"iPhone_5";
else if ([platform isEqualToString:#"iPod1,1"]) return #"iPod_Touch 1G";
else if ([platform isEqualToString:#"iPod2,1"]) return #"iPod_Touch 2G";
else if ([platform isEqualToString:#"iPod3,1"]) return #"iPod_Touch 3G";
else if ([platform isEqualToString:#"iPod4,1"]) return #"iPod_Touch 4G";
else if ([platform isEqualToString:#"iPad1,1"]) return #"iPad_1G";
else if ([platform isEqualToString:#"iPad2,1"]) return #"iPad_2(WiFi)";
else if ([platform isEqualToString:#"iPad2,2"]) return #"iPad_2(GSM)";
else if ([platform isEqualToString:#"iPad2,3"]) return #"iPad_2(CDMA)";
else if ([platform isEqualToString:#"iPad3,1"]) return #"iPad_3";
else if ([platform isEqualToString:#"iPad3,2"]) return #"iPad_3(GSM/CDMA)";
else if ([platform isEqualToString:#"iPad3,3"]) return #"iPad_3(GSM)";
else if ([platform isEqualToString:#"iPad3,4"]) return #"iPad_3(GSM)";
else if ([platform isEqualToString:#"iPad2,5"]) return #"iPad_mini_1G";
else if ([platform isEqualToString:#"i386"]) return #"Simulator";
else if ([platform isEqualToString:#"x86_64"]) return #"Simulator";
return platform;
}
Related
I know that someone was able to dig out iphone6,1 platform string from IOS 7 code. However, I don't know what it maps to iPhone 5S or 5C.
If anyone has early access to iPhone 5S/5C, please post platform string for everyone.
For more info on platform string, see these links theiphonewiki, stackoverflow and stackoverflow
iPhone6,1 = iPhone 5S GSM
iPhone6,2 = iPhone 5S Global
iPhone5,3 = iPhone 5C GSM
iPhone5,4 = iPhone 5C Global
Code:
if ([platform hasPrefix:#"iPhone5,3"]) return #"iPhone 5C (GSM)";
if ([platform hasPrefix:#"iPhone5,4"]) return #"iPhone 5C (Global)";
if ([platform hasPrefix:#"iPhone6,1"]) return #"iPhone 5S (GSM)";
if ([platform hasPrefix:#"iPhone6,2"]) return #"iPhone 5S (Global)";
This question already has an answer here:
iOS iPhone 5 Choose Correct Storyboard
(1 answer)
Closed 9 years ago.
I have two storyboard with size for iphone 5 and size for iphone 4. All this device have 6 IOS. So i have my code for check version of IOS ...
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// 1
UIStoryboard * mainStoryboard = nil ;
if ( SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO ( # "6.0" ) ) {
mainStoryboard = [ UIStoryboard storyboardWithName : # "iPhones6.0" bundle : nil ] ;
} else {
mainStoryboard = [ UIStoryboard storyboardWithName : # "iPhones3-5" bundle : nil ] ;
}
// 2
self.window = [ [ UIWindow alloc ] initWithFrame : [ [ UIScreen mainScreen ] bounds ] ] ;
self.window.rootViewController = [ mainStoryboard instantiateInitialViewController ] ;
[ self.window makeKeyAndVisible ] ;
return YES;
}
If i have iphone 4 with 6 iOS and iphone also 6 IOS, i have big size display and for iPhone but for iphone 4 not work. SO how can i know what device i used, for make checking for model.
UIDevice+CKHardware.h
// The MIT License (MIT)
//
// Copyright (c) 2013 Erica Sadun
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#import <UIKit/UIKit.h>
#define IFPGA_NAMESTRING #"iFPGA"
#define IPHONE_1G_NAMESTRING #"iPhone 1G"
#define IPHONE_3G_NAMESTRING #"iPhone 3G"
#define IPHONE_3GS_NAMESTRING #"iPhone 3GS"
#define IPHONE_4_NAMESTRING #"iPhone 4"
#define IPHONE_4S_NAMESTRING #"iPhone 4S"
#define IPHONE_5_NAMESTRING #"iPhone 5"
#define IPHONE_UNKNOWN_NAMESTRING #"Unknown iPhone"
#define IPOD_1G_NAMESTRING #"iPod touch 1G"
#define IPOD_2G_NAMESTRING #"iPod touch 2G"
#define IPOD_3G_NAMESTRING #"iPod touch 3G"
#define IPOD_4G_NAMESTRING #"iPod touch 4G"
#define IPOD_UNKNOWN_NAMESTRING #"Unknown iPod"
#define IPAD_1G_NAMESTRING #"iPad 1G"
#define IPAD_2G_NAMESTRING #"iPad 2G"
#define IPAD_3G_NAMESTRING #"iPad 3G"
#define IPAD_4G_NAMESTRING #"iPad 4G"
#define IPAD_UNKNOWN_NAMESTRING #"Unknown iPad"
#define APPLETV_2G_NAMESTRING #"Apple TV 2G"
#define APPLETV_3G_NAMESTRING #"Apple TV 3G"
#define APPLETV_4G_NAMESTRING #"Apple TV 4G"
#define APPLETV_UNKNOWN_NAMESTRING #"Unknown Apple TV"
#define IOS_FAMILY_UNKNOWN_DEVICE #"Unknown iOS device"
#define SIMULATOR_NAMESTRING #"iPhone Simulator"
#define SIMULATOR_IPHONE_NAMESTRING #"iPhone Simulator"
#define SIMULATOR_IPAD_NAMESTRING #"iPad Simulator"
#define SIMULATOR_APPLETV_NAMESTRING #"Apple TV Simulator" // :)
typedef enum {
UIDeviceUnknown,
UIDeviceSimulator,
UIDeviceSimulatoriPhone,
UIDeviceSimulatoriPad,
UIDeviceSimulatorAppleTV,
UIDevice1GiPhone,
UIDevice3GiPhone,
UIDevice3GSiPhone,
UIDevice4iPhone,
UIDevice4SiPhone,
UIDevice5iPhone,
UIDevice1GiPod,
UIDevice2GiPod,
UIDevice3GiPod,
UIDevice4GiPod,
UIDevice1GiPad,
UIDevice2GiPad,
UIDevice3GiPad,
UIDevice4GiPad,
UIDeviceAppleTV2,
UIDeviceAppleTV3,
UIDeviceAppleTV4,
UIDeviceUnknowniPhone,
UIDeviceUnknowniPod,
UIDeviceUnknowniPad,
UIDeviceUnknownAppleTV,
UIDeviceIFPGA,
} UIDevicePlatform;
typedef enum {
UIDeviceFamilyiPhone,
UIDeviceFamilyiPod,
UIDeviceFamilyiPad,
UIDeviceFamilyAppleTV,
UIDeviceFamilyUnknown,
} UIDeviceFamily;
#interface UIDevice (CKHardware)
- (NSString *) platform;
- (NSString *) hwmodel;
- (NSUInteger) platformType;
- (NSString *) platformString;
- (NSUInteger) cpuFrequency;
- (NSUInteger) busFrequency;
- (NSUInteger) cpuCount;
- (NSUInteger) totalMemory;
- (NSUInteger) userMemory;
- (NSNumber *) totalDiskSpace;
- (NSNumber *) freeDiskSpace;
- (CGFloat) appUsedSpace;
- (NSString *) macaddress;
- (BOOL) hasRetinaDisplay;
- (UIDeviceFamily) deviceFamily;
#end
UIDevice+CKHardware.m
// The MIT License (MIT)
//
// Copyright (c) 2013 Erica Sadun, Emanuele Vulcano, Kevin Ballard/Eridius, Ryandjohnson, Matt Brown
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#include <sys/socket.h> // Per msqr
#include <sys/sysctl.h>
#include <net/if.h>
#include <net/if_dl.h>
#import "UIDevice+CKHardware.h"
#implementation UIDevice (CKHardware)
/*
Platforms
iFPGA -> ??
iPhone1,1 -> iPhone 1G, M68
iPhone1,2 -> iPhone 3G, N82
iPhone2,1 -> iPhone 3GS, N88
iPhone3,1 -> iPhone 4/AT&T, N89
iPhone3,2 -> iPhone 4/Other Carrier?, ??
iPhone3,3 -> iPhone 4/Verizon, TBD
iPhone4,1 -> (iPhone 4S/GSM), TBD
iPhone4,2 -> (iPhone 4S/CDMA), TBD
iPhone4,3 -> (iPhone 4S/???)
iPhone5,1 -> iPhone Next Gen, TBD
iPhone5,1 -> iPhone Next Gen, TBD
iPhone5,1 -> iPhone Next Gen, TBD
iPod1,1 -> iPod touch 1G, N45
iPod2,1 -> iPod touch 2G, N72
iPod2,2 -> Unknown, ??
iPod3,1 -> iPod touch 3G, N18
iPod4,1 -> iPod touch 4G, N80
// Thanks NSForge
iPad1,1 -> iPad 1G, WiFi and 3G, K48
iPad2,1 -> iPad 2G, WiFi, K93
iPad2,2 -> iPad 2G, GSM 3G, K94
iPad2,3 -> iPad 2G, CDMA 3G, K95
iPad3,1 -> (iPad 3G, WiFi)
iPad3,2 -> (iPad 3G, GSM)
iPad3,3 -> (iPad 3G, CDMA)
iPad4,1 -> (iPad 4G, WiFi)
iPad4,2 -> (iPad 4G, GSM)
iPad4,3 -> (iPad 4G, CDMA)
AppleTV2,1 -> AppleTV 2, K66
AppleTV3,1 -> AppleTV 3, ??
i386, x86_64 -> iPhone Simulator
*/
#pragma mark sysctlbyname utils
- (NSString *) getSysInfoByName:(char *)typeSpecifier
{
size_t size;
sysctlbyname(typeSpecifier, NULL, &size, NULL, 0);
char *answer = malloc(size);
sysctlbyname(typeSpecifier, answer, &size, NULL, 0);
NSString *results = [NSString stringWithCString:answer encoding: NSUTF8StringEncoding];
free(answer);
return results;
}
- (NSString *) platform
{
return [self getSysInfoByName:"hw.machine"];
}
// Thanks, Tom Harrington (Atomicbird)
- (NSString *) hwmodel
{
return [self getSysInfoByName:"hw.model"];
}
#pragma mark sysctl utils
- (NSUInteger) getSysInfo: (uint) typeSpecifier
{
size_t size = sizeof(int);
int results;
int mib[2] = {CTL_HW, typeSpecifier};
sysctl(mib, 2, &results, &size, NULL, 0);
return (NSUInteger) results;
}
- (NSUInteger) cpuFrequency
{
return [self getSysInfo:HW_CPU_FREQ];
}
- (NSUInteger) busFrequency
{
return [self getSysInfo:HW_BUS_FREQ];
}
- (NSUInteger) cpuCount
{
return [self getSysInfo:HW_NCPU];
}
- (NSUInteger) totalMemory
{
return [self getSysInfo:HW_PHYSMEM];
}
- (NSUInteger) userMemory
{
return [self getSysInfo:HW_USERMEM];
}
- (NSUInteger) maxSocketBufferSize
{
return [self getSysInfo:KIPC_MAXSOCKBUF];
}
#pragma mark file system -- Thanks Joachim Bean!
/*
extern NSString *NSFileSystemSize;
extern NSString *NSFileSystemFreeSize;
extern NSString *NSFileSystemNodes;
extern NSString *NSFileSystemFreeNodes;
extern NSString *NSFileSystemNumber;
*/
- (NSNumber *) totalDiskSpace
{
NSDictionary *fattributes = [[NSFileManager defaultManager] attributesOfFileSystemForPath:NSHomeDirectory() error:nil];
return [fattributes objectForKey:NSFileSystemSize];
}
- (NSNumber *) freeDiskSpace
{
NSDictionary *fattributes = [[NSFileManager defaultManager] attributesOfFileSystemForPath:NSHomeDirectory() error:nil];
return [fattributes objectForKey:NSFileSystemFreeSize];
}
// -----------------------------------------------------------------------------
- (CGFloat) appUsedSpace {
NSError *error = nil;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *path = [paths lastObject];
NSArray *filesArray = [[NSFileManager defaultManager] subpathsOfDirectoryAtPath:path error:&error];
NSEnumerator *filesEnumerator = [filesArray objectEnumerator];
NSString *fileName;
unsigned long long int fileSize = 0;
while (fileName = [filesEnumerator nextObject]) {
NSString *fullPath = [path stringByAppendingPathComponent:fileName];
NSDictionary *fileDictionary = [[NSFileManager defaultManager] attributesOfItemAtPath:fullPath error:&error];
fileSize += [fileDictionary fileSize];
}
return fileSize;
}
// -----------------------------------------------------------------------------
#pragma mark platform type and name utils
- (NSUInteger) platformType
{
NSString *platform = [self platform];
// The ever mysterious iFPGA
if ([platform isEqualToString:#"iFPGA"]) return UIDeviceIFPGA;
// iPhone
if ([platform isEqualToString:#"iPhone1,1"]) return UIDevice1GiPhone;
if ([platform isEqualToString:#"iPhone1,2"]) return UIDevice3GiPhone;
if ([platform hasPrefix:#"iPhone2"]) return UIDevice3GSiPhone;
if ([platform hasPrefix:#"iPhone3"]) return UIDevice4iPhone;
if ([platform hasPrefix:#"iPhone4"]) return UIDevice4SiPhone;
if ([platform hasPrefix:#"iPhone5"]) return UIDevice5iPhone;
// iPod
if ([platform hasPrefix:#"iPod1"]) return UIDevice1GiPod;
if ([platform hasPrefix:#"iPod2"]) return UIDevice2GiPod;
if ([platform hasPrefix:#"iPod3"]) return UIDevice3GiPod;
if ([platform hasPrefix:#"iPod4"]) return UIDevice4GiPod;
// iPad
if ([platform hasPrefix:#"iPad1"]) return UIDevice1GiPad;
if ([platform hasPrefix:#"iPad2"]) return UIDevice2GiPad;
if ([platform hasPrefix:#"iPad3"]) return UIDevice3GiPad;
if ([platform hasPrefix:#"iPad4"]) return UIDevice4GiPad;
// Apple TV
if ([platform hasPrefix:#"AppleTV2"]) return UIDeviceAppleTV2;
if ([platform hasPrefix:#"AppleTV3"]) return UIDeviceAppleTV3;
if ([platform hasPrefix:#"iPhone"]) return UIDeviceUnknowniPhone;
if ([platform hasPrefix:#"iPod"]) return UIDeviceUnknowniPod;
if ([platform hasPrefix:#"iPad"]) return UIDeviceUnknowniPad;
if ([platform hasPrefix:#"AppleTV"]) return UIDeviceUnknownAppleTV;
// Simulator thanks Jordan Breeding
if ([platform hasSuffix:#"86"] || [platform isEqual:#"x86_64"])
{
BOOL smallerScreen = [[UIScreen mainScreen] bounds].size.width < 768;
return smallerScreen ? UIDeviceSimulatoriPhone : UIDeviceSimulatoriPad;
}
return UIDeviceUnknown;
}
- (NSString *) platformString
{
switch ([self platformType])
{
case UIDevice1GiPhone: return IPHONE_1G_NAMESTRING;
case UIDevice3GiPhone: return IPHONE_3G_NAMESTRING;
case UIDevice3GSiPhone: return IPHONE_3GS_NAMESTRING;
case UIDevice4iPhone: return IPHONE_4_NAMESTRING;
case UIDevice4SiPhone: return IPHONE_4S_NAMESTRING;
case UIDevice5iPhone: return IPHONE_5_NAMESTRING;
case UIDeviceUnknowniPhone: return IPHONE_UNKNOWN_NAMESTRING;
case UIDevice1GiPod: return IPOD_1G_NAMESTRING;
case UIDevice2GiPod: return IPOD_2G_NAMESTRING;
case UIDevice3GiPod: return IPOD_3G_NAMESTRING;
case UIDevice4GiPod: return IPOD_4G_NAMESTRING;
case UIDeviceUnknowniPod: return IPOD_UNKNOWN_NAMESTRING;
case UIDevice1GiPad : return IPAD_1G_NAMESTRING;
case UIDevice2GiPad : return IPAD_2G_NAMESTRING;
case UIDevice3GiPad : return IPAD_3G_NAMESTRING;
case UIDevice4GiPad : return IPAD_4G_NAMESTRING;
case UIDeviceUnknowniPad : return IPAD_UNKNOWN_NAMESTRING;
case UIDeviceAppleTV2 : return APPLETV_2G_NAMESTRING;
case UIDeviceAppleTV3 : return APPLETV_3G_NAMESTRING;
case UIDeviceAppleTV4 : return APPLETV_4G_NAMESTRING;
case UIDeviceUnknownAppleTV: return APPLETV_UNKNOWN_NAMESTRING;
case UIDeviceSimulator: return SIMULATOR_NAMESTRING;
case UIDeviceSimulatoriPhone: return SIMULATOR_IPHONE_NAMESTRING;
case UIDeviceSimulatoriPad: return SIMULATOR_IPAD_NAMESTRING;
case UIDeviceSimulatorAppleTV: return SIMULATOR_APPLETV_NAMESTRING;
case UIDeviceIFPGA: return IFPGA_NAMESTRING;
default: return IOS_FAMILY_UNKNOWN_DEVICE;
}
}
- (BOOL) hasRetinaDisplay
{
return ([UIScreen mainScreen].scale == 2.0f);
}
- (UIDeviceFamily) deviceFamily
{
NSString *platform = [self platform];
if ([platform hasPrefix:#"iPhone"]) return UIDeviceFamilyiPhone;
if ([platform hasPrefix:#"iPod"]) return UIDeviceFamilyiPod;
if ([platform hasPrefix:#"iPad"]) return UIDeviceFamilyiPad;
if ([platform hasPrefix:#"AppleTV"]) return UIDeviceFamilyAppleTV;
return UIDeviceFamilyUnknown;
}
#pragma mark MAC addy
// Return the local MAC addy
// Courtesy of FreeBSD hackers email list
// Accidentally munged during previous update. Fixed thanks to mlamb.
- (NSString *) macaddress
{
int mib[6];
size_t len;
char *buf;
unsigned char *ptr;
struct if_msghdr *ifm;
struct sockaddr_dl *sdl;
mib[0] = CTL_NET;
mib[1] = AF_ROUTE;
mib[2] = 0;
mib[3] = AF_LINK;
mib[4] = NET_RT_IFLIST;
if ((mib[5] = if_nametoindex("en0")) == 0) {
printf("Error: if_nametoindex error\n");
return NULL;
}
if (sysctl(mib, 6, NULL, &len, NULL, 0) < 0) {
printf("Error: sysctl, take 1\n");
return NULL;
}
if ((buf = malloc(len)) == NULL) {
printf("Error: Memory allocation error\n");
return NULL;
}
if (sysctl(mib, 6, buf, &len, NULL, 0) < 0) {
printf("Error: sysctl, take 2\n");
free(buf); // Thanks, Remy "Psy" Demerest
return NULL;
}
ifm = (struct if_msghdr *)buf;
sdl = (struct sockaddr_dl *)(ifm + 1);
ptr = (unsigned char *)LLADDR(sdl);
NSString *outstring = [NSString stringWithFormat:#"%02X:%02X:%02X:%02X:%02X:%02X", *ptr, *(ptr+1), *(ptr+2), *(ptr+3), *(ptr+4), *(ptr+5)];
free(buf);
return outstring;
}
#end
Happy coding ^_^
You should not select your storyboard according to iOS version but select it according to the screen size. Like this
CGRect screenBounds = [[UIScreen mainScreen] bounds];
if (screenBounds.size.height == 568) {
//device is iphone 5
//add storyboard that have large screen (320*568)
} else {
//device is iphone 4
//add story board that have small screen (320*480)
}
Because it does matter which iOS is it when we displaying our screen it depend on iPhone Screen Size.
You can also differentiate iPhone and iPad using this code
if ([[UIDevice currentDevice] userInterfaceIdiom] ==UIUserInterfaceIdiomPhone)
{
//device is iPhone
}
else
{
//device is iPad
}
And for differentiate which iOS version in your device you can use this code,
float currentVersion = 6.0;
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= currentVersion)
{
//device have iOS 6 or above
}else{
//device have iOS 5.1 or belove
}
You are not checking correctly in the first place.
You could've used the UIScreen to get the size of the screen and determine which device is used.
Also if you are developing for iOS 6 then you only need 1 Storyboard and you can use Autolayout option for the controllers and create NSLayoutContrains from the interface builder.
THis should be a lot easier than having 2 stroyboards for each iPhone.
There is no need to have 2 storyboards for 4inch devices (iPhone 5) and 3.5inch devices (iPhone 4S and lower).
The iPad requires a separate storyboard as the screen is far larger, but for an extra 88 pixels in height on iPhone 5, theres not really a lot more you can fit on as extra.
AutoLayout from iOS6 solves this problem, even the old Autoresizing properties solves this.
If you have an extra view (or any UI element) just for the iPhone 5, then simply detect the screen height as suggested by Dilip and if it's not iPhone 5 then hide the UI element using myElement.hidden = YES;.
CGRect screenBounds = [[UIScreen mainScreen] bounds];
if (screenBounds.size.height <= 480) {
myElement.hidden = YES;
}
In Storyboard view of Xcode theres a button on the iPhone storyboard which switches between 3.5 inch and 4 inch so you can adjust components positions to suit the device as shown below on the left.
I have found the solutions from here:
Determine device (iPhone, iPod Touch) with iPhone SDK
From the link, it suggests to use the library https://gist.github.com/1323251
But obviously the library is quite outdated. I couldn't find the iPhone 5 and new iPad and etc in the list.
Does anyone know how can I find the completed and updated list?
Thank you so much.
you can easily detect iphone, iphone5 and iPad with below condition:-
if([[UIDevice currentDevice]userInterfaceIdiom]==UIUserInterfaceIdiomPhone)
{
if ([[UIScreen mainScreen] bounds].size.height == 568.0f)
{
}
else
{
//iphone 3.5 inch screen
}
}
else
{
//[ipad]
}
my answer:-
Detect device type
Here's the updated version of https://gist.github.com/1323251 .
I'll keep it updated when new devices are released.
https://github.com/froztbytes/UIDeviceHardware
This works just fine:
if([UIDevice currentDevice].userInterfaceIdiom==UIUserInterfaceIdiomPad) {
NSLog(#"IPAD");
}else{
NSLog(#"IPHONE");
}
Just adding to #Mohammad Kamran Usmani answer. More specific iPhone types:
#import UIKit;
//Check which iPhone it is
double screenHeight = [[UIScreen mainScreen] bounds].size.height;
if(UI_USER_INTERFACE_IDIOM()==UIUserInterfaceIdiomPad)
{
NSLog(#"All iPads");
} else if (UI_USER_INTERFACE_IDIOM()== UIUserInterfaceIdiomPhone)
{
if(screenHeight == 480) {
NSLog(#"iPhone 4/4S");
smallFonts = true;
} else if (screenHeight == 568) {
NSLog(#"iPhone 5/5S/SE");
smallFonts = true;
} else if (screenHeight == 667) {
NSLog(#"iPhone 6/6S");
} else if (screenHeight == 736) {
NSLog(#"iPhone 6+, 6S+");
} else {
NSLog(#"Others");
}
}
Use the following code:
#import <sys/utsname.h>
- (NSString *)machineName
{
struct utsname systemInfo;
uname(&systemInfo);
NSString *temp = [NSString stringWithCString:systemInfo.machine
encoding:NSUTF8StringEncoding];
if ([temp rangeOfString:#"iPod"].location != NSNotFound)
{
return #"iPod";
}
if ([temp rangeOfString:#"iPad"].location != NSNotFound)
{
return #"iPad";
}
if ([temp rangeOfString:#"iPhone"].location != NSNotFound)
{
return #"iPhone";
}
return #"Unknown device";
}
I'm with other guys are maintaining the code on GitHub so please take the latest code from there. We're continuously adding new devices in the list.
Objective-C : GitHub/DeviceUtil
Swift : GitHub/DeviceGuru
#include <sys/types.h>
#include <sys/sysctl.h>
- (NSString*)hardwareDescription {
NSString *hardware = [self hardwareString];
if ([hardware isEqualToString:#"iPhone1,1"]) return #"iPhone 2G";
if ([hardware isEqualToString:#"iPhone1,2"]) return #"iPhone 3G";
if ([hardware isEqualToString:#"iPhone3,1"]) return #"iPhone 4";
if ([hardware isEqualToString:#"iPhone4,1"]) return #"iPhone 4S";
if ([hardware isEqualToString:#"iPhone5,1"]) return #"iPhone 5";
if ([hardware isEqualToString:#"iPod1,1"]) return #"iPodTouch 1G";
if ([hardware isEqualToString:#"iPod2,1"]) return #"iPodTouch 2G";
if ([hardware isEqualToString:#"iPad1,1"]) return #"iPad";
if ([hardware isEqualToString:#"iPad2,6"]) return #"iPad Mini";
if ([hardware isEqualToString:#"iPad4,1"]) return #"iPad Air WIFI";
//there are lots of other strings too, checkout the github repo
//link is given at the top of this answer
if ([hardware isEqualToString:#"i386"]) return #"Simulator";
if ([hardware isEqualToString:#"x86_64"]) return #"Simulator";
return nil;
}
- (NSString*)hardwareString {
size_t size = 100;
char *hw_machine = malloc(size);
int name[] = {CTL_HW,HW_MACHINE};
sysctl(name, 2, hw_machine, &size, NULL, 0);
NSString *hardware = [NSString stringWithUTF8String:hw_machine];
free(hw_machine);
return hardware;
}
You can use the following code
if(screenSize.width==2048 && screenSize.height==1536)
{
LetterParams.DeviceType=1;//IPadRetina
}
else if(screenSize.width==2048/2 && screenSize.height==1536/2)
{
LetterParams.DeviceType=2;//IPad Non-Retina
}
else if(screenSize.width==1136 && screenSize.height==640)
{
LetterParams.DeviceType=3;//IPhoneRetina
}
else
{
LetterParams.DeviceType=4;//IPhone & Ipod
}
Here is a method that I came up with that focuses on key devices for screen measurement functions. It is a quick way to determine what you need. This will detect up to iPhone 5 and 5th Gen. iPod touches.
typedef enum{
iPadRetina,iPadNoRetina,iPhoneiPod35InchRetina,iPhoneiPod35InchNoRetina,iPhoneiPod4InchRetina}DeviceType;
-(void)yourCustomFunctionThatNeedsToKnowDeviceType
{
NSLog(#"device type = %i",[self getDeviceType]);
switch ([self getDeviceType])
{
case iPadRetina:
{
NSLog(#"This device is one of the following: iPad 3, iPad 4");
break;
}
case iPadNoRetina:
{
NSLog(#"This device is one of the following: iPad 1, iPad 2, iPad mini");
break;
}
case iPhoneiPod35InchRetina:
{
NSLog(#"This device is one of the following: iPhone 4/4S or iPod Touch 4th Generation");
break;
}
case iPhoneiPod35InchNoRetina:
{
NSLog(#"This device is one of the following: iPhone 3G/3GS or iPod Touch 3rd Generation");
break;
}
case iPhoneiPod4InchRetina:
{
NSLog(#"This device is one of the following: iPhone 5 or iPod Touch 5th Generation");
break;
}
}
}
-(int)getDeviceType
{
// Get the ratio of the device's screen (height/width)
CGFloat screenRatio = [UIScreen mainScreen].bounds.size.height/[UIScreen mainScreen].bounds.size.width;
// Initialize return value to negative value
DeviceType type = -1;
if(screenRatio > 1.5)
{
/*
4.0-Inch Screen
This implies that the device is either an iPhone 5 or a 5th generation iPod
Retina display is implicit
*/
type = iPhoneiPod4InchRetina;
}
else
{
/*
Device must be iPad 1/2/3/4/mini or iPhone 4/4S or iPhone 3G/3GS
*/
// Take a screenshot to determine if the device has retina display or not
UIGraphicsBeginImageContextWithOptions(self.view.bounds.size, NO, 0.0);
[self.view.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *scaleCheckImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad)
{
/*
Device must be iPad 1/2/3/4/mini
*/
if(scaleCheckImage.scale == 1)
{
// iPad 1/2/mini (No Retina)
type = iPadNoRetina;
}
else if(scaleCheckImage.scale == 2)
{
// iPad 3/4 (Retina)
type = iPadRetina;
}
}
else
{
/*
Device must be iPhone 4/4S or iPhone 3G/3GS or iPod Touch 3rd Generation or iPod Touch 4th Generation
*/
if(scaleCheckImage.scale == 1)
{
// iPhone 3G/3GS or iPod Touch 3rd Generation (No Retina)
type = iPhoneiPod35InchNoRetina;
}
else if(scaleCheckImage.scale == 2)
{
// iPhone 4/4S or iPod Touch 4th Generation (Retina)
type = iPhoneiPod35InchRetina;
}
}
}
return type;
}
if(UI_USER_INTERFACE_IDIOM()==UIUserInterfaceIdiomPad)
{
NSLog(#"All iPads");
}
else
{
else if (UI_USER_INTERFACE_IDIOM()== UIUserInterfaceIdiomPhone)
{
if( screenHeight > 480 && screenHeight < 667 )
{
NSLog(#"iPhone 5/5s/6");
}
else if ( screenHeight > 480 && screenHeight < 736 )
{
NSLog(#"Other iPhones Resizable");
}
else if ( screenHeight > 480 )
{
NSLog(#"iPhone 6 +");
}
else
{
NSLog(#"iPhone 4s and others");
}
}
I have a toggle in my app that's "download on WiFi only". However, that toggle is useless for iPod touch or WiFi-iPads.
Is there a way to know if the device has cellular data capabilities in code? Something that would work in the future would be great too (like if an iPod touch 5th gen with 3G comes out).
Hi you should be able to check if it has the pdp_ip0 interface
#import <ifaddrs.h>
- (bool) hasCellular {
struct ifaddrs * addrs;
const struct ifaddrs * cursor;
bool found = false;
if (getifaddrs(&addrs) == 0) {
cursor = addrs;
while (cursor != NULL) {
NSString *name = [NSString stringWithUTF8String:cursor->ifa_name];
if ([name isEqualToString:#"pdp_ip0"]) {
found = true;
break;
}
cursor = cursor->ifa_next;
}
freeifaddrs(addrs);
}
return found;
}
This doesn't use any private APIs.
3G by itself seems tough to find. You can find out whether a device can make calls using [[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:#"tel://"]]. You can check whether a device can get to the internet, period (and by which method that can currently happen) using Reachability code:
NetworkStatus currentStatus = [[Reachability reachabilityForInternetConnection]
currentReachabilityStatus];
if(currentStatus == kReachableViaWWAN) // 3G
else if(currentStatus == kReachableViaWifi) // ...wifi
else if(currentStatus == kNotReachable) // no connection currently possible
..but aside from that, I don't think you can check for the existence of a 3G modem in the device.***** If it can't make a call, and doesn't currently have cell data turned on and wifi turned off, you won't be able to find out if it's 3G-capable.
An alternative way (not forward-compatible though, so you probably don't want to do this) is to compare the device's model with an exhaustive list, knowing which ones have 3G modems in them, as shown here.
***** As per bentech's answer, if you want to go digging around with device names (this may stop working with no advance warning if Apple decide to change the 3g interface name), call getifaddrs and check for the pdp_ip0 interface.
Swift 3.0 (UIDevice+Extension) of #bentech's answer
Add this line to your BridgingHeader.h:
#import <ifaddrs.h>
Somewhere else:
extension UIDevice {
/// A Boolean value indicating whether the device has cellular data capabilities (true) or not (false).
var hasCellularCapabilites: Bool {
var addrs: UnsafeMutablePointer<ifaddrs>?
var cursor: UnsafeMutablePointer<ifaddrs>?
defer { freeifaddrs(addrs) }
guard getifaddrs(&addrs) == 0 else { return false }
cursor = addrs
while cursor != nil {
guard
let utf8String = cursor?.pointee.ifa_name,
let name = NSString(utf8String: utf8String),
name == "pdp_ip0"
else {
cursor = cursor?.pointee.ifa_next
continue
}
return true
}
return false
}
}
In iOS 6.1, I've been able to use Core Telephony to successfully check for the presence of cellular baseband capabilities. This works on all iPads I tested: Verizon with service activated and without, AT&T with service currently deactivated, SIM card in and out, and a Wi-Fi-only iPad.
The code I used looks like this:
CTTelephonyNetworkInfo* ctInfo = [[CTTelephonyNetworkInfo alloc] init];
CTCarrier* carrier = ctInfo.subscriberCellularProvider;
self.hasWWANCapability = carrier != nil;
For all the iPads with cellular baseband hardware, carrier is not nil. For the Wi-Fi-only iPad, carrier is nil.
I'd think you should be able to use the CoreTelephony Framework.
It does call out that it is for carriers to use, so I am not sure if it is against TOS to access it.
Carriers can use this information to write applications that provide services only for their own subscribers
One way of doing it is to ask for the users location. When it is as accurate as possibLe, you will know if the device have GPS. All devices that have GPS will have 3G. And those that don't GPS won't have 3G.
Apple provided code here.
https://developer.apple.com/library/ios/samplecode/Reachability/Introduction/Intro.html
You should copy Reachability.h and Reachability.m to your project and import
Reachability.h to your class,then
Reachability *networkReachability = [Reachability reachabilityForInternetConnection];
NetworkStatus networkStatus = [networkReachability currentReachabilityStatus];
while (networkStatus==NotReachable) {
NSLog(#"not reachable");
//no internet connection
return;
}
while (networkStatus==ReachableViaWWAN) {
NSLog(#" ReachableViaWWAN ");
}
while (networkStatus==ReachableViaWiFi) {
NSLog(#"ReachableViaWiFi");
}
Another way is to extend this: https://github.com/monospacecollective/UIDevice-Hardware/blob/master/UIDevice-Hardware.m with this:
-(bool) hasCellular:(NSString*)modelIdentifier {
if ([modelIdentifier hasPrefix:#"iPhone"]) return YES;
if ([modelIdentifier hasPrefix:#"iPod"]) return NO;
if ([modelIdentifier isEqualToString:#"iPad1,1"]) return NO;
if ([modelIdentifier isEqualToString:#"iPad2,1"]) return NO;
if ([modelIdentifier isEqualToString:#"iPad2,2"]) return YES;
if ([modelIdentifier isEqualToString:#"iPad2,3"]) return YES;
if ([modelIdentifier isEqualToString:#"iPad2,4"]) return NO;
if ([modelIdentifier isEqualToString:#"iPad2,5"]) return NO;
if ([modelIdentifier isEqualToString:#"iPad2,6"]) return YES;
if ([modelIdentifier isEqualToString:#"iPad2,7"]) return YES;
if ([modelIdentifier isEqualToString:#"iPad3,1"]) return NO;
if ([modelIdentifier isEqualToString:#"iPad3,2"]) return YES;
if ([modelIdentifier isEqualToString:#"iPad3,3"]) return YES;
if ([modelIdentifier isEqualToString:#"iPad3,4"]) return NO;
if ([modelIdentifier isEqualToString:#"iPad3,5"]) return YES;
if ([modelIdentifier isEqualToString:#"iPad3,6"]) return YES;
if ([modelIdentifier isEqualToString:#"iPad4,1"]) return NO;
if ([modelIdentifier isEqualToString:#"iPad4,2"]) return YES;
if ([modelIdentifier isEqualToString:#"iPad2,5"]) return NO;
if ([modelIdentifier isEqualToString:#"iPad2,6"]) return YES;
if ([modelIdentifier isEqualToString:#"iPad2,7"]) return YES;
if ([modelIdentifier isEqualToString:#"iPad4,4"]) return NO;
if ([modelIdentifier isEqualToString:#"iPad4,5"]) return YES;
if ([modelIdentifier isEqualToString:#"i386"]) return NO;
if ([modelIdentifier isEqualToString:#"x86_64"]) return NO;
return YES;
}
(Clearly it could be edited down to remove either the NO or YES only depending on which way you want to err in case there is a new model...)
While it's not good practise to find out and use this information in your application, is there a way to find what model of iPhone / iPod / iPad you have. For example: 2G/3GS/4G etc
Try:
char deviceString[256];
size_t size = 255;
sysctlbyname("hw.machine", NULL, &size, NULL, 0);
if (size > 255) { size = 255; }
sysctlbyname("hw.machine", deviceString, &size, NULL, 0);
if (strcmp(deviceString,"iPhone1,1") == 0) { etc... } // 2G
1,2 is a 3G,
2,1 is a 3GS,
3,1 is an i4, etc.
I think that this is already answered here: Determine device (iPhone, iPod Touch) with iPhone SDK, though I've added a bit to it:
- (NSString *) platformString{
NSString *platform = [self platform];
if ([platform isEqualToString:#"iPhone1,1"]) return #"iPhone 1G";
if ([platform isEqualToString:#"iPhone1,2"]) return #"iPhone 3G";
if ([platform isEqualToString:#"iPhone2,1"]) return #"iPhone 3GS";
if ([platform isEqualToString:#"iPhone3,1"]) return #"iPhone 4";
if ([platform isEqualToString:#"iPod1,1"]) return #"iPod Touch 1G";
if ([platform isEqualToString:#"iPod2,1"]) return #"iPod Touch 2G";
if ([platform isEqualToString:#"iPod3,1"]) return #"iPod Touch 3G";
if ([platform isEqualToString:#"iPod4,1"]) return #"iPod Touch 4G";
if ([platform isEqualToString:#"iPad1,1"]) return #"iPad";
if ([platform isEqualToString:#"i386"]) return #"iPhone Simulator";
return platform;
}
to account for recent additions to the family. You can checkout everyipod.com, for example, specs for iPhone 4 to get platform strings.
-[UIDevice model], but I'm not sure if it returns anything more specific than "iPhone" or "iPod Touch".
I thought iTunes/Xcode Organizer did this already for some reason (at least I seem to remember it correctly identifying my old iPod Touch as a 1st gen), that's definitely not the case for my iPhone 3GS. Nor does the iPhone Configuration Utility help.
So I fired up System Profiler to see if the device shows up on the USB list; it does. It also shows the "Product ID" (in my case, 0x1294). I typed that into Google and came up with this:
http://theiphonewiki.com/wiki/index.php?title=Normal_Mode
Device IDs
It appears that it uses different device IDs:
iPhone - 0x1290
iPod touch - 0x1291
iPhone 3G - 0x1292
iPod touch 2G - 0x1293
iPhone 3GS - 0x1294
iPod touch 3G - 0x1299
iPad - 0x129a
iPhone 4 -
iPod touch 4G - 0x129e
Apple TV 2G -