I was wondering if it's possible to determine what kind of iPhone (for example) the currentdevice is? I know it's possible to get the model through NSString *deviceType = [[UIDevice currentDevice] model]; which will just return whether I have an "iPhone" or an "iPod", BUT I was wondering if it's possible to detect/know if I have an iPhone 3GS vs. and iPhone 4 vs. an iPhone 4S (in actuality, all I really want to do is determine if I have a 3G or not, because I'm doing fairly graphics intensive stuff).

所以,请告诉我,谢谢!


当前回答

[[UIDevice currentDevice] model]只返回iPhone或iPod,你不会得到能让你区分不同代设备的型号的数字。

编写这个方法:

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

+ (NSString *)getModel {
    size_t size;
    sysctlbyname("hw.machine", NULL, &size, NULL, 0);
    char *model = malloc(size);
    sysctlbyname("hw.machine", model, &size, NULL, 0);
    NSString *deviceModel = [NSString stringWithCString:model encoding:NSUTF8StringEncoding];
    free(model);
    return deviceModel;
}

当你需要模型的时候调用方法[self getModel],你会得到例如:"iPhone5,1"对于超薄而快速的iPhone5。

一个好的做法是创建一个名为Utils.h/Utils的类。m并在那里放置像getModel这样的方法,这样你就可以从应用程序的任何地方获得这些信息,只需导入类并调用[Utils getModel];

其他回答

虽然这个问题在2012年就被提出了,但苹果仍然没有给出将设备模式标识符转换为设备名称的方法。 有很多答案依赖于硬编码这些名称,不幸的是,当苹果发布新设备时,这些名称很快就过时了。

我们需要的是一种方法来获得一个不断更新的列表,它就在这里:https://github.com/ptrkstr/Devices

每次添加新设备时,这个Swift包都会更新,你所需要做的就是更新你的依赖项来获得它们。

我优化了NicolasMiari的实现,并添加了模拟器,在这里:

+ (NSString*)deviceName {

  static NSDictionary* deviceNamesByCode = nil;
  static NSString* deviceName = nil;

  if (deviceName) {
    return deviceName;
  }

  deviceNamesByCode = @{
    @"i386"      :@"Simulator",
    @"iPod1,1"   :@"iPod Touch",      // (Original)
    @"iPod2,1"   :@"iPod Touch",      // (Second Generation)
    @"iPod3,1"   :@"iPod Touch",      // (Third Generation)
    @"iPod4,1"   :@"iPod Touch",      // (Fourth Generation)
    @"iPhone1,1" :@"iPhone",          // (Original)
    @"iPhone1,2" :@"iPhone",          // (3G)
    @"iPhone2,1" :@"iPhone",          // (3GS)
    @"iPad1,1"   :@"iPad",            // (Original)
    @"iPad2,1"   :@"iPad 2",          //
    @"iPad3,1"   :@"iPad",            // (3rd Generation)
    @"iPhone3,1" :@"iPhone 4",        //
    @"iPhone4,1" :@"iPhone 4S",       //
    @"iPhone5,1" :@"iPhone 5",        // (model A1428, AT&T/Canada)
    @"iPhone5,2" :@"iPhone 5",        // (model A1429, everything else)
    @"iPad3,4"   :@"iPad",            // (4th Generation)
    @"iPad2,5"   :@"iPad Mini",       // (Original)
    @"iPhone5,3" :@"iPhone 5c",       // (model A1456, A1532 | GSM)
    @"iPhone5,4" :@"iPhone 5c",       // (model A1507, A1516, A1526 (China), A1529 | Global)
    @"iPhone6,1" :@"iPhone 5s",       // (model A1433, A1533 | GSM)
    @"iPhone6,2" :@"iPhone 5s",       // (model A1457, A1518, A1528 (China), A1530 | Global)
    @"iPad4,1"   :@"iPad Air",        // 5th Generation iPad (iPad Air) - Wifi
    @"iPad4,2"   :@"iPad Air",        // 5th Generation iPad (iPad Air) - Cellular
    @"iPad4,4"   :@"iPad Mini",       // (2nd Generation iPad Mini - Wifi)
    @"iPad4,5"   :@"iPad Mini"        // (2nd Generation iPad Mini - Cellular)
  };

  struct utsname systemInfo;
  uname(&systemInfo);
  NSString* code = [NSString stringWithCString:systemInfo.machine encoding:NSUTF8StringEncoding];

  deviceName = [deviceNamesByCode objectForKey:code];

  if (!deviceName) {
    // Not found in database. At least guess main device type from string contents:

    if ([code rangeOfString:@"iPod"].location != NSNotFound) {
      deviceName = @"iPod Touch";
    } else if([code rangeOfString:@"iPad"].location != NSNotFound) {
      deviceName = @"iPad";
    } else if([code rangeOfString:@"iPhone"].location != NSNotFound){
      deviceName = @"iPhone";
    } else {
      deviceName = @"Simulator";
    }
  }

  return deviceName;
}

