diff --git a/ios-sdk b/ios-sdk index e774c7523..4783fc3a6 160000 --- a/ios-sdk +++ b/ios-sdk @@ -1 +1 @@ -Subproject commit e774c7523d48b16ce5321fa167688311d04b2537 +Subproject commit 4783fc3a6a5c5ec1d0fabfdec950e8b219ba29d5 diff --git a/ownCloud/AppDelegate.swift b/ownCloud/AppDelegate.swift index 0bafce07e..5fbe5c248 100644 --- a/ownCloud/AppDelegate.swift +++ b/ownCloud/AppDelegate.swift @@ -153,17 +153,19 @@ class AppDelegate: UIResponder, UIApplicationDelegate { return true } - // If the app was re-installed, make sure to wipe keychain data. Since iOS 10.3 keychain entries are not deleted if the app is deleted, but since everything else is lost, - // it might lead to some inconsistency in the app state. Nevertheless we shall be careful here and consider that prior versions of the app didn't have the flag created upon - // very first app launch in UserDefaults. Thus we will check few more factors: no bookmarks configured and no passcode is set - if OCBookmarkManager.shared.bookmarks.count == 0 && AppLockManager.shared.lockEnabled == false { - VendorServices.shared.onFirstLaunch { - OCAppIdentity.shared.keychain?.wipe() - } - } + // If the app was re-installed, make sure to wipe keychain data. Since iOS 10.3 keychain entries are not deleted if the app is deleted, but since everything else is lost, + // it might lead to some inconsistency in the app state. Nevertheless we shall be careful here and consider that prior versions of the app didn't have the flag created upon + // very first app launch in UserDefaults. Thus we will check few more factors: no bookmarks configured and no passcode is set + if OCBookmarkManager.shared.bookmarks.count == 0 && AppLockManager.shared.lockEnabled == false { + VendorServices.shared.onFirstLaunch { + OCAppIdentity.shared.keychain?.wipe() + } + } setupAndHandleCrashReports() + setupMDMPushRelaunch() + return true } @@ -271,3 +273,34 @@ extension AppDelegate { crashReporter.enable() } } + +extension AppDelegate : NotificationResponseHandler { + func setupMDMPushRelaunch() { + NotificationCenter.default.addObserver(self, selector: #selector(offerRelaunchAfterMDMPush), name: .OCClassSettingsManagedSettingsChanged, object: nil) + } + + @objc func offerRelaunchAfterMDMPush() { + NotificationManager.shared.requestAuthorization(options: [.alert, .sound], completionHandler: { (granted, _) in + if granted { + let content = UNMutableNotificationContent() + + content.title = "New settings received from MDM".localized + content.body = "Tap to quit the app.".localized + + let request = UNNotificationRequest(identifier: NotificationManagerComposeIdentifier(AppDelegate.self, "terminate-app"), content: content, trigger: nil) + + NotificationManager.shared.add(request, withCompletionHandler: { (_) in }) + } + }) + } + + static func handle(_ center: UNUserNotificationCenter, response: UNNotificationResponse, identifier: String, completionHandler: @escaping () -> Void) { + if identifier == "terminate-app", response.actionIdentifier == UNNotificationDefaultActionIdentifier { + UNUserNotificationCenter.postLocalNotification(with: "mdm-relaunch", title: "Tap to launch the app.".localized, body: nil, after: 0.1) { (error) in + if error == nil { + exit(0) + } + } + } + } +} diff --git a/ownCloud/Resources/en.lproj/Localizable.strings b/ownCloud/Resources/en.lproj/Localizable.strings index 82076d6fd..3f6f8ae5f 100644 --- a/ownCloud/Resources/en.lproj/Localizable.strings +++ b/ownCloud/Resources/en.lproj/Localizable.strings @@ -846,3 +846,8 @@ "Limited Photo Access" = "Limited Photo Access"; "Access for the media selected for upload is limited" = "Access for the media selected for upload is limited"; "No Access to the media selected for upload" = "No Access to the media selected for upload"; + +/* MDM settings push */ +"New settings received from MDM" = "New settings received from MDM"; +"Tap to quit the app." = "Tap to quit the app."; +"Tap to launch the app." = "Tap to launch the app."; diff --git a/ownCloud/Tasks/UNUserNotificationCenter+Extensions.swift b/ownCloud/Tasks/UNUserNotificationCenter+Extensions.swift index 13bf556d0..081454232 100644 --- a/ownCloud/Tasks/UNUserNotificationCenter+Extensions.swift +++ b/ownCloud/Tasks/UNUserNotificationCenter+Extensions.swift @@ -7,26 +7,29 @@ // /* -* Copyright (C) 2020, ownCloud GmbH. -* -* This code is covered by the GNU Public License Version 3. -* -* For distribution utilizing Apple mechanisms please see https://owncloud.org/contribute/iOS-license-exception/ -* You should have received a copy of this license along with this program. If not, see . -* -*/ + * Copyright (C) 2020, ownCloud GmbH. + * + * This code is covered by the GNU Public License Version 3. + * + * For distribution utilizing Apple mechanisms please see https://owncloud.org/contribute/iOS-license-exception/ + * You should have received a copy of this license along with this program. If not, see . + * + */ import UserNotifications import ownCloudApp extension UNUserNotificationCenter { - class func postLocalNotification(with identifier:String, title:String, body:String, after:TimeInterval = 0.5, completion:((Error?) -> Void)? = nil) { + class func postLocalNotification(with identifier:String, title:String, body:String?, after:TimeInterval = 0.5, completion:((Error?) -> Void)? = nil) { NotificationManager.shared.getNotificationSettings(completionHandler: { (settings) in if settings.authorizationStatus == .authorized { let content = UNMutableNotificationContent() content.title = title - content.body = body + + if let body = body { + content.body = body + } let trigger = UNTimeIntervalNotificationTrigger(timeInterval: after, repeats: false) diff --git a/ownCloudAppFramework/Notifications/NotificationManager.h b/ownCloudAppFramework/Notifications/NotificationManager.h index c928814d7..4fc3e75d8 100644 --- a/ownCloudAppFramework/Notifications/NotificationManager.h +++ b/ownCloudAppFramework/Notifications/NotificationManager.h @@ -34,7 +34,8 @@ NS_ASSUME_NONNULL_BEGIN - (void)requestAuthorizationWithOptions:(UNAuthorizationOptions)options completionHandler:(void (^)(BOOL granted, NSError *__nullable error))completionHandler; @end -#define ComposeNotificationIdentifier(aClass,identifier) [NSStringFromClass(aClass.class) stringByAppendingFormat:@":%@", identifier] +NSString *NotificationManagerComposeIdentifier(Class aClass, NSString *identifier); +#define ComposeNotificationIdentifier(aClass,identifier) NotificationManagerComposeIdentifier(aClass.class, identifier) @protocol NotificationResponseHandler + (void)handleNotificationCenter:(UNUserNotificationCenter *)center response:(UNNotificationResponse *)response identifier:(NSString *)identifier completionHandler:(dispatch_block_t)completionHandler; diff --git a/ownCloudAppFramework/Notifications/NotificationManager.m b/ownCloudAppFramework/Notifications/NotificationManager.m index 38e815379..a7d1698df 100644 --- a/ownCloudAppFramework/Notifications/NotificationManager.m +++ b/ownCloudAppFramework/Notifications/NotificationManager.m @@ -135,3 +135,8 @@ - (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNoti } @end + +NSString *NotificationManagerComposeIdentifier(Class aClass, NSString *identifier) +{ + return ([NSStringFromClass(aClass) stringByAppendingFormat:@":%@", identifier]); +}