有没有办法在Swift中获得设备型号名称(iPhone 4S, iPhone 5, iPhone 5S等)?
我知道有一个名为UIDevice.currentDevice()的属性。模型,但它只返回设备类型(iPod touch, iPhone, iPad, iPhone模拟器等)。
我也知道在Objective-C中使用以下方法可以轻松完成:
#import <sys/utsname.h>
struct utsname systemInfo;
uname(&systemInfo);
NSString* deviceModel = [NSString stringWithCString:systemInfo.machine
encoding:NSUTF8StringEncoding];
但是我正在Swift中开发我的iPhone应用程序,所以有人可以帮助我用等效的方法在Swift中解决这个问题吗?
维基设备
异步库,从iphonewiki给你答案
A crazy little experiment for automation fans like me. I made this algorithm that reads the identification code of the device, physical or simulated, and load the theiphonewiki page to extrapolate the model name based on the identification code (example iPhone11,2 -> iPhone XS). The algorithm interfaces with the WIKI page using the internal Wiki API Sandbox tool that allows you to have a JSON response, however the content is not obtainable in JSON (just the part that was needed, that is the wikitables) so I parsed the HTML content to get to the device name, without using third parts HTML parsing libraries.
优点:总是更新,你不需要添加新的设备
缺点:异步回答使用维基页面从网络
附注:请随意改进我的代码,以获得更精确的结果和更优雅的语法
P.S.S.如果你需要更直接的答案,请使用我之前在本页的答案
public extension UIDevice {
var identifier: String {
var systemInfo = utsname()
uname(&systemInfo)
let modelCode = withUnsafePointer(to: &systemInfo.machine) {
$0.withMemoryRebound(to: CChar.self, capacity: 1) {
ptr in String.init(validatingUTF8: ptr)
}
}
if modelCode == "x86_64" {
if let simModelCode = ProcessInfo().environment["SIMULATOR_MODEL_IDENTIFIER"] {
if let simMap = String(validatingUTF8: simModelCode) {
return simMap
}
}
}
return modelCode ?? "?unrecognized?"
}
}
class WikiDevice {
static func model(_ completion: @escaping ((String) -> ())){
let unrecognized = "?unrecognized?"
guard let wikiUrl=URL(string:"https://www.theiphonewiki.com//w/api.php?action=parse&format=json&page=Models") else { return completion(unrecognized) }
var identifier: String {
var systemInfo = utsname()
uname(&systemInfo)
let modelCode = withUnsafePointer(to: &systemInfo.machine) {
$0.withMemoryRebound(to: CChar.self, capacity: 1) {
ptr in String.init(validatingUTF8: ptr)
}
}
if modelCode == "x86_64" {
if let simModelCode = ProcessInfo().environment["SIMULATOR_MODEL_IDENTIFIER"] {
if let simMap = String(validatingUTF8: simModelCode) {
return simMap
}
}
}
return modelCode ?? unrecognized
}
guard identifier != unrecognized else { return completion(unrecognized)}
let request = URLRequest(url: wikiUrl)
URLSession.shared.dataTask(with: request) { (data, response, error) in
do {
guard let data = data,
let response = response as? HTTPURLResponse, (200 ..< 300) ~= response.statusCode,
error == nil else { return completion(unrecognized) }
guard let convertedString = String(data: data, encoding: String.Encoding.utf8) else { return completion(unrecognized) }
var wikiTables = convertedString.components(separatedBy: "wikitable")
wikiTables.removeFirst()
var tables = [[String]]()
wikiTables.enumerated().forEach{ index,table in
let rawRows = table.components(separatedBy: #"<tr>\n<td"#)
var counter = 0
var rows = [String]()
while counter < rawRows.count {
let rawRow = rawRows[counter]
if let subRowsNum = rawRow.components(separatedBy: #"rowspan=\""#).dropFirst().compactMap({ sub in
(sub.range(of: #"\">"#)?.lowerBound).flatMap { endRange in
String(sub[sub.startIndex ..< endRange])
}
}).first {
if let subRowsTot = Int(subRowsNum) {
var otherRows = ""
for i in counter..<counter+subRowsTot {
otherRows += rawRows[i]
}
let row = rawRow + otherRows
rows.append(row)
counter += subRowsTot-1
}
} else {
rows.append(rawRows[counter])
}
counter += 1
}
tables.append(rows)
}
for table in tables {
if let rowIndex = table.firstIndex(where: {$0.lowercased().contains(identifier.lowercased())}) {
let rows = table[rowIndex].components(separatedBy: "<td>")
if rows.count>0 {
if rows[0].contains("title") { //hyperlink
if let (cleanedGen) = rows[0].components(separatedBy: #">"#).dropFirst().compactMap({ sub in
(sub.range(of: "</")?.lowerBound).flatMap { endRange in
String(sub[sub.startIndex ..< endRange]).replacingOccurrences(of: #"\n"#, with: "")
}
}).first {
completion(cleanedGen)
}
} else {
let raw = rows[0].replacingOccurrences(of: "<td>", with: "")
let cleanedGen = raw.replacingOccurrences(of: #"\n"#, with: "")
completion(cleanedGen)
}
return
}
}
}
completion(unrecognized)
}
}.resume()
}
}
用法:
var deviceModel:String = ""
WikiDevice.model { (model) in
print("Using WikiDevice, running on: \(model)")
deviceModel = model
}
输出:
Using WikiDevice, running on: iPhone 11 Pro Max
GitHUB:
如果您需要测试这个库,您可以从这里下载测试项目