Reputation: 3462
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).
So yeah, let me know, thank you!
Upvotes: 274
Views: 290579
Reputation: 2382
Although this question was asked in 2012, Apple still doesn't give a way to convert a device modal identifier to the device name. There have been a lot of answers which rely on hardcoding these names which unfortunately quickly goes out of date when Apple release new devices.
What we need is a way to get a constantly updated list and that exists here: https://github.com/ptrkstr/Devices
Every time new devices get added, this Swift package will update and all you need to do is update your dependency to get them.
Upvotes: 3
Reputation: 1542
For anyone not wanting to use Swift's Mirror
, here's a solution using normal types (with support for simulators too):
#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)))
}
}
Upvotes: 0
Reputation: 1504
Add a new file with following code and simply call UIDevice.modelName
This consists of all models released till date including iPhone 13 series and in Swift 5.0
import UIKit
import SystemConfiguration
public extension UIDevice {
static let modelName: String = {
var systemInfo = utsname()
uname(&systemInfo)
let machineMirror = Mirror(reflecting: systemInfo.machine)
let identifier = machineMirror.children.reduce("") { identifier, element in
guard let value = element.value as? Int8, value != 0 else { return identifier }
return identifier + String(UnicodeScalar(UInt8(value)))
}
let deviceMapping = ["i386": "iPhone Simulator",
"x86_64": "iPhone Simulator",
"arm64": "iPhone Simulator",
"iPhone1,1": "iPhone",
"iPhone1,2": "iPhone 3G",
"iPhone2,1": "iPhone 3GS",
"iPhone3,1": "iPhone 4",
"iPhone3,2": "iPhone 4 GSM Rev A",
"iPhone3,3": "iPhone 4 CDMA",
"iPhone4,1": "iPhone 4S",
"iPhone5,1": "iPhone 5 (GSM)",
"iPhone5,2": "iPhone 5 (GSM+CDMA)",
"iPhone5,3": "iPhone 5C (GSM)",
"iPhone5,4": "iPhone 5C (Global)",
"iPhone6,1": "iPhone 5S (GSM)",
"iPhone6,2": "iPhone 5S (Global)",
"iPhone7,1": "iPhone 6 Plus",
"iPhone7,2": "iPhone 6",
"iPhone8,1": "iPhone 6s",
"iPhone8,2": "iPhone 6s Plus",
"iPhone8,4": "iPhone SE (GSM)",
"iPhone9,1": "iPhone 7",
"iPhone9,2": "iPhone 7 Plus",
"iPhone9,3": "iPhone 7",
"iPhone9,4": "iPhone 7 Plus",
"iPhone10,1": "iPhone 8",
"iPhone10,2": "iPhone 8 Plus",
"iPhone10,3": "iPhone X Global",
"iPhone10,4": "iPhone 8",
"iPhone10,5": "iPhone 8 Plus",
"iPhone10,6": "iPhone X GSM",
"iPhone11,2": "iPhone XS",
"iPhone11,4": "iPhone XS Max",
"iPhone11,6": "iPhone XS Max Global",
"iPhone11,8": "iPhone XR",
"iPhone12,1": "iPhone 11",
"iPhone12,3": "iPhone 11 Pro",
"iPhone12,5": "iPhone 11 Pro Max",
"iPhone12,8": "iPhone SE 2nd Gen",
"iPhone13,1": "iPhone 12 Mini",
"iPhone13,2": "iPhone 12",
"iPhone13,3": "iPhone 12 Pro",
"iPhone13,4": "iPhone 12 Pro Max",
"iPhone14,2": "iPhone 13 Pro",
"iPhone14,3": "iPhone 13 Pro Max",
"iPhone14,4": "iPhone 13 Mini",
"iPhone14,5": "iPhone 13",
"iPod1,1": "1st Gen iPod",
"iPod2,1": "2nd Gen iPod",
"iPod3,1": "3rd Gen iPod",
"iPod4,1": "4th Gen iPod",
"iPod5,1": "5th Gen iPod",
"iPod7,1": "6th Gen iPod",
"iPod9,1": "7th Gen iPod",
"iPad1,1": "iPad",
"iPad1,2": "iPad 3G",
"iPad2,1": "2nd Gen iPad",
"iPad2,2": "2nd Gen iPad GSM",
"iPad2,3": "2nd Gen iPad CDMA",
"iPad2,4": "2nd Gen iPad New Revision",
"iPad3,1": "3rd Gen iPad",
"iPad3,2": "3rd Gen iPad CDMA",
"iPad3,3": "3rd Gen iPad GSM",
"iPad2,5": "iPad mini",
"iPad2,6": "iPad mini GSM+LTE",
"iPad2,7": "iPad mini CDMA+LTE",
"iPad3,4": "4th Gen iPad",
"iPad3,5": "4th Gen iPad GSM+LTE",
"iPad3,6": "4th Gen iPad CDMA+LTE",
"iPad4,1": "iPad Air (WiFi)",
"iPad4,2": "iPad Air (GSM+CDMA)",
"iPad4,3": "1st Gen iPad Air (China)",
"iPad4,4": "iPad mini Retina (WiFi)",
"iPad4,5": "iPad mini Retina (GSM+CDMA)",
"iPad4,6": "iPad mini Retina (China)",
"iPad4,7": "iPad mini 3 (WiFi)",
"iPad4,8": "iPad mini 3 (GSM+CDMA)",
"iPad4,9": "iPad Mini 3 (China)",
"iPad5,1": "iPad mini 4 (WiFi)",
"iPad5,2": "4th Gen iPad mini (WiFi+Cellular)",
"iPad5,3": "iPad Air 2 (WiFi)",
"iPad5,4": "iPad Air 2 (Cellular)",
"iPad6,3": "iPad Pro (9.7 inch, WiFi)",
"iPad6,4": "iPad Pro (9.7 inch, WiFi+LTE)",
"iPad6,7": "iPad Pro (12.9 inch, WiFi)",
"iPad6,8": "iPad Pro (12.9 inch, WiFi+LTE)",
"iPad6,11": "iPad (2017)",
"iPad6,12": "iPad (2017)",
"iPad7,1": "iPad Pro 2nd Gen (WiFi)",
"iPad7,2": "iPad Pro 2nd Gen (WiFi+Cellular)",
"iPad7,3": "iPad Pro 10.5-inch",
"iPad7,4": "iPad Pro 10.5-inch",
"iPad7,5": "iPad 6th Gen (WiFi)",
"iPad7,6": "iPad 6th Gen (WiFi+Cellular)",
"iPad7,11": "iPad 7th Gen 10.2-inch (WiFi)",
"iPad7,12": "iPad 7th Gen 10.2-inch (WiFi+Cellular)",
"iPad8,1": "iPad Pro 11 inch 3rd Gen (WiFi)",
"iPad8,2": "iPad Pro 11 inch 3rd Gen (1TB, WiFi)",
"iPad8,3": "iPad Pro 11 inch 3rd Gen (WiFi+Cellular)",
"iPad8,4": "iPad Pro 11 inch 3rd Gen (1TB, WiFi+Cellular)",
"iPad8,5": "iPad Pro 12.9 inch 3rd Gen (WiFi)",
"iPad8,6": "iPad Pro 12.9 inch 3rd Gen (1TB, WiFi)",
"iPad8,7": "iPad Pro 12.9 inch 3rd Gen (WiFi+Cellular)",
"iPad8,8": "iPad Pro 12.9 inch 3rd Gen (1TB, WiFi+Cellular)",
"iPad8,9": "iPad Pro 11 inch 4th Gen (WiFi)",
"iPad8,10": "iPad Pro 11 inch 4th Gen (WiFi+Cellular)",
"iPad8,11": "iPad Pro 12.9 inch 4th Gen (WiFi)",
"iPad8,12": "iPad Pro 12.9 inch 4th Gen (WiFi+Cellular)",
"iPad11,1": "iPad mini 5th Gen (WiFi)",
"iPad11,2": "iPad mini 5th Gen",
"iPad11,3": "iPad Air 3rd Gen (WiFi)",
"iPad11,4": "iPad Air 3rd Gen",
"iPad11,6": "iPad 8th Gen (WiFi)",
"iPad11,7": "iPad 8th Gen (WiFi+Cellular)",
"iPad13,1": "iPad air 4th Gen (WiFi)",
"iPad13,2": "iPad air 4th Gen (WiFi+Cellular)",
"iPad13,4": "iPad Pro 11 inch 3rd Gen",
"iPad13,5": "iPad Pro 11 inch 3rd Gen",
"iPad13,6": "iPad Pro 11 inch 3rd Gen",
"iPad13,7": "iPad Pro 11 inch 3rd Gen",
"iPad13,8": "iPad Pro 12.9 inch 5th Gen",
"iPad13,9": "iPad Pro 12.9 inch 5th Gen",
"iPad13,10": "iPad Pro 12.9 inch 5th Gen",
"iPad13,11": "iPad Pro 12.9 inch 5th Gen"]
return deviceMapping[identifier] ?? identifier
}()
}
Upvotes: 12
Reputation: 791
It is possible to get the device name in Swift without using a Mirror. Swift can automatically convert things into pointers where needed. It's as simple as this:
/// Returns "iPhone1,1", etc.
var deviceName: String {
var sysinfo = utsname()
uname(&sysinfo)
return String(cString: &sysinfo.machine.0)
}
(Hat-tip to this underrated answer https://stackoverflow.com/a/43599474/843454)
Upvotes: 3
Reputation: 3668
Here’s a modern version of Aniruddh’s uname
-based approach that doesn’t rely on Mirror
and should work for Swift 4.2 and up:
import UIKit
extension UIDevice {
var machineName: String {
var info = utsname()
return withUnsafeMutablePointer(to: &info) { info in
// We could alternatively return nil here, or handle
// errors some other way.
guard uname(info) == 0 else { return model }
let offset = MemoryLayout.offset(of: \utsname.machine)!
let machine = UnsafeRawPointer(info).advanced(by: offset).assumingMemoryBound(to: CChar.self)
return String(cString: machine)
}
}
}
Upvotes: 3
Reputation: 7668
EITHER try this library: http://github.com/erica/uidevice-extension/ (by Erica Sadun). (The library is 7-8 years old, and hence is obsolete)
(Sample Code):
[[UIDevice currentDevice] platformType] // ex: UIDevice4GiPhone
[[UIDevice currentDevice] platformString] // ex: @"iPhone 4G"
OR You can use this method:
You can get the device model number using uname from sys/utsname.h. For example:
Objective-C
#import <sys/utsname.h> // import it in your header or implementation file.
NSString* deviceName()
{
struct utsname systemInfo;
uname(&systemInfo);
return [NSString stringWithCString:systemInfo.machine
encoding:NSUTF8StringEncoding];
}
Swift 3
extension UIDevice {
var modelName: String {
var systemInfo = utsname()
uname(&systemInfo)
let machineMirror = Mirror(reflecting: systemInfo.machine)
let identifier = machineMirror.children.reduce("") { identifier, element in
guard let value = element.value as? Int8, value != 0 else { return identifier }
return identifier + String(UnicodeScalar(UInt8(value)))
}
return identifier
}
}
print(UIDevice.current.modelName)
The result should be:
// Output on a simulator
@"i386" on 32-bit Simulator
@"x86_64" on 64-bit Simulator
// Output on an iPhone
@"iPhone1,1" on iPhone
@"iPhone1,2" on iPhone 3G
@"iPhone2,1" on iPhone 3GS
@"iPhone3,1" on iPhone 4 (GSM)
@"iPhone3,2" on iPhone 4 (GSM Rev A)
@"iPhone3,3" on iPhone 4 (CDMA/Verizon/Sprint)
@"iPhone4,1" on iPhone 4S
@"iPhone5,1" on iPhone 5 (model A1428, AT&T/Canada)
@"iPhone5,2" on iPhone 5 (model A1429, everything else)
@"iPhone5,3" on iPhone 5c (model A1456, A1532 | GSM)
@"iPhone5,4" on iPhone 5c (model A1507, A1516, A1526 (China), A1529 | Global)
@"iPhone6,1" on iPhone 5s (model A1433, A1533 | GSM)
@"iPhone6,2" on iPhone 5s (model A1457, A1518, A1528 (China), A1530 | Global)
@"iPhone7,1" on iPhone 6 Plus
@"iPhone7,2" on iPhone 6
@"iPhone8,1" on iPhone 6S
@"iPhone8,2" on iPhone 6S Plus
@"iPhone8,4" on iPhone SE
@"iPhone9,1" on iPhone 7 (CDMA)
@"iPhone9,3" on iPhone 7 (GSM)
@"iPhone9,2" on iPhone 7 Plus (CDMA)
@"iPhone9,4" on iPhone 7 Plus (GSM)
@"iPhone10,1" on iPhone 8 (CDMA)
@"iPhone10,4" on iPhone 8 (GSM)
@"iPhone10,2" on iPhone 8 Plus (CDMA)
@"iPhone10,5" on iPhone 8 Plus (GSM)
@"iPhone10,3" on iPhone X (CDMA)
@"iPhone10,6" on iPhone X (GSM)
@"iPhone11,2" on iPhone XS
@"iPhone11,4" on iPhone XS Max
@"iPhone11,6" on iPhone XS Max China
@"iPhone11,8" on iPhone XR
@"iPhone12,1" on iPhone 11
@"iPhone12,3" on iPhone 11 Pro
@"iPhone12,5" on iPhone 11 Pro Max
@"iPhone12,8" on iPhone SE (2nd Gen)
@"iPhone13,1" on iPhone 12 Mini
@"iPhone13,2" on iPhone 12
@"iPhone13,3" on iPhone 12 Pro
@"iPhone13,4" on iPhone 12 Pro Max
//iPad 1
@"iPad1,1" on iPad - Wifi (model A1219)
@"iPad1,2" on iPad - Wifi + Cellular (model A1337)
//iPad 2
@"iPad2,1" - Wifi (model A1395)
@"iPad2,2" - GSM (model A1396)
@"iPad2,3" - 3G (model A1397)
@"iPad2,4" - Wifi (model A1395)
// iPad Mini
@"iPad2,5" - Wifi (model A1432)
@"iPad2,6" - Wifi + Cellular (model A1454)
@"iPad2,7" - Wifi + Cellular (model A1455)
//iPad 3
@"iPad3,1" - Wifi (model A1416)
@"iPad3,2" - Wifi + Cellular (model A1403)
@"iPad3,3" - Wifi + Cellular (model A1430)
//iPad 4
@"iPad3,4" - Wifi (model A1458)
@"iPad3,5" - Wifi + Cellular (model A1459)
@"iPad3,6" - Wifi + Cellular (model A1460)
//iPad AIR
@"iPad4,1" - Wifi (model A1474)
@"iPad4,2" - Wifi + Cellular (model A1475)
@"iPad4,3" - Wifi + Cellular (model A1476)
// iPad Mini 2
@"iPad4,4" - Wifi (model A1489)
@"iPad4,5" - Wifi + Cellular (model A1490)
@"iPad4,6" - Wifi + Cellular (model A1491)
// iPad Mini 3
@"iPad4,7" - Wifi (model A1599)
@"iPad4,8" - Wifi + Cellular (model A1600)
@"iPad4,9" - Wifi + Cellular (model A1601)
// iPad Mini 4
@"iPad5,1" - Wifi (model A1538)
@"iPad5,2" - Wifi + Cellular (model A1550)
//iPad AIR 2
@"iPad5,3" - Wifi (model A1566)
@"iPad5,4" - Wifi + Cellular (model A1567)
// iPad PRO 9.7"
@"iPad6,3" - Wifi (model A1673)
@"iPad6,4" - Wifi + Cellular (model A1674)
@"iPad6,4" - Wifi + Cellular (model A1675)
//iPad PRO 12.9"
@"iPad6,7" - Wifi (model A1584)
@"iPad6,8" - Wifi + Cellular (model A1652)
//iPad (5th generation)
@"iPad6,11" - Wifi (model A1822)
@"iPad6,12" - Wifi + Cellular (model A1823)
//iPad PRO 12.9" (2nd Gen)
@"iPad7,1" - Wifi (model A1670)
@"iPad7,2" - Wifi + Cellular (model A1671)
@"iPad7,2" - Wifi + Cellular (model A1821)
//iPad PRO 10.5"
@"iPad7,3" - Wifi (model A1701)
@"iPad7,4" - Wifi + Cellular (model A1709)
// iPad (6th Gen)
@"iPad7,5" - WiFi
@"iPad7,6" - WiFi + Cellular
// iPad (7th Gen)
@"iPad7,11" - WiFi
@"iPad7,12" - WiFi + Cellular
//iPad PRO 11"
@"iPad8,1" - WiFi
@"iPad8,2" - 1TB, WiFi
@"iPad8,3" - WiFi + Cellular
@"iPad8,4" - 1TB, WiFi + Cellular
//iPad PRO 12.9" (3rd Gen)
@"iPad8,5" - WiFi
@"iPad8,6" - 1TB, WiFi
@"iPad8,7" - WiFi + Cellular
@"iPad8,8" - 1TB, WiFi + Cellular
//iPad PRO 11" (2nd Gen)
@"iPad8,9" - WiFi
@"iPad8,10" - 1TB, WiFi
//iPad PRO 12.9" (4th Gen)
@"iPad8,11" - (WiFi)
@"iPad8,12" - (WiFi+Cellular)
// iPad mini 5th Gen
@"iPad11,1" - WiFi
@"iPad11,2" - Wifi + Cellular
// iPad Air 3rd Gen
@"iPad11,3" - Wifi
@"iPad11,4" - Wifi + Cellular
// iPad (8th Gen)
@"iPad11,6" - iPad 8th Gen (WiFi)
@"iPad11,7" - iPad 8th Gen (WiFi+Cellular)
// iPad Air 4th Gen
@"iPad13,1" - iPad air 4th Gen (WiFi)
@"iPad13,2" - iPad air 4th Gen (WiFi+Cellular)
//iPod Touch
@"iPod1,1" on iPod Touch
@"iPod2,1" on iPod Touch Second Generation
@"iPod3,1" on iPod Touch Third Generation
@"iPod4,1" on iPod Touch Fourth Generation
@"iPod5,1" on iPod Touch 5th Generation
@"iPod7,1" on iPod Touch 6th Generation
@"iPod9,1" on iPod Touch 7th Generation
// Apple Watch
@"Watch1,1" on Apple Watch 38mm case
@"Watch1,2" on Apple Watch 38mm case
@"Watch2,6" on Apple Watch Series 1 38mm case
@"Watch2,7" on Apple Watch Series 1 42mm case
@"Watch2,3" on Apple Watch Series 2 38mm case
@"Watch2,4" on Apple Watch Series 2 42mm case
@"Watch3,1" on Apple Watch Series 3 38mm case (GPS+Cellular)
@"Watch3,2" on Apple Watch Series 3 42mm case (GPS+Cellular)
@"Watch3,3" on Apple Watch Series 3 38mm case (GPS)
@"Watch3,4" on Apple Watch Series 3 42mm case (GPS)
@"Watch4,1" on Apple Watch Series 4 40mm case (GPS)
@"Watch4,2" on Apple Watch Series 4 44mm case (GPS)
@"Watch4,3" on Apple Watch Series 4 40mm case (GPS+Cellular)
@"Watch4,4" on Apple Watch Series 4 44mm case (GPS+Cellular)
@"Watch5,1" on Apple Watch Series 5 40mm case (GPS)
@"Watch5,2" on Apple Watch Series 5 44mm case (GPS)
@"Watch5,3" on Apple Watch Series 5 40mm case (GPS+Cellular)
@"Watch5,4" on Apple Watch Series 5 44mm case (GPS+Cellular)
@"Watch5,9" on Apple Watch SE 40mm case (GPS)
@"Watch5,10" on Apple Watch SE 44mm case (GPS)
@"Watch5,11" on Apple Watch SE 40mm case (GPS+Cellular)
@"Watch5,12" on Apple Watch SE 44mm case (GPS+Cellular)
@"Watch6,1" on Apple Watch Series 6 40mm case (GPS)
@"Watch6,2" on Apple Watch Series 6 44mm case (GPS)
@"Watch6,3" on Apple Watch Series 6 40mm case (GPS+Cellular)
@"Watch6,4" on Apple Watch Series 6 44mm case (GPS+Cellular)
Upvotes: 596
Reputation: 9
Kotlin Native:
memScoped {
val q = alloc<utsname>()
uname(q.ptr)
val identifier = NSString.stringWithCString(q.machine, encoding = NSUTF8StringEncoding)
}
Upvotes: -5
Reputation: 2375
What about using ideviceinfo to get these values? Should be able to install it using brew install ideviceinfo
Then run:
PRODUCT_NAME=$(ideviceinfo --udid $DEVICE_UDID --key ProductName)
PRODUCT_TYPE=$(ideviceinfo --udid $DEVICE_UDID --key ProductType)
PRODUCT_VERSION=$(ideviceinfo --udid $DEVICE_UDID --key ProductVersion)
Upvotes: 0
Reputation: 16246
Expanding on OhhMee's answer above, I added some failsafe to support future devices not (yet) included on the list:
#import <sys/utsname.h>
#import "MyClass.h"
@implementation MyClass
{
//(your private ivars)
}
- (NSString*) deviceName
{
struct utsname systemInfo;
uname(&systemInfo);
NSString* code = [NSString stringWithCString:systemInfo.machine
encoding:NSUTF8StringEncoding];
static NSDictionary* deviceNamesByCode = nil;
if (!deviceNamesByCode) {
deviceNamesByCode = @{@"i386" : @"Simulator",
@"x86_64" : @"Simulator",
@"iPod1,1" : @"iPod Touch", // (Original)
@"iPod2,1" : @"iPod Touch", // (Second Generation)
@"iPod3,1" : @"iPod Touch", // (Third Generation)
@"iPod4,1" : @"iPod Touch", // (Fourth Generation)
@"iPod7,1" : @"iPod Touch", // (6th 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", // (GSM)
@"iPhone3,3" : @"iPhone 4", // (CDMA/Verizon/Sprint)
@"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)
@"iPhone7,1" : @"iPhone 6 Plus", //
@"iPhone7,2" : @"iPhone 6", //
@"iPhone8,1" : @"iPhone 6S", //
@"iPhone8,2" : @"iPhone 6S Plus", //
@"iPhone8,4" : @"iPhone SE", //
@"iPhone9,1" : @"iPhone 7", //
@"iPhone9,3" : @"iPhone 7", //
@"iPhone9,2" : @"iPhone 7 Plus", //
@"iPhone9,4" : @"iPhone 7 Plus", //
@"iPhone10,1": @"iPhone 8", // CDMA
@"iPhone10,4": @"iPhone 8", // GSM
@"iPhone10,2": @"iPhone 8 Plus", // CDMA
@"iPhone10,5": @"iPhone 8 Plus", // GSM
@"iPhone10,3": @"iPhone X", // CDMA
@"iPhone10,6": @"iPhone X", // GSM
@"iPhone11,2": @"iPhone XS", //
@"iPhone11,4": @"iPhone XS Max", //
@"iPhone11,6": @"iPhone XS Max", // China
@"iPhone11,8": @"iPhone XR", //
@"iPhone12,1": @"iPhone 11", //
@"iPhone12,3": @"iPhone 11 Pro", //
@"iPhone12,5": @"iPhone 11 Pro Max", //
@"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)
@"iPad4,7" : @"iPad Mini", // (3rd Generation iPad Mini - Wifi (model A1599))
@"iPad6,7" : @"iPad Pro (12.9\")", // iPad Pro 12.9 inches - (model A1584)
@"iPad6,8" : @"iPad Pro (12.9\")", // iPad Pro 12.9 inches - (model A1652)
@"iPad6,3" : @"iPad Pro (9.7\")", // iPad Pro 9.7 inches - (model A1673)
@"iPad6,4" : @"iPad Pro (9.7\")" // iPad Pro 9.7 inches - (models A1674 and A1675)
};
}
NSString* deviceName = [deviceNamesByCode objectForKey:code];
if (!deviceName) {
// Not found on 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 = @"Unknown";
}
}
return deviceName;
}
// (rest of class implementation omitted)
@end
I also omitted the detailed information (e.g. "model A1507, A1516, A1526 (China), A1529 | Global") and placed it in the comments instead, in case you want to use this as user-facing strings and not freak them out.
Edit: This answer provides a similar implementation using Swift 2.
Edit 2: I just added the iPad Pro models (both sizes). For future reference, the model numbers/etc. can be found in The iPhone Wiki.
Edit 3: Add support for iPhone XS, iPhone XS Max and iPhone XR.
Edit 4: Add support for iPhone 11, iPhone 11 Pro and iPhone 11 Pro Max.
Upvotes: 140
Reputation: 1280
I've made the plist file to help you to get the complete name for each device (source code right at the end of my answer)
Based on OhhMee's answer, you can use it like this:
Swift 4.0
static func deviceName() -> String {
var systemInfo = utsname()
uname(&systemInfo)
guard let iOSDeviceModelsPath = Bundle.main.path(forResource: "iOSDeviceModelMapping", ofType: "plist") else { return "" }
guard let iOSDevices = NSDictionary(contentsOfFile: iOSDeviceModelsPath) else { return "" }
let machineMirror = Mirror(reflecting: systemInfo.machine)
let identifier = machineMirror.children.reduce("") { identifier, element in
guard let value = element.value as? Int8, value != 0 else { return identifier }
return identifier + String(UnicodeScalar(UInt8(value)))
}
return iOSDevices.value(forKey: identifier) as! String
}
Don't forget to add #import <sys/utsname.h>
in your Bridging Header.
Objective C
#import <sys/utsname.h>
NSString *machineName()
{
struct utsname systemInfo;
uname(&systemInfo);
NSString *iOSDeviceModelsPath = [[NSBundle mainBundle] pathForResource:@"iOSDeviceModelMapping" ofType:@"plist"];
NSDictionary *iOSDevices = [NSDictionary dictionaryWithContentsOfFile:iOSDeviceModelsPath];
NSString* deviceModel = [NSString stringWithCString:systemInfo.machine
encoding:NSUTF8StringEncoding];
return [iOSDevices valueForKey:deviceModel];
}
The plist file :
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>x86_64</key>
<string>Simulator</string>
<key>i386</key>
<string>Simulator</string>
<key>iPod1,1</key>
<string>iPod Touch 1st Gen</string>
<key>iPod2,1</key>
<string>iPod Touch 2nd Gen</string>
<key>iPod3,1</key>
<string>iPod Touch 3rd Gen</string>
<key>iPod4,1</key>
<string>iPod Touch 4th Gen</string>
<key>iPod5,1</key>
<string>iPod Touch 5th Gen</string>
<key>iPod7,1</key>
<string>iPod Touch 6th Gen</string>
<key>iPhone1,1</key>
<string>iPhone</string>
<key>iPhone1,2</key>
<string>iPhone 3G</string>
<key>iPhone2,1</key>
<string>iPhone 3GS</string>
<key>iPhone3,1</key>
<string>iPhone 4</string>
<key>iPhone3,2</key>
<string>iPhone 4</string>
<key>iPhone3,3</key>
<string>iPhone 4</string>
<key>iPhone4,1</key>
<string>iPhone 4S</string>
<key>iPhone5,1</key>
<string>iPhone 5 model A1428</string>
<key>iPhone5,2</key>
<string>iPhone 5 model A1429</string>
<key>iPhone5,3</key>
<string>iPhone 5C</string>
<key>iPhone5,4</key>
<string>iPhone 5C</string>
<key>iPhone6,1</key>
<string>iPhone 5S</string>
<key>iPhone6,2</key>
<string>iPhone 5S</string>
<key>iPhone7,2</key>
<string>iPhone 6</string>
<key>iPhone7,1</key>
<string>iPhone 6 Plus</string>
<key>iPhone8,1</key>
<string>iPhone 6S</string>
<key>iPhone8,2</key>
<string>iPhone 6S Plus</string>
<key>iPhone8,4</key>
<string>iPhone SE</string>
<key>iPhone9,1</key>
<string>iPhone 7</string>
<key>iPhone9,2</key>
<string>iPhone 7 Plus</string>
<key>iPhone9,3</key>
<string>iPhone 7</string>
<key>iPhone9,4</key>
<string>iPhone 7 Plus</string>
<key>iPhone10,1</key>
<string>iPhone 8</string>
<key>iPhone10,4</key>
<string>iPhone 8</string>
<key>iPhone10,2</key>
<string>iPhone 8 Plus</string>
<key>iPhone10,5</key>
<string>iPhone 8 Plus</string>
<key>iPhone10,3</key>
<string>iPhone X</string>
<key>iPhone10,6</key>
<string>iPhone X</string>
<key>iPhone11,2</key>
<string>iPhone XS</string>
<key>iPhone11,4</key>
<string>iPhone XS Max</string>
<key>iPhone11,6</key>
<string>iPhone XS Max</string>
<key>iPhone11,8</key>
<string>iPhone XR</string>
<key>iPad1,1</key>
<string>iPad</string>
<key>iPad2,1</key>
<string>iPad 2</string>
<key>iPad2,2</key>
<string>iPad 2</string>
<key>iPad2,3</key>
<string>iPad 2</string>
<key>iPad2,4</key>
<string>iPad 2</string>
<key>iPad3,1</key>
<string>iPad 3rd Gen</string>
<key>iPad3,2</key>
<string>iPad 3rd Gen</string>
<key>iPad3,3</key>
<string>iPad 3rd Gen</string>
<key>iPad3,4</key>
<string>iPad 4th Gen</string>
<key>iPad3,5</key>
<string>iPad 4th Gen</string>
<key>iPad3,6</key>
<string>iPad 4th Gen</string>
<key>iPad4,1</key>
<string>iPad Air</string>
<key>iPad4,2</key>
<string>iPad Air</string>
<key>iPad4,3</key>
<string>iPad Air</string>
<key>iPad2,5</key>
<string>iPad Mini 1st Gen</string>
<key>iPad2,6</key>
<string>iPad Mini 1st Gen</string>
<key>iPad2,7</key>
<string>iPad Mini 1st Gen</string>
<key>iPad4,4</key>
<string>iPad Mini 2nd Gen</string>
<key>iPad4,5</key>
<string>iPad Mini 2nd Gen</string>
<key>iPad4,6</key>
<string>iPad Mini 2nd Gen</string>
<key>iPad4,7</key>
<string>iPad Mini 3rd Gen</string>
<key>iPad4,8</key>
<string>iPad Mini 3rd Gen</string>
<key>iPad4,9</key>
<string>iPad Mini 3rd Gen</string>
<key>iPad5,1</key>
<string>iPad Mini 4</string>
<key>iPad5,2</key>
<string>iPad Mini 4</string>
<key>iPad5,3</key>
<string>iPad Air 2</string>
<key>iPad5,4</key>
<string>iPad Air 2</string>
<key>iPad6,3</key>
<string>iPad Pro 9.7 inch</string>
<key>iPad6,4</key>
<string>iPad Pro 9.7 inch</string>
<key>iPad6,7</key>
<string>iPad Pro 12.9 inch</string>
<key>iPad6,8</key>
<string>iPad Pro 12.9 inch</string>
<key>iPad7,1</key>
<string>iPad Pro 12.9 inch 2nd Gen</string>
<key>iPad7,2</key>
<string>iPad Pro 12.9 inch 2nd Gen</string>
<key>iPad7,3</key>
<string>iPad Pro 10.5 inch</string>
<key>iPad7,4</key>
<string>iPad Pro 10.5 inch</string>
<key>iPad8,1</key>
<string>iPad Pro 11 inch</string>
<key>iPad8,2</key>
<string>iPad Pro 11 inch</string>
<key>iPad8,3</key>
<string>iPad Pro 11 inch</string>
<key>iPad8,4</key>
<string>iPad Pro 11 inch</string>
<key>iPad8,5</key>
<string>iPad Pro 12.9 inch 3rd Gen</string>
<key>iPad8,6</key>
<string>iPad Pro 12.9 inch 3rd Gen</string>
<key>iPad8,7</key>
<string>iPad Pro 12.9 inch 3rd Gen</string>
<key>iPad8,8</key>
<string>iPad Pro 12.9 inch 3rd Gen</string>
</dict>
</plist>
Upvotes: 48
Reputation: 236360
Swift 4 or later
extension UIDevice {
var modelName: String {
if let modelName = ProcessInfo.processInfo.environment["SIMULATOR_MODEL_IDENTIFIER"] { return modelName }
var info = utsname()
uname(&info)
return String(String.UnicodeScalarView(
Mirror(reflecting: info.machine)
.children
.compactMap {
guard let value = $0.value as? Int8 else { return nil }
let unicode = UnicodeScalar(UInt8(value))
return unicode.isASCII ? unicode : nil
}))
}
}
UIDevice.current.modelName // "iPad6,4"
Upvotes: 2
Reputation: 2971
This solution works for both physical devices and iOS simulator in a way that simulator returns the same model as physical device would return for a model e.g. "iPhone10,6" for iPhone X (GSM) rather than "x86_64".
Definition - Swift 4:
import UIKit
extension UIDevice {
var modelName: String {
var systemInfo = utsname()
uname(&systemInfo)
let machineMirror = Mirror(reflecting: systemInfo.machine)
let identifier = machineMirror.children.reduce("") { identifier, element in
guard let value = element.value as? Int8, value != 0 else { return identifier }
return identifier + String(UnicodeScalar(UInt8(value)))
}
if let value = ProcessInfo.processInfo.environment["SIMULATOR_MODEL_IDENTIFIER"] {
return value
} else {
return identifier
}
}
}
Usage:
print(UIDevice.current.modelName)
Upvotes: 5
Reputation: 6373
For save time of others. Because accepted, must voted answer propose library that uses private API and my app was rejected because of uidevice-extension just yesterday! I am switching to GBDeviceInfo library, installed as pod as well, for now it looks nice, maintained and updated to latest devices.
Upvotes: 1
Reputation: 3011
//
// UIDevice+Hardware.h
// gauravds
//
#import <UIKit/UIKit.h>
@interface UIDevice (Hardware)
- (NSString *)modelIdentifier;
- (NSString *)modelName;
@end
Why not create a category. Don't use malloc method security leak issue. Use safe functions.
NSLog(@"%@ %@", [[UIDevice currentDevice] modelName], [[UIDevice currentDevice] modelIdentifier]);
See the implentations
//
// UIDevice+Hardware.m
// gauravds
//
#import "UIDevice+Hardware.h"
#import <sys/utsname.h>
@implementation UIDevice (Hardware)
- (NSString *)modelIdentifier {
struct utsname systemInfo;
uname(&systemInfo);
return [NSString stringWithCString:systemInfo.machine encoding:NSUTF8StringEncoding];
}
- (NSString *)modelName {
return [self modelNameForModelIdentifier:[self modelIdentifier]];
}
- (NSString *)modelNameForModelIdentifier:(NSString *)modelIdentifier {
// iPhone http://theiphonewiki.com/wiki/IPhone
if ([modelIdentifier isEqualToString:@"iPhone1,1"]) return @"iPhone 1G";
if ([modelIdentifier isEqualToString:@"iPhone1,2"]) return @"iPhone 3G";
if ([modelIdentifier isEqualToString:@"iPhone2,1"]) return @"iPhone 3GS";
if ([modelIdentifier isEqualToString:@"iPhone3,1"]) return @"iPhone 4 (GSM)";
if ([modelIdentifier isEqualToString:@"iPhone3,2"]) return @"iPhone 4 (GSM Rev A)";
if ([modelIdentifier isEqualToString:@"iPhone3,3"]) return @"iPhone 4 (CDMA)";
if ([modelIdentifier isEqualToString:@"iPhone4,1"]) return @"iPhone 4S";
if ([modelIdentifier isEqualToString:@"iPhone5,1"]) return @"iPhone 5 (GSM)";
if ([modelIdentifier isEqualToString:@"iPhone5,2"]) return @"iPhone 5 (Global)";
if ([modelIdentifier isEqualToString:@"iPhone5,3"]) return @"iPhone 5c (GSM)";
if ([modelIdentifier isEqualToString:@"iPhone5,4"]) return @"iPhone 5c (Global)";
if ([modelIdentifier isEqualToString:@"iPhone6,1"]) return @"iPhone 5s (GSM)";
if ([modelIdentifier isEqualToString:@"iPhone6,2"]) return @"iPhone 5s (Global)";
if ([modelIdentifier isEqualToString:@"iPhone7,1"]) return @"iPhone 6 Plus";
if ([modelIdentifier isEqualToString:@"iPhone7,2"]) return @"iPhone 6";
if ([modelIdentifier isEqualToString:@"iPhone8,1"]) return @"iPhone 6s";
if ([modelIdentifier isEqualToString:@"iPhone8,2"]) return @"iPhone 6s Plus";
if ([modelIdentifier isEqualToString:@"iPhone8,4"]) return @"iPhone SE";
if ([modelIdentifier isEqualToString:@"iPhone9,1"]) return @"iPhone 7";
if ([modelIdentifier isEqualToString:@"iPhone9,2"]) return @"iPhone 7 Plus";
if ([modelIdentifier isEqualToString:@"iPhone9,3"]) return @"iPhone 7";
if ([modelIdentifier isEqualToString:@"iPhone9,4"]) return @"iPhone 7 Plus";
if ([modelIdentifier isEqualToString:@"iPhone10,1"]) return @"iPhone 8"; // US (Verizon), China, Japan
if ([modelIdentifier isEqualToString:@"iPhone10,2"]) return @"iPhone 8 Plus"; // US (Verizon), China, Japan
if ([modelIdentifier isEqualToString:@"iPhone10,3"]) return @"iPhone X"; // US (Verizon), China, Japan
if ([modelIdentifier isEqualToString:@"iPhone10,4"]) return @"iPhone 8"; // AT&T, Global
if ([modelIdentifier isEqualToString:@"iPhone10,5"]) return @"iPhone 8 Plus"; // AT&T, Global
if ([modelIdentifier isEqualToString:@"iPhone10,6"]) return @"iPhone X"; // AT&T, Global
// iPad http://theiphonewiki.com/wiki/IPad
if ([modelIdentifier isEqualToString:@"iPad1,1"]) return @"iPad 1G";
if ([modelIdentifier isEqualToString:@"iPad2,1"]) return @"iPad 2 (Wi-Fi)";
if ([modelIdentifier isEqualToString:@"iPad2,2"]) return @"iPad 2 (GSM)";
if ([modelIdentifier isEqualToString:@"iPad2,3"]) return @"iPad 2 (CDMA)";
if ([modelIdentifier isEqualToString:@"iPad2,4"]) return @"iPad 2 (Rev A)";
if ([modelIdentifier isEqualToString:@"iPad3,1"]) return @"iPad 3 (Wi-Fi)";
if ([modelIdentifier isEqualToString:@"iPad3,2"]) return @"iPad 3 (GSM)";
if ([modelIdentifier isEqualToString:@"iPad3,3"]) return @"iPad 3 (Global)";
if ([modelIdentifier isEqualToString:@"iPad3,4"]) return @"iPad 4 (Wi-Fi)";
if ([modelIdentifier isEqualToString:@"iPad3,5"]) return @"iPad 4 (GSM)";
if ([modelIdentifier isEqualToString:@"iPad3,6"]) return @"iPad 4 (Global)";
if ([modelIdentifier isEqualToString:@"iPad6,11"]) return @"iPad (5th gen) (Wi-Fi)";
if ([modelIdentifier isEqualToString:@"iPad6,12"]) return @"iPad (5th gen) (Cellular)";
if ([modelIdentifier isEqualToString:@"iPad4,1"]) return @"iPad Air (Wi-Fi)";
if ([modelIdentifier isEqualToString:@"iPad4,2"]) return @"iPad Air (Cellular)";
if ([modelIdentifier isEqualToString:@"iPad5,3"]) return @"iPad Air 2 (Wi-Fi)";
if ([modelIdentifier isEqualToString:@"iPad5,4"]) return @"iPad Air 2 (Cellular)";
// iPad Mini http://theiphonewiki.com/wiki/IPad_mini
if ([modelIdentifier isEqualToString:@"iPad2,5"]) return @"iPad mini 1G (Wi-Fi)";
if ([modelIdentifier isEqualToString:@"iPad2,6"]) return @"iPad mini 1G (GSM)";
if ([modelIdentifier isEqualToString:@"iPad2,7"]) return @"iPad mini 1G (Global)";
if ([modelIdentifier isEqualToString:@"iPad4,4"]) return @"iPad mini 2G (Wi-Fi)";
if ([modelIdentifier isEqualToString:@"iPad4,5"]) return @"iPad mini 2G (Cellular)";
if ([modelIdentifier isEqualToString:@"iPad4,6"]) return @"iPad mini 2G (Cellular)"; // TD-LTE model see https://support.apple.com/en-us/HT201471#iPad-mini2
if ([modelIdentifier isEqualToString:@"iPad4,7"]) return @"iPad mini 3G (Wi-Fi)";
if ([modelIdentifier isEqualToString:@"iPad4,8"]) return @"iPad mini 3G (Cellular)";
if ([modelIdentifier isEqualToString:@"iPad4,9"]) return @"iPad mini 3G (Cellular)";
if ([modelIdentifier isEqualToString:@"iPad5,1"]) return @"iPad mini 4G (Wi-Fi)";
if ([modelIdentifier isEqualToString:@"iPad5,2"]) return @"iPad mini 4G (Cellular)";
// iPad Pro https://www.theiphonewiki.com/wiki/IPad_Pro
if ([modelIdentifier isEqualToString:@"iPad6,3"]) return @"iPad Pro (9.7 inch) 1G (Wi-Fi)"; // http://pdadb.net/index.php?m=specs&id=9938&c=apple_ipad_pro_9.7-inch_a1673_wifi_32gb_apple_ipad_6,3
if ([modelIdentifier isEqualToString:@"iPad6,4"]) return @"iPad Pro (9.7 inch) 1G (Cellular)"; // http://pdadb.net/index.php?m=specs&id=9981&c=apple_ipad_pro_9.7-inch_a1675_td-lte_32gb_apple_ipad_6,4
if ([modelIdentifier isEqualToString:@"iPad6,7"]) return @"iPad Pro (12.9 inch) 1G (Wi-Fi)"; // http://pdadb.net/index.php?m=specs&id=8960&c=apple_ipad_pro_wifi_a1584_128gb
if ([modelIdentifier isEqualToString:@"iPad6,8"]) return @"iPad Pro (12.9 inch) 1G (Cellular)"; // http://pdadb.net/index.php?m=specs&id=8965&c=apple_ipad_pro_td-lte_a1652_32gb_apple_ipad_6,8
if ([modelIdentifier isEqualToString:@"iPad 7,1"]) return @"iPad Pro (12.9 inch) 2G (Wi-Fi)";
if ([modelIdentifier isEqualToString:@"iPad 7,2"]) return @"iPad Pro (12.9 inch) 2G (Cellular)";
if ([modelIdentifier isEqualToString:@"iPad 7,3"]) return @"iPad Pro (10.5 inch) 1G (Wi-Fi)";
if ([modelIdentifier isEqualToString:@"iPad 7,4"]) return @"iPad Pro (10.5 inch) 1G (Cellular)";
// iPod http://theiphonewiki.com/wiki/IPod
if ([modelIdentifier isEqualToString:@"iPod1,1"]) return @"iPod touch 1G";
if ([modelIdentifier isEqualToString:@"iPod2,1"]) return @"iPod touch 2G";
if ([modelIdentifier isEqualToString:@"iPod3,1"]) return @"iPod touch 3G";
if ([modelIdentifier isEqualToString:@"iPod4,1"]) return @"iPod touch 4G";
if ([modelIdentifier isEqualToString:@"iPod5,1"]) return @"iPod touch 5G";
if ([modelIdentifier isEqualToString:@"iPod7,1"]) return @"iPod touch 6G"; // as 6,1 was never released 7,1 is actually 6th generation
// Apple TV https://www.theiphonewiki.com/wiki/Apple_TV
if ([modelIdentifier isEqualToString:@"AppleTV1,1"]) return @"Apple TV 1G";
if ([modelIdentifier isEqualToString:@"AppleTV2,1"]) return @"Apple TV 2G";
if ([modelIdentifier isEqualToString:@"AppleTV3,1"]) return @"Apple TV 3G";
if ([modelIdentifier isEqualToString:@"AppleTV3,2"]) return @"Apple TV 3G"; // small, incremental update over 3,1
if ([modelIdentifier isEqualToString:@"AppleTV5,3"]) return @"Apple TV 4G"; // as 4,1 was never released, 5,1 is actually 4th generation
// Simulator
if ([modelIdentifier hasSuffix:@"86"] || [modelIdentifier isEqual:@"x86_64"])
{
BOOL smallerScreen = ([[UIScreen mainScreen] bounds].size.width < 768.0);
return (smallerScreen ? @"iPhone Simulator" : @"iPad Simulator");
}
return modelIdentifier;
}
@end
Upvotes: 2
Reputation: 12948
If you have a plist of devices (eg maintained by @Tib above in https://stackoverflow.com/a/17655825/849616) to handle it if Swift 3 you'd use:
extension UIDevice {
/// Fetches the information about the name of the device.
///
/// - Returns: Should return meaningful device name, if not found will return device system code.
public static func modelName() -> String {
let physicalName = deviceSystemCode()
if let deviceTypes = deviceTypes(), let modelName = deviceTypes[physicalName] as? String {
return modelName
}
return physicalName
}
}
private extension UIDevice {
/// Fetches from system the code of the device
static func deviceSystemCode() -> String {
var systemInfo = utsname()
uname(&systemInfo)
let machineMirror = Mirror(reflecting: systemInfo.machine)
let identifier = machineMirror.children.reduce("") { identifier, element in
guard let value = element.value as? Int8, value != 0 else { return identifier }
return identifier + String(UnicodeScalar(UInt8(value)))
}
return identifier
}
/// Fetches the plist entries from plist maintained in https://stackoverflow.com/a/17655825/849616
///
/// - Returns: A dictionary with pairs of deviceSystemCode <-> meaningfulDeviceName.
static func deviceTypes() -> NSDictionary? {
if let fileUrl = Bundle.main.url(forResource: "your plist name", withExtension: "plist"),
let configurationDictionary = NSDictionary(contentsOf: fileUrl) {
return configurationDictionary
}
return nil
}
}
Later you can call it using UIDevice.modelName()
.
Additional credits go to @Tib (for plist), @Aniruddh Joshi (for deviceSystemCode()
function).
Upvotes: 0
Reputation: 8124
My solution to this issue is basically looks related to @NicolasMiari answer within this thread. Separate utility class has a predefined set of Device and Machine names and then depending on the real machine name, retrieve the Device Name.
Note: This answer and it's linked GitHub project has been updated to identify current latest iPhones (iPhone 8, 8+, X) as of October 2017. And this works on iOS11 too. Please visit the GitHub repo and see, and give me feedback if something is wrong.
/*
* Retrieves back the device name or if not the machine name.
*/
+ (NSString*)deviceModelName {
struct utsname systemInfo;
uname(&systemInfo);
NSString *machineName = [NSString stringWithCString:systemInfo.machine encoding:NSUTF8StringEncoding];
//MARK: More official list is at
//http://theiphonewiki.com/wiki/Models
//MARK: You may just return machineName. Following is for convenience
NSDictionary *commonNamesDictionary =
@{
@"i386": @"i386 Simulator",
@"x86_64": @"x86_64 Simulator",
@"iPhone1,1": @"iPhone",
@"iPhone1,2": @"iPhone 3G",
@"iPhone2,1": @"iPhone 3GS",
@"iPhone3,1": @"iPhone 4",
@"iPhone3,2": @"iPhone 4(Rev A)",
@"iPhone3,3": @"iPhone 4(CDMA)",
@"iPhone4,1": @"iPhone 4S",
@"iPhone5,1": @"iPhone 5(GSM)",
@"iPhone5,2": @"iPhone 5(GSM+CDMA)",
@"iPhone5,3": @"iPhone 5c(GSM)",
@"iPhone5,4": @"iPhone 5c(GSM+CDMA)",
@"iPhone6,1": @"iPhone 5s(GSM)",
@"iPhone6,2": @"iPhone 5s(GSM+CDMA)",
@"iPhone7,1": @"iPhone 6+(GSM+CDMA)",
@"iPhone7,2": @"iPhone 6(GSM+CDMA)",
@"iPhone8,1": @"iPhone 6S(GSM+CDMA)",
@"iPhone8,2": @"iPhone 6S+(GSM+CDMA)",
@"iPhone8,4": @"iPhone SE(GSM+CDMA)",
@"iPhone9,1": @"iPhone 7(GSM+CDMA)",
@"iPhone9,2": @"iPhone 7+(GSM+CDMA)",
@"iPhone9,3": @"iPhone 7(GSM+CDMA)",
@"iPhone9,4": @"iPhone 7+(GSM+CDMA)",
@"iPad1,1": @"iPad",
@"iPad2,1": @"iPad 2(WiFi)",
@"iPad2,2": @"iPad 2(GSM)",
@"iPad2,3": @"iPad 2(CDMA)",
@"iPad2,4": @"iPad 2(WiFi Rev A)",
@"iPad2,5": @"iPad Mini 1G (WiFi)",
@"iPad2,6": @"iPad Mini 1G (GSM)",
@"iPad2,7": @"iPad Mini 1G (GSM+CDMA)",
@"iPad3,1": @"iPad 3(WiFi)",
@"iPad3,2": @"iPad 3(GSM+CDMA)",
@"iPad3,3": @"iPad 3(GSM)",
@"iPad3,4": @"iPad 4(WiFi)",
@"iPad3,5": @"iPad 4(GSM)",
@"iPad3,6": @"iPad 4(GSM+CDMA)",
@"iPad4,1": @"iPad Air(WiFi)",
@"iPad4,2": @"iPad Air(GSM)",
@"iPad4,3": @"iPad Air(GSM+CDMA)",
@"iPad5,3": @"iPad Air 2 (WiFi)",
@"iPad5,4": @"iPad Air 2 (GSM+CDMA)",
@"iPad4,4": @"iPad Mini 2G (WiFi)",
@"iPad4,5": @"iPad Mini 2G (GSM)",
@"iPad4,6": @"iPad Mini 2G (GSM+CDMA)",
@"iPad4,7": @"iPad Mini 3G (WiFi)",
@"iPad4,8": @"iPad Mini 3G (GSM)",
@"iPad4,9": @"iPad Mini 3G (GSM+CDMA)",
@"iPod1,1": @"iPod 1st Gen",
@"iPod2,1": @"iPod 2nd Gen",
@"iPod3,1": @"iPod 3rd Gen",
@"iPod4,1": @"iPod 4th Gen",
@"iPod5,1": @"iPod 5th Gen",
@"iPod7,1": @"iPod 6th Gen",
};
NSString *deviceName = commonNamesDictionary[machineName];
if (deviceName == nil) {
deviceName = machineName;
}
return deviceName;
}
I have added this implementation and few other convenient utility methods in a class and put it out there in this GitHub Repository. And also you can find the up to date device information list within this Wiki page.
Please visit it and get use of it.
Update:
You may requires to import sys framework,
#import <sys/utsname.h>
Upvotes: 9
Reputation: 10365
[[UIDevice currentDevice] model]
just returns iPhone
or iPod
, you don't get the numbers of the model that would let you differentiate between different generations of devices.
Code this method:
#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;
}
And call the method [self getModel]
whenever you need the model and you'll get i.e: "iPhone5,1" for the ridiculously thin and speedy iPhone 5.
One good practice is to create a class called Utils.h/Utils.m
and put methods like getModel
there so you can get this info from anywhere in your App simply by importing the class and invoking [Utils getModel];
Upvotes: 21
Reputation: 21520
Swift 3 compatible
// MARK: - UIDevice Extension -
private let DeviceList = [
/* iPod 5 */ "iPod5,1": "iPod Touch 5",
/* iPhone 4 */ "iPhone3,1": "iPhone 4", "iPhone3,2": "iPhone 4", "iPhone3,3": "iPhone 4",
/* iPhone 4S */ "iPhone4,1": "iPhone 4S",
/* iPhone 5 */ "iPhone5,1": "iPhone 5", "iPhone5,2": "iPhone 5",
/* iPhone 5C */ "iPhone5,3": "iPhone 5C", "iPhone5,4": "iPhone 5C",
/* iPhone 5S */ "iPhone6,1": "iPhone 5S", "iPhone6,2": "iPhone 5S",
/* iPhone 6 */ "iPhone7,2": "iPhone 6",
/* iPhone 6 Plus */ "iPhone7,1": "iPhone 6 Plus",
/* iPhone 6S */ "iPhone8,1": "iPhone 6S",
/* iPhone 6S Plus */ "iPhone8,2": "iPhone 6S Plus",
/* iPhone SE */ "iPhone8,4": "iPhone SE",
/* iPhone 7 */ "iPhone9,1": "iPhone 7",
/* iPhone 7 */ "iPhone9,3": "iPhone 7",
/* iPhone 7 Plus */ "iPhone9,2": "iPhone 7 Plus",
/* iPhone 7 Plus */ "iPhone9,4": "iPhone 7 Plus",
/* iPad 2 */ "iPad2,1": "iPad 2", "iPad2,2": "iPad 2", "iPad2,3": "iPad 2", "iPad2,4": "iPad 2",
/* iPad 3 */ "iPad3,1": "iPad 3", "iPad3,2": "iPad 3", "iPad3,3": "iPad 3",
/* iPad 4 */ "iPad3,4": "iPad 4", "iPad3,5": "iPad 4", "iPad3,6": "iPad 4",
/* iPad Air */ "iPad4,1": "iPad Air", "iPad4,2": "iPad Air", "iPad4,3": "iPad Air",
/* iPad Air 2 */ "iPad5,1": "iPad Air 2", "iPad5,3": "iPad Air 2", "iPad5,4": "iPad Air 2",
/* iPad Mini */ "iPad2,5": "iPad Mini 1", "iPad2,6": "iPad Mini 1", "iPad2,7": "iPad Mini 1",
/* iPad Mini 2 */ "iPad4,4": "iPad Mini 2", "iPad4,5": "iPad Mini 2", "iPad4,6": "iPad Mini 2",
/* iPad Mini 3 */ "iPad4,7": "iPad Mini 3", "iPad4,8": "iPad Mini 3", "iPad4,9": "iPad Mini 3",
/* iPad Pro 12.9 */ "iPad6,7": "iPad Pro 12.9", "iPad6,8": "iPad Pro 12.9",
/* iPad Pro 9.7 */ "iPad6,3": "iPad Pro 9.7", "iPad6,4": "iPad Pro 9.7",
/* Simulator */ "x86_64": "Simulator", "i386": "Simulator"
]
extension UIDevice {
static var modelName: String {
var systemInfo = utsname()
uname(&systemInfo)
let machine = systemInfo.machine
let mirror = Mirror(reflecting: machine)
var identifier = ""
for child in mirror.children {
if let value = child.value as? Int8, value != 0 {
identifier += String(UnicodeScalar(UInt8(value)))
}
}
return DeviceList[identifier] ?? identifier
}
static var isIphone4: Bool {
return modelName == "iPhone 5" || modelName == "iPhone 5C" || modelName == "iPhone 5S" || UIDevice.isSimulatorIPhone4
}
static var isIphone5: Bool {
return modelName == "iPhone 4S" || modelName == "iPhone 4" || UIDevice.isSimulatorIPhone5
}
static var isIphone6: Bool {
return modelName == "iPhone 6" || UIDevice.isSimulatorIPhone6
}
static var isIphone6Plus: Bool {
return modelName == "iPhone 6 Plus" || UIDevice.isSimulatorIPhone6Plus
}
static var isIpad: Bool {
if UIDevice.current.model.contains("iPad") {
return true
}
return false
}
static var isIphone: Bool {
return !self.isIpad
}
/// Check if current device is iPhone4S (and earlier) relying on screen heigth
static var isSimulatorIPhone4: Bool {
return UIDevice.isSimulatorWithScreenHeigth(480)
}
/// Check if current device is iPhone5 relying on screen heigth
static var isSimulatorIPhone5: Bool {
return UIDevice.isSimulatorWithScreenHeigth(568)
}
/// Check if current device is iPhone6 relying on screen heigth
static var isSimulatorIPhone6: Bool {
return UIDevice.isSimulatorWithScreenHeigth(667)
}
/// Check if current device is iPhone6 Plus relying on screen heigth
static var isSimulatorIPhone6Plus: Bool {
return UIDevice.isSimulatorWithScreenHeigth(736)
}
private static func isSimulatorWithScreenHeigth(_ heigth: CGFloat) -> Bool {
let screenSize: CGRect = UIScreen.main.bounds
return modelName == "Simulator" && screenSize.height == heigth
}
}
Upvotes: 7
Reputation: 22245
In general, it is desirable to avoid arbitrary string comparisons throughout your code. It is better to update the strings in one place and hide the magic string from your app. I provide a category on UIDevice
for that purpose.
For my specific needs I need to know which device I am using without the need to know specifics about networking capability that can be easily retrieved in other ways. So you will find a coarser grained enum
than the ever growing list of devices.
Updating is a matter of adding the device to the enum and the lookup table.
typedef NS_ENUM(NSUInteger, NTNUDeviceType) {
DeviceAppleUnknown,
DeviceAppleSimulator,
DeviceAppleiPhone,
DeviceAppleiPhone3G,
DeviceAppleiPhone3GS,
DeviceAppleiPhone4,
DeviceAppleiPhone4S,
DeviceAppleiPhone5,
DeviceAppleiPhone5C,
DeviceAppleiPhone5S,
DeviceAppleiPhone6,
DeviceAppleiPhone6_Plus,
DeviceAppleiPhone6S,
DeviceAppleiPhone6S_Plus,
DeviceAppleiPhoneSE,
DeviceAppleiPhone7,
DeviceAppleiPhone7_Plus,
DeviceAppleiPodTouch,
DeviceAppleiPodTouch2G,
DeviceAppleiPodTouch3G,
DeviceAppleiPodTouch4G,
DeviceAppleiPad,
DeviceAppleiPad2,
DeviceAppleiPad3G,
DeviceAppleiPad4G,
DeviceAppleiPad5G_Air,
DeviceAppleiPadMini,
DeviceAppleiPadMini2G,
DeviceAppleiPadPro12,
DeviceAppleiPadPro9
};
@interface UIDevice (NTNUExtensions)
- (NSString *)ntnu_deviceDescription;
- (NTNUDeviceType)ntnu_deviceType;
@end
#import <sys/utsname.h>
#import "UIDevice+NTNUExtensions.h"
@implementation UIDevice (NTNUExtensions)
- (NSString *)ntnu_deviceDescription
{
struct utsname systemInfo;
uname(&systemInfo);
return [NSString stringWithCString:systemInfo.machine encoding:NSUTF8StringEncoding];
}
- (NTNUDeviceType)ntnu_deviceType
{
NSNumber *deviceType = [[self ntnu_deviceTypeLookupTable] objectForKey:[self ntnu_deviceDescription]];
return [deviceType unsignedIntegerValue];
}
- (NSDictionary *)ntnu_deviceTypeLookupTable
{
return @{
@"i386": @(DeviceAppleSimulator),
@"x86_64": @(DeviceAppleSimulator),
@"iPod1,1": @(DeviceAppleiPodTouch),
@"iPod2,1": @(DeviceAppleiPodTouch2G),
@"iPod3,1": @(DeviceAppleiPodTouch3G),
@"iPod4,1": @(DeviceAppleiPodTouch4G),
@"iPhone1,1": @(DeviceAppleiPhone),
@"iPhone1,2": @(DeviceAppleiPhone3G),
@"iPhone2,1": @(DeviceAppleiPhone3GS),
@"iPhone3,1": @(DeviceAppleiPhone4),
@"iPhone3,3": @(DeviceAppleiPhone4),
@"iPhone4,1": @(DeviceAppleiPhone4S),
@"iPhone5,1": @(DeviceAppleiPhone5),
@"iPhone5,2": @(DeviceAppleiPhone5),
@"iPhone5,3": @(DeviceAppleiPhone5C),
@"iPhone5,4": @(DeviceAppleiPhone5C),
@"iPhone6,1": @(DeviceAppleiPhone5S),
@"iPhone6,2": @(DeviceAppleiPhone5S),
@"iPhone7,1": @(DeviceAppleiPhone6_Plus),
@"iPhone7,2": @(DeviceAppleiPhone6),
@"iPhone8,1" :@(DeviceAppleiPhone6S),
@"iPhone8,2" :@(DeviceAppleiPhone6S_Plus),
@"iPhone8,4" :@(DeviceAppleiPhoneSE),
@"iPhone9,1" :@(DeviceAppleiPhone7),
@"iPhone9,3" :@(DeviceAppleiPhone7),
@"iPhone9,2" :@(DeviceAppleiPhone7_Plus),
@"iPhone9,4" :@(DeviceAppleiPhone7_Plus),
@"iPad1,1": @(DeviceAppleiPad),
@"iPad2,1": @(DeviceAppleiPad2),
@"iPad3,1": @(DeviceAppleiPad3G),
@"iPad3,4": @(DeviceAppleiPad4G),
@"iPad2,5": @(DeviceAppleiPadMini),
@"iPad4,1": @(DeviceAppleiPad5G_Air),
@"iPad4,2": @(DeviceAppleiPad5G_Air),
@"iPad4,4": @(DeviceAppleiPadMini2G),
@"iPad4,5": @(DeviceAppleiPadMini2G),
@"iPad4,7":@(DeviceAppleiPadMini),
@"iPad6,7":@(DeviceAppleiPadPro12),
@"iPad6,8":@(DeviceAppleiPadPro12),
@"iPad6,3":@(DeviceAppleiPadPro9),
@"iPad6,4":@(DeviceAppleiPadPro9)
};
}
@end
Upvotes: 13
Reputation: 10752
Below Function Perfectly Working on iOS7 or later version in Swift
func DeviceName()-> String {
var myDeviceName : String = String()
var systemInfo = [UInt8](count: sizeof(utsname), repeatedValue: 0)
let model = systemInfo.withUnsafeMutableBufferPointer { (inout body: UnsafeMutableBufferPointer<UInt8>) -> String? in
if uname(UnsafeMutablePointer(body.baseAddress)) != 0 {
return nil
}
return String.fromCString(UnsafePointer(body.baseAddress.advancedBy(Int(_SYS_NAMELEN * 4))))
}
let deviceNamesByCode : [String: String] = ["iPod1,1":"iPod Touch 1",
"iPod2,1":"iPod Touch 2",
"iPod3,1":"iPod Touch 3",
"iPod4,1":"iPod Touch 4",
"iPod5,1":"iPod Touch 5",
"iPod7,1":"iPod Touch 6",
"iPhone1,1":"iPhone",
"iPhone1,2":"iPhone ",
"iPhone2,1":"iPhone ",
"iPhone3,1":"iPhone 4",
"iPhone3,2":"iPhone 4",
"iPhone3,3":"iPhone 4",
"iPhone4,1":"iPhone 4s",
"iPhone5,1":"iPhone 5",
"iPhone5,2":"iPhone 5",
"iPhone5,3":"iPhone 5c",
"iPhone5,4":"iPhone 5c",
"iPhone6,1":"iPhone 5s",
"iPhone6,2":"iPhone 5s",
"iPhone7,2":"iPhone 6",
"iPhone7,1":"iPhone 6 Plus",
"iPhone8,1":"iPhone 6s",
"iPhone8,2":"iPhone 6s Plus",
"iPhone8,4":"iPhone SE",
"iPad2,1":"iPad 2",
"iPad2,2":"iPad 2",
"iPad2,3":"iPad 2",
"iPad2,4":"iPad 2",
"iPad3,1":"iPad 3",
"iPad3,2":"iPad 3",
"iPad3,3":"iPad 3",
"iPad3,4":"iPad 4",
"iPad3,5":"iPad 4",
"iPad3,6":"iPad 4",
"iPad4,1":"iPad Air",
"iPad4,2":"iPad Air",
"iPad4,3":"iPad Air",
"iPad5,3":"iPad Air 2",
"iPad5,4":"iPad Air 2",
"iPad2,5":"iPad Mini",
"iPad2,6":"iPad Mini",
"iPad2,7":"iPad Mini",
"iPad4,4":"iPad Mini 2",
"iPad4,5":"iPad Mini 2",
"iPad4,6":"iPad Mini 2",
"iPad4,7":"iPad Mini 3",
"iPad4,8":"iPad Mini 3",
"iPad4,9":"iPad Mini 3",
"iPad5,1":"iPad Mini 4",
"iPad5,2":"iPad Mini 4",
"iPad6,3":"iPad Pro",
"iPad6,4":"iPad Pro",
"iPad6,7":"iPad Pro",
"iPad6,8":"iPad Pro",
"AppleTV5,3":"Apple TV",
"i386":"Simulator",
"x86_64":"Simulator"
]
if model!.characters.count > 0 {
myDeviceName = deviceNamesByCode[model!]!
}else{
myDeviceName = UIDevice.currentDevice().model
}
print("myDeviceName==\(myDeviceName)")
return myDeviceName
}
Upvotes: 3
Reputation: 39988
Below is the code for that (code may not contain all device's string, I'm with other guys are maintaining the same code on GitHub so please take the latest code from there)
Objective-C : GitHub/DeviceUtil
Swift : GitHub/DeviceGuru
#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;
}
Upvotes: 14
Reputation: 1753
#import <sys/utsname.h>
#define HARDWARE @{@"i386": @"Simulator",@"x86_64": @"Simulator",@"iPod1,1": @"iPod Touch",@"iPod2,1": @"iPod Touch 2nd Generation",@"iPod3,1": @"iPod Touch 3rd Generation",@"iPod4,1": @"iPod Touch 4th Generation",@"iPhone1,1": @"iPhone",@"iPhone1,2": @"iPhone 3G",@"iPhone2,1": @"iPhone 3GS",@"iPhone3,1": @"iPhone 4",@"iPhone4,1": @"iPhone 4S",@"iPhone5,1": @"iPhone 5",@"iPhone5,2": @"iPhone 5",@"iPhone5,3": @"iPhone 5c",@"iPhone5,4": @"iPhone 5c",@"iPhone6,1": @"iPhone 5s",@"iPhone6,2": @"iPhone 5s",@"iPad1,1": @"iPad",@"iPad2,1": @"iPad 2",@"iPad3,1": @"iPad 3rd Generation ",@"iPad3,4": @"iPad 4th Generation ",@"iPad2,5": @"iPad Mini",@"iPad4,4": @"iPad Mini 2nd Generation - Wifi",@"iPad4,5": @"iPad Mini 2nd Generation - Cellular",@"iPad4,1": @"iPad Air 5th Generation - Wifi",@"iPad4,2": @"iPad Air 5th Generation - Cellular"}
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
struct utsname systemInfo;
uname(&systemInfo);
NSLog(@"hardware: %@",[HARDWARE objectForKey:[NSString stringWithCString: systemInfo.machine encoding:NSUTF8StringEncoding]]);
}
Upvotes: 4
Reputation: 476
I've optimized NicolasMiari's implementation, and added Simulator
, here:
+ (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;
}
```
Upvotes: 12