identify iPhone 3, 4 and 5 in the same #define - iphone

I've been using the next line in my constants
to differentiate between devices and get back the number of the device.
What's the appropriate way to identify iPhone 5 and still keep it in a one line format?
#define iPhoneType [[UIScreen mainScreen] scale]==2 || [UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad ? #"4" : #"3"
Thanks
Edit: A lot of good answers but my goal is to keep it in a one line format for all devices.
Edit:
Based on the comments, this question needs some clarification. Here are the requirements:
A single-line macro that returns either #"3", #"4", or #"5" depending on the iOS device.
The 4" devices (currently iPhone 5 and 5th gen iPod touch) should return #"5".
All iPads and all remaining retina iPhones and iPod touches should return #"4".
All remaining non-retina iPhones and iPod touches should return #"3".

According to your question I'm assuming you want to identify the hardware device, not the iOS version.
/*
Erica Sadun, http://ericasadun.com
iPhone Developer's Cookbook, 6.x Edition
BSD License, Use at your own risk
*/
#include <sys/sysctl.h>
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 getSysInfoByName("hw.machine");
}
Import those functions in the .pch, then you are free to call this one liner:
BOOL isIphone5 = [platform() hasPrefix:#"iPhone5"];
It works for any device. See UIDevice-Hardware.m for a list of the strings returned.

Assuming the updated requirements are correct, the following should work:
#define iPhoneType (fabs((double)[UIScreen mainScreen].bounds.size.height - (double)568) < DBL_EPSILON) ? #"5" : ([UIScreen mainScreen].scale==2 || UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad ? #"4" : #"3")
This will return #"5" for the 4" screened iPhones and iPod touches. This will return #"4" for all iPads and retina iPhones and iPod touches. And it will return #"3" for non-retina iPhones and iPod touches.

Define Following Constants in .pch file of your project
#define IS_IPHONE5 ([[UIScreen mainScreen] bounds].size.width >= 568 || [[UIScreen mainScreen] bounds].size.height >= 568)?YES:NO
#define IS_IPHONE (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone)?YES:NO
#define IS_IPAD (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)?YES:NO
#define DeviceType ((IS_IPAD)?#"IPAD":(IS_IPHONE5)?#"IPHONE 5":#"IPHONE")
Now Check device type
NSLog(#"%# %#",DeviceType,[DeviceType isEqualToString:#"IPAD"]?#"YES":#"NO");
Use following sequence to Identify Device Type
if(IS_IPAD)
NSLog(#"IPAD");
else if(IS_IPHONE5)
NSLog(#"IPHONE 5");
else
NSLog(#"IPHONE");

The best way to identify the different iOS devices programatically is their screen resolution. I done same in my application it is working great. Please refer my code.
- (NSString *) getDeviceScreenWidth
{
CGRect screenBounds = [[UIScreen mainScreen] bounds];
CGFloat width = CGRectGetWidth(screenBounds);
NSNumber* number = [NSNumber numberWithFloat:width];
NSNumberFormatter *numberFormatter = [[NSNumberFormatter alloc] init];
[numberFormatter setNumberStyle:kCFNumberFormatterDecimalStyle];
NSString* commaString = [numberFormatter stringForObjectValue:number];
NSString *screenWidth = [NSString stringWithFormat:#"%#",commaString];
NSLog(#"screen Width is: %#",screenWidth);
return screenWidth;
}
- (NSString *) getDeviceScreenHeight
{
CGRect screenBounds = [[UIScreen mainScreen] bounds];
CGFloat height = CGRectGetHeight(screenBounds);
NSNumber* number = [NSNumber numberWithFloat:height];
NSNumberFormatter *numberFormatter = [[NSNumberFormatter alloc] init];
[numberFormatter setNumberStyle:kCFNumberFormatterDecimalStyle];
NSString* commaString = [numberFormatter stringForObjectValue:number];
NSString *screenHeight = [NSString stringWithFormat:#"%#",commaString];
NSLog(#"screen height is: %#",screenHeight);
return screenHeight;
}

As sample you may found this code in cocos2d framework:
-(NSInteger) runningDevice
{
NSInteger ret=-1;
#ifdef __CC_PLATFORM_IOS
if( UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
{
ret = (CC_CONTENT_SCALE_FACTOR() == 2) ? kCCDeviceiPadRetinaDisplay : kCCDeviceiPad;
}
else if( UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone )
{
// From http://stackoverflow.com/a/12535566
BOOL isiPhone5 = CGSizeEqualToSize([[UIScreen mainScreen] preferredMode].size,CGSizeMake(640, 1136));
if( CC_CONTENT_SCALE_FACTOR() == 2 ) {
ret = isiPhone5 ? kCCDeviceiPhone5RetinaDisplay : kCCDeviceiPhoneRetinaDisplay;
} else
ret = isiPhone5 ? kCCDeviceiPhone5 : kCCDeviceiPhone;
}
#elif defined(__CC_PLATFORM_MAC)
// XXX: Add here support for Mac Retina Display
ret = kCCDeviceMac;
#endif // __CC_PLATFORM_MAC
return ret;
}
I hope this code helps change your macro.

Related

How can I detect if an iOS device supports the blur effect?

It appears that different iOS devices render UINavigationBars with barStyle = UIBarStyleBlack and translucent = YES very differently. Consider:
iPhone 4, no tint:
iPhone 5, no tint:
iPhone 4, barTintColor = [UIColor colorWithWhite:0.0f alpha:0.5f]:
iPhone 5, barTintColor = [UIColor colorWithWhite:0.0f alpha:0.5f]:
The iPhone 5 produces the desired effect without a tint, but the 4 is opaque. Adding a semitransparent tint makes the 4 look good, but screws up the 5.
The same holds true for the iPad 2 and 3, and theoretically any device that does not support the iOS 7 blur effects.
Short of blacklisting these older devices, how can I detect if a device supports the blurring so that I can conditionally work around the rendering differences? Or is there a way to normalize the appearance without using a tint at all?
What about this UIDevice category along with observing for UIAccessibilityReduceTransparencyStatusDidChangeNotification?
#interface UIDevice (Additions)
#property (readonly) NSString *platform;
#property (readonly) BOOL canBlur;
#end
#implementation UIDevice (Additions)
- (NSString *)platform {
int mib[] = { CTL_HW, HW_MACHINE };
size_t len = 0;
sysctl(mib, 2, NULL, &len, NULL, 0);
char *machine = malloc(len);
sysctl(mib, 2, machine, &len, NULL, 0);
NSString *platform = [NSString stringWithCString:machine encoding:NSASCIIStringEncoding];
free(machine);
return platform;
}
- (BOOL)canBlur {
if(NSStringFromClass([UIVisualEffectView class]) && UIDevice.currentDevice.systemVersion.floatValue >= 8.0 && !UIAccessibilityIsReduceTransparencyEnabled()) {
NSString *platform = self.platform;
CGFloat deviceVersion = [[[platform stringByReplacingOccurrencesOfString:#"[^0-9,.]" withString:#"" options:NSRegularExpressionSearch range:NSMakeRange(0, platform.length)] stringByReplacingOccurrencesOfString:#"," withString:#"."] floatValue];
if([platform isEqualToString:#"i386"] || [platform isEqualToString:#"x86_64"]) {
return YES;
} else if([platform rangeOfString:#"iPhone"].location != NSNotFound) {
return (deviceVersion >= 4.1);
} else if([platform rangeOfString:#"iPod"].location != NSNotFound) {
return (deviceVersion >= 5.1);
} else if([platform rangeOfString:#"iPad"].location != NSNotFound) {
return (deviceVersion >= 3.4);
}
}
return NO;
}
Don't forget to #include in your implementation file.
I think this question is what you want to do. Just to write conditional code for different devices:
Determine device (iPhone, iPod Touch) with iPhone SDK

How to check if an iOS device is a retina display iPod touch?

Is there a safe way to determine that a device is of a particular model? For example I must know if the device the user uses is a retina display iPod touch.
NSRange r = [[[UIDevice currentDevice] model] rangeOfString:#"iPod"];
float s = [[UIScreen mainScreen] scale];
if (r.location != NSNotFound && s > 1.5f) {
// retina iTouch
}
I would probably try something like this:
+(BOOL) isRetinaiPod
{
return [[[UIDevice currentDevice] model] isEqualToString:#"iPod touch"] && [UIScreen mainScreen].scale >= 2.0f;
}
However you can return the device's name with this:
+ (NSString *) deviceName
{
struct utsname u;
uname(&u);
return [NSString stringWithUTF8String:u.sysname];
}

How to detect iOS device programmatically

I need to know which iOS device is currently running app (saying more exactly I need to know is device armv6 or armv7). UIUserInterfaceIdiomPad() could not check is device an iPhone4S or iPhone3G. Is it possible?
Download https://github.com/erica/uidevice-extension (UIDevice-Hardware class) and you can use these:
[UIDevice currentDevice] platformType] // returns UIDevice4GiPhone
[[UIDevice currentDevice] platformString] // returns #"iPhone 4G"
Or check if its retina
+ (BOOL) isRetina
{
if([[UIScreen mainScreen] respondsToSelector:#selector(scale)])
return [[UIScreen mainScreen] scale] == 2.0 ? YES : NO;
return NO;
}
Or check iOs version
+ (BOOL) isIOS5
{
NSString *os5 = #"5.0";
NSString *currSysVer = [[UIDevice currentDevice] systemVersion];
// currSysVer = #"5.0.1";
if ([currSysVer compare:os5 options:NSNumericSearch] == NSOrderedAscending) //lower than 4
{
return NO;
}
else if ([currSysVer compare:os5 options:NSNumericSearch] == NSOrderedDescending) //5.0.1 and above
{
return YES;
}
else // IOS 5
{
return YES;
}
return NO;
}
If you really want to know (at run time) if you are running on arm6 or arm7, you can use "NXGetArchInfoFromCPUType" (much more detail is available in the accepted answer to this question).
Otherwise you can use platformType or platformString, as our incredibly quick answering friend Omar suggested (and +1 to him!).

How do I determine whether the current device is an iPhone or iPad?

In my universal app I need to check if the current device is an iPad or iPhone. How can I do this programmatically? I plan to put the code in my viewDidLoad.
check if UISplitViewController class available on the platform, if so make sure it is iPad using Apple's macro (notice that UIUserInterfaceIdiomPad constant is available only on iOS 3.2 and up).
if (NSClassFromString(#"UISplitViewController") != nil && UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
//currentDeviceType = iPad;
}
else {
//currentDeviceType = iPhone;
}
Proper method to detect device model (iPhone/iPod Touch)?
I use this simple function in all my apps:
#import "isPad.h"
BOOL isPad () {
static BOOL isPad;
static BOOL used = NO;
if (used)
return isPad;
used = YES;
NSRange range = [[[UIDevice currentDevice] model] rangeOfString:#"iPad"];
isPad = range.location != NSNotFound;
return isPad;
}
try this.. this will help you.
NSString *deviceType = [UIDevice currentDevice].model;
if([deviceType isEqualToString:#"iPod touch"]||[deviceType isEqualToString:#"iPhone"]||[deviceType isEqualToString:#"iPad"]){
}
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
{
// Statements
}
else if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone)
{
// Statements
}

iPhone - iPad Device Type Trick in the Header File

So I've got a function that really helps when I'm crafting device specific URLS but I'd like to place it in a global header file so any class could use it easily
- (NSString *)deviceType
{
NSString *deviceName = #"iphone";
if([[UIScreen mainScreen] respondsToSelector:#selector(scale)])
{
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad){
deviceName = #"ipad";
}
else {
deviceName = #"iphone4";
}
}
return deviceName;
}
That may or may not be the best way of doing it but I'd like to know how to get that into a global header so I can do something like this
NSString *deviceName = GETDEVICENAME;
#define GETDEVICENAME [whatever deviceType] maybe?
There is an issue with your function though, on 3.2 UIScreen doesn't respond to scale (at least no publicly. I wouldn't rely on that to check for iPad.
With in your project should be a file called %PROJECT%_Prefix.pch.
Any headers you include in that file will be accessible by all files in your project.
Got the answer that worked for me,
In a global header file Globals.h I placed
NSString* deviceType();
in Globals.m I placed a modified function
NSString* deviceType()
{
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad){
return #"ipad";
}
else if([[UIScreen mainScreen] respondsToSelector:#selector(scale)])
{
return #"iphone4";
}
else{
return #"iphone";
}
}