weareopensource/Swift

View on GitHub
waosSwift/modules/app/AppDelegate.swift

Summary

Maintainability
A
0 mins
Test Coverage
/**
 * Dependencies
 */

import UIKit
import RxFlow
import ReactorKit
import UserNotifications

/**
 * Delegate
 */

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?

    let disposeBag = DisposeBag() // ReactorKit
    var coordinator = FlowCoordinator() //that handles the navigation between Flows.
    var appFlow: AppFlow! // represents the main navigation

    lazy var servicesProvider = {
        return AppServicesProvider()
    }()

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        guard let window = self.window else { return false }

        // MARK: Flow

//        self.coordinator.rx.willNavigate.subscribe(onNext: { (flow, step) in
//            log.debug("🚀 will nav to \(flow) & step \(step)")
//        }).disposed(by: self.disposeBag)
//
//        self.coordinator.rx.didNavigate.subscribe(onNext: { (flow, step) in
//            log.debug("🚀 did nav to \(flow) & step \(step)")
//        }).disposed(by: self.disposeBag)

        self.appFlow = AppFlow(withWindow: window, andServices: self.servicesProvider)

        coordinator.coordinate(flow: self.appFlow, with: AppStepper(withServices: self.servicesProvider))

        // MARK: Notifications

        if(config["notifications"].bool ?? false) {
            registerForPushNotifications()
            let notificationOption = launchOptions?[.remoteNotification]
            if let notification = notificationOption as? [String: AnyObject], let aps = notification["aps"] as? [String: AnyObject] {
                log.verbose("📱 Launched from notification notificationOption: \(String(describing: notificationOption))")
                log.verbose("📱 Launched from notification aps: \(aps)")
                handleNotification(aps: aps)
            }
        }

        return true
    }

    func application( _ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {

        // MARK: Notifications

        if(config["notifications"].bool ?? false) {
            let tokenParts = deviceToken.map { data in String(format: "%02.2hhx", data) }
            let token = tokenParts.joined()
            log.verbose("📱 Device Token: \(token)")
            self.servicesProvider.userService.updateDeviceToken(token)
        }
    }

    func application( _ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {

        // MARK: Notifications

        if(config["notifications"].bool ?? false) {
            log.error("📱 Failed to register: \(error)")
        }
    }

    func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any], fetchCompletionHandler completionHandler:@escaping (UIBackgroundFetchResult) -> Void) {

        // MARK: Notifications

        if(config["notifications"].bool ?? false) {
            guard let aps = userInfo["aps"] as? [String: AnyObject] else {
                completionHandler(.failed)
                return
            }
            log.debug("📱 Received notification aps: \(aps)")
            if (UIApplication.shared.applicationState != .active) {
                handleNotification(aps: aps)
            }
        }
    }

    // MARK: Notifications

    func registerForPushNotifications() {
        UNUserNotificationCenter.current().requestAuthorization(
            options: [.alert, .sound, .badge]) { [weak self] granted, _ in
            log.verbose("📱 Permission granted: \(granted)")
            guard granted else { return }
            self?.getNotificationSettings()
        }
    }

    func getNotificationSettings() {
        UNUserNotificationCenter.current().getNotificationSettings { settings in
            log.verbose("📱 Notification settings: \(settings)")
            guard settings.authorizationStatus == .authorized else { return }
            DispatchQueue.main.async {
                UIApplication.shared.registerForRemoteNotifications()
            }
        }
    }

    func handleNotification(aps: [String: AnyObject]) {
        // handling instrucions => action:id
        if let instrucion = aps["link_url"] as? String {
            let action = instrucion.split(separator: ":")
            if action.count == 2 {
                NotificationCenter.default.post(name: Notification.Name(String(action[0])), object: nil, userInfo: ["id": String(action[1])])
            }
        }
    }

}