mirror of
https://github.com/Ranchero-Software/NetNewsWire
synced 2025-08-12 06:26:36 +00:00
download themes using url scheme
this build enables iOS functionality only.
This commit is contained in:
@@ -9,15 +9,16 @@
|
||||
import UIKit
|
||||
import UserNotifications
|
||||
import Account
|
||||
import Zip
|
||||
|
||||
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
|
||||
class SceneDelegate: UIResponder, UIWindowSceneDelegate, URLSessionDownloadDelegate {
|
||||
|
||||
var window: UIWindow?
|
||||
var window: UIWindow?
|
||||
var coordinator = SceneCoordinator()
|
||||
|
||||
// UIWindowScene delegate
|
||||
|
||||
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
|
||||
// UIWindowScene delegate
|
||||
|
||||
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
|
||||
|
||||
window = UIWindow(windowScene: scene as! UIWindowScene)
|
||||
window!.tintColor = AppAssets.primaryAccentColor
|
||||
@@ -46,12 +47,12 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate {
|
||||
return
|
||||
}
|
||||
|
||||
if let userActivity = connectionOptions.userActivities.first ?? session.stateRestorationActivity {
|
||||
if let userActivity = connectionOptions.userActivities.first ?? session.stateRestorationActivity {
|
||||
coordinator.handle(userActivity)
|
||||
}
|
||||
|
||||
window!.makeKeyAndVisible()
|
||||
}
|
||||
}
|
||||
|
||||
func windowScene(_ windowScene: UIWindowScene, performActionFor shortcutItem: UIApplicationShortcutItem, completionHandler: @escaping (Bool) -> Void) {
|
||||
appDelegate.resumeDatabaseProcessingIfNecessary()
|
||||
@@ -79,9 +80,9 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate {
|
||||
coordinator.resetFocus()
|
||||
}
|
||||
|
||||
func stateRestorationActivity(for scene: UIScene) -> NSUserActivity? {
|
||||
func stateRestorationActivity(for scene: UIScene) -> NSUserActivity? {
|
||||
return coordinator.stateRestorationActivity
|
||||
}
|
||||
}
|
||||
|
||||
// API
|
||||
|
||||
@@ -89,7 +90,7 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate {
|
||||
appDelegate.resumeDatabaseProcessingIfNecessary()
|
||||
coordinator.handle(response)
|
||||
}
|
||||
|
||||
|
||||
func suspend() {
|
||||
coordinator.suspend()
|
||||
}
|
||||
@@ -165,8 +166,69 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate {
|
||||
let filename = context.url.standardizedFileURL.path
|
||||
if filename.hasSuffix(ArticleTheme.nnwThemeSuffix) {
|
||||
self.coordinator.importTheme(filename: filename)
|
||||
return
|
||||
}
|
||||
|
||||
// Handle theme URLs: netnewswire://theme/add?url={url}
|
||||
guard let comps = URLComponents(url: context.url, resolvingAgainstBaseURL: false),
|
||||
"theme" == comps.host,
|
||||
let queryItems = comps.queryItems else {
|
||||
return
|
||||
}
|
||||
|
||||
if let providedThemeURL = queryItems.first(where: { $0.name == "url" })?.value {
|
||||
if let themeURL = URL(string: providedThemeURL) {
|
||||
let request = URLRequest(url: themeURL)
|
||||
let session = URLSession(configuration: .default, delegate: self, delegateQueue: nil)
|
||||
let downloadTask = session.downloadTask(with: request)
|
||||
downloadTask.resume()
|
||||
} else {
|
||||
print("No theme URL")
|
||||
return
|
||||
}
|
||||
} else {
|
||||
return
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - URLSessionDownloadDelegate
|
||||
|
||||
func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didFinishDownloadingTo location: URL) {
|
||||
var downloadDirectory = FileManager.default.urls(for: .downloadsDirectory, in: .userDomainMask).first!
|
||||
try? FileManager.default.createDirectory(at: downloadDirectory, withIntermediateDirectories: true, attributes: nil)
|
||||
let tmpFileName = UUID().uuidString + ".zip"
|
||||
downloadDirectory.appendPathComponent("\(tmpFileName)")
|
||||
|
||||
do {
|
||||
try FileManager.default.moveItem(at: location, to: downloadDirectory)
|
||||
|
||||
var unzippedDir = downloadDirectory
|
||||
unzippedDir = unzippedDir.deletingLastPathComponent()
|
||||
unzippedDir.appendPathComponent("newtheme.nnwtheme")
|
||||
|
||||
try Zip.unzipFile(downloadDirectory, destination: unzippedDir, overwrite: true, password: nil, progress: nil, fileOutputHandler: nil)
|
||||
try FileManager.default.removeItem(at: downloadDirectory)
|
||||
|
||||
let decoder = PropertyListDecoder()
|
||||
let plistURL = URL(fileURLWithPath: unzippedDir.appendingPathComponent("Info.plist").path)
|
||||
|
||||
let data = try Data(contentsOf: plistURL)
|
||||
let plist = try decoder.decode(ArticleThemePlist.self, from: data)
|
||||
|
||||
// rename
|
||||
var renamedUnzippedDir = unzippedDir.deletingLastPathComponent()
|
||||
renamedUnzippedDir.appendPathComponent(plist.name + ".nnwtheme")
|
||||
if FileManager.default.fileExists(atPath: renamedUnzippedDir.path) {
|
||||
try FileManager.default.removeItem(at: renamedUnzippedDir)
|
||||
}
|
||||
try FileManager.default.moveItem(at: unzippedDir, to: renamedUnzippedDir)
|
||||
DispatchQueue.main.async {
|
||||
self.coordinator.importTheme(filename: renamedUnzippedDir.path)
|
||||
}
|
||||
} catch {
|
||||
print(error)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user