2014-10-31 15 views
5

Ho il seguente codice snip per rilevare il dispositivo iOS.Controllare il tipo di simulatore iOS e la versione

NSString * platformNSString() { 
    size_t size; 
    sysctlbyname("hw.machine", NULL, &size, NULL, 0); 
    char *machine = malloc(size); 
    sysctlbyname("hw.machine", machine, &size, NULL, 0); 
    NSString *platform = [NSString stringWithUTF8String:machine]; 
    free(machine); 
    return platform; 
} 

NSString * platformString() { 
    NSString *platform = platformNSString(); 

    // iphones 
    if ([platform isEqualToString:@"iPhone1,1"]) return @"iPhone 2G"; 
    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 @"iPhone 4"; 
    if ([platform isEqualToString:@"iPhone3,3"]) return @"iPhone 4 (CDMA)"; 
    if ([platform isEqualToString:@"iPhone4,1"]) return @"iPhone 4S"; 
    if ([platform isEqualToString:@"iPhone5,1"]) return @"iPhone 5"; 
    if ([platform isEqualToString:@"iPhone5,2"]) return @"iPhone 5 (GSM+CDMA)"; 
    if ([platform isEqualToString:@"iPhone5,3"]) return @"iPhone 5c (GSM+CDMA)"; 
    if ([platform isEqualToString:@"iPhone5,4"]) return @"iPhone 5c (UK+Europe+Asis+China)"; 
    if ([platform isEqualToString:@"iPhone6,1"]) return @"iPhone 5s (GSM+CDMA)"; 
    if ([platform isEqualToString:@"iPhone6,2"]) return @"iPhone 5s (UK+Europe+Asis+China)"; 
    if ([platform isEqualToString:@"iPhone7,1"]) return @"iPhone 6"; 
    if ([platform isEqualToString:@"iPhone7,2"]) return @"iPhone 6 Plus"; 

    // ipods 
    if ([platform isEqualToString:@"iPod1,1"]) return @"iPod Touch (1 Gen)"; 
    if ([platform isEqualToString:@"iPod2,1"]) return @"iPod Touch (2 Gen)"; 
    if ([platform isEqualToString:@"iPod3,1"]) return @"iPod Touch (3 Gen)"; 
    if ([platform isEqualToString:@"iPod4,1"]) return @"iPod Touch (4 Gen)"; 
    if ([platform isEqualToString:@"iPod5,1"]) return @"iPod Touch (5 Gen)"; 

    // ipads 
    if ([platform isEqualToString:@"iPad1,1"]) return @"iPad"; 
    if ([platform isEqualToString:@"iPad1,2"]) return @"iPad 3G"; 
    if ([platform isEqualToString:@"iPad2,1"]) return @"iPad 2 (WiFi)"; 
    if ([platform isEqualToString:@"iPad2,2"]) return @"iPad 2"; 
    if ([platform isEqualToString:@"iPad2,3"]) return @"iPad 2 (CDMA)"; 
    if ([platform isEqualToString:@"iPad2,4"]) return @"iPad 2"; 
    if ([platform isEqualToString:@"iPad2,5"]) return @"iPad Mini (WiFi)"; 
    if ([platform isEqualToString:@"iPad2,6"]) return @"iPad Mini"; 
    if ([platform isEqualToString:@"iPad2,7"]) return @"iPad Mini (GSM+CDMA)"; 
    if ([platform isEqualToString:@"iPad3,1"]) return @"iPad 3 (WiFi)"; 
    if ([platform isEqualToString:@"iPad3,2"]) return @"iPad 3 (GSM+CDMA)"; 
    if ([platform isEqualToString:@"iPad3,3"]) return @"iPad 3"; 
    if ([platform isEqualToString:@"iPad3,4"]) return @"iPad 4 (WiFi)"; 
    if ([platform isEqualToString:@"iPad3,5"]) return @"iPad 4"; 
    if ([platform isEqualToString:@"iPad3,6"]) return @"iPad 4 (GSM+CDMA)"; 
    if ([platform isEqualToString:@"iPad4,1"]) return @"iPad Air (WiFi)"; 
    if ([platform isEqualToString:@"iPad4,2"]) return @"iPad Air (GSM+CDMA)"; 
    if ([platform isEqualToString:@"iPad4,4"]) return @"iPad Mini Retina (WiFi)"; 
    if ([platform isEqualToString:@"iPad4,5"]) return @"iPad Mini Retina (GSM+CDMA)"; 
    if ([platform isEqualToString:@"iPad4,5"]) return @"iPad Mini Retina (GSM+CDMA)"; 
    // iPad5,3 

    // simulators 
    if ([platform isEqualToString:@"i386"] || [platform isEqualToString:@"x86_64"] || [platform isEqualToString:@"ppc"] || [platform isEqualToString:@"ppc64"]) { 

    } 

    else return @"Unknown"; 
    return platform; 
} 

