kap kap - 3 months ago 66
iOS Question

iOS, locking the device from code

for testing purposes (making a screenshot of a local notification) i need to be able to lock the device (simulator) from code (either tests code or app code).
I've looked at a couple of answers from here (GSEventLockDevice), but they are quite old and didn't work for me

Answer

There is a private method in XCUIDevice, so you can lock device/simulator using it.

Example for Swift 3:

import XCTest

class LockTests: XCTestCase {
  func testExample() {
    XCUIDevice.shared().perform(NSSelectorFromString("pressLockButton"))

    let localNotification = UILocalNotification()
    localNotification.fireDate = Date(timeIntervalSinceNow: 2)
    localNotification.alertBody = "This is local notification"
    localNotification.timeZone = NSTimeZone.local
    localNotification.category = "Message"
    UIApplication.shared.scheduleLocalNotification(localNotification)
  }
}

And will receive something like this:

enter image description here

I have no experience with snapshot tool you are using, but you need to know that moving to locking state takes time, so it might be useful to wait a bit of time before creating snapshot (you can use code like this):

let date = Date(timeIntervalSinceNow: 3)
while date.timeIntervalSinceNow > 0 {
  CFRunLoopRunInMode(CFRunLoopMode.defaultMode, 0.1, true)
}

Also, you can return to SpringBoard in the end of the test by calling (iOS 10 only):

XCUIDevice.shared().press(.home)

Hope it helps!