| 1 | efrain | 1 | //
 | 
        
           |  |  | 2 | //  AppDelegate.swift
 | 
        
           |  |  | 3 | //  twogetskills
 | 
        
           |  |  | 4 | //
 | 
        
           |  |  | 5 | //  Created by Efrain Yanez Recanatini on 2/23/22.
 | 
        
           |  |  | 6 | //
 | 
        
           |  |  | 7 |   | 
        
           |  |  | 8 | import Foundation
 | 
        
           |  |  | 9 | import Firebase
 | 
        
           |  |  | 10 | import Messages
 | 
        
           |  |  | 11 | import BackgroundTasks
 | 
        
           | 17 | efrain | 12 | import SwiftUI
 | 
        
           | 1 | efrain | 13 |   | 
        
           |  |  | 14 | //UIResponder, UIApplicationDelegate {
 | 
        
           |  |  | 15 |   | 
        
           |  |  | 16 | class AppDelegate : NSObject, UIApplicationDelegate {
 | 
        
           | 17 | efrain | 17 |   | 
        
           | 1 | efrain | 18 |     private let gcmMessageIDKey = "gcm.message_id"
 | 
        
           | 21 | efrain | 19 |     private var appData = Environment(\.appData).wrappedValue
 | 
        
           | 17 | efrain | 20 |     public static var orientationLock = UIInterfaceOrientationMask.portrait
 | 
        
           |  |  | 21 |   | 
        
           | 1 | efrain | 22 |   | 
        
           | 17 | efrain | 23 |   | 
        
           | 1 | efrain | 24 |     func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
 | 
        
           |  |  | 25 |         return AppDelegate.orientationLock
 | 
        
           |  |  | 26 |     }
 | 
        
           |  |  | 27 |   | 
        
           |  |  | 28 |     func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions:
 | 
        
           |  |  | 29 |         [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
 | 
        
           |  |  | 30 |   | 
        
           | 17 | efrain | 31 |         /*        let database = Database.sharedInstance
 | 
        
           |  |  | 32 |         if database.open() != nil  {
 | 
        
           |  |  | 33 |             database.createTables()
 | 
        
           |  |  | 34 |         }
 | 
        
           | 1 | efrain | 35 |   | 
        
           | 17 | efrain | 36 |         */
 | 
        
           | 15 | efrain | 37 |   | 
        
           | 17 | efrain | 38 |         /*
 | 
        
           |  |  | 39 |         for  fontFamily in  UIFont.familyNames {
 | 
        
           |  |  | 40 |             for fontName in UIFont.fontNames(forFamilyName: fontFamily) {
 | 
        
           |  |  | 41 |                 print("\(fontName)")
 | 
        
           |  |  | 42 |             }
 | 
        
           |  |  | 43 |         }*/
 | 
        
           |  |  | 44 |   | 
        
           | 21 | efrain | 45 |   | 
        
           | 15 | efrain | 46 |   | 
        
           |  |  | 47 |   | 
        
           |  |  | 48 |   | 
        
           | 1 | efrain | 49 |   | 
        
           |  |  | 50 |   | 
        
           |  |  | 51 |         FirebaseApp.configure()
 | 
        
           |  |  | 52 |   | 
        
           | 15 | efrain | 53 |         Messaging.messaging().delegate = self
 | 
        
           | 1 | efrain | 54 |   | 
        
           | 15 | efrain | 55 |         if #available(iOS 10.0, *) {
 | 
        
           |  |  | 56 |             // For iOS 10 display notification (sent via APNS)
 | 
        
           |  |  | 57 |             UNUserNotificationCenter.current().delegate = self
 | 
        
           | 1 | efrain | 58 |   | 
        
           | 15 | efrain | 59 |             let authOptions: UNAuthorizationOptions = [.alert, .badge, .sound]
 | 
        
           |  |  | 60 |             UNUserNotificationCenter.current().requestAuthorization(
 | 
        
           |  |  | 61 |                 options: authOptions,
 | 
        
           |  |  | 62 |                 completionHandler: {_, _ in })
 | 
        
           |  |  | 63 |         } else {
 | 
        
           |  |  | 64 |             let settings: UIUserNotificationSettings =
 | 
        
           |  |  | 65 |                 UIUserNotificationSettings(types: [.alert, .badge, .sound], categories: nil)
 | 
        
           |  |  | 66 |             application.registerUserNotificationSettings(settings)
 | 
        
           |  |  | 67 |         }
 | 
        
           | 1 | efrain | 68 |   | 
        
           | 15 | efrain | 69 |         application.registerForRemoteNotifications()
 | 
        
           | 12 | efrain | 70 |   | 
        
           |  |  | 71 |   | 
        
           |  |  | 72 |   | 
        
           |  |  | 73 |         registerBGTasksScheduler()
 | 
        
           |  |  | 74 |         scheduleProcess()
 | 
        
           |  |  | 75 |         scheduleRefresh()
 | 
        
           |  |  | 76 |   | 
        
           |  |  | 77 |         return true
 | 
        
           | 1 | efrain | 78 |     }
 | 
        
           |  |  | 79 |   | 
        
           | 15 | efrain | 80 |     // Storage of the UID once the notification is received
 | 
        
           | 17 | efrain | 81 |     /*
 | 
        
           |  |  | 82 |      @objc func receivingNewDevice(n: NSNotification){
 | 
        
           | 15 | efrain | 83 |   | 
        
           |  |  | 84 |             print("receivingNewDevice")
 | 
        
           |  |  | 85 |             if n.userInfo != nil{
 | 
        
           |  |  | 86 |                 if let new_uuid = n.userInfo?["uuid"]! as? String {
 | 
        
           |  |  | 87 |                     let old_uuid = appData.deviceUuid
 | 
        
           |  |  | 88 |                     if new_uuid != old_uuid {
 | 
        
           |  |  | 89 |   | 
        
           | 17 | efrain | 90 |                         var sync = SyncModel()
 | 
        
           |  |  | 91 |                         sync.type = Constants.SYNC_ADAPTER_TYPE_DEVICE
 | 
        
           |  |  | 92 |                         sync.data = new_uuid
 | 
        
           | 15 | efrain | 93 |   | 
        
           | 17 | efrain | 94 |                         let syncDao = SyncDao()
 | 
        
           |  |  | 95 |                         if syncDao.insert(record: sync) > 0 {
 | 
        
           |  |  | 96 |                             appData.deviceUuid = new_uuid
 | 
        
           |  |  | 97 |                             appData.save()
 | 
        
           | 15 | efrain | 98 |   | 
        
           | 17 | efrain | 99 |                             syncAdapter.sync(isForeground: true) {
 | 
        
           |  |  | 100 |                                 success in
 | 
        
           | 15 | efrain | 101 |                             }
 | 
        
           |  |  | 102 |                         }
 | 
        
           |  |  | 103 |   | 
        
           |  |  | 104 |                     }
 | 
        
           |  |  | 105 |                 }
 | 
        
           |  |  | 106 |             }
 | 
        
           |  |  | 107 |         }
 | 
        
           |  |  | 108 |   | 
        
           |  |  | 109 |         @objc func receivingNewToken(n: NSNotification){
 | 
        
           |  |  | 110 |             if n.userInfo != nil{
 | 
        
           |  |  | 111 |                 if let token = n.userInfo?["token"]! as? String {
 | 
        
           |  |  | 112 |                     if !token.isEmpty {
 | 
        
           |  |  | 113 |                         if appData.fcmToken != token  {
 | 
        
           |  |  | 114 |   | 
        
           | 17 | efrain | 115 |                             var sync = SyncModel()
 | 
        
           |  |  | 116 |                             sync.data = token
 | 
        
           |  |  | 117 |                             sync.type = Constants.SYNC_ADAPTER_TYPE_FCM
 | 
        
           | 15 | efrain | 118 |   | 
        
           | 17 | efrain | 119 |                             let syncDao = SyncDao()
 | 
        
           |  |  | 120 |                             if syncDao.insert(record: sync) > 0 {
 | 
        
           |  |  | 121 |                                 appData.fcmToken = token
 | 
        
           |  |  | 122 |                                 appData.save()
 | 
        
           | 15 | efrain | 123 |   | 
        
           | 17 | efrain | 124 |                                 syncAdapter.sync(isForeground: true) {
 | 
        
           |  |  | 125 |                                     success in
 | 
        
           | 15 | efrain | 126 |                                 }
 | 
        
           |  |  | 127 |                             }
 | 
        
           | 17 | efrain | 128 |   | 
        
           | 15 | efrain | 129 |                         }
 | 
        
           |  |  | 130 |                    }
 | 
        
           |  |  | 131 |                }
 | 
        
           |  |  | 132 |            }
 | 
        
           | 17 | efrain | 133 |         }*/
 | 
        
           | 15 | efrain | 134 |   | 
        
           | 1 | efrain | 135 |     func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any],
 | 
        
           |  |  | 136 |                          fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
 | 
        
           |  |  | 137 |   | 
        
           |  |  | 138 |         if let messageID = userInfo[gcmMessageIDKey] {
 | 
        
           |  |  | 139 |             print("Message ID: \(messageID)")
 | 
        
           |  |  | 140 |         }
 | 
        
           |  |  | 141 |   | 
        
           |  |  | 142 |   | 
        
           |  |  | 143 |         processNotification(userInfo: userInfo, isForeground: false)
 | 
        
           |  |  | 144 |         completionHandler(UIBackgroundFetchResult.newData)
 | 
        
           |  |  | 145 |     }
 | 
        
           |  |  | 146 |   | 
        
           | 12 | efrain | 147 |     func registerBGTasksScheduler() {
 | 
        
           | 17 | efrain | 148 |         print("background :  registerBGTasksScheduler");
 | 
        
           | 12 | efrain | 149 |         BGTaskScheduler.shared.register(forTaskWithIdentifier: Constants.BACKGROUND_TASK_REFRESH, using: nil) { task in
 | 
        
           |  |  | 150 |                  self.handleRefreshTask(task: task as! BGAppRefreshTask)
 | 
        
           |  |  | 151 |         }
 | 
        
           |  |  | 152 |   | 
        
           |  |  | 153 |         BGTaskScheduler.shared.register(forTaskWithIdentifier: Constants.BACKGROUND_TASK_PROCESS, using: nil) { task in
 | 
        
           |  |  | 154 |                  self.handleProcessTask(task: task as! BGProcessingTask)
 | 
        
           |  |  | 155 |         }
 | 
        
           | 1 | efrain | 156 |   | 
        
           | 12 | efrain | 157 |     }
 | 
        
           |  |  | 158 |   | 
        
           |  |  | 159 |     func scheduleRefresh() {
 | 
        
           | 17 | efrain | 160 |         print("background: scheduleRefresh")
 | 
        
           | 12 | efrain | 161 |         let request = BGAppRefreshTaskRequest(identifier: Constants.BACKGROUND_TASK_REFRESH)
 | 
        
           |  |  | 162 |         request.earliestBeginDate = Date(timeIntervalSinceNow: 10 * 60)
 | 
        
           |  |  | 163 |   | 
        
           |  |  | 164 |   | 
        
           |  |  | 165 |   | 
        
           |  |  | 166 |         do {
 | 
        
           |  |  | 167 |              try BGTaskScheduler.shared.submit(request)
 | 
        
           |  |  | 168 |         } catch {
 | 
        
           | 17 | efrain | 169 |             print("background: Could not schedule app refresh: \(error)")
 | 
        
           | 12 | efrain | 170 |         }
 | 
        
           |  |  | 171 |     }
 | 
        
           |  |  | 172 |   | 
        
           |  |  | 173 |     func scheduleProcess() {
 | 
        
           | 17 | efrain | 174 |         print("background: scheduleProcess")
 | 
        
           | 12 | efrain | 175 |         let request = BGProcessingTaskRequest(identifier: Constants.BACKGROUND_TASK_PROCESS)
 | 
        
           |  |  | 176 |         request.earliestBeginDate = Date(timeIntervalSinceNow: 10 * 60)
 | 
        
           |  |  | 177 |         request.requiresNetworkConnectivity = true
 | 
        
           |  |  | 178 |         request.requiresExternalPower = false
 | 
        
           |  |  | 179 |   | 
        
           |  |  | 180 |         do {
 | 
        
           |  |  | 181 |             try BGTaskScheduler.shared.submit(request)
 | 
        
           |  |  | 182 |         } catch {
 | 
        
           | 17 | efrain | 183 |             print("background: Could not schedule processing: \(error)")
 | 
        
           | 12 | efrain | 184 |         }
 | 
        
           |  |  | 185 |     }
 | 
        
           |  |  | 186 |   | 
        
           |  |  | 187 |     func handleProcessTask(task: BGProcessingTask) {
 | 
        
           |  |  | 188 |         scheduleProcess()
 | 
        
           | 17 | efrain | 189 |         print("background: handleProcessTask")
 | 
        
           | 12 | efrain | 190 |   | 
        
           |  |  | 191 |         let syncAdapter = SyncAdapter()
 | 
        
           | 15 | efrain | 192 |         syncAdapter.sync(isForeground: false) { success in
 | 
        
           | 12 | efrain | 193 |             task.setTaskCompleted(success: success)
 | 
        
           |  |  | 194 |         }
 | 
        
           |  |  | 195 |   | 
        
           |  |  | 196 |         task.setTaskCompleted(success: true)
 | 
        
           |  |  | 197 |     }
 | 
        
           |  |  | 198 |   | 
        
           |  |  | 199 |     func handleRefreshTask(task: BGAppRefreshTask) {
 | 
        
           |  |  | 200 |         scheduleRefresh()
 | 
        
           |  |  | 201 |   | 
        
           | 17 | efrain | 202 |         print("background: handleRefreshTask")
 | 
        
           | 12 | efrain | 203 |   | 
        
           |  |  | 204 |         let syncAdapter = SyncAdapter()
 | 
        
           |  |  | 205 |         if syncAdapter.isCheckChangesRequired() {
 | 
        
           |  |  | 206 |             syncAdapter.checkChanges(isForeground: false) { success in
 | 
        
           |  |  | 207 |                 task.setTaskCompleted(success: success)
 | 
        
           |  |  | 208 |             }
 | 
        
           |  |  | 209 |         } else {
 | 
        
           |  |  | 210 |             task.expirationHandler = {
 | 
        
           |  |  | 211 |                 task.setTaskCompleted(success: false)
 | 
        
           |  |  | 212 |              }
 | 
        
           |  |  | 213 |         }
 | 
        
           |  |  | 214 |   | 
        
           |  |  | 215 |   | 
        
           |  |  | 216 |         task.setTaskCompleted(success: true)
 | 
        
           |  |  | 217 |     }
 | 
        
           | 1 | efrain | 218 |   | 
        
           | 12 | efrain | 219 |   | 
        
           |  |  | 220 |   | 
        
           | 1 | efrain | 221 | }
 | 
        
           |  |  | 222 |   | 
        
           |  |  | 223 | extension AppDelegate: MessagingDelegate {
 | 
        
           |  |  | 224 |   | 
        
           |  |  | 225 |     func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String?) {
 | 
        
           |  |  | 226 |   | 
        
           | 17 | efrain | 227 |   | 
        
           | 1 | efrain | 228 |         let token = fcmToken ?? ""
 | 
        
           | 15 | efrain | 229 |         print( "MessagingDelegate didReceiveRegistrationToken: \(token)")
 | 
        
           | 1 | efrain | 230 |   | 
        
           | 15 | efrain | 231 |         let userInfo = ["token": token]
 | 
        
           | 17 | efrain | 232 |         NotificationCenter.default.post(name: Constants.NOTIFICATION_NAME_FCM_REGISTER_NAME , object: self, userInfo: userInfo)
 | 
        
           | 15 | efrain | 233 |   | 
        
           | 1 | efrain | 234 |   | 
        
           | 15 | efrain | 235 |   | 
        
           | 1 | efrain | 236 |     }
 | 
        
           |  |  | 237 | }
 | 
        
           |  |  | 238 |   | 
        
           |  |  | 239 | @available(iOS 10, *)
 | 
        
           |  |  | 240 | extension AppDelegate : UNUserNotificationCenterDelegate {
 | 
        
           |  |  | 241 |   | 
        
           |  |  | 242 |   // Receive displayed notifications for iOS 10 devices.
 | 
        
           |  |  | 243 |   func userNotificationCenter(_ center: UNUserNotificationCenter,
 | 
        
           |  |  | 244 |                               willPresent notification: UNNotification,
 | 
        
           |  |  | 245 |     withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
 | 
        
           |  |  | 246 |     let userInfo = notification.request.content.userInfo
 | 
        
           |  |  | 247 |   | 
        
           |  |  | 248 |     if let messageID = userInfo[gcmMessageIDKey] {
 | 
        
           |  |  | 249 |         print("Message ID: \(messageID)")
 | 
        
           |  |  | 250 |     }
 | 
        
           |  |  | 251 |   | 
        
           |  |  | 252 |     processNotification(userInfo: userInfo, isForeground: true)
 | 
        
           |  |  | 253 |     completionHandler([[.banner, .badge, .sound]])
 | 
        
           |  |  | 254 |   }
 | 
        
           |  |  | 255 |   | 
        
           |  |  | 256 |     private func processNotification(userInfo : [AnyHashable : Any], isForeground : Bool) {
 | 
        
           |  |  | 257 |         let now = Date()
 | 
        
           |  |  | 258 |         let dateFormatter = DateFormatter()
 | 
        
           |  |  | 259 |         dateFormatter.dateFormat = Constants.FORMAT_DATE_YMD
 | 
        
           |  |  | 260 |   | 
        
           |  |  | 261 |         let timeFormatter = DateFormatter()
 | 
        
           |  |  | 262 |         timeFormatter.dateFormat = Constants.FORMAT_TIME_12
 | 
        
           |  |  | 263 |   | 
        
           |  |  | 264 |   | 
        
           |  |  | 265 |         guard let apsDict = userInfo["aps"]as?[String:Any] else {return}
 | 
        
           |  |  | 266 |         guard let alertDict = apsDict["alert"]as?[String:Any]else {return}
 | 
        
           |  |  | 267 |   | 
        
           |  |  | 268 |   | 
        
           |  |  | 269 |         let title = alertDict["title"]  as? String ?? ""
 | 
        
           |  |  | 270 |         let body = alertDict["body"]  as? String ?? ""
 | 
        
           |  |  | 271 |         let url = userInfo.index(forKey: "url")  == nil ?  "" : userInfo["url"] as? String ?? ""
 | 
        
           |  |  | 272 |         let command = userInfo.index(forKey: "command") == nil ? "" : userInfo["command"] as? String ?? ""
 | 
        
           |  |  | 273 |         let newCapsules = userInfo.index(forKey: "new_capsules") == nil ? 0 : Int(userInfo["new_capsules"] as? String ?? "") ?? 0
 | 
        
           |  |  | 274 |   | 
        
           |  |  | 275 |   | 
        
           |  |  | 276 |         if command == "signout" {
 | 
        
           | 17 | efrain | 277 |             let userinfo = [
 | 
        
           |  |  | 278 |                 "is_foreground" : (isForeground ? "1" : "0")
 | 
        
           |  |  | 279 |             ]
 | 
        
           |  |  | 280 |   | 
        
           |  |  | 281 |             NotificationCenter.default.post(name: Constants.NOTIFICATION_NAME_COMMAND_EXIT , object: self, userInfo: userinfo)
 | 
        
           | 1 | efrain | 282 |         }
 | 
        
           |  |  | 283 |         else if command == "content-refresh" {
 | 
        
           |  |  | 284 |             let userinfo = [
 | 
        
           |  |  | 285 |                 "title" : title,
 | 
        
           |  |  | 286 |                 "body" : body,
 | 
        
           |  |  | 287 |                 "new_capsules" : String(newCapsules),
 | 
        
           |  |  | 288 |                 "is_foreground" : (isForeground ? "1" : "0")
 | 
        
           |  |  | 289 |             ]
 | 
        
           |  |  | 290 |   | 
        
           |  |  | 291 |             NotificationCenter.default.post(name: Constants.NOTIFICATION_NAME_COMMAND_REFRESH_CONTENT , object: self, userInfo: userinfo)
 | 
        
           |  |  | 292 |         } else {
 | 
        
           |  |  | 293 |   | 
        
           |  |  | 294 |             let userinfo = [
 | 
        
           |  |  | 295 |                 "title" : title,
 | 
        
           |  |  | 296 |                 "body" : body,
 | 
        
           |  |  | 297 |                 "url" : url,
 | 
        
           |  |  | 298 |             ]
 | 
        
           |  |  | 299 |   | 
        
           |  |  | 300 |             NotificationCenter.default.post(name: Constants.NOTIFICATION_NAME_PUSH , object: self, userInfo: userInfo)
 | 
        
           |  |  | 301 |   | 
        
           |  |  | 302 |   | 
        
           |  |  | 303 |         }
 | 
        
           |  |  | 304 |     }
 | 
        
           |  |  | 305 |   | 
        
           |  |  | 306 |     func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
 | 
        
           |  |  | 307 |   | 
        
           | 15 | efrain | 308 |         print( "didRegisterForRemoteNotificationsWithDeviceToken")
 | 
        
           | 1 | efrain | 309 |   | 
        
           | 17 | efrain | 310 |   | 
        
           |  |  | 311 |   | 
        
           | 15 | efrain | 312 |         let tokenParts = deviceToken.map { data in String(format: "%02.2hhx", data) }
 | 
        
           |  |  | 313 |         let token = tokenParts.joined()
 | 
        
           | 1 | efrain | 314 |             print("token: ", token)
 | 
        
           | 15 | efrain | 315 |   | 
        
           | 1 | efrain | 316 |   | 
        
           | 15 | efrain | 317 |         let userInfo = ["token": token]
 | 
        
           | 17 | efrain | 318 |         NotificationCenter.default.post(name: Constants.NOTIFICATION_NAME_FCM_REGISTER_NAME , object: self, userInfo: userInfo)
 | 
        
           | 15 | efrain | 319 |   | 
        
           | 1 | efrain | 320 |     }
 | 
        
           |  |  | 321 |   | 
        
           |  |  | 322 |   | 
        
           |  |  | 323 |   | 
        
           |  |  | 324 |     func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
 | 
        
           |  |  | 325 |         print( "didFailToRegisterForRemoteNotificationsWithError")
 | 
        
           |  |  | 326 |     }
 | 
        
           |  |  | 327 |   | 
        
           |  |  | 328 |   func userNotificationCenter(_ center: UNUserNotificationCenter,
 | 
        
           |  |  | 329 |                               didReceive response: UNNotificationResponse,
 | 
        
           |  |  | 330 |                               withCompletionHandler completionHandler: @escaping () -> Void) {
 | 
        
           |  |  | 331 |     let userInfo = response.notification.request.content.userInfo
 | 
        
           |  |  | 332 |   | 
        
           |  |  | 333 |     if let messageID = userInfo[gcmMessageIDKey] {
 | 
        
           |  |  | 334 |       print("Message ID from userNotificationCenter didReceive: \(messageID)")
 | 
        
           |  |  | 335 |     }
 | 
        
           |  |  | 336 |   | 
        
           |  |  | 337 |   | 
        
           |  |  | 338 |     processNotification(userInfo: userInfo, isForeground: true)
 | 
        
           |  |  | 339 |   | 
        
           |  |  | 340 |     completionHandler()
 | 
        
           |  |  | 341 |   }
 | 
        
           |  |  | 342 | }
 |