AppDelegate.swift 7.51 KB
Newer Older
Guillaume Roguez's avatar
Guillaume Roguez committed
1 2 3 4
/*
 *  Copyright (C) 2016 Savoir-faire Linux Inc.
 *
 *  Author: Edric Ladent-Milaret <edric.ladent-milaret@savoirfairelinux.com>
5
 *  Author: Romain Bertozzi <romain.bertozzi@savoirfairelinux.com>
Guillaume Roguez's avatar
Guillaume Roguez committed
6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.
 */

import UIKit
import CoreData

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?
29 30
    static let daemonService = DaemonService(dRingAdaptor: DRingAdapter())
    static let accountService = AccountsService(withAccountAdapter: AccountAdapter())
Guillaume Roguez's avatar
Guillaume Roguez committed
31

32
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
Romain Bertozzi's avatar
Romain Bertozzi committed
33
        SystemAdapter().registerConfigurationHandler()
34
        self.startDaemon()
Guillaume Roguez's avatar
Guillaume Roguez committed
35 36
        return true
    }
Edric Milaret's avatar
Edric Milaret committed
37

38
    func applicationWillResignActive(_ application: UIApplication) {
Guillaume Roguez's avatar
Guillaume Roguez committed
39 40 41 42
        // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
        // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
    }

43
    func applicationDidEnterBackground(_ application: UIApplication) {
Guillaume Roguez's avatar
Guillaume Roguez committed
44 45 46 47
        // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
        // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
    }

48
    func applicationWillEnterForeground(_ application: UIApplication) {
Guillaume Roguez's avatar
Guillaume Roguez committed
49 50 51
        // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
    }

52
    func applicationDidBecomeActive(_ application: UIApplication) {
Guillaume Roguez's avatar
Guillaume Roguez committed
53 54 55
        // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
    }

56
    func applicationWillTerminate(_ application: UIApplication) {
Guillaume Roguez's avatar
Guillaume Roguez committed
57
        self.saveContext()
58
        self.stopDaemon()
Guillaume Roguez's avatar
Guillaume Roguez committed
59 60 61 62
    }

    // MARK: - Core Data stack

63
    lazy var applicationDocumentsDirectory: URL = {
Guillaume Roguez's avatar
Guillaume Roguez committed
64
        // The directory the application uses to store the Core Data store file. This code uses a directory named "cx.ring.Ring" in the application's documents Application Support directory.
65
        let urls = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
Edric Milaret's avatar
Edric Milaret committed
66
        return urls[urls.count - 1]
Guillaume Roguez's avatar
Guillaume Roguez committed
67 68 69 70
    }()

    lazy var managedObjectModel: NSManagedObjectModel = {
        // The managed object model for the application. This property is not optional. It is a fatal error for the application not to be able to find and load its model.
71 72
        let modelURL = Bundle.main.url(forResource: "Ring", withExtension: "momd")!
        return NSManagedObjectModel(contentsOf: modelURL)!
Guillaume Roguez's avatar
Guillaume Roguez committed
73 74 75 76 77 78
    }()

    lazy var persistentStoreCoordinator: NSPersistentStoreCoordinator = {
        // The persistent store coordinator for the application. This implementation creates and returns a coordinator, having added the store for the application to it. This property is optional since there are legitimate error conditions that could cause the creation of the store to fail.
        // Create the coordinator and store
        let coordinator = NSPersistentStoreCoordinator(managedObjectModel: self.managedObjectModel)
79
        let url = self.applicationDocumentsDirectory.appendingPathComponent("SingleViewCoreData.sqlite")
Guillaume Roguez's avatar
Guillaume Roguez committed
80 81
        var failureReason = "There was an error creating or loading the application's saved data."
        do {
82
            try coordinator.addPersistentStore(ofType: NSSQLiteStoreType, configurationName: nil, at: url, options: nil)
Guillaume Roguez's avatar
Guillaume Roguez committed
83 84 85
        } catch {
            // Report any error we got.
            var dict = [String: AnyObject]()
86 87
            dict[NSLocalizedDescriptionKey] = "Failed to initialize the application's saved data" as AnyObject?
            dict[NSLocalizedFailureReasonErrorKey] = failureReason as AnyObject?
Guillaume Roguez's avatar
Guillaume Roguez committed
88 89 90 91 92 93 94 95

            dict[NSUnderlyingErrorKey] = error as NSError
            let wrappedError = NSError(domain: "YOUR_ERROR_DOMAIN", code: 9999, userInfo: dict)
            // Replace this with code to handle the error appropriately.
            // abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
            NSLog("Unresolved error \(wrappedError), \(wrappedError.userInfo)")
            abort()
        }
Edric Milaret's avatar
Edric Milaret committed
96

Guillaume Roguez's avatar
Guillaume Roguez committed
97 98 99 100 101 102
        return coordinator
    }()

    lazy var managedObjectContext: NSManagedObjectContext = {
        // Returns the managed object context for the application (which is already bound to the persistent store coordinator for the application.) This property is optional since there are legitimate error conditions that could cause the creation of the context to fail.
        let coordinator = self.persistentStoreCoordinator
103
        var managedObjectContext = NSManagedObjectContext(concurrencyType: .mainQueueConcurrencyType)
Guillaume Roguez's avatar
Guillaume Roguez committed
104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123
        managedObjectContext.persistentStoreCoordinator = coordinator
        return managedObjectContext
    }()

    // MARK: - Core Data Saving support

    func saveContext () {
        if managedObjectContext.hasChanges {
            do {
                try managedObjectContext.save()
            } catch {
                // Replace this implementation with code to handle the error appropriately.
                // abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
                let nserror = error as NSError
                NSLog("Unresolved error \(nserror), \(nserror.userInfo)")
                abort()
            }
        }
    }

124 125 126
    // MARK: - Ring Daemon
    fileprivate func startDaemon() {
        do {
127
            try AppDelegate.daemonService.startDaemon()
128 129 130 131 132 133 134 135 136 137 138 139 140
        } catch StartDaemonError.InitializationFailure {
            print("Daemon failed to initialize.")
        } catch StartDaemonError.StartFailure {
            print("Daemon failed to start.")
        } catch StartDaemonError.DaemonAlreadyRunning {
            print("Daemon already running.")
        } catch {
            print("Unknown error in Daemon start.")
        }
    }

    fileprivate func stopDaemon() {
        do {
141
            try AppDelegate.daemonService.stopDaemon()
142 143 144 145 146 147
        } catch StopDaemonError.DaemonNotRunning {
            print("Daemon failed to stop because it was not already running.")
        } catch {
            print("Unknown error in Daemon stop.")
        }
    }
Guillaume Roguez's avatar
Guillaume Roguez committed
148 149
}