2011-11-06 8 views
8

He escrito la siguiente categoría de UIDevice en función de diferentes fuentes. Actualicé el método platformCode por lo que es menos de bajo nivel que se puede ver.Determine el dispositivo del usuario utilizando iOS SDK y el código Cocoa Touch/Objective-C completo

Esto funciona perfectamente, pero el método platformCode es de bajo nivel. ¿Sabes si este tipo de llamada se puede reemplazar con el código Cocoa Touch? Aquí está el código correspondiente:

UIDevice_enhanced.h

@interface UIDevice (Enhanced) 

typedef enum { 
    kUnknownPlatform = 0, 
    kiPhone1G, 
    kiPhone3G, 
    kiPhone3GS, 
    kiPhone4, 
    kiPhone4Verizon, 
    kiPhone4S, 
    kiPodTouch1G, 
    kiPodTouch2G, 
    kiPodTouch3G, 
    kiPodTouch4G, 
    kiPad, 
    kiPad2Wifi, 
    kiPad2GSM, 
    kiPad2CMDA, 
    kSimulator 
} PlatformType; 

- (NSString *) platformName; 
- (PlatformType) platform; 

@end 

UIDevice_enhanced.m

#import "UIDevice_enhanced.h" 
#include <sys/utsname.h> 

@interface UIDevice (Enhanced) 
- (NSString *) platformCode; 
@end 


@implementation UIDevice (Enhanced) 

// Utility method (private) 
- (NSString*) platformCode { 
    struct utsname systemInfo; 
    uname(&systemInfo); 
    NSString* platform = [NSString stringWithCString:systemInfo.machine encoding:NSUTF8StringEncoding]; 

    return platform; 
} 

// Public method to use 
- (NSString*) platformName { 
    NSString* platform = [self platformCode]; 

    if ([platform isEqualToString:@"iPhone1,1"]) return @"iPhone 1G"; 
    if ([platform isEqualToString:@"iPhone1,2"]) return @"iPhone 3G"; 
    if ([platform isEqualToString:@"iPhone2,1"]) return @"iPhone 3GS"; 
    if ([platform isEqualToString:@"iPhone3,1"]) return @"iPhone 4"; 
    if ([platform isEqualToString:@"iPhone3,2"]) return @"Verizon iPhone 4"; 
    if ([platform isEqualToString:@"iPhone4,1"]) return @"iPhone 4S"; 
    if ([platform isEqualToString:@"iPod1,1"])  return @"iPod Touch 1G"; 
    if ([platform isEqualToString:@"iPod2,1"])  return @"iPod Touch 2G"; 
    if ([platform isEqualToString:@"iPod3,1"])  return @"iPod Touch 3G"; 
    if ([platform isEqualToString:@"iPod4,1"])  return @"iPod Touch 4G"; 
    if ([platform isEqualToString:@"iPad1,1"])  return @"iPad"; 
    if ([platform isEqualToString:@"iPad2,1"])  return @"iPad 2 (WiFi)"; 
    if ([platform isEqualToString:@"iPad2,2"])  return @"iPad 2 (GSM)"; 
    if ([platform isEqualToString:@"iPad2,3"])  return @"iPad 2 (CDMA)"; 
    if ([platform isEqualToString:@"i386"])   return @"Simulator"; 

    return platform; 
} 

// Public method to use 
- (PlatformType) platform { 
    NSString *platform = [self platformCode]; 
    if ([platform isEqualToString:@"iPhone1,1"]) return kiPhone1G; 
    if ([platform isEqualToString:@"iPhone1,2"]) return kiPhone3G; 
    if ([platform isEqualToString:@"iPhone2,1"]) return kiPhone3GS; 
    if ([platform isEqualToString:@"iPhone3,1"]) return kiPhone4; 
    if ([platform isEqualToString:@"iPhone3,2"]) return kiPhone4Verizon; 
    if ([platform isEqualToString:@"iPhone4,1"]) return kiPhone4S; 
    if ([platform isEqualToString:@"iPod1,1"])  return kiPodTouch1G; 
    if ([platform isEqualToString:@"iPod2,1"])  return kiPodTouch2G; 
    if ([platform isEqualToString:@"iPod3,1"])  return kiPodTouch3G; 
    if ([platform isEqualToString:@"iPod4,1"])  return kiPodTouch4G; 
    if ([platform isEqualToString:@"iPad1,1"])  return kiPad; 
    if ([platform isEqualToString:@"iPad2,1"])  return kiPad2Wifi; 
    if ([platform isEqualToString:@"iPad2,2"])  return kiPad2GSM; 
    if ([platform isEqualToString:@"iPad2,3"])  return kiPad2CMDA; 
    if ([platform isEqualToString:@"i386"])   return kSimulator; 

    return kUnknownPlatform; 
} 

