API, чтобы определить, работает ли на iPhone или iPad

Есть ли API для проверки во время выполнения, работаете ли вы на iPhone или iPad?

Один из способов, который я могу придумать, это использовать:

[[UIDevice currentDevice] model];

И обнаружить наличие строки @"iPad" - которая кажется немного хрупкой.

В 3.2 SDK я вижу, что UIDevice также есть свойство, которое действительно то, что я ищу, но не работает для pre-3.2 (очевидно):

[[UIDevice currentDevice] userInterfaceIdiom]; 

Есть ли другие способы, кроме проверки на наличие "iPad" для универсального приложения?

5 ответов

Решение

Проверять, выписываться UI_USER_INTERFACE_IDIOM,

Возвращает интерфейс, поддерживаемый текущим устройством.

Возвращаемое значение
UIUserInterfaceIdiomPhone если это устройство iPhone или iPod touch или UIUserInterfaceIdiomPad если устройство iPad.

UIUserInterfaceIdiom

Тип интерфейса, который должен использоваться на текущем устройстве

typedef enum {
   UIUserInterfaceIdiomPhone,
   UIUserInterfaceIdiomPad,
} UIUserInterfaceIdiom;

Просто для справки:

@property (nonatomic, readonly) BOOL isPhone;

-(BOOL)isPhone {
    return (UI_USER_INTERFACE_IDIOM()==UIUserInterfaceIdiomPhone);
}

или используйте #define

#define IS_PHONE  (UI_USER_INTERFACE_IDIOM()==UIUserInterfaceIdiomPhone)

Однако, если вы используете 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_PER_DEVICE(); }

И я добавляю подкласс под названием TheClassPhone для версии телефона.

Примечание. Поскольку в Objective-C нет множественного наследования, использование наследования для решения ваших проблем несколько переоценено (т. Е. Оно не работает, если у вас есть подклассы подклассов). Ничего хорошего if когда тебе это нужно.

  1. Проверьте наличие свойства userInterfaceIdiom, используя responsedsToSelector:. Если его нет, значит, мы работаем с устройством до 3.2, то есть не с iPad.
  2. Если userInterfaceIdiom существует, используйте его.

Редактировать:... что, очевидно, именно то, что делает макрос UI_USER_INTERFACE_IDIOM(), так что используйте его вместо этого.:)

Вы можете проверить, запускаете ли вы приложение на 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;
}

Используйте NSClassFromString и класс для iPad. Узнайте больше здесь:

http://developer.apple.com/iphone/library/documentation/General/Conceptual/iPadProgrammingGuide/StartingYourProject/StartingYourProject.html

Другие вопросы по тегам