guru_sdk/guru_app/plugins/vibration/ios/Classes/VibrationPluginSwift.swift

176 lines
5.8 KiB
Swift

import AudioToolbox
import CoreHaptics
import Flutter
import UIKit
public class VibrationPluginSwift: NSObject, FlutterPlugin {
#if targetEnvironment(simulator)
private let isDevice = false
#else
private let isDevice = true
#endif
private static let feedbackGenerator = UIImpactFeedbackGenerator(style: .light)
@available(iOS 13.0, *)
public static var engine: CHHapticEngine?
public static func register(with registrar: FlutterPluginRegistrar) {
let channel = FlutterMethodChannel(name: "vibration", binaryMessenger: registrar.messenger())
let instance = VibrationPluginSwift()
if #available(iOS 13.0, *) {
VibrationPluginSwift.createEngine()
}
feedbackGenerator.prepare()
registrar.addMethodCallDelegate(instance, channel: channel)
}
@available(iOS 13.0, *)
public static func createEngine() {
// Create and configure a haptic engine.
do {
VibrationPluginSwift.engine = try CHHapticEngine()
} catch {
print("Engine creation error: \(error)")
return
}
if VibrationPluginSwift.engine == nil {
print("Failed to create engine!")
}
// The stopped handler alerts you of engine stoppage due to external causes.
VibrationPluginSwift.engine?.stoppedHandler = { reason in
print("The engine stopped for reason: \(reason.rawValue)")
}
// The reset handler provides an opportunity for your app to restart the engine in case of failure.
VibrationPluginSwift.engine?.resetHandler = {
// Try restarting the engine.
print("The engine reset --> Restarting now!")
do {
try VibrationPluginSwift.engine?.start()
} catch {
print("Failed to restart the engine: \(error)")
}
}
}
private func supportsHaptics() -> Bool {
if #available(iOS 13.0, *) {
return CHHapticEngine.capabilitiesForHardware().supportsHaptics
}
return false;
}
@available(iOS 13.0, *)
private func playPattern(myArgs: [String: Any], pattern: [Int]) -> Void {
// Get event parameters, if any
var params: [CHHapticEventParameter] = []
//var amplitudes: [Int] = []
let amplitudes = myArgs["intensities"] as! [Int]
// Create haptic events
var hapticEvents: [CHHapticEvent] = []
var i: Int = 0
var rel: Double = 0.0
while i < pattern.count {
// Get intensity parameter, if any
if (i < amplitudes.count) {
if(amplitudes[i] != 0) {
let p = CHHapticEventParameter(parameterID: .hapticIntensity, value: Float(Double(amplitudes[i]) / 255.0))
// Get wait time and duration
let duration = Double(pattern[i]) / 1000.0
// Create haptic event
let e = CHHapticEvent(
eventType: .hapticContinuous,
parameters: [p],
relativeTime: rel,
duration: duration
)
hapticEvents.append(e)
// Add duration to relative time
rel += duration
}
else {
let waitTime = Double(pattern[i]) / 1000.0
rel += waitTime
}
}
i += 1
}
// Try to play engine
do {
if let engine = VibrationPluginSwift.engine {
let patternToPlay = try CHHapticPattern(events: hapticEvents, parameters: [])
let player = try engine.makePlayer(with: patternToPlay)
try engine.start()
try player.start(atTime: 0)
}
} catch {
print("Failed to play pattern: \(error.localizedDescription).")
}
}
public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
switch call.method {
case "hasVibrator":
result(isDevice)
case "hasAmplitudeControl":
result(isDevice)
case "hasCustomVibrationsSupport":
result(supportsHaptics())
case "vibrate":
VibrationPluginSwift.feedbackGenerator.impactOccurred()
result(isDevice)
// guard let args = call.arguments else {
// result(false)
// return
// }
//
// guard let myArgs = args as? [String: Any] else {
// AudioServicesPlaySystemSound(kSystemSoundID_Vibrate)
// result(true)
// return
// }
//
// guard let pattern = myArgs["pattern"] as? [Int] else {
// AudioServicesPlaySystemSound(kSystemSoundID_Vibrate)
// result(true)
// return
// }
//
// if pattern.count == 0 {
// AudioServicesPlaySystemSound(kSystemSoundID_Vibrate)
// result(true)
// return
// }
//
// assert(pattern.count % 2 == 0, "Pattern must have even number of elements!")
//
// if !supportsHaptics() {
// AudioServicesPlaySystemSound(kSystemSoundID_Vibrate)
// result(true)
// return
// }
//
// if #available(iOS 13.0, *) {
// playPattern(myArgs: myArgs, pattern: pattern)
// }
//
// result(isDevice)
case "cancel":
result(nil)
default:
result(FlutterMethodNotImplemented)
}
}
}