IOS 10には、開発者がタプティックエンジンUIFeedbackGeneratorを利用できるようにする新しいAPIがあります。
このAPIはiOS 10で利用できますが、新しいデバイスであるiPhone 7および7 Plusでのみ機能します。 6Sまたは6S Plusを含む古いデバイスでは機能しません。タプティックエンジンを搭載しているデバイスでも同様です。 7と7プラスのタプティックエンジンは、より強力な別のエンジンだと思います。
デバイスが新しいAPIの使用をサポートしているかどうかを確認する方法が見つからないようです。私はいくつかの振動コードを意味のあるタプティックコードに置き換えたいと思います。
編集:
検索目的で3つの具象サブクラスを追加:UIImpactFeedbackGenerator UINotificationFeedbackGenerator UISelectionFeedbackGenerator
編集2:
私は理論を持っていますが、それをテストするためのiPhone 7デバイスはありません。 UIFeedbackGeneratorにはprepare()というメソッドがあります。 UIImpactFeedbackGeneratorのインスタンスを出力すると、「prepared」という名前のプロパティが出力され、0と表示されることに気付きました。シミュレータまたはiPhone 6Sでprepare()を呼び出しても、インスタンスを出力すると、preparedが0と表示されます。 ()iPhone7からのUIImpactFeedbackGeneratorのインスタンスで、インスタンスをコンソールに出力して、prepareが1に設定されているかどうかを確認しますか?この値は公開されていませんが、プライベートAPIを使用してこの情報を取得する方法がない場合があります。
したがって、明らかにこれはプライベートAPI呼び出しで実行できます。
Objective-C:
_[[UIDevice currentDevice] valueForKey:@"_feedbackSupportLevel"];
_
Swift:
UIDevice.currentDevice().valueForKey("_feedbackSupportLevel");
...これらのメソッドは次のように返します:
0
_=タプティックは使用できません1
_=第一世代(iPhone 6sでテスト済み)... UINotificationFeedbackGenerator
などをサポートしていません。2
_=第2世代(iPhone 7でテスト済み)...が実行するサポートしています。残念ながら、ここに2つの警告があります。
Tim OliverおよびSteve TSに感謝します。デバイス。 https://Twitter.com/TimOliverAU/status/7781050296434360
現在、最善の方法は、次を使用してデバイスのモデルを確認することです。
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)
}
}
IPhone 7および7 plusのプラットフォーム名は次のとおりです:"iPhone9,1", "iPhone9,3", "iPhone9,2", "iPhone9,4"
出典: iOS:Swiftで現在のiPhone /デバイスモデルを確認する方法
関数を作成できます:
public extension UIDevice {
public var hasHapticFeedback: Bool {
return ["iPhone9,1", "iPhone9,3", "iPhone9,2", "iPhone9,4"].contains(platform())
}
}
class func isFeedbackSupport() -> Bool {
if let value = UIDevice.current.value(forKey: "_feedbackSupportLevel") {
let result = value as! Int
return result == 2 ? true : false
}
return false
}
クリサマンスの答え を拡張しました。 Appleが新しい内部命名スキームの導入を決定しない限り、将来の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
}
}
次のように使用します。
if UIDevice.current.hasHapticFeedback {
// work with taptic engine
} else {
// fallback for older devices
}