用于确定是否在iPhone或iPad上运行的API

用于确定是否在iPhone或iPad上运行的API,iphone,objective-c,cocoa-touch,ipad,uidevice,Iphone,Objective C,Cocoa Touch,Ipad,Uidevice,是否有API用于在运行时检查您是在iPhone上运行还是在iPad上运行 我能想到的一种方法是: [[UIDevice currentDevice] model]; 并检测字符串的存在"iPad",这似乎有点脆弱 在3.2 SDK中,我看到UIDevice也有一个属性,这正是我所寻找的,但不适用于3.2之前的版本(显然): 除了检查通用应用程序是否存在@“iPad”,还有其他方法吗?检查 返回当前设备支持的接口习惯用法 返回值 UIUserInterfaceIdiomPhone如果设备是iPh

是否有API用于在运行时检查您是在iPhone上运行还是在iPad上运行

我能想到的一种方法是:

[[UIDevice currentDevice] model];
并检测字符串的存在"iPad",这似乎有点脆弱

在3.2 SDK中,我看到
UIDevice
也有一个属性,这正是我所寻找的,但不适用于3.2之前的版本(显然):

除了检查通用应用程序是否存在@“iPad”,还有其他方法吗?

检查

返回当前设备支持的接口习惯用法

返回值
UIUserInterfaceIdiomPhone
如果设备是iPhone或iPod touch,或者
UIUserInterfaceIdiomPad
如果设备是iPad

应在当前设备上使用的接口类型


使用NSClassFromString和特定于iPad的类。请在此处阅读更多信息:

  • 使用respondsToSelector:,检查userInterfaceIdiom属性是否存在。如果它不存在,我们就在3.2之前的设备上,因此不是iPad
  • 如果userInterfaceIdiom存在,请使用它
  • 编辑:。。。这显然正是UI\u USER\u INTERFACE\u IDIOM()宏所做的,因此请改用它。:)

    仅供我参考:

    @property (nonatomic, readonly) BOOL isPhone;
    
    -(BOOL)isPhone {
        return (UI_USER_INTERFACE_IDIOM()==UIUserInterfaceIdiomPhone);
    }
    
    或者使用#define

    但是,如果您在代码中使用
    isPhone
    ,这通常是不好的做法。使用工厂模式和多态性来保持包含
    if
    语句,这样您就可以为手机或iPad创建对象,然后使用它们

    已添加

    我现在在我的代码中使用这个解决方案。它将标准工厂模式添加到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\
    
    然后我的alloc看起来像这样:

    +alloc { ALLOC_PER_DEVICE(); }
    
    我为手机版本添加了一个名为
    TheClassPhone
    的子类


    注意:因为Objective-C中没有多重继承,所以使用继承来解决问题有点被高估了(即,如果您有子类的子类,它就不起作用)。当你需要时,最好的
    (如果
    )。

    你可以使用以下代码检查你是否在iPhone或iPad上运行该应用程序:

    - (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;
    }
    

    明白了-我可以使用respondsToSelector:@selector(userInterfaceIdiom)而不是检查字符串“iPad”的存在。谢谢使用宏-稍后的操作系统将响应选择器,但不一定是iPad。好的,我正在学习。:)我的#fail:我一直在使用模拟器在iPhone和iPad之间切换,在3.2和3.1之间切换活动SDK,当活动SDK为3.1时,它不再编译。然后我用一些咖啡因刺激神经元,并在其周围插入“IfdefUI用户界面”的习惯用语。。。不管怎样,谢谢你的跟进,如果我刚刚把我的“失败”和“失败”加在一起,请告诉我为了交叉链接的缘故:有一个警告:如果iPad用户运行的是纯iPhone应用程序(如非通用应用程序),UI_用户界面_惯用语函数会将设备报告为iPhone。-1很难说你在这里的回答是什么。要么删除,要么修复?嗨,这里是Objective-C的学习者。只是想知道为什么说创建一个utilities类,然后在其中添加一个“isPhone”静态方法,这样我就可以在整个项目中处理([utilities isPhone]){/*iphone stuff/}或者{/ipad stuff*/}了,这不一定是个好主意?另外,为什么要将方法定义为属性?使用类方法的实用程序类是可以的。我将它定义为一个属性,因为我想这样使用它。如果您的
    实用程序
    类是一个单例,那么您可以使用
    实用程序isPhone
    或者生成类方法。单身绝对是推荐的方式。方法作为属性是相同的。Objective-C就是这样灵活的。
    #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\
    
    +alloc { ALLOC_PER_DEVICE(); }
    
    - (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;
    }