#iphone #ios #ipad #sdk #ipod
#iPhone #iOS #iPad #sdk #ipod
Вопрос:
Я написал следующую категорию пользовательских устройств на основе разных источников. Я обновил platformCode
метод, чтобы он был менее низкоуровневым, чем можно увидеть.
Это работает отлично, но platformCode
метод низкого уровня. Вы знаете, можно ли заменить этот вид вызова кодом Cocoa Touch? Вот соответствующий код:
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(amp;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
Комментарии:
1. Это совершенно допустимый Objective-C (как и весь код C), он также не слишком низкоуровневый (я рекомендую использовать перечисления, а не строки для конечных наборов с несколькими вариантами выбора).
Ответ №1:
Это можно считать способом «objective-c»:
// 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];
}
Это будет версия obj-c utsname
machine
(из этой строки: NSString* platform = [NSString stringWithCString:systemInfo.machine encoding:NSUTF8StringEncoding];
).
utsname
:
<sys/utsname.h>
Заголовок определяет структуру utsname, которая включает в себя, по крайней мере, следующие элементы:
char sysname[]
название этой реализации операционной системы
char nodename[]
имя этого узла в сети связи, зависящей от реализации
char release[]
текущий уровень выпуска этой реализации
char version[]
текущий уровень версии этого выпуска
char machine[]
название типа оборудования, на котором запущена система
systemName
Название операционной системы, запущенной на устройстве, представленном получателем. (только для чтения)
@property (nonatomic, readonly, retain) NSString *system
Но, поскольку systemName возвращает только @»iPhone OS», чтобы получить фактический номер модели устройства, вы должны использовать c-код. Вот еще один способ сделать это:
#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, amp;size, NULL, 0);
// Allocate the space to store name
char *name = malloc(size);
// Get the platform name
sysctlbyname("hw.machine", name, amp;size, NULL, 0);
// Place name into a string
NSString *machine = [NSString stringWithCString:name];
// Done with this
free(name);
return machine;
}
Комментарии:
1. Да, это objective-C, но это не позволяет различать устройства…
2. Я думал, вы спрашивали, как преобразовать код c для
platformCode
метода в objective-c? Было ли что-то еще, о чем вы спрашивали?3. Нет, это было именно то, о чем я просил, но ваш код не возвращает те же значения, что и вызов C, он действительно менее плохой. На самом деле, насколько я видел, он не возвращает ничего, что можно было бы использовать для достижения той же цели, что и вызов C.
4. Ах, я думаю, я понимаю, о чем вы спрашиваете. Но ответ на это заключается в том, что вы должны использовать c. Нет способа ObjC получить номер модели.
5. Обновлена ссылка для ссылки на класс UIDevice: developer.apple.com/library/ios/documentation/UIKit/Reference /…
Ответ №2:
Вам придется использовать вызов C низкого уровня, чтобы получить информацию. Для своих целей я написал крошечную библиотеку Objective-C, которая абстрагирует это и представляет интерфейс 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
Вы можете получить его на github, если хотите: GBDeviceInfo