检查设备是否支持iOS 10中的UIFeedbackGenerator
在iOS 10中,有一个新的api,允许开发人员使用taptic引擎UIFeedbackGenerator 虽然此api在iOS 10中可用,但它仅适用于新设备iPhone 7和7 plus。它不适用于包括6S或6S Plus在内的旧设备,即使是那些有taptic引擎的设备。我想7和7 plus上的taptic引擎是另一个更强大的引擎 我似乎找不到一种方法来查看设备是否支持使用新的api。我想用taptic代码替换一些振动代码,这是有意义的 编辑: 为搜索目的添加3个具体子类: 冲击反馈发生器 UINotificationFeedbackGenerator UIS选择反馈发生器 编辑2:检查设备是否支持iOS 10中的UIFeedbackGenerator,ios,iphone,ios10,taptic-engine,Ios,Iphone,Ios10,Taptic Engine,在iOS 10中,有一个新的api,允许开发人员使用taptic引擎UIFeedbackGenerator 虽然此api在iOS 10中可用,但它仅适用于新设备iPhone 7和7 plus。它不适用于包括6S或6S Plus在内的旧设备,即使是那些有taptic引擎的设备。我想7和7 plus上的taptic引擎是另一个更强大的引擎 我似乎找不到一种方法来查看设备是否支持使用新的api。我想用taptic代码替换一些振动代码,这是有意义的 编辑: 为搜索目的添加3个具体子类: 冲击反馈发生器
我有一个理论,但没有iPhone7设备来测试它,所以如果你有一个,试一试。UIFeedbackGenerator有一个名为prepare()的方法。打印UIImpactFeedbackGenerator实例时,我注意到它打印了一个名为“prepared”的属性,该属性将显示0。在模拟器或iPhone 6S上调用prepare(),然后打印出的实例仍然显示prepared为0。是否有人可以从iPhone7调用UIImpactFeedbackGenerator实例的prepare(),然后将该实例打印到控制台,查看prepared是否设置为1?此值未公开,但可能有一种方法可以不使用专用API获取此信息。因此,显然这可以通过专用API调用完成 目标-C:
[[UIDevice currentDevice]valueForKey:@“\u反馈支持级别”]代码>
Swift:
UIDevice.currentDevice().valueForKey(“反馈支持级别”)代码>
。。。这些方法似乎会返回:
0
=Taptic不可用
1
=第一代(在iPhone 6s上测试)。。。它不支持UINotificationFeedbackGenerator等
2
=第二代(在iPhone 7上测试)。。。哪个支持它
不幸的是,这里有两个警告:
在应用商店的应用程序审查中,使用这些可能会导致你的应用程序被苹果拒绝,但目前似乎没有其他方法
我们不知道实际值代表什么
特别感谢蒂姆·奥利弗和史蒂夫·T-S,感谢他们帮助用不同的设备进行测试 目前,最好的方法是使用以下工具检查设备型号:
public extension UIDevice
public func platform() -> String {
var sysinfo = utsname()
uname(&sysinfo) // ignore return value
return String(bytes: Data(bytes: &sysinfo.machine, count: Int(_SYS_NAMELEN)), encoding: .ascii)!.trimmingCharacters(in: .controlCharacters)
}
}
iPhone7和7 plus的平台名称是:“iPhone9,1”、“iPhone9,3”、“iPhone9,2”、“iPhone9,4”
资料来源:
您可以创建一个函数:
public extension UIDevice {
public var hasHapticFeedback: Bool {
return ["iPhone9,1", "iPhone9,3", "iPhone9,2", "iPhone9,4"].contains(platform())
}
}
我已经延长了。它从模型标识符中提取生成编号,并检查其是否等于或大于9。除非苹果决定引入一个新的内部命名方案,否则应该与未来的iPhone机型一起使用
public extension UIDevice {
var modelIdentifier: String {
var sysinfo = utsname()
uname(&sysinfo) // ignore return value
return String(bytes: Data(bytes: &sysinfo.machine, count: Int(_SYS_NAMELEN)), encoding: .ascii)!.trimmingCharacters(in: .controlCharacters)
}
var hasHapticFeedback: Bool {
// assuming that iPads and iPods don't have a Taptic Engine
if !modelIdentifier.contains("iPhone") {
return false
}
// e.g. will equal to "9,5" for "iPhone9,5"
let subString = String(modelIdentifier[modelIdentifier.index(modelIdentifier.startIndex, offsetBy: 6)..<modelIdentifier.endIndex])
// will return true if the generationNumber is equal to or greater than 9
if let generationNumberString = subString.components(separatedBy: ",").first,
let generationNumber = Int(generationNumberString),
generationNumber >= 9 {
return true
}
return false
}
}
根据我阅读的内容,您不需要检查设备是否支持这些API。在较旧的设备上调用时,对它们的调用将保持沉默。@AndyIbanez我确实需要检查一下,以达到我自己的目的。我在振动和敲击反馈之间切换,我不想在支持它的设备上同时播放这两种反馈。如果不可用,我们会退回到标准的“设备振动”,因为以前的操作系统版本和较旧的硬件上都使用过这种方式。需要知道是否有可能以触觉的方式进行操作。@BenGuild您能否提供一个链接,链接到有关这方面的文档。我确实试过了,但没有得到震动。@KrisGellci如前所述,我还需要知道这是否可行。有人提到,UIDevice
上有一些标志,可能可以检查,但它不是一个公共API。但你的问题是,下一代iPhone何时问世,它们显然不支持它。是的,这是一个问题,如果需要,应该更新代码。但目前,这是一种可能的解决方案,而不是使用私有API。另一个问题是用户可以在设备设置中禁用触觉反馈,此解决方案将不包括这些内容。向公共API公开可用性检查绝对值得关注。@BenGuild为什么使用此方法的应用程序会被苹果拒绝?这在iOS 11上不再适用。将导致崩溃,原因是此类不符合key _feedbackSupportLevel的键值编码。
。您回答的不仅是当前问题,将来还会被其他用户使用。请添加解释。效果很好,但为什么在开始时使用“类”。。。如果在代码中引入此代码,定义的“func”就足够了,不是吗???无法再访问iOS 11中的私钥“\u feedbackupportlevel”。这将导致你的应用程序崩溃。这是一个很好的答案,它不依赖于私有API,为未来减少头痛和汗水,谢谢!
public extension UIDevice {
var modelIdentifier: String {
var sysinfo = utsname()
uname(&sysinfo) // ignore return value
return String(bytes: Data(bytes: &sysinfo.machine, count: Int(_SYS_NAMELEN)), encoding: .ascii)!.trimmingCharacters(in: .controlCharacters)
}
var hasHapticFeedback: Bool {
// assuming that iPads and iPods don't have a Taptic Engine
if !modelIdentifier.contains("iPhone") {
return false
}
// e.g. will equal to "9,5" for "iPhone9,5"
let subString = String(modelIdentifier[modelIdentifier.index(modelIdentifier.startIndex, offsetBy: 6)..<modelIdentifier.endIndex])
// will return true if the generationNumber is equal to or greater than 9
if let generationNumberString = subString.components(separatedBy: ",").first,
let generationNumber = Int(generationNumberString),
generationNumber >= 9 {
return true
}
return false
}
}
if UIDevice.current.hasHapticFeedback {
// work with taptic engine
} else {
// fallback for older devices
}