Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[feature/postbuild-settings] Postbuild Settings #1179

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion ios-sdk
5 changes: 5 additions & 0 deletions ownCloud.xcodeproj/xcshareddata/xcschemes/ownCloud.xcscheme
Original file line number Diff line number Diff line change
Expand Up @@ -417,6 +417,11 @@
value = "31"
isEnabled = "NO">
</EnvironmentVariable>
<EnvironmentVariable
key = "oc:post-build.allowed-settings"
value = "[branding.app-name]"
isEnabled = "NO">
</EnvironmentVariable>
</EnvironmentVariables>
<AdditionalOptions>
<AdditionalOption
Expand Down
121 changes: 111 additions & 10 deletions ownCloud/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
url.matchesAppScheme { // + URL matches app scheme
guard let window = UserInterfaceContext.shared.currentWindow else { return false }

openPrivateLink(url: url, in: window)
openAppSchemeLink(url: url, in: window)
} else if url.isFileURL {
var copyBeforeUsing = true
if let shouldOpenInPlace = options[UIApplication.OpenURLOptionsKey.openInPlace] as? Bool {
Expand Down Expand Up @@ -211,7 +211,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate {

guard let window = UserInterfaceContext.shared.currentWindow else { return false }

openPrivateLink(url: url, in: window)
openAppSchemeLink(url: url, in: window)

return true
}
Expand All @@ -228,17 +228,114 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set<UISceneSession>) {
}

private func openPrivateLink(url:URL, in window:UIWindow) {
if UIApplication.shared.applicationState == .background {
// If the app is already running, just start link resolution
url.resolveAndPresent(in: window)
} else {
// MARK: - App Scheme URL handling
open func openAppSchemeLink(url: URL, in inWindow: UIWindow? = nil, scene: UIScene? = nil, autoDelay: Bool = true) {
guard let window = inWindow ?? (scene as? UIWindowScene)?.windows.first else { return }

if UIApplication.shared.applicationState != .background, autoDelay {
// Delay a resolution of private link on cold launch, since it could be that we would otherwise interfer
// with activities of the just instantiated ServerListTableViewController
OnMainThread(after:delayForLinkResolution) {
url.resolveAndPresent(in: window)
OnMainThread(after: delayForLinkResolution) {
self.openAppSchemeLink(url: url, in: window, autoDelay: false)
}

return
}

// App is already running, just start link resolution
if openPrivateLink(url: url, in: window) { return }
if openPostBuild(url: url, in: window) { return }
}

// MARK: Post Build
private func openPostBuild(url: URL, in window: UIWindow) -> Bool {
// owncloud://pb/[set|clear]/[all|flatID]/?[int|string|sarray]=[value]
/*
Examples:
owncloud://pb/set/branding.app-name?string=ocisCloud
owncloud://pb/clear/branding.app-name
owncloud://pb/clear/all
*/
if url.host == "pb" {
let components = url.pathComponents

if components.count >= 3 {
let command = components[1]
let targetID = components[2]
var relaunchReason: String?

switch command {
case "set":
if targetID == "all" { break }

let urlComponents = URLComponents(url: url, resolvingAgainstBaseURL: true)
if let queryItems = urlComponents?.queryItems {
for queryItem in queryItems {
if let value = queryItem.value {
switch queryItem.name {
case "int":
if let intVal = Int(value) as? NSNumber {
let error = OCClassSettingsFlatSourcePostBuild.sharedPostBuildSettings.setValue(intVal, forFlatIdentifier: targetID)
if error == nil {
relaunchReason = "Changed \(targetID) to int(\(intVal)).".localized
}
}

case "string":
let error = OCClassSettingsFlatSourcePostBuild.sharedPostBuildSettings.setValue(value, forFlatIdentifier: targetID)
if error == nil {
relaunchReason = "Changed \(targetID) to string(\(value)).".localized
}

case "sarray":
let strings = (value as NSString).components(separatedBy: ".")
let error = OCClassSettingsFlatSourcePostBuild.sharedPostBuildSettings.setValue(strings, forFlatIdentifier: targetID)
if error == nil {
relaunchReason = "Changed \(targetID) to stringArray(\(strings.joined(separator: ", "))).".localized
}

default: break
}
}
}
}

case "clear":
if targetID == "all" {
// Clear all post build settings
OCClassSettingsFlatSourcePostBuild.sharedPostBuildSettings.clear()
relaunchReason = "Cleared all.".localized
break
}

// Clear specific setting
let error = OCClassSettingsFlatSourcePostBuild.sharedPostBuildSettings.setValue(nil, forFlatIdentifier: targetID)
if error == nil {
relaunchReason = "Cleared \(targetID).".localized
}

default: break
}

if let relaunchReason {
OnMainThread {
self.offerRelaunchForReason(relaunchReason)
}
}
}
return true
}
return false
}

// MARK: Private Link
private func openPrivateLink(url: URL, in window: UIWindow) -> Bool {
if url.privateLinkItemID() != nil {
url.resolveAndPresent(in: window)
return true
}

return false
}
}

Expand Down Expand Up @@ -278,11 +375,15 @@ extension AppDelegate : NotificationResponseHandler {
}

@objc func offerRelaunchAfterMDMPush() {
offerRelaunchForReason("New settings received from MDM".localized)
}

func offerRelaunchForReason(_ reason: String) {
NotificationManager.shared.requestAuthorization(options: [.alert, .sound], completionHandler: { (granted, _) in
if granted {
let content = UNMutableNotificationContent()

content.title = "New settings received from MDM".localized
content.title = reason
content.body = "Tap to quit the app.".localized

let request = UNNotificationRequest(identifier: NotificationManagerComposeIdentifier(AppDelegate.self, "terminate-app"), content: content, trigger: nil)
Expand Down
21 changes: 6 additions & 15 deletions ownCloud/SceneDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate {
// Was the app launched with registered URL scheme?
if let urlContext = connectionOptions.urlContexts.first {
if urlContext.url.matchesAppScheme {
openPrivateLink(url: urlContext.url, in: scene)
openAppSchemeLink(url: urlContext.url, scene: scene)
} else {
ImportFilesController.shared.importFile(ImportFile(url: urlContext.url, fileIsLocalCopy: urlContext.options.openInPlace))
}
Expand Down Expand Up @@ -147,7 +147,7 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate {
if let firstURL = URLContexts.first?.url { // Ensure the set isn't empty
if !OCAuthenticationBrowserSessionCustomScheme.handleOpen(firstURL), // No custom scheme URL handling for this URL
firstURL.matchesAppScheme { // + URL matches app scheme
openPrivateLink(url: firstURL, in: scene)
openAppSchemeLink(url: firstURL, scene: scene)
} else {
if firstURL.isFileURL, // Ensure the URL is a file URL
ImportFilesController.shared.importAllowed(alertUserOtherwise: true) { // Ensure import is allowed
Expand All @@ -165,21 +165,12 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate {
return
}

guard let windowScene = scene as? UIWindowScene else { return }

guard let window = windowScene.windows.first else { return }

url.resolveAndPresent(in: window)
openAppSchemeLink(url: url, scene: scene)
}

private func openPrivateLink(url:URL, in scene:UIScene?) {
if url.privateLinkItemID() != nil {

guard let windowScene = scene as? UIWindowScene else { return }

guard let window = windowScene.windows.first else { return }

url.resolveAndPresent(in: window)
private func openAppSchemeLink(url: URL, scene: UIScene? = nil) {
if let appDelegate = UIApplication.shared.delegate as? AppDelegate {
appDelegate.openAppSchemeLink(url: url, scene: scene)
}
}
}