```

下面是它的代码(代码可能不包含所有设备的字符串,我和其他人在GitHub上维护相同的代码,所以请从那里获取最新的代码)

Objective-C: GitHub/DeviceUtil

吉hub /恶魔大师


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

- (NSString*)hardwareDescription {
    NSString *hardware = [self hardwareString];
    if ([hardware isEqualToString:@"iPhone1,1"]) return @"iPhone 2G";
    if ([hardware isEqualToString:@"iPhone1,2"]) return @"iPhone 3G";
    if ([hardware isEqualToString:@"iPhone3,1"]) return @"iPhone 4";
    if ([hardware isEqualToString:@"iPhone4,1"]) return @"iPhone 4S";
    if ([hardware isEqualToString:@"iPhone5,1"]) return @"iPhone 5";
    if ([hardware isEqualToString:@"iPod1,1"]) return @"iPodTouch 1G";
    if ([hardware isEqualToString:@"iPod2,1"]) return @"iPodTouch 2G";
    if ([hardware isEqualToString:@"iPad1,1"]) return @"iPad";
    if ([hardware isEqualToString:@"iPad2,6"]) return @"iPad Mini";
    if ([hardware isEqualToString:@"iPad4,1"]) return @"iPad Air WIFI";
    //there are lots of other strings too, checkout the github repo
    //link is given at the top of this answer

    if ([hardware isEqualToString:@"i386"]) return @"Simulator";
    if ([hardware isEqualToString:@"x86_64"]) return @"Simulator";

    return nil;
}

- (NSString*)hardwareString {
    size_t size = 100;
    char *hw_machine = malloc(size);
    int name[] = {CTL_HW,HW_MACHINE};
    sysctl(name, 2, hw_machine, &size, NULL, 0);
    NSString *hardware = [NSString stringWithUTF8String:hw_machine];
    free(hw_machine);
    return hardware;
}

芬兰湾的科特林本机:

memScoped {
            val q = alloc<utsname>()
            uname(q.ptr)
            val identifier = NSString.stringWithCString(q.machine, encoding = NSUTF8StringEncoding)
        }

对于那些不想使用Swift的Mirror的人,这里有一个使用普通类型的解决方案(也支持模拟器):

#if targetEnvironment(simulator)
@objc public protocol UIDevicePrivate {
    @objc func _deviceInfoForKey(_:String) -> Any?
}
#endif

extension UIDevice {
    var hardwareModel: String {
#if targetEnvironment(simulator)
        let privateSelf = unsafeBitCast(self, to:UIDevicePrivate.self)
        if let model = privateSelf._deviceInfoForKey("HWModelStr") as? String {
            return model + " (Simulator)"
        }
#endif
        var systemInfo = utsname()
        uname(&systemInfo)
        return String(characters: systemInfo.machine)
    }
}

typealias StaticArray256<Element> = (Element, Element, Element,Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element, Element)

// This function is necessary because Swift really doesn't like creating a 256 element long static array

func enumerate<T>(tuple: StaticArray256<T>, body: (Int, T) -> Void) {
    body(0, tuple.0)
    body(1, tuple.1)
    body(2, tuple.2)
    body(3, tuple.3)
    body(4, tuple.4)
    body(5, tuple.5)
    body(6, tuple.6)
    body(7, tuple.7)
    body(8, tuple.8)
    body(9, tuple.9)
    body(10, tuple.10)
    body(11, tuple.11)
    body(12, tuple.12)
    body(13, tuple.13)
    body(14, tuple.14)
    body(15, tuple.15)
    body(16, tuple.16)
    body(17, tuple.17)
    body(18, tuple.18)
    body(19, tuple.19)
    body(20, tuple.20)
    body(21, tuple.21)
    body(22, tuple.22)
    body(23, tuple.23)
    body(24, tuple.24)
    body(25, tuple.25)
    body(26, tuple.26)
    body(27, tuple.27)
    body(28, tuple.28)
    body(29, tuple.29)
    body(30, tuple.30)
    body(31, tuple.31)
    body(32, tuple.32)
    body(33, tuple.33)
    body(34, tuple.34)
    body(35, tuple.35)
    body(36, tuple.36)
    body(37, tuple.37)
    body(38, tuple.38)
    body(39, tuple.39)
    body(40, tuple.40)
    body(41, tuple.41)
    body(42, tuple.42)
    body(43, tuple.43)
    body(44, tuple.44)
    body(45, tuple.45)
    body(46, tuple.46)
    body(47, tuple.47)
    body(48, tuple.48)
    body(49, tuple.49)
    body(50, tuple.50)
    body(51, tuple.51)
    body(52, tuple.52)
    body(53, tuple.53)
    body(54, tuple.54)
    body(55, tuple.55)
    body(56, tuple.56)
    body(57, tuple.57)
    body(58, tuple.58)
    body(59, tuple.59)
    body(60, tuple.60)
    body(61, tuple.61)
    body(62, tuple.62)
    body(63, tuple.63)
    body(64, tuple.64)
    body(65, tuple.65)
    body(66, tuple.66)
    body(67, tuple.67)
    body(68, tuple.68)
    body(69, tuple.69)
    body(70, tuple.70)
    body(71, tuple.71)
    body(72, tuple.72)
    body(73, tuple.73)
    body(74, tuple.74)
    body(75, tuple.75)
    body(76, tuple.76)
    body(77, tuple.77)
    body(78, tuple.78)
    body(79, tuple.79)
    body(80, tuple.80)
    body(81, tuple.81)
    body(82, tuple.82)
    body(83, tuple.83)
    body(84, tuple.84)
    body(85, tuple.85)
    body(86, tuple.86)
    body(87, tuple.87)
    body(88, tuple.88)
    body(89, tuple.89)
    body(90, tuple.90)
    body(91, tuple.91)
    body(92, tuple.92)
    body(93, tuple.93)
    body(94, tuple.94)
    body(95, tuple.95)
    body(96, tuple.96)
    body(97, tuple.97)
    body(98, tuple.98)
    body(99, tuple.99)
    body(100, tuple.100)
    body(101, tuple.101)
    body(102, tuple.102)
    body(103, tuple.103)
    body(104, tuple.104)
    body(105, tuple.105)
    body(106, tuple.106)
    body(107, tuple.107)
    body(108, tuple.108)
    body(109, tuple.109)
    body(110, tuple.110)
    body(111, tuple.111)
    body(112, tuple.112)
    body(113, tuple.113)
    body(114, tuple.114)
    body(115, tuple.115)
    body(116, tuple.116)
    body(117, tuple.117)
    body(118, tuple.118)
    body(119, tuple.119)
    body(120, tuple.120)
    body(121, tuple.121)
    body(122, tuple.122)
    body(123, tuple.123)
    body(124, tuple.124)
    body(125, tuple.125)
    body(126, tuple.126)
    body(127, tuple.127)
    body(128, tuple.128)
    body(129, tuple.129)
    body(130, tuple.130)
    body(131, tuple.131)
    body(132, tuple.132)
    body(133, tuple.133)
    body(134, tuple.134)
    body(135, tuple.135)
    body(136, tuple.136)
    body(137, tuple.137)
    body(138, tuple.138)
    body(139, tuple.139)
    body(140, tuple.140)
    body(141, tuple.141)
    body(142, tuple.142)
    body(143, tuple.143)
    body(144, tuple.144)
    body(145, tuple.145)
    body(146, tuple.146)
    body(147, tuple.147)
    body(148, tuple.148)
    body(149, tuple.149)
    body(150, tuple.150)
    body(151, tuple.151)
    body(152, tuple.152)
    body(153, tuple.153)
    body(154, tuple.154)
    body(155, tuple.155)
    body(156, tuple.156)
    body(157, tuple.157)
    body(158, tuple.158)
    body(159, tuple.159)
    body(160, tuple.160)
    body(161, tuple.161)
    body(162, tuple.162)
    body(163, tuple.163)
    body(164, tuple.164)
    body(165, tuple.165)
    body(166, tuple.166)
    body(167, tuple.167)
    body(168, tuple.168)
    body(169, tuple.169)
    body(170, tuple.170)
    body(171, tuple.171)
    body(172, tuple.172)
    body(173, tuple.173)
    body(174, tuple.174)
    body(175, tuple.175)
    body(176, tuple.176)
    body(177, tuple.177)
    body(178, tuple.178)
    body(179, tuple.179)
    body(180, tuple.180)
    body(181, tuple.181)
    body(182, tuple.182)
    body(183, tuple.183)
    body(184, tuple.184)
    body(185, tuple.185)
    body(186, tuple.186)
    body(187, tuple.187)
    body(188, tuple.188)
    body(189, tuple.189)
    body(190, tuple.190)
    body(191, tuple.191)
    body(192, tuple.192)
    body(193, tuple.193)
    body(194, tuple.194)
    body(195, tuple.195)
    body(196, tuple.196)
    body(197, tuple.197)
    body(198, tuple.198)
    body(199, tuple.199)
    body(200, tuple.200)
    body(201, tuple.201)
    body(202, tuple.202)
    body(203, tuple.203)
    body(204, tuple.204)
    body(205, tuple.205)
    body(206, tuple.206)
    body(207, tuple.207)
    body(208, tuple.208)
    body(209, tuple.209)
    body(210, tuple.210)
    body(211, tuple.211)
    body(212, tuple.212)
    body(213, tuple.213)
    body(214, tuple.214)
    body(215, tuple.215)
    body(216, tuple.216)
    body(217, tuple.217)
    body(218, tuple.218)
    body(219, tuple.219)
    body(220, tuple.220)
    body(221, tuple.221)
    body(222, tuple.222)
    body(223, tuple.223)
    body(224, tuple.224)
    body(225, tuple.225)
    body(226, tuple.226)
    body(227, tuple.227)
    body(228, tuple.228)
    body(229, tuple.229)
    body(230, tuple.230)
    body(231, tuple.231)
    body(232, tuple.232)
    body(233, tuple.233)
    body(234, tuple.234)
    body(235, tuple.235)
    body(236, tuple.236)
    body(237, tuple.237)
    body(238, tuple.238)
    body(239, tuple.239)
    body(240, tuple.240)
    body(241, tuple.241)
    body(242, tuple.242)
    body(243, tuple.243)
    body(244, tuple.244)
    body(245, tuple.245)
    body(246, tuple.246)
    body(247, tuple.247)
    body(248, tuple.248)
    body(249, tuple.249)
    body(250, tuple.250)
    body(251, tuple.251)
    body(252, tuple.252)
    body(253, tuple.253)
    body(254, tuple.254)
    body(255, tuple.255)
}

extension Array {
    init(staticArray: StaticArray256<Element>) {
        var array = [Element]()
        enumerate(tuple: staticArray) { array.append($1) }
        self = array
    }
}

extension String {
    init(characters: StaticArray256<CChar>) {
        self.init(String.UnicodeScalarView(Array(staticArray: characters).compactMap(Int.init).filter({ $0 > 0 }).compactMap(UnicodeScalar.init)))
    }
}