Files
tauri-plugins-workspace/plugins/haptics/ios/Sources/HapticsPlugin.swift
Fabian-Lars 9606089b2a feat: Add geolocation and haptics plugins (#1599)
* init geolocation plugin

* ios impl (w/o js api)

* generate ts api

* use newer tauri commit

* add temporary postinstall

* include src in files

* guest-js

* just ship dist-js for now

* fix watcher

* fix android compile error

* fix android build for real

* fix heading type

* initial getCurrentPosition android impl (wip)

* prevent panics if errors (strings) are sent over the channel

* Add android watchPosition implementation

* init haptics plugin (android)

* ios and new apis (ANDROID IS LIKELY BROKEN - MAY NOT EVEN COMPILE)

* use tauri-specta that accounts for raw fn arg idents

* add complete android support (it's not working great due to random soft-/hardware support)

* fix(haptics): Fix the NotificationFeedbackType::Success and Version (#1)

* Fix success feedback and version

* Apply suggestions from code review

* Update package.json

---------

Co-authored-by: Fabian-Lars <118197967+FabianLars-crabnebula@users.noreply.github.com>

* android: improve permission callback handling

* keep track of ongoing perms requests

* rebuild

* license headers

* rm sqlite feat

* fmt

* what diff u talkin bout?

* ignore dist-js again

* fix audits

* dedupe api.js

* clippy

* changefiles

* readmes

* clean up todos

* rm dsstore

* rm wrong feats

* mirror

* covector

* rebuild

* ios requires the wry feature

* lint

* update lock

---------

Co-authored-by: fabianlars <fabianlars@fabianlars.de>
Co-authored-by: Brendan Allan <brendonovich@outlook.com>
Co-authored-by: Naman Garg <155433377+naman-crabnebula@users.noreply.github.com>
Co-authored-by: Lucas Nogueira <lucas@crabnebula.dev>
2024-08-02 10:45:47 -03:00

134 lines
3.4 KiB
Swift

// Copyright 2019-2023 Tauri Programme within The Commons Conservancy
// SPDX-License-Identifier: Apache-2.0
// SPDX-License-Identifier: MIT
import SwiftRs
import Tauri
import UIKit
import WebKit
import CoreHaptics
import AudioToolbox
class ImpactFeedbackOptions: Decodable {
let style: ImpactFeedbackStyle
}
enum ImpactFeedbackStyle: String, Decodable {
case light, medium, heavy, soft, rigid
func into() -> UIImpactFeedbackGenerator.FeedbackStyle {
switch self {
case .light:
return .light
case .medium:
return .medium
case .heavy:
return .heavy
case .soft:
return .soft
case .rigid:
return .rigid
}
}
}
class NotificationFeedbackOptions: Decodable {
let type: NotificationFeedbackType
}
enum NotificationFeedbackType: String, Decodable {
case success, warning, error
func into() -> UINotificationFeedbackGenerator.FeedbackType {
switch self {
case .success:
return .success
case .warning:
return .warning
case .error:
return .error
}
}
}
class VibrateOptions: Decodable {
// TODO: Array
let duration: Double
}
class HapticsPlugin: Plugin {
//
// Tauri commands
//
@objc public func vibrate(_ invoke: Invoke) throws {
let args = try invoke.parseArgs(VibrateOptions.self)
if CHHapticEngine.capabilitiesForHardware().supportsHaptics {
do {
let engine = try CHHapticEngine()
try engine.start()
engine.resetHandler = { [] in
do {
try engine.start()
} catch {
AudioServicesPlayAlertSound(kSystemSoundID_Vibrate)
}
}
// TODO: Make some of this (or all) configurable?
let intensity: CHHapticEventParameter = CHHapticEventParameter(parameterID: .hapticIntensity, value: 1.0)
let sharpness: CHHapticEventParameter = CHHapticEventParameter(parameterID: .hapticSharpness, value: 1.0)
let continuousEvent = CHHapticEvent(
eventType: .hapticContinuous,
parameters: [intensity, sharpness],
relativeTime: 0.0,
duration: args.duration/1000
)
let pattern = try CHHapticPattern(events: [continuousEvent], parameters: [])
let player = try engine.makePlayer(with: pattern)
try player.start(atTime: 0)
} catch {
AudioServicesPlayAlertSound(kSystemSoundID_Vibrate)
}
} else {
AudioServicesPlayAlertSound(kSystemSoundID_Vibrate)
}
Logger.error("VIBRATE END")
invoke.resolve()
}
@objc public func impactFeedback(_ invoke: Invoke) throws {
let args = try invoke.parseArgs(ImpactFeedbackOptions.self)
let generator = UIImpactFeedbackGenerator(style: args.style.into())
generator.prepare()
generator.impactOccurred()
invoke.resolve()
}
@objc public func notificationFeedback(_ invoke: Invoke) throws {
let args = try invoke.parseArgs(NotificationFeedbackOptions.self)
let generator = UINotificationFeedbackGenerator()
generator.prepare()
generator.notificationOccurred(args.type.into())
invoke.resolve()
}
// TODO: Consider breaking this up into Start,Change,End like capacitor
@objc public func selectionFeedback(_ invoke: Invoke) throws {
let generator = UISelectionFeedbackGenerator()
generator.prepare()
generator.selectionChanged()
invoke.resolve()
}
}
@_cdecl("init_plugin_haptics")
func initPlugin() -> Plugin {
return HapticsPlugin()
}