cs193p – Lecture #13 Application Lifecycle and Core Motion

By Zina Deretsky, National Science Foundation (From [1]) [Public domain], via Wikimedia Commons

Please note, this blog entry is from a previous course. You might want to check out the current one.


Notifications provide a way to react to asynchronous events. e.g.:


func addObserverForName(String, // name of the "radio station"
    object: AnyObject?, // broadcaster (or nil for "anyone")
    queue: NSOperationQueue?) // queue to execute the closure on 
    { (notification: NSNotification) -> Void in
        let info: [NSObject:AnyObject]? = notification.userInfo // notification-specific information

Application Lifecycle

An app has four different states:

Application Lifecycle
Application Lifecycle

When in foreground, the app can either be inactive (running, but no UI events) or active (running, receiving and processing UI events).

In background code can run, but only for a limited time and without UI events.

When suspended, no code is running, and the app can be killed at any time.

When launching, the app goes from not running to inactive – the application delegate is called with didFinishLaunchingWithOptions, UIApplicationDidFinishLaunchingNotification is sent to any observer – and then to active – the application delegate is called with applicationDidBecomeActive, UIApplicationDidBecomeActiveNotification is sent to any observer.

When switching to another app, the app goes from active to inactive – the application delegate is called with applicationWillResignActive,UIApplicationWillResignActiveNotification is sent to any observer – to background – the application delegate is called with applicationDidEnterBackground, UIApplicationDidEnterBackgroundNotification is sent to any observer – and then to suspended.

When an app switches from background to foreground, the application delegete is called with applicationWillEnterForeground, UIApplicationWillEnterForegroundNotification is sent to any observer.

When an app gets killed it goes from suspended to not running – without any notification.

Other methods of the delegation methods are

  • local notifications – timers set to go off at certain times to wake the app if needed
    func (un)registerForRemoteNotifications()
    func scheduleLocalNotification(UILocalNotification)
    func registerUserNotificationSettings(UIUserNotificationSettings)
  • state restoration – saving the state of the UI to be able to restore it even if the app was killed
  • data protection – protecting files when the device’s screen is locked
  • open URL – opening registered for URLs
    func openURL(NSURL)
    func canOpenURL(NSURL) -> Bool
  • background fetching – fetching and receiving results in the background
    func setMinimumBackgroundFetchInterval(NSTimeInterval) // UIApplicationBackgroundFetchIntervalMinimum
    func backgroundTaskWithExpirationHandler(handler: () -> Void) -> UIBackgroundTaskIdentifier
  • var networkActivityIndicatorVisible: Bool
    var backgroundTimeRemaining: NSTimeInterval { get }
    preferredContentSizeCategory: String { get }
    var applicationState: UIApplicationState { get }

The just learned – including manipulating Info.plist – is shown in the Airdrop demo Trax.

Core Motion

  1. Check which hardware is available.
    var {accelerometer,gyro,magnetometer,deviceMotion}Available: Bool
  2. Start sampling ans poll the motion manager for the latest result.
    func start{Accelerometer,Gyro,Magnetometer,DeviceMotion}Updates()
    var {accelerometer,gyro,magnetometer,deviceMotion}Active: Bool
    var accelerometerData: CMAccelerometerData
    var acceleration: CMAcceleration
    var gravity: CMAcceleration
    var userAcceleration: CMAcceleration
    struct CMAcceleration {
        var x: Double // in g (9.8m/s/s) 
        var y: Double // in g 
        var z: Double // in g
    var gyroData: CMGyroData
    var rotationRate: CMRotationRate
    struct CMRotationRate {
        var x: Double // in radians/s 
        var y: Double // in radians/s 
        var z: Double // in radians/s
    var attitude: CMAttitude
    class CMAttitude: NSObject {
        var roll: Double
        var pitch: Double
        var yaw: Double
    var magneticField: CMCalibratedMagneticField
    struct CMCalibratedMagneticField {
          var field: CMMagneticField
          var accuracy: CMMagneticFieldCalibrationAccuracy
    var magnetometerData: CMMagnetometerData
    var magneticField: CMMagneticField
    struct CMMagneticField {
        var x: Double // in microteslas 
        var y: Double // in microteslas 
        var z: Double // in microteslas
  3. Stop sampling.
    func stop{Accelerometer,Gyro,Magnetometer,DeviceMotion}Updates()


  1. Set the rate for receiving new values
    var accelerometerUpdateInterval: NSTimeInterval
    var gyroUpdateInterval: NSTimeInterval
    var magnetometerUpdateInterval: NSTimeInterval
    var deviceMotionUpdateInterval: NSTimeInterval
  2. Register a closure to use those values
    func startAccelerometerUpdatesToQueue(queue: NSOperationQueue!,
                                    withHandler: CMAccelerometerHandler)
    typealias CMAccelerationHandler = (CMAccelerometerData!, NSError!) -> Void
    func startDeviceMotionUpdatesToQueue(queue: NSOperationQueue!,
                                   withHandler: CMDeviceMotionHandler)
    typealias CMDeviceMotionHandler = (CMDeviceMotion!, NSError!) -> Void

Core Motion is demonstrated in the Bouncer demo.

The lecture and its slides are available via iTunes named “13. Application Lifecycle and Core Motion”. The code for Trax is available on GitHub and at Stanford. The code for Bouncer is available on GitHub and at Stanford


Leave a Reply

Your email address will not be published.