web-dev-qa-db-ja.com

デバイスがiOS 10でUIFeedbackGeneratorをサポートしているかどうかを確認する

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を使用してこの情報を取得する方法がない場合があります。

16
Kris Gellci

したがって、明らかにこれはプライベートAPI呼び出しで実行できます。

Objective-C:

_[[UIDevice currentDevice] valueForKey:@"_feedbackSupportLevel"];_

Swift:

UIDevice.currentDevice().valueForKey("_feedbackSupportLevel");


...これらのメソッドは次のように返します:

  • _0_=タプティックは使用できません
  • _1_=第一世代(iPhone 6sでテスト済み)... UINotificationFeedbackGeneratorなどをサポートしていません。
  • _2_=第2世代(iPhone 7でテスト済み)...が実行するサポートしています。

残念ながら、ここに2つの警告があります。

  1. これらを使用すると、App StoreのApp Review中にAppleによってアプリが拒否される可能性がありますが、現時点では他の方法はないようです。
  2. actualの値が何を表すのかわかりません。

Tim OliverおよびSteve TSに感謝します。デバイス。 https://Twitter.com/TimOliverAU/status/7781050296434360

14
Ben Guild

現在、最善の方法は、次を使用してデバイスのモデルを確認することです。

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())
    } 
}
1
chrisamanse
class func isFeedbackSupport() -> Bool {
    if let value = UIDevice.current.value(forKey: "_feedbackSupportLevel") {
        let result = value as! Int
        return result == 2 ? true : false
    }
    return false
}
0
Wan Mook Kang

クリサマンスの答え を拡張しました。 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
}
0
MJQZ1347