Detecting shake in AppDelegate
Asked Answered
D

3

12

How can I detect a device shake in the AppDelegate (across the entire app) in Swift?

I've found answers that describe how to do so in a view controller, but looking to do so across my app.

Downhaul answered 13/1, 2016 at 17:20 Comment(1)
Possible duplicate of How do I detect when someone shakes an iPhone?Garotte
C
8

Add the following snippet in your AppDelegate:

override func motionBegan(motion: UIEvent.EventSubtype, withEvent event: UIEvent?) {
    if motion == .MotionShake {
        print("Device shaken")
    }
}

Swift 3.0 version:

override func motionBegan(_ motion: UIEventSubtype, with event: UIEvent?) {
    if motion == .motionShake {
        print("Device shaken")
    }
}

As for later versions this does not seem to work anymore. You need to add the above code in your view controller instead

Caylacaylor answered 13/1, 2016 at 18:5 Comment(6)
This did not work, since the app delegate is not in the responder chain.Rashidarashidi
@SaRaVaNaNDM, sure it is just tested it and have tested it before. Did you get any errors? How did you implement it?Caylacaylor
Same as the way you suggested in Swift 3.0 version. Do i need to do anything else ?Banff
That is enough with the code above. Are you trying on a real device? @SaRaVaNaNDMCaylacaylor
Worked on real device iPad 2/9.3, swift 3.0.2 for me.Thunderpeal
@SaRaVaNaNDM, this seems to be blocked now. You need to add the code in your view controller instead.Caylacaylor
P
32

If you want to globally detect shake motion, the UIWindow implements UIResponder that can receive shake motion event. You can add the following snippet to AppDelegate

extension UIWindow {
    open override func motionEnded(_ motion: UIEventSubtype, with event: UIEvent?) {
        if motion == .motionShake {
            print("Device shaken")
        }
    }
}
Polygraph answered 18/4, 2017 at 6:36 Comment(4)
This worked for me. Just adding it (without the UIWindow extension) didn't work when I put it in the app delegate. Had to add open in front of func for iOS 10.3/Xcode8.3.Caudate
Quite strange, motionBegan get called, but motionEnded doesn't.Sharyl
After trying many other solutions, this is the only one that works for me. Also, I learned that I can override functions in extensions. Awesome!Lunitidal
Bad idea to use the extension. Provide your own subclass, define the method in it. See https://mcmap.net/q/94227/-subclassing-uiwindow-while-using-storyboards . You can then pass the events to super - maybe they are needed there.Accumbent
C
8

Add the following snippet in your AppDelegate:

override func motionBegan(motion: UIEvent.EventSubtype, withEvent event: UIEvent?) {
    if motion == .MotionShake {
        print("Device shaken")
    }
}

Swift 3.0 version:

override func motionBegan(_ motion: UIEventSubtype, with event: UIEvent?) {
    if motion == .motionShake {
        print("Device shaken")
    }
}

As for later versions this does not seem to work anymore. You need to add the above code in your view controller instead

Caylacaylor answered 13/1, 2016 at 18:5 Comment(6)
This did not work, since the app delegate is not in the responder chain.Rashidarashidi
@SaRaVaNaNDM, sure it is just tested it and have tested it before. Did you get any errors? How did you implement it?Caylacaylor
Same as the way you suggested in Swift 3.0 version. Do i need to do anything else ?Banff
That is enough with the code above. Are you trying on a real device? @SaRaVaNaNDMCaylacaylor
Worked on real device iPad 2/9.3, swift 3.0.2 for me.Thunderpeal
@SaRaVaNaNDM, this seems to be blocked now. You need to add the code in your view controller instead.Caylacaylor
M
0

As of Swift 4 or 5, it's UIEvent.EventSubtype, not UIEventSubtype.

Also don't forget to add a call to super.motionEnded(motion, with: event). This preserves any motionEnded customizations on your view controllers.

extension UIWindow {
    open override func motionEnded(_ motion: UIEvent.EventSubtype, with event: UIEvent?) {
        super.motionEnded(motion, with: event)
        
        if motion == .motionShake {
            print("Device shaken")
        }
    }
}
Moustache answered 10/3, 2022 at 17:54 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.