jjrscott

iOS Application state diagrams

Documents such as Managing Your App’s Life Cycle provides a good summary of an application’s lifecycle, but which UIApplicationDelegate methods and notifications are called (and when) is often hard to determine.

To improve my understanding, I set about creating a few method traces myself. Below is a selection of diagrams I made to understand the general application lifecycle and UITextField specifically.

Application lifecycle

App startup

With a storyboard defined in Info.plist

> [UIStoryboard instantiateInitialViewController]
  > [UIStoryboard instantiateInitialViewControllerWithCreator:]
    - [UIStoryboard instantiateViewControllerWithIdentifier:]
  < [UIStoryboard instantiateInitialViewControllerWithCreator:]
< [UIStoryboard instantiateInitialViewController]
- [UIApplicationDelegate application:supportedInterfaceOrientationsForWindow:]
- [UIApplicationDelegate application:willFinishLaunchingWithOptions:]
- [UIApplicationDelegate application:didFinishLaunchingWithOptions:]
- [UIApplicationDelegate applicationShouldAutomaticallyLocalizeKeyCommands:]
- [UIApplication beginIgnoringInteractionEvents]
- [UIApplicationDelegate application:supportedInterfaceOrientationsForWindow:]
- [UIApplication endIgnoringInteractionEvents]
- [UIApplicationDelegate application:supportedInterfaceOrientationsForWindow:]
* UIApplicationDidFinishLaunchingNotification
- [UIApplicationDelegate application:supportedInterfaceOrientationsForWindow:]
- [UIApplicationDelegate applicationDidBecomeActive:]
* UIApplicationDidBecomeActiveNotification

Tap Home button

While the keyboard is visible

- [UIApplicationDelegate applicationWillResignActive:]
* UIApplicationWillResignActiveNotification
- [UIApplicationDelegate applicationDidEnterBackground:]
* UIApplicationDidEnterBackgroundNotification
- [UIApplicationDelegate application:shouldSaveSecureApplicationState:]
- [UIApplicationDelegate application:willEncodeRestorableStateWithCoder:]
- [UIKeyInput hasText]
- [UIApplicationDelegate application:supportedInterfaceOrientationsForWindow:]

Reopen app

- [UIApplicationDelegate applicationWillEnterForeground:]
* UIApplicationWillEnterForegroundNotification
- [UIKeyInput hasText]
- [UIApplicationDelegate application:supportedInterfaceOrientationsForWindow:]
- [UIKeyInput hasText]
- [UIApplicationDelegate application:supportedInterfaceOrientationsForWindow:]
- [UIApplicationDelegate applicationDidBecomeActive:]
* UIApplicationDidBecomeActiveNotification

Double tap on Home

To bring up the mult-tasking screen

- [UIApplicationDelegate applicationWillResignActive:]
* UIApplicationWillResignActiveNotification

Terminate app

- [UIApplicationDelegate applicationDidEnterBackground:]
* UIApplicationDidEnterBackgroundNotification
- [UIApplicationDelegate applicationWillTerminate:]
* UIApplicationWillTerminateNotification

UITextField lifecycle

Tap on UITextField

> [UIApplication sendEvent:]
  // type: touches
  > [UIResponder touchesBegan:withEvent:]
    > [UIControl(Private) _sendActionsForEvents:withEvent:]
      // events: touch down, all touch events, all events
    < [UIControl(Private) _sendActionsForEvents:withEvent:]
  < [UIResponder touchesBegan:withEvent:]
< [UIApplication sendEvent:]
> [UIApplication sendEvent:]
  // type: touches
  > [UIApplication sendAction:to:from:forEvent:]
    > [UIResponder becomeFirstResponder]
      > [UIResponder canBecomeFirstResponder]
        - [UITextFieldDelegate textFieldShouldBeginEditing:]
      < [UIResponder canBecomeFirstResponder]
      > [UIControl(Private) _sendActionsForEvents:withEvent:]
        // events: editing did begin, all editing events, all events
      < [UIControl(Private) _sendActionsForEvents:withEvent:]
      - [UITextFieldDelegate textFieldDidBeginEditing:]
      * UITextFieldTextDidBeginEditingNotification
      - [UIKeyInput hasText]
      - [UIApplicationDelegate application:supportedInterfaceOrientationsForWindow:]
      - [UIKeyInput hasText]
      - [UIApplicationDelegate application:supportedInterfaceOrientationsForWindow:]
    < [UIResponder becomeFirstResponder]
    - [UIKeyInput hasText]
  < [UIApplication sendAction:to:from:forEvent:]
  > [UIResponder touchesCancelled:withEvent:]
    > [UIControl(Private) _sendActionsForEvents:withEvent:]
      // events: touch cancel, all touch events, all events
    < [UIControl(Private) _sendActionsForEvents:withEvent:]
  < [UIResponder touchesCancelled:withEvent:]
