From 3d9417c071aa66a6f3b961739a80af442f302703 Mon Sep 17 00:00:00 2001 From: Riley Testut Date: Mon, 13 Jul 2020 17:59:52 -0700 Subject: [PATCH] Switches to UIScene-based lifecycle --- AltStore.xcodeproj/project.pbxproj | 4 ++ AltStore/AppDelegate.swift | 29 +++++++++++++ AltStore/Info.plist | 21 ++++++++++ AltStore/SceneDelegate.swift | 52 ++++++++++++++++++++++++ AltStoreCore/Model/DatabaseManager.swift | 43 +++++++++++--------- 5 files changed, 130 insertions(+), 19 deletions(-) create mode 100644 AltStore/SceneDelegate.swift diff --git a/AltStore.xcodeproj/project.pbxproj b/AltStore.xcodeproj/project.pbxproj index 01aea842..ebe68293 100644 --- a/AltStore.xcodeproj/project.pbxproj +++ b/AltStore.xcodeproj/project.pbxproj @@ -112,6 +112,7 @@ BF45884A2298D55000BD7491 /* thread.c in Sources */ = {isa = PBXBuildFile; fileRef = BF4588482298D55000BD7491 /* thread.c */; }; BF45884B2298D55000BD7491 /* thread.h in Headers */ = {isa = PBXBuildFile; fileRef = BF4588492298D55000BD7491 /* thread.h */; }; BF4588882298DD3F00BD7491 /* libxml2.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = BF4588872298DD3F00BD7491 /* libxml2.tbd */; }; + BF4B78FE24B3D1DB008AB4AC /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF4B78FD24B3D1DB008AB4AC /* SceneDelegate.swift */; }; BF56D2AC23DF8E170006506D /* FetchAppIDsOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF56D2AB23DF8E170006506D /* FetchAppIDsOperation.swift */; }; BF56D2AF23DF9E310006506D /* AppIDsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF56D2AE23DF9E310006506D /* AppIDsViewController.swift */; }; BF58047E246A28F7008AE704 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF58047D246A28F7008AE704 /* AppDelegate.swift */; }; @@ -500,6 +501,7 @@ BF4588872298DD3F00BD7491 /* libxml2.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libxml2.tbd; path = Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk/usr/lib/libxml2.tbd; sourceTree = DEVELOPER_DIR; }; BF4588962298DE6E00BD7491 /* libzip.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = libzip.framework; sourceTree = BUILT_PRODUCTS_DIR; }; BF4713A422976CFC00784A2F /* openssl.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = openssl.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + BF4B78FD24B3D1DB008AB4AC /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; }; BF56D2AB23DF8E170006506D /* FetchAppIDsOperation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FetchAppIDsOperation.swift; sourceTree = ""; }; BF56D2AE23DF9E310006506D /* AppIDsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppIDsViewController.swift; sourceTree = ""; }; BF58047B246A28F7008AE704 /* AltBackup.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = AltBackup.app; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -1298,6 +1300,7 @@ children = ( BF219A7E22CAC431007676A6 /* AltStore.entitlements */, BFD2476D2284B9A500981D42 /* AppDelegate.swift */, + BF4B78FD24B3D1DB008AB4AC /* SceneDelegate.swift */, BFD247732284B9A500981D42 /* Main.storyboard */, BFE338E722F10E56002E24B9 /* LaunchViewController.swift */, BF41B805233423AE00C593A3 /* TabBarController.swift */, @@ -2291,6 +2294,7 @@ BF9ABA4922DD0742008935CF /* ScreenshotCollectionViewCell.swift in Sources */, BF9ABA4D22DD16DE008935CF /* PillButton.swift in Sources */, BFE6326C22A86FF300F30809 /* AuthenticationOperation.swift in Sources */, + BF4B78FE24B3D1DB008AB4AC /* SceneDelegate.swift in Sources */, BF6C8FB02429599900125131 /* TextCollectionReusableView.swift in Sources */, BF663C4F2433ED8200DAA738 /* FileManager+DirectorySize.swift in Sources */, BFB6B220231870B00022A802 /* NewsCollectionViewCell.swift in Sources */, diff --git a/AltStore/AppDelegate.swift b/AltStore/AppDelegate.swift index dd39953a..ea57446b 100644 --- a/AltStore/AppDelegate.swift +++ b/AltStore/AppDelegate.swift @@ -73,6 +73,17 @@ class AppDelegate: UIResponder, UIApplicationDelegate { func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { + DatabaseManager.shared.start { (error) in + if let error = error + { + print("Failed to start DatabaseManager. Error:", error as Any) + } + else + { + print("Started DatabaseManager.") + } + } + AnalyticsManager.shared.start() self.setTintColor() @@ -119,6 +130,24 @@ class AppDelegate: UIResponder, UIApplicationDelegate { } } +@available(iOS 13, *) +extension AppDelegate +{ + func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration + { + // Called when a new scene session is being created. + // Use this method to select a configuration to create the new scene with. + return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role) + } + + func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set) + { + // Called when the user discards a scene session. + // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions. + // Use this method to release any resources that were specific to the discarded scenes, as they will not return. + } +} + private extension AppDelegate { func setTintColor() diff --git a/AltStore/Info.plist b/AltStore/Info.plist index 50995dd1..37f0e89a 100644 --- a/AltStore/Info.plist +++ b/AltStore/Info.plist @@ -85,6 +85,27 @@ NSLocalNetworkUsageDescription AltStore uses the local network to find and communicate with AltServer. + UIApplicationSceneManifest + + UIApplicationSupportsMultipleScenes + + UISceneConfigurations + + UIWindowSceneSessionRoleApplication + + + UILaunchStoryboardName + LaunchScreen + UISceneConfigurationName + Default Configuration + UISceneDelegateClassName + $(PRODUCT_MODULE_NAME).SceneDelegate + UISceneStoryboardFile + Main + + + + UIBackgroundModes audio diff --git a/AltStore/SceneDelegate.swift b/AltStore/SceneDelegate.swift new file mode 100644 index 00000000..602b6f8f --- /dev/null +++ b/AltStore/SceneDelegate.swift @@ -0,0 +1,52 @@ +// +// SceneDelegate.swift +// AltStore +// +// Created by Riley Testut on 7/6/20. +// Copyright © 2020 Riley Testut. All rights reserved. +// + +import UIKit +import AltStoreCore + +@available(iOS 13, *) +class SceneDelegate: UIResponder, UIWindowSceneDelegate +{ + var window: UIWindow? + + func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) + { + // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`. + // If using a storyboard, the `window` property will automatically be initialized and attached to the scene. + // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead). + guard let _ = (scene as? UIWindowScene) else { return } + } + + func sceneWillEnterForeground(_ scene: UIScene) + { + // Called as the scene transitions from the background to the foreground. + // Use this method to undo the changes made on entering the background. + + // applicationWillEnterForeground is _not_ called when launching app, + // whereas sceneWillEnterForeground _is_ called when launching. + // As a result, DatabaseManager might not be started yet, so just return if it isn't + // (since all these methods are called separately during app startup). + guard DatabaseManager.shared.isStarted else { return } + + AppManager.shared.update() + ServerManager.shared.startDiscovering() + + PatreonAPI.shared.refreshPatreonAccount() + } + + func sceneDidEnterBackground(_ scene: UIScene) + { + // Called as the scene transitions from the foreground to the background. + // Use this method to save data, release shared resources, and store enough scene-specific state information + // to restore the scene back to its current state. + + guard UIApplication.shared.applicationState == .background else { return } + + ServerManager.shared.stopDiscovering() + } +} diff --git a/AltStoreCore/Model/DatabaseManager.swift b/AltStoreCore/Model/DatabaseManager.swift index 844979ff..d351002d 100644 --- a/AltStoreCore/Model/DatabaseManager.swift +++ b/AltStoreCore/Model/DatabaseManager.swift @@ -20,6 +20,7 @@ public class DatabaseManager public private(set) var isStarted = false private var startCompletionHandlers = [(Error?) -> Void]() + private let dispatchQueue = DispatchQueue(label: "io.altstore.DatabaseManager") private init() { @@ -32,30 +33,34 @@ public extension DatabaseManager { func start(completionHandler: @escaping (Error?) -> Void) { - self.startCompletionHandlers.append(completionHandler) - - guard self.startCompletionHandlers.count == 1 else { return } - func finish(_ error: Error?) { - self.startCompletionHandlers.forEach { $0(error) } - self.startCompletionHandlers.removeAll() + self.dispatchQueue.async { + if error == nil + { + self.isStarted = true + } + + self.startCompletionHandlers.forEach { $0(error) } + self.startCompletionHandlers.removeAll() + } } - guard !self.isStarted else { return finish(nil) } - - self.persistentContainer.loadPersistentStores { (description, error) in - guard error == nil else { return finish(error!) } + self.dispatchQueue.async { + self.startCompletionHandlers.append(completionHandler) + guard self.startCompletionHandlers.count == 1 else { return } - self.prepareDatabase() { (result) in - switch result - { - case .failure(let error): - finish(error) - - case .success: - self.isStarted = true - finish(nil) + guard !self.isStarted else { return finish(nil) } + + self.persistentContainer.loadPersistentStores { (description, error) in + guard error == nil else { return finish(error!) } + + self.prepareDatabase() { (result) in + switch result + { + case .failure(let error): finish(error) + case .success: finish(nil) + } } } }