/Sources/Haptico/Extensions/UIDevice+Extensions.swift

https://github.com/iSapozhnik/Haptico · Swift · 311 lines · 254 code · 37 blank · 20 comment · 49 complexity · 810317549b201c4d1bb97bcb2b599f52 MD5 · raw file

  1. //
  2. // UIDevice+Extensions.swift
  3. // Haptico
  4. //
  5. // Created by Ivan Sapozhnik on 02.03.18.
  6. //
  7. import UIKit
  8. // https://github.com/schickling/Device.swift/blob/master/Device/UIDeviceExtension.swift
  9. // https://ipsw.me/otas
  10. // MARK: -
  11. internal extension UIDevice {
  12. /// Returns the `DeviceType` of the device in use
  13. internal var deviceType: DeviceType {
  14. return DeviceType.current
  15. }
  16. internal var hasTapticEngine: Bool {
  17. get {
  18. return deviceType == .iPhone6S || deviceType == .iPhone6SPlus ||
  19. deviceType == .iPhone7 || deviceType == .iPhone7Plus ||
  20. deviceType == .iPhone8 || deviceType == .iPhone8Plus ||
  21. deviceType == .iPhoneX || deviceType == .iPhoneXR ||
  22. deviceType == .iPhoneXS || deviceType == .iPhoneXSMax ||
  23. deviceType == .iPhone11 || deviceType == .iPhone11Pro ||
  24. deviceType == .iPhone11ProMax || deviceType == .iPhoneSEGen2
  25. }
  26. }
  27. internal var hasHapticFeedback: Bool {
  28. get {
  29. return deviceType == .iPhone7 || deviceType == .iPhone7Plus ||
  30. deviceType == .iPhone8 || deviceType == .iPhone8Plus ||
  31. deviceType == .iPhoneX || deviceType == .iPhoneXR ||
  32. deviceType == .iPhoneXS || deviceType == .iPhoneXSMax ||
  33. deviceType == .iPhone11 || deviceType == .iPhone11Pro ||
  34. deviceType == .iPhone11ProMax || deviceType == .iPhoneSEGen2
  35. }
  36. }
  37. }
  38. /// Enum representing the different types of iOS devices available
  39. internal enum DeviceType: String {
  40. case iPhone2G
  41. case iPhone3G
  42. case iPhone3GS
  43. case iPhone4
  44. case iPhone4S
  45. case iPhone5
  46. case iPhone5C
  47. case iPhone5S
  48. case iPhone6
  49. case iPhone6Plus
  50. case iPhone6S
  51. case iPhone6SPlus
  52. case iPhoneSE
  53. case iPhone7
  54. case iPhone7Plus
  55. case iPhone8
  56. case iPhone8Plus
  57. case iPhoneX
  58. case iPhoneXS
  59. case iPhoneXSMax
  60. case iPhoneXR
  61. case iPhone11
  62. case iPhone11Pro
  63. case iPhone11ProMax
  64. case iPhoneSEGen2
  65. case iPodTouch1G
  66. case iPodTouch2G
  67. case iPodTouch3G
  68. case iPodTouch4G
  69. case iPodTouch5G
  70. case iPodTouch6G
  71. case iPad
  72. case iPad2
  73. case iPad3
  74. case iPad4
  75. case iPadMini
  76. case iPadMiniRetina
  77. case iPadMini3
  78. case iPadMini4
  79. case iPadAir
  80. case iPadAir2
  81. case iPadPro9Inch
  82. case iPadPro10p5Inch
  83. case iPadPro11Inch
  84. case iPadPro12Inch
  85. case simulator
  86. case notAvailable
  87. // MARK: - Constants
  88. /// Returns the current device type
  89. internal static var current: DeviceType {
  90. var systemInfo = utsname()
  91. uname(&systemInfo)
  92. let machine = systemInfo.machine
  93. let mirror = Mirror(reflecting: machine)
  94. var identifier = ""
  95. for child in mirror.children {
  96. if let value = child.value as? Int8, value != 0 {
  97. identifier.append(String(UnicodeScalar(UInt8(value))))
  98. }
  99. }
  100. return DeviceType(identifier: identifier)
  101. }
  102. // MARK: Variables
  103. /// Returns the display name of the device type
  104. internal var displayName: String {
  105. switch self {
  106. case .iPhone2G: return "iPhone 2G"
  107. case .iPhone3G: return "iPhone 3G"
  108. case .iPhone3GS: return "iPhone 3GS"
  109. case .iPhone4: return "iPhone 4"
  110. case .iPhone4S: return "iPhone 4S"
  111. case .iPhone5: return "iPhone 5"
  112. case .iPhone5C: return "iPhone 5C"
  113. case .iPhone5S: return "iPhone 5S"
  114. case .iPhone6Plus: return "iPhone 6 Plus"
  115. case .iPhone6: return "iPhone 6"
  116. case .iPhone6S: return "iPhone 6S"
  117. case .iPhone6SPlus: return "iPhone 6S Plus"
  118. case .iPhoneSE: return "iPhone SE"
  119. case .iPhone7: return "iPhone 7"
  120. case .iPhone7Plus: return "iPhone 7 Plus"
  121. case .iPhone8: return "iPhone 8"
  122. case .iPhone8Plus: return "iPhone 8 Plus"
  123. case .iPhoneX: return "iPhone X"
  124. case .iPhoneXS: return "iPHone XS"
  125. case .iPhoneXSMax: return "iPhone XS Max"
  126. case .iPhoneXR: return "iPhone XR"
  127. case .iPhone11: return "iPhone 11"
  128. case .iPhone11Pro: return "iPhone 11 Pro"
  129. case .iPhone11ProMax: return "iPhone 11 Pro Max"
  130. case .iPhoneSEGen2: return "iPhone SE (2nd Gen)"
  131. case .iPodTouch1G: return "iPod Touch 1G"
  132. case .iPodTouch2G: return "iPod Touch 2G"
  133. case .iPodTouch3G: return "iPod Touch 3G"
  134. case .iPodTouch4G: return "iPod Touch 4G"
  135. case .iPodTouch5G: return "iPod Touch 5G"
  136. case .iPodTouch6G: return "iPod Touch 6G"
  137. case .iPad: return "iPad"
  138. case .iPad2: return "iPad 2"
  139. case .iPad3: return "iPad 3"
  140. case .iPad4: return "iPad 4"
  141. case .iPadMini: return "iPad Mini"
  142. case .iPadMiniRetina: return "iPad Mini Retina"
  143. case .iPadMini3: return "iPad Mini 3"
  144. case .iPadMini4: return "iPad Mini 4"
  145. case .iPadAir: return "iPad Air"
  146. case .iPadAir2: return "iPad Air 2"
  147. case .iPadPro9Inch: return "iPad Pro 9 Inch"
  148. case .iPadPro10p5Inch: return "iPad Pro 10.5 Inch"
  149. case .iPadPro11Inch: return "iPad Pro 11 Inch"
  150. case .iPadPro12Inch: return "iPad Pro 12 Inch"
  151. case .simulator: return "Simulator"
  152. case .notAvailable: return "Not Available"
  153. }
  154. }
  155. internal var identifiers: [String] {
  156. switch self {
  157. case .notAvailable: return []
  158. case .simulator: return ["i386", "x86_64"]
  159. case .iPhone2G: return ["iPhone1,1"]
  160. case .iPhone3G: return ["iPhone1,2"]
  161. case .iPhone3GS: return ["iPhone2,1"]
  162. case .iPhone4: return ["iPhone3,1", "iPhone3,2", "iPhone3,3"]
  163. case .iPhone4S: return ["iPhone4,1"]
  164. case .iPhone5: return ["iPhone5,1", "iPhone5,2"]
  165. case .iPhone5C: return ["iPhone5,3", "iPhone5,4"]
  166. case .iPhone5S: return ["iPhone6,1", "iPhone6,2"]
  167. case .iPhone6: return ["iPhone7,2"]
  168. case .iPhone6Plus: return ["iPhone7,1"]
  169. case .iPhone6S: return ["iPhone8,1"]
  170. case .iPhone6SPlus: return ["iPhone8,2"]
  171. case .iPhoneSE: return ["iPhone8,4"]
  172. case .iPhone7: return ["iPhone9,1", "iPhone9,3"]
  173. case .iPhone7Plus: return ["iPhone9,2", "iPhone9,4"]
  174. case .iPhone8: return ["iPhone10,1", "iPhone10,4"]
  175. case .iPhone8Plus: return ["iPhone10,2", "iPhone10,5"]
  176. case .iPhoneX: return ["iPhone10,3", "iPhone10,6"]
  177. case .iPhoneXS: return ["iPhone11,2"]
  178. case .iPhoneXSMax: return ["iPhone11,4", "iPhone11,6"]
  179. case .iPhoneXR: return ["iPhone11,8"]
  180. case .iPhone11: return ["iPhone12,1"]
  181. case .iPhone11Pro: return ["iPhone12,3"]
  182. case .iPhone11ProMax: return ["iPhone12,5"]
  183. case .iPhoneSEGen2: return ["iPhone12,8"]
  184. case .iPodTouch1G: return ["iPod1,1"]
  185. case .iPodTouch2G: return ["iPod2,1"]
  186. case .iPodTouch3G: return ["iPod3,1"]
  187. case .iPodTouch4G: return ["iPod4,1"]
  188. case .iPodTouch5G: return ["iPod5,1"]
  189. case .iPodTouch6G: return ["iPod7,1"]
  190. case .iPad: return ["iPad1,1", "iPad1,2"]
  191. case .iPad2: return ["iPad2,1", "iPad2,2", "iPad2,3", "iPad2,4"]
  192. case .iPad3: return ["iPad3,1", "iPad3,2", "iPad3,3"]
  193. case .iPad4: return ["iPad3,4", "iPad3,5", "iPad3,6"]
  194. case .iPadMini: return ["iPad2,5", "iPad2,6", "iPad2,7"]
  195. case .iPadMiniRetina: return ["iPad4,4", "iPad4,5", "iPad4,6"]
  196. case .iPadMini3: return ["iPad4,7", "iPad4,8", "iPad4,9"]
  197. case .iPadMini4: return ["iPad5,1", "iPad5,2"]
  198. case .iPadAir: return ["iPad4,1", "iPad4,2", "iPad4,3"]
  199. case .iPadAir2: return ["iPad5,3", "iPad5,4"]
  200. case .iPadPro9Inch: return ["iPad6,3", "iPad6,4"]
  201. case .iPadPro10p5Inch: return ["iPad7,3", "iPad7,4"]
  202. case .iPadPro11Inch: return ["iPad8,1", "iPad8,2", "iPad8,3", "iPad8,4"]
  203. case .iPadPro12Inch: return ["iPad6,7", "iPad6,8", "iPad7,1", "iPad7,2", "iPad8,5", "iPad8,6", "iPad8,7", "iPad8,8"]
  204. }
  205. }
  206. // MARK: - Inits
  207. /** Creates a device type
  208. - parameter identifier: The identifier of the device
  209. - returns: The device type based on the provided identifier
  210. */
  211. internal init(identifier: String) {
  212. for device in DeviceType.all {
  213. for deviceId in device.identifiers {
  214. guard identifier == deviceId else { continue }
  215. self = device
  216. return
  217. }
  218. }
  219. self = .notAvailable
  220. }
  221. }
  222. extension DeviceType {
  223. static var all: [DeviceType] {
  224. return [
  225. iPhone2G,
  226. iPhone3G,
  227. iPhone3GS,
  228. iPhone4,
  229. iPhone4S,
  230. iPhone5,
  231. iPhone5C,
  232. iPhone5S,
  233. iPhone6,
  234. iPhone6Plus,
  235. iPhone6S,
  236. iPhone6SPlus,
  237. iPhoneSE,
  238. iPhone7,
  239. iPhone7Plus,
  240. iPhone8,
  241. iPhone8Plus,
  242. iPhoneX,
  243. iPhoneXS,
  244. iPhoneXSMax,
  245. iPhoneXR,
  246. iPhone11,
  247. iPhone11Pro,
  248. iPhone11ProMax,
  249. iPhoneSEGen2,
  250. iPodTouch1G,
  251. iPodTouch2G,
  252. iPodTouch3G,
  253. iPodTouch4G,
  254. iPodTouch5G,
  255. iPodTouch6G,
  256. iPad,
  257. iPad2,
  258. iPad3,
  259. iPad4,
  260. iPadMini,
  261. iPadMiniRetina,
  262. iPadMini3,
  263. iPadMini4,
  264. iPadAir,
  265. iPadAir2,
  266. iPadPro9Inch,
  267. iPadPro10p5Inch,
  268. iPadPro11Inch,
  269. iPadPro12Inch,
  270. simulator,
  271. notAvailable
  272. ]
  273. }
  274. }