I'm programming a timer in SwiftUI. When my timer is finished, I want to make a haptic return, I want a rather heavy vibration like for alarm clocks on phones.
The problem is that when the haptic return occurs, nothing happens and I get an error on the terminal.
Here's the error: CAReportingClient.mm:532 Attempted to remove a reporter not created by this client { careporter_id=16 578 573 762 561 }
Here's my code:
import Foundation
import SwiftUI
import CoreHaptics
struct Exercice_TimerButton: View {
@State var totalSeconds: Int
@State public var remainingSeconds: Int
@State private var timer: Timer?
var body: some View {
ZStack(alignment:.leading) {
Rectangle()
.foregroundColor(Constants.color_background2)
.frame(width: width, height: height)
.cornerRadius(20)
Rectangle()
.foregroundColor(Constants.color_primaire2)
.frame(width: calculateProgressBarWidth(), height: height)
.cornerRadius(20)
Text("\(remainingSeconds) secondes")
.font(.system(size: 15, weight: .regular, width: .expanded))
.foregroundColor(Constants.color_text2)
.frame(width: UIScreen.main.bounds.width - 60, height:height)
}
.frame(width:CGFloat(UIScreen.screenWidth - 60),height:40)
.onAppear {
startTimer()
}
.padding(.all,35)
}
private func startTimer() {
timer = Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true) { timer in
withAnimation(.linear(duration: 1.0)) {
updateTimer()
}
}
}
private func updateTimer() {
guard remainingSeconds > 0 else {
// Timer completed, stop the timer
timer?.invalidate()
generateAlarmVibration() //HERE I WANT TO EXECUTE THE VIBRATIONS
return
}
remainingSeconds -= 1
}
private func calculateProgressBarWidth() -> CGFloat {
let progressPercentage = CGFloat(remainingSeconds) / CGFloat(totalSeconds)
return width * (1.0 - progressPercentage)
}
//FROM HERE ON, THE PART FOR HAPTIC FEEDBACK
private func generateAlarmVibration() {
// Create haptic events
let hapticEvents = createHapticEvents()
// Play haptic events
playHapticEvents(events: hapticEvents)
}
private func createHapticEvents() -> [CHHapticEvent] {
var events: [CHHapticEvent] = []
// First loop
for i in stride(from: 0, to: 1, by: 0.1) {
let intensity = CHHapticEventParameter(parameterID: .hapticIntensity, value: Float(i))
let sharpness = CHHapticEventParameter(parameterID: .hapticSharpness, value: Float(i))
let event = CHHapticEvent(eventType: .hapticTransient, parameters: [intensity, sharpness], relativeTime: i)
events.append(event)
}
// Second loop
for i in stride(from: 0, to: 1, by: 0.1) {
let intensity = CHHapticEventParameter(parameterID: .hapticIntensity, value: Float(1 - i))
let sharpness = CHHapticEventParameter(parameterID: .hapticSharpness, value: Float(1 - i))
let event = CHHapticEvent(eventType: .hapticTransient, parameters: [intensity, sharpness], relativeTime: 1 + i)
events.append(event)
}
return events
}
private func playHapticEvents(events: [CHHapticEvent]) {
// Check if the device supports haptic feedback
guard CHHapticEngine.capabilitiesForHardware().supportsHaptics else {
print("Device does not support haptic feedback.")
return
}
do {
// Create the haptic engine
let engine = try CHHapticEngine()
try engine.start()
// Create a haptic pattern
let pattern = try CHHapticPattern(events: events, parameters: [])
// Create a haptic player and play the pattern
let player = try engine.makePlayer(with: pattern)
try player.start(atTime: 0)
} catch let error {
print("Error creating haptic engine or playing pattern: \(error.localizedDescription)")
}
}
}
If you have any ideas, I'd love to hear from you, Thanks in advance.
I've tried several methods for the vibrations, the classic vibrations (success, error...) work well, but I'd like something more advanced. Every time it bells and I get the same error message.