< [UIApplication sendEvent:]
- [UIApplication sendAction:to:from:forEvent:]

Tap on letter

> [UIApplication sendEvent:]
  // type: touches
  // window: UIRemoteKeyboardWindow
  - [UIKeyInput hasText]
< [UIApplication sendEvent:]
> [UIApplication sendEvent:]
  // type: touches
  // window: UIRemoteKeyboardWindow
  - [UIApplicationDelegate application:supportedInterfaceOrientationsForWindow:]
  - [UIKeyInput hasText]
  - [UITextFieldDelegate textField:shouldChangeCharactersInRange:replacementString:]
  - [UIKeyInput hasText]
< [UIApplication sendEvent:]
> [UIControl(Private) _sendActionsForEvents:withEvent:]
  // events: editing changed, all editing events, all events
< [UIControl(Private) _sendActionsForEvents:withEvent:]
* UITextFieldTextDidChangeNotification
- [UIKeyInput hasText]

Tap delete key

> [UIApplication sendEvent:]
  // type: touches
  // window: UIRemoteKeyboardWindow
  - [UIKeyInput hasText]
< [UIApplication sendEvent:]
- [UITextFieldDelegate textField:shouldChangeCharactersInRange:replacementString:]
- [UITextInput textInRange:]
- [UIKeyInput hasText]
> [UIKeyInput deleteBackward]
  > [UIControl(Private) _sendActionsForEvents:withEvent:]
    // events: editing changed, all editing events, all events
  < [UIControl(Private) _sendActionsForEvents:withEvent:]
  * UITextFieldTextDidChangeNotification
< [UIKeyInput deleteBackward]
- [UIKeyInput hasText]
> [UIApplication sendEvent:]
  // type: touches
  // window: UIRemoteKeyboardWindow
< [UIApplication sendEvent:]

Tap Return

> [UIApplication sendEvent:]
  // type: touches
  // window: UIRemoteKeyboardWindow
  - [UIKeyInput hasText]
< [UIApplication sendEvent:]
> [UIApplication sendEvent:]
  // type: touches
  // window: UIRemoteKeyboardWindow
  - [UITextFieldDelegate textFieldShouldReturn:]
  - [UIKeyInput hasText]
< [UIApplication sendEvent:]
> [UIControl(Private) _sendActionsForEvents:withEvent:]
  // events: editing did end on exit, all editing events, all events
  > [UIControl(Private) _sendActionsForEvents:withEvent:]
    // events: primary action triggered, all events
  < [UIControl(Private) _sendActionsForEvents:withEvent:]
< [UIControl(Private) _sendActionsForEvents:withEvent:]
- [UIKeyInput hasText]

Tap on different UITextField

> [UIApplication sendEvent:]
  // type: touches
< [UIApplication sendEvent:]
- [UIApplicationDelegate application:supportedInterfaceOrientationsForWindow:]
> [UIApplication sendEvent:]
  // type: touches
  > [UIApplication sendAction:to:from:forEvent:]
    > [UIResponder resignFirstResponder]
      > [UIResponder canResignFirstResponder]
        - [UITextFieldDelegate textFieldShouldEndEditing:]
      < [UIResponder canResignFirstResponder]
      - [UIKeyInput hasText]
      - [UITextInput unmarkText]
      > [UIControl(Private) _sendActionsForEvents:withEvent:]
        // events: editing did end, all editing events, all events
      < [UIControl(Private) _sendActionsForEvents:withEvent:]
      - [UITextFieldDelegate textFieldDidEndEditing:reason:]
      * UITextFieldTextDidEndEditingNotification
    < [UIResponder resignFirstResponder]
    - [UIApplicationDelegate application:supportedInterfaceOrientationsForWindow:]
  < [UIApplication sendAction:to:from:forEvent:]
< [UIApplication sendEvent:]
- [UIApplication sendAction:to:from:forEvent:]