@end 
+0

Esto es perfectamente válido Objective-C (como todo el código C), tampoco es demasiado bajo nivel (yo recomiendo el uso de enumeraciones en lugar de cadenas para conjuntos finitos de opción múltiple). –

Respuesta

2

Esto puede considerarse como una forma "objetiva-c" de hacerlo:

// Utility method (private) 
- (NSString *)platformCode { 
    // This may or not be necessary 
    // Im not sure if you can have a device thats not currentDevice can you? 
    // if ([self isEqual:[UIDevice currentDevice]]) { 

    NSString* platform =  [[self.systemName copy] autorelease]; 
    return platform; 

    // Could probably shorten to just 
    // return [[self.systemName copy] autorelease]; 

    // or - return [NSString stringWithString:self.systemName]; 
} 

Esta sería la versión obj-c de utsnamemachine (de esta línea: NSString* platform =  [NSString stringWithCString:systemInfo.machine encoding:NSUTF8StringEncoding];).

utsname:

El <sys/utsname.h> encabezado define utsname estructura, que incluye al menos los siguientes miembros:

char sysname[]     nombre de esta aplicación del sistema operativo
char nodename[] nombre de este nodo dentro de una red de comunicaciones dependiente de la implementación
char release[]     nivel actual liberación de esta implementación
char version[]     nivel de la versión actual de este liberar
char machine[]     nombre del tipo de hardware en el que el sistema se está ejecutando

UIDevice Class Reference:

systemName El nombre del sistema operativo que se ejecuta en el dispositivo representado por el receptor. (Sólo lectura)
@property (nonatomic, readonly, retain) NSString *system


Pero, puesto que sólo devuelve systemName @ "iPhone OS", para obtener el número de modelo del dispositivo real, usted tiene que utilizar el código c. Aquí hay otra forma de hacerlo:

#include <sys/types.h> 
#include <sys/sysctl.h> 

- (NSString *)machine { 
    size_t size; 

    // Set 'oldp' parameter to NULL to get the size of the data 
    // returned so we can allocate appropriate amount of space 
    sysctlbyname("hw.machine", NULL, &size, NULL, 0); 

    // Allocate the space to store name 
    char *name = malloc(size); 

    // Get the platform name 
    sysctlbyname("hw.machine", name, &size, NULL, 0); 

    // Place name into a string 
    NSString *machine = [NSString stringWithCString:name]; 

    // Done with this 
    free(name); 

    return machine; 
} 
+0

Sí, este es el objetivo-C, pero eso no permite diferenciar los dispositivos ... – Oliver

+0

Pensé que estabas preguntando cómo convertir el código c para el método 'platformCode' en objetivo-c? ¿Había algo más por lo que preguntabas? – chown

+0

No, eso era exactamente lo que estaba pidiendo, pero su código no devuelve los mismos valores que la llamada C, es realmente menos pobre. De hecho, hasta donde he visto, no devuelve nada que pueda usarse para lograr el mismo objetivo que la llamada C. – Oliver

1

Deberá usar la llamada de bajo nivel C para obtener el infoString. Para mis propósitos, he escrito una pequeña biblioteca de Objective-C que abstrae esto y presenta una interfaz Objective-C.

NSLog(@"Big model number: %d", deviceDetails.bigModel); 
//Big model number: 4 

NSLog(@"Small model number: %d", deviceDetails.smallModel); 
//Small model number: 1 

if (deviceDetails.model == GBDeviceModeliPhone4S) { 
    NSLog(@"It's a 4S"); 
} 
//It's a 4S 

if (deviceDetails.family != GBDeviceFamilyiPad) { 
    NSLog(@"It's not an iPad"); 
} 
//It's not an iPad 

NSLog(@"systemInfo string: %@", [GBDeviceInfo rawSystemInfoString]); 
//systemInfo string: iPhone4,1 

Se puede conseguir en github si te gusta: GBDeviceInfo

Cuestiones relacionadas