Quello che mi aspetto è anche avere un elenco di simulatori iOS?

Vedere l'immagine seguente.

LIST OF IOS SIMULATORS

In breve, voglio anche per rilevare che tipo di simulatore di quale versione di iOS è in uso run-time come si rileva il dispositivo.

Ecco il blocco di codice di cui indica i miei sforzi sullo stesso.

// simulators 
if ([platform isEqualToString:@"i386"] || [platform isEqualToString:@"x86_64"] || [platform isEqualToString:@"ppc"] || [platform isEqualToString:@"ppc64"]) { 
    CGSize size = [[UIScreen mainScreen] bounds].size; 
    CGFloat simulatorHeight = (size.height>size.width)?size.height:size.width; 
    if(simulatorHeight>=2048) { 
     return @"Retina iPad Simulator"; 
    } else if(simulatorHeight>=1920) { 
     return @"Retina iPhone 6+ Simulator"; 
    } else if(simulatorHeight>=1334) { 
     return @"Retina iPhone 6 Simulator"; 
    } else if(simulatorHeight>=1136) { 
     return @"Retina iPhone 5/5S/5C Simulator"; 
    } else if(simulatorHeight>=960) { 
     return @"Retina iPhone 4/4S Simulator"; 
    } else if(simulatorHeight>=480) { 
     return @"Retina iPhone 4/4S Simulator"; 
    } 
} 
+0

In qualità di sviluppatore, non è necessario effettuare alcuna determinazione in base a tali informazioni. Per favore, spiega perché hai bisogno di queste informazioni e ti aiuterò a trovare un'alternativa migliore. –

+1

Bene. Non posso avere tutti i dispositivi contemporaneamente come iPhone6, iPhone6 ​​+, iPad Air2, iPadAir, iPadMini3 ecc. A volte abbiamo integrato un codice specifico del dispositivo. Ma risulta difficile controllare quei codici specifici sui simulatori. –

+0

Il mio punto è che non dovresti aver bisogno di conoscere questi identificatori. Non dovresti prendere decisioni nella tua applicazione sulla base di questi identificatori. Dovresti prendere decisioni basate su criteri OTHER, non sull'identificatore hardware. –

risposta

6

Come indicato nel mio commento sopra, non si dovrebbe davvero bisogno di queste informazioni.

Ma nell'interesse di fornire almeno una risposta, con Xcode 6, è possibile utilizzare getenv("SIMULATOR_MODEL_IDENTIFIER") anziché sysctlbyname("hw.machine", ...). Non c'è alcuna garanzia che questo funzionerà nelle versioni future.

+0

Queste informazioni sono utili quando si impostano NSLayoutConstraints personalizzati in base al dispositivo. Potresti includere uno snippet di codice per ottenere l'NSString completo del tipo di Simulator da eseguire? – TheJeff

+0

Xcode 8 Analysis segnalerà una perdita di memoria su "machine" se si sostituisce la linea "getenv" per la seconda linea "sysctlbyname", anche con la riga "free (machine)". Ciò può essere risolto mantenendo la seconda linea "sysctlbyname" e mettendo immediatamente la linea "getenv". Ma, stranamente, devi sbarazzarti della linea "libera (macchina)". Nessuna perdita di memoria segnalata, nessun problema di deallocazione delle variabili. – GlennRay

+0

Giusto per essere chiari, ricevo un errore di compilazione se lascio la riga "libera (macchina)" dicendo che la variabile non può essere liberata perché non è mai stata assegnata. Faccio, tuttavia, impostare i valori delle variabili che uso (compresa la "macchina") su zero alla fine del modulo. – GlennRay

Problemi correlati