使用iOS SDK和完整的Cocoa Touch / Objective-C代码确定用户的设备

时间:2011-11-06 02:28:21

标签: iphone ios ipad sdk ipod

我根据不同的来源编写了以下UIDevice类别。我已经升级了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(&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

2 个答案:

答案 0 :(得分:2)

这可能被视为“客观-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];
}

这是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[]硬件类型的名称   系统正在运行

UIDevice Class Reference

  

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, &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;
}

答案 1 :(得分:1)

您必须使用低级别C调用来获取infoString。为了我的目的,我写了一个很小的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