5 // Created by Pawel Dabrowski on 29/03/2018.
6 // Copyright © 2018 Fundacja Nowoczesna Polska. All rights reserved.
17 import UserNotifications
20 class AppDelegate: UIResponder, UIApplicationDelegate {
23 var windowHud: MBProgressHUD?
24 var mainNavigator: MainNavigator!
25 var syncManager = SyncManager()
26 weak var sideMenuNavigationController: UINavigationController?
27 weak var safariParentViewController: UIViewController?
28 let gcmMessageIDKey = "gcm.message_id"
32 guard let window = window else {return}
34 if let windowHud = windowHud {
35 windowHud.show(animated: true)
38 windowHud = MBProgressHUD.showAdded(to: window, animated: true)
43 windowHud?.hide(animated: true)
46 var backgroundSessionCompletionHandler : (() -> Void)?
48 func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
49 // Override point for customization after application launch.
51 Fabric.with([Crashlytics.self])
52 FirebaseApp.configure()
54 mainNavigator = MainNavigator(window: window!)
57 if syncManager.isLoggedIn(){
61 // configureMessaging(application: application)
66 func configureMessaging(application: UIApplication) {
67 // [START set_messaging_delegate]
68 Messaging.messaging().delegate = self
69 // [END set_messaging_delegate]
71 // Register for remote notifications. This shows a permission dialog on first run, to
72 // show the dialog at a more appropriate time move this registration accordingly.
73 // [START register_for_notifications]
74 if #available(iOS 10.0, *) {
75 // For iOS 10 display notification (sent via APNS)
76 UNUserNotificationCenter.current().delegate = self
78 let authOptions: UNAuthorizationOptions = [.alert, .badge, .sound]
79 UNUserNotificationCenter.current().requestAuthorization(
81 completionHandler: {_, _ in })
83 let settings: UIUserNotificationSettings =
84 UIUserNotificationSettings(types: [.alert, .badge, .sound], categories: nil)
85 application.registerUserNotificationSettings(settings)
88 application.registerForRemoteNotifications()
90 // [END register_for_notifications]
93 func setCustomAppearance() {
95 UINavigationBar.appearance().isTranslucent = false
96 UINavigationBar.appearance().tintColor = .white
97 UINavigationBar.appearance().titleTextAttributes = [NSAttributedStringKey.foregroundColor : UIColor.white]
98 UINavigationBar.appearance().barTintColor = Constants.Colors.navbarBgColor()
99 UINavigationBar.appearance().barStyle = .blackOpaque
100 UIApplication.shared.statusBarStyle = .lightContent
103 func applicationWillResignActive(_ application: UIApplication) {
104 // 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.
105 // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.
108 func applicationDidEnterBackground(_ application: UIApplication) {
109 // 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.
110 // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
113 func applicationWillEnterForeground(_ application: UIApplication) {
114 // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
117 func applicationDidBecomeActive(_ application: UIApplication) {
118 // 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.
119 mainNavigator.updateSettingsViewIfPresented()
122 func applicationWillTerminate(_ application: UIApplication) {
123 // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
126 func application(_ application: UIApplication, handleEventsForBackgroundURLSession identifier: String, completionHandler: @escaping () -> Void) {
127 backgroundSessionCompletionHandler = completionHandler
130 func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool {
132 applicationHandle(url: url)
136 private func applicationHandle(url: URL) {
137 if url.host == Constants.callbackOauthHost {
139 syncManager.accessToken { (result) in
142 case .success(let model):
143 self.syncManager.updateUserCredentials(oAuthTokenModel: (model as! OAuthTokenModel))
144 self.safariParentViewController?.presentedViewController?.dismiss(animated: true, completion: nil)
145 self.mainNavigator.presentLibrary(dismissSideMenu: true)
148 case .failure/*(let error)*/:
153 else if url.host == Constants.callbackPaypalSuccessHost {
154 self.safariParentViewController?.presentedViewController?.dismiss(animated: true, completion: nil)
155 safariParentViewController?.presentToast(message: "premium_purchase_succeeded".localized)
156 DatabaseManager.shared.setUserPremium()
157 mainNavigator.reset()
159 else if url.host == Constants.callbackPaypalErrorHost {
160 self.safariParentViewController?.presentedViewController?.dismiss(animated: true, completion: nil)
161 safariParentViewController?.presentToast(message: "premium_purchase_failed".localized)
165 private func fetchUsername(){
167 self.syncManager.getUsername(completionHandler: { (result) in
170 case .success(let model):
171 DatabaseManager.shared.updateUser(usernameModel: model as? UsernameModel)
172 self.mainNavigator.setLoggedIn()
174 case .failure/*(let error)*/:
175 //We can download username later
176 self.mainNavigator.setLoggedIn()
182 func login(fromViewController: UIViewController){
183 let oauthswift = OAuth1Swift(
184 consumerKey: Config.CONSUMER_KEY,
185 consumerSecret: Config.CONSUMER_SECRET,
186 requestTokenUrl: Config.OAUTH_REQUEST_TOKEN,
187 authorizeUrl: Config.OAUTH_AUTHORIZE,
188 accessTokenUrl: Config.OAUTH_ACCESS_TOKEN
191 safariParentViewController = fromViewController
193 let handler = SafariURLHandler(viewController: fromViewController, oauthSwift: oauthswift)
194 handler.presentCompletion = {
195 print("Safari presented")
197 handler.dismissCompletion = {
198 print("Safari dismissed")
200 handler.factory = { url in
201 let controller = SFSafariViewController(url: url)
202 // Customize it, for instance
203 if #available(iOS 10.0, *) {
204 // controller.preferredBarTintColor = UIColor.red
209 oauthswift.authorizeURLHandler = handler
211 syncManager.requestToken { (result) in
214 case .success(let model):
215 let url = URL(string: String(format: Constants.authorizationUrlFormat, (model as! OAuthTokenModel).token))
216 oauthswift.authorizeURLHandler.handle(url!)
218 case .failure/*(let error)*/:
224 func presentPaypal(fromViewController: UIViewController) {
226 let controller = SFSafariViewController(url: URL(string: Constants.webPaypalFormUrl)!)
227 safariParentViewController = fromViewController
228 fromViewController.present(controller, animated: true, completion: nil)
232 // ############################################
234 // ############################################
236 // [START receive_message]
237 func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any]) {
238 // If you are receiving a notification message while your app is in the background,
239 // this callback will not be fired till the user taps on the notification launching the application.
240 // TODO: Handle data of notification
242 // With swizzling disabled you must let Messaging know about the message, for Analytics
243 // Messaging.messaging().appDidReceiveMessage(userInfo)
246 if let messageID = userInfo[gcmMessageIDKey] {
247 print("Message ID: \(messageID)")
250 // Print full message.
254 func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any],
255 fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
256 // If you are receiving a notification message while your app is in the background,
257 // this callback will not be fired till the user taps on the notification launching the application.
258 // TODO: Handle data of notification
260 // With swizzling disabled you must let Messaging know about the message, for Analytics
261 // Messaging.messaging().appDidReceiveMessage(userInfo)
264 if let messageID = userInfo[gcmMessageIDKey] {
265 print("Message ID: \(messageID)")
268 // Print full message.
271 completionHandler(UIBackgroundFetchResult.newData)
273 // [END receive_message]
275 func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
276 print("Unable to register for remote notifications: \(error.localizedDescription)")
279 // This function is added here only for debugging purposes, and can be removed if swizzling is enabled.
280 // If swizzling is disabled then this function must be implemented so that the APNs token can be paired to
281 // the FCM registration token.
282 func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
283 print("APNs token retrieved: \(deviceToken)")
285 // With swizzling disabled you must set the APNs token here.
286 // Messaging.messaging().apnsToken = deviceToken
290 // [START ios_10_message_handling]
291 @available(iOS 10, *)
292 extension AppDelegate : UNUserNotificationCenterDelegate {
294 // Receive displayed notifications for iOS 10 devices.
295 func userNotificationCenter(_ center: UNUserNotificationCenter,
296 willPresent notification: UNNotification,
297 withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
298 let userInfo = notification.request.content.userInfo
300 // With swizzling disabled you must let Messaging know about the message, for Analytics
301 // Messaging.messaging().appDidReceiveMessage(userInfo)
304 if let messageID = userInfo[gcmMessageIDKey] {
305 print("Message ID: \(messageID)")
308 // Print full message.
311 // Change this to your preferred presentation option
312 completionHandler([])
315 func userNotificationCenter(_ center: UNUserNotificationCenter,
316 didReceive response: UNNotificationResponse,
317 withCompletionHandler completionHandler: @escaping () -> Void) {
318 let userInfo = response.notification.request.content.userInfo
320 if let messageID = userInfo[gcmMessageIDKey] {
321 print("Message ID: \(messageID)")
324 // Print full message.
330 // [END ios_10_message_handling]
333 extension AppDelegate : MessagingDelegate {
334 // [START refresh_token]
335 func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String) {
336 print("Firebase registration token: \(fcmToken)")
338 let dataDict:[String: String] = ["token": fcmToken]
340 Messaging.messaging().subscribe(toTopic: "wolnelektury")
341 // NotificationCenter.default.post(name: Notification.Name("FCMToken"), object: nil, userInfo: dataDict)
342 // TODO: If necessary send token to application server.
343 // Note: This callback is fired at each app startup and whenever a new token is generated.
345 // [END refresh_token]
347 // [START ios_10_data_message]
348 // Receive data messages on iOS 10+ directly from FCM (bypassing APNs) when the app is in the foreground.
349 // To enable direct data messages, you can set Messaging.messaging().shouldEstablishDirectChannel to true.
350 func messaging(_ messaging: Messaging, didReceive remoteMessage: MessagingRemoteMessage) {
351 print("Received data message: \(remoteMessage.appData)")
353 // [END ios_10_data_message]