Search code examples
swiftxcodeswiftuiwatchoshaptic-feedback

Cannot get Haptic Feedback to work with Swift


I'm a CS major in college who had an idea for an Apple Watch app that vibrates every time it reaches a certain time interval, for example the user picks intervals of 20s through a picker, taps "start" and the app starts a timer from 0 to 20 and once it reaches 20 I want the watch to vibrate and start counting up to 20 again until the user chooses to stop it. I want to use it for runners to have an idea of consistent paces to run. The problem is that I can't get UIImpactFeedbackGenerator to work and none of the other methods of haptic feedback either. I have no swift experience, only python and Java but I am basically done except for this haptic part. The one error I get is UIImpactFeedbackGenerator is out of scope where the generator is declared under SecondView. Thank you in advance! Here's my code:

import SwiftUI
    

struct ContentView: View {
    @State var timerScreenShown = false
    @State var timeVal = 10
    
    var body: some View {
        VStack{
            Text("Select \(timeVal)s intervals").padding()

            Picker(
                selection: $timeVal,
                label: Text("")){
                    ForEach(10...120, id: \.self) {
                        Text("\($0)")
                    }
                }
            
            NavigationLink(destination: SecondView(timerScreenShown: $timerScreenShown, timeVal: timeVal), isActive: $timerScreenShown, label: {Text("Go")})
            
        }
    }
}

struct SecondView: View{
    @Binding var timerScreenShown:Bool
    @State var timeVal = 10
    @State var startVal = 0
    
    var body: some View {
        VStack{
            if timeVal > 0 {
                Text("Timer")
                    .font(.system(size: 14))
                Text("\(startVal)")
                    .font(.system(size: 40))
                    .onAppear(){
                        Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true) { _ in
                            if self.timeVal > 0{
                                self.startVal += 1
                                if self.timeVal == self.startVal{
                                    
                                    let generator = UIImpactFeedbackGenerator(style: .medium)
                                    generator.impactOccurred()
                                    
                                    self.startVal = 0
                                }
                            }
                        }
                    }
                Text("seconds")
                    .font(.system(size: 14))
                Button(action: {
                    self.timerScreenShown = false
                }) {
                    Text("Cancel")
                        .foregroundColor(.red)
                }
            } else {
                Button(action: {
                    self.timerScreenShown = false
                }) {
                    Text("Done")
                        .foregroundColor(.green)
                }
            }
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        Group {
            ContentView()
            ContentView()
        }
    }
}

Solution

  • WatchOs does have the play(_:) - method for notification.

    try WKInterfaceDevice.current().play(.click)

    for more information take a look at the documentation -- https://developer.apple.com/documentation/watchkit/wkinterfacedevice/1628128-play