-1

I'm creating a simple game in Swift. If the time is almost over (5 seconds) I would like to vibrate the phone.

When 5 or 4 seconds left: normal vibration with AudioServicesPlaySystemSound(kSystemSoundID_Vibrate) once per second.

Question 1:

When 3 or 2 seconds left: short vibration, twice per second. When 1 second left, short vibration, thrice per second.

Question 2:

When 0 seconds left, vibrate for 2 or 3 seconds.

Is this possible? How can I change the duration of the vibration? I read online that increasing the duration of the vibration is not allowed, thats fine for me, but can I decrease the duration?

I have already checked How to make iPhone vibrate using Swift? but this question from 2014 did not cover Swift 3 or 4. If I try to play the sound 1519, 1520 or 1521 it just does nothing. The answer posted by Malmer only targets iPhone's with a haptic feedback. I want to find a solution for the iPhone 6s and lower, since they still run the newest iOS (11) and are able to run short vibrations when you're browsing through the iOS Settings for notification sounds.

Kevin
  • 2,760
  • 3
  • 15
  • 30
  • 1
    Possible duplicate of [How to make iPhone vibrate using Swift?](https://stackoverflow.com/questions/26455880/how-to-make-iphone-vibrate-using-swift) – nathangitter Nov 07 '17 at 15:21
  • I did find that post, but it did not provide a way of doing this in Swift 3 or 4 on iPhones older than the iPhone 7. – Kevin Nov 07 '17 at 15:24
  • Did you see this answer? https://stackoverflow.com/a/42990919/6658553 Otherwise there is no API for shorter vibrations pre-iPhone 7. – nathangitter Nov 07 '17 at 15:26

3 Answers3

2

In terms of vibrating the device, possibilities are very limited. As far as I know, this is the only method available (if you need to support all iPhones):

AudioServicesPlayAlertSound(SystemSoundID(kSystemSoundID_Vibrate))

From the docs: "function to invoke a brief vibration. On the iPod touch, does nothing.".

You would have to create som logic in order for this to repeat. One solution could be to use the NSTimer API. E.g. scheduledTimerWithTimeInterval.

Example implementation:

var gameTimer: Timer!

// Execute doTimedStuff method every 2 seconds
gameTimer = Timer.scheduledTimer(timeInterval: 2, target: self, selector: #selector(doTimedStuff), userInfo: nil, repeats: true)

// Invalidate timer when done
gameTimer.invalidate()
oyvindhauge
  • 3,496
  • 2
  • 29
  • 45
  • Do iPads have vibration? AudioServicesPlayAlertSound(SystemSoundID(kSystemSoundID_Vibrate)) doesn't work on iPad 6th gen. – drewster Jul 09 '18 at 20:27
0

One option is to use UIFeedbackGenerator to produce haptic feedback. Documentation Link

This allows you to choose from a few pre-set haptic vibrations, which you can fire at your desired time intervals.

Here is a quick example, although make sure you visit the documentation linked above for all the haptic feedback options and best practices.

let feedbackGenerator = UISelectionFeedbackGenerator()
feedbackGenerator.prepare()
feedbackGenerator.selectionChanged()

(Note that this only works on iPhone 7 and newer devices.)

nathangitter
  • 9,607
  • 3
  • 33
  • 42
  • Hmm yeah I'd like to find a solution for shorter feedback to also work on iPhones before the iPhone 7. You can, for example, select different notification vibration patterns in the iOS settings app, so I hoped app developers could use these patterns too. – Kevin Nov 07 '17 at 15:17
0

Use .hapticContinuous event type with CHHapticEvent. You can customize the the time of vibration and intensity of vibrations.

let intensity = CHHapticEventParameter(parameterID: .hapticIntensity, value: 1.0)
let sharpness = CHHapticEventParameter(parameterID: .hapticSharpness, value: 0.5) 

var events = [CHHapticEvent]()
var relativeTimer = 0.0

let event1 = CHHapticEvent(eventType: .hapticContinuous, parameters: [intensity, sharpness], relativeTime: relativeTimer, duration: longDuration)
            relativeTimer += event1.duration
            events.append(event1)
 do {
        let pattern = try CHHapticPattern(events: events, parameters: [])
        let player = try engine.makePlayer(with: pattern)

        try engine.start()
        try player.start(atTime: 0)
    } catch {
        print("Haptic Error: \(error.localizedDescription).")
    }
Naren
  • 115
  • 2
  • 14