iOS - Application Lifecycle Module
To receive application lifecycle events, a proper implementation of the
ApplicationLifecycleModule protocol is required. Q2MobileCore will interact with your
module for various application lifecycle events.
The ApplicationLifecycleModule interface is used when creating a module that needs to
respond to application lifecycle events. The implementation should be responsible for
handling various application states including launch, foreground/background transitions,
memory warnings, and termination events.
ApplicationLifecycleModule Methods
The module provides the following capabilities:
Launch Events
- application(_:didFinishLaunchingWithOptions:) - Called when the launch process is almost done and the app is almost ready to run
Foreground/Background Events
- applicationWillEnterForeground(_:) - Called when the app is about to enter the foreground
- applicationDidBecomeActive(_:) - Called when the app has become active
- applicationWillResignActive(_:) - Called when the app is about to become inactive
- applicationDidEnterBackground(_:) - Called when the app is now in the background
System Events
- applicationDidReceiveMemoryWarning(_:) - Called when the app receives a memory warning from the system
- applicationWillTerminate(_:) - Called when the app is about to terminate
- applicationSignificantTimeChange(_:) - Called when there is a significant change in the time
Protocol Definition
/// A type that handles events related to application lifecycle.
public protocol ApplicationLifecycleModule: LifecycleModule {
/// Tells the delegate that the launch process is almost done and the app is almost ready to run.
/// - Parameters:
/// - application: The singleton app object.
/// - launchOptions: A dictionary indicating the reason the app was launched (if any). The contents of this dictionary may be empty in situations where the user launched the app directly.
/// - Returns: `false` if the app cannot handle the URL resource or continue a user activity, otherwise return `true`. The return value is ignored if the app is launched as a result of a remote notification.
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool?
/// Tells the delegate that the app is about to enter the foreground.
/// - Parameter application: Your singleton app object.
func applicationWillEnterForeground(_ application: UIApplication)
/// Tells the delegate that the app has become active.
/// - Parameter application: Your singleton app object.
func applicationDidBecomeActive(_ application: UIApplication)
/// Tells the delegate that the app is about to become inactive.
/// - Parameter application: Your singleton app object.
func applicationWillResignActive(_ application: UIApplication)
/// Tells the delegate that the app is now in the background.
/// - Parameter application: Your singleton app object.
func applicationDidEnterBackground(_ application: UIApplication)
/// Tells the delegate when the app receives a memory warning from the system.
/// - Parameter application: Your singleton app object.
func applicationDidReceiveMemoryWarning(_ application: UIApplication)
/// Tells the delegate when the app is about to terminate.
/// - Parameter application: Your singleton app object.
func applicationWillTerminate(_ application: UIApplication)
/// Tells the delegate when there is a significant change in the time.
/// - Parameter application: Your singleton app object.
func applicationSignificantTimeChange(_ application: UIApplication)
}
Implementation
There are two ways to implement an ApplicationLifecycleModule depending on your needs:
Option 1: Inherit from Q2ModuleBase (Recommended)
If your module inherits from Q2ModuleBase, you only need to override the methods required
for your specific functionality. This approach provides default implementations for all
protocol methods, making your code cleaner and more focused.
import Q2ModuleInterfaces
class CustomApplicationLifecycleModule: Q2ModuleBase {
override func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool? {
print("CustomApplicationLifecycleModule: didFinishLaunchingWithOptions")
// Add your custom launch logic here
return nil
}
override func applicationWillEnterForeground(_ application: UIApplication) {
print("CustomApplicationLifecycleModule: applicationWillEnterForeground")
// Add your custom foreground logic here
}
override func applicationDidBecomeActive(_ application: UIApplication) {
print("CustomApplicationLifecycleModule: applicationDidBecomeActive")
// Add your custom activation logic here
}
override func applicationWillResignActive(_ application: UIApplication) {
print("CustomApplicationLifecycleModule: applicationWillResignActive")
// Add your custom deactivation logic here
}
override func applicationDidEnterBackground(_ application: UIApplication) {
print("CustomApplicationLifecycleModule: applicationDidEnterBackground")
// Add your custom background logic here
}
override func applicationDidReceiveMemoryWarning(_ application: UIApplication) {
print("CustomApplicationLifecycleModule: applicationDidReceiveMemoryWarning")
// Add your custom memory warning handling here
}
override func applicationWillTerminate(_ application: UIApplication) {
print("CustomApplicationLifecycleModule: applicationWillTerminate")
// Add your custom termination logic here
}
override func applicationSignificantTimeChange(_ application: UIApplication) {
print("CustomApplicationLifecycleModule: applicationSignificantTimeChange")
// Add your custom time change handling here
}
}
Option 2: Raw Implementation
For full control over all protocol methods, you can implement the ApplicationLifecycleModule
protocol directly by creating an NSObject class that conforms to all protocol requirements.
import Q2ModuleInterfaces
class CustomApplicationLifecycleModule: NSObject, ApplicationLifecycleModule {
var moduleDelegate: ModuleDelegate?
var moduleDataSource: ModuleDataSource?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool? {
print("CustomApplicationLifecycleModule: didFinishLaunchingWithOptions")
// Add your custom launch logic here
return nil
}
func applicationWillEnterForeground(_ application: UIApplication) {
print("CustomApplicationLifecycleModule: applicationWillEnterForeground")
// Add your custom foreground logic here
}
func applicationDidBecomeActive(_ application: UIApplication) {
print("CustomApplicationLifecycleModule: applicationDidBecomeActive")
// Add your custom activation logic here
}
func applicationWillResignActive(_ application: UIApplication) {
print("CustomApplicationLifecycleModule: applicationWillResignActive")
// Add your custom deactivation logic here
}
func applicationDidEnterBackground(_ application: UIApplication) {
print("CustomApplicationLifecycleModule: applicationDidEnterBackground")
// Add your custom background logic here
}
func applicationDidReceiveMemoryWarning(_ application: UIApplication) {
print("CustomApplicationLifecycleModule: applicationDidReceiveMemoryWarning")
// Add your custom memory warning handling here
}
func applicationWillTerminate(_ application: UIApplication) {
print("CustomApplicationLifecycleModule: applicationWillTerminate")
// Add your custom termination logic here
}
func applicationSignificantTimeChange(_ application: UIApplication) {
print("CustomApplicationLifecycleModule: applicationSignificantTimeChange")
// Add your custom time change handling here
}
// MARK: - Module Protocol Requirements
func log(_ message: String, level: LogLevel) {
print("CustomApplicationLifecycleModule: \(message)")
}
func logEvent(_ name: String, attributes: [String: Any]?) {
print("CustomApplicationLifecycleModule: Event - \(name), attributes: \(attributes ?? [:])")
}
func logError(error: Error, attributes: [String: Any]?) {
print("CustomApplicationLifecycleModule: Error - \(error), attributes: \(attributes ?? [:])")
}
}
Usage Example
Here's an example of how you might use an ApplicationLifecycleModule to track user
session analytics:
import Q2ModuleInterfaces
class SessionAnalyticsModule: Q2ModuleBase {
private var sessionStartTime: Date?
override func applicationDidBecomeActive(_ application: UIApplication) {
sessionStartTime = Date()
logEvent("session_started", attributes: ["timestamp": sessionStartTime?.timeIntervalSince1970])
}
override func applicationWillResignActive(_ application: UIApplication) {
guard let startTime = sessionStartTime else { return }
let sessionDuration = Date().timeIntervalSince(startTime)
logEvent("session_ended", attributes: [
"duration": sessionDuration,
"timestamp": Date().timeIntervalSince1970
])
}
override func applicationDidReceiveMemoryWarning(_ application: UIApplication) {
logEvent("memory_warning_received", attributes: ["timestamp": Date().timeIntervalSince1970])
}
}