2010-05-21 15 views
32

¿Existe una API para el control en tiempo de ejecución si se está ejecutando en un iPhone o un iPad?API para determinar si se ejecuta en iPhone o iPad

Una forma que se me ocurre sería utilizar:

[[UIDevice currentDevice] model]; 

y detectar la existencia de la cadena @ "IPAD" - que parece un poco frágil.

En el SDK 3.2, veo que también tiene una propiedad que es realmente lo que estoy buscando, pero no funciona para la pre-3.2 (obviamente):

[[UIDevice currentDevice] userInterfaceIdiom]; 

¿Hay otra formas de comprobar la existencia de @ "iPad" para una aplicación universal?

Respuesta

41

Pedido UI_USER_INTERFACE_IDIOM.

Devuelve la interfaz idiomática admitida por el dispositivo actual.

Valor de retorno
UIUserInterfaceIdiomPhone si el dispositivo es un iPhone o un iPod o UIUserInterfaceIdiomPad si el dispositivo es un iPad.

UIUserInterfaceIdiom

El tipo de interfaz que se debe utilizar en el dispositivo actual

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

Gotcha - Puedo utilizar respondsToSelector: @selector (userInterfaceIdiom) en lugar de la comprobación de la existencia de la cadena " iPad ". ¡Gracias! – Eric

+7

use la macro - más tarde OS responderá al selector, pero no necesariamente será un iPad. – Andiih

+1

Ok, estoy aprendiendo. :) Mi #fail: He estado usando el simulador para alternar entre iPhone y iPad al cambiar el Active SDK entre 3.2 y 3.1, en el cual ya no compila cuando el Active SDK es 3.1. Luego sacudí las neuronas con algo de cafeína y conecté el #ifdef UI_USER_INTERFACE_IDIOM a su alrededor ... De todos modos, gracias por el seguimiento Andiih - y si acabo de componer mi #fail a algo #worsethanfailure con el #ifdef, déjame saber. :) – Eric

1
  1. comprobar la presencia de la propiedad userInterfaceIdiom, usings respondsToSelector :. Si no existe, estamos en un dispositivo pre-3.2, por lo tanto no es un iPad.
  2. Si userInterfaceIdiom existe, lo utilizan.

Editar: ... que obviamente es exactamente lo que hace el UI_USER_INTERFACE_IDIOM() macro, a fin de utilizar en su lugar. :)

15

Sólo por mi referencia:

@property (nonatomic, readonly) BOOL isPhone; 

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

o utilizar un #define

#define IS_PHONE (UI_USER_INTERFACE_IDIOM()==UIUserInterfaceIdiomPhone) 

Sin embargo, si usted está utilizando isPhone todo su código, que es generalmente una mala práctica. Utilice el patrón de fábrica y el polimorfismo para mantener sus declaraciones if contenidas, para que pueda obtener los objetos creados para el teléfono o para iPad y luego trabajar con ellos.

Agregado

estoy usando esta solución todo mi código ahora. Agrega un patrón de fábrica estándar en el 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\ 

Entonces mis allocs tener este aspecto:

+alloc { ALLOC_PER_DEVICE(); } 

Y añado una subclase llamada TheClassPhone para la versión del teléfono.

Nota: Ya que no hay herencia múltiple en Objective-C, utilizando la herencia para resolver sus problemas es un poco sobrevalorado (es decir, no funciona si tiene subclases de subclases). No hay nada como un buen if cuando lo necesite.

+0

Hola, aprendiz de Objective-C aquí. Solo me pregunto por qué no es necesariamente una buena idea decir una clase de utilidades y luego agregarle un método estático "isPhone" para que pueda hacerlo si ([utilities isPhone]) {/ * iphone stuff * /} else {/ * cosas de iPad * /} a lo largo de mi proyecto? Además, ¿por qué defines tu método como una propiedad? – Macmee

+0

clase de utilidades con métodos de clase está bien. Lo defino como una propiedad porque quiero usarlo de esa manera. –

+0

Si su clase 'Utilities' es un singleton, entonces puede usar' utility isPhone'; de lo contrario, cree métodos de clase. Singleton es definitivamente el camino recomendado para seguir. Métodos como propiedades son lo mismo. Objective-C es flexible así. –

1

Puede comprobar si ejecuta la aplicación en el iPhone o iPad utilizando el siguiente código:

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