2010-05-21 4 views
32

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

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

[[UIDevice currentDevice] model]; 

И обнаружить существование строки @ «IPad» - который, кажется, немного хрупкой.

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

[[UIDevice currentDevice] userInterfaceIdiom]; 

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

ответ

41

Оформить заказ UI_USER_INTERFACE_IDIOM.

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

Возвращаемое значение
UIUserInterfaceIdiomPhone, если устройство является сенсорным iPhone или IPod или UIUserInterfaceIdiomPad, если устройство является IPad.

UIUserInterfaceIdiom

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

typedef enum { 
    UIUserInterfaceIdiomPhone, 
    UIUserInterfaceIdiomPad, 
} UIUserInterfaceIdiom; 
+0

Гоча - Я могу использовать respondsToSelector: @selector (userInterfaceIdiom) вместо проверки на существование строки " IPad». Благодаря! – Eric

+7

использовать макрос - более поздние ОС ответят на селектор, но не обязательно будут iPad. – Andiih

+1

Хорошо, я учусь. :) My #fail: Я использовал симулятор для переключения между iPhone и iPad, переключив активный SDK между 3,2 и 3,1 - в котором он больше не компилируется, когда активным SDK является 3.1. Затем я встряхнул нейроны с каким-то кофеином и подключил к нему #ifdef UI_USER_INTERFACE_IDIOM ... В любом случае, спасибо за продолжение Andiih - и если я просто усугубил свой #fail чем-то #worsethanfailure с #ifdef, позвольте мне знать. :) – Eric

0

Использование NSClassFromString и IPAD конкретного класса. Подробнее здесь:

http://developer.apple.com/iphone/library/documentation/General/Conceptual/iPadProgrammingGuide/StartingYourProject/StartingYourProject.html#//apple_ref/doc/uid/TP40009370-CH9-SW3

+4

-1 действительно сложно сказать, что вы отвечаете здесь. Может быть, удалить или исправить? –

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

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

15

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

@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\ 

Тогда мои ALLOCS выглядеть следующим образом:

+alloc { ALLOC_PER_DEVICE(); } 

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

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

+0

Привет, ученик Objective-C здесь. Просто интересно, почему не обязательно говорить о том, чтобы сделать класс утилиты, а затем добавить к нему статический метод «isPhone», чтобы я мог делать, если ([utilities isPhone]) {/ * iphone stuff * /} else {/ * ipad stuff * /} на протяжении всего моего проекта? Кроме того, почему вы определяете свой метод как свойство? – Macmee

+0

класс утилит с методами класса в порядке. Я определяю его как свойство, потому что я хочу использовать его таким образом. –

+0

Если ваш класс 'Utilities' является одноэлементным, то вы можете использовать' utilities isPhone', в противном случае - методы класса. Синглтон определенно является рекомендуемым способом. Методы как свойства одинаковы. Объектив-C такой же гибкий. –

1

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