mirror of
https://github.com/SideStore/SideStore.git
synced 2026-02-11 15:53:30 +01:00
refactor to SideStoreAppKit
This commit is contained in:
@@ -72,6 +72,7 @@ let package = Package(
|
||||
.executableTarget(
|
||||
name: "SideStore",
|
||||
dependencies: [
|
||||
"SideStoreAppKit",
|
||||
"SidePatcher",
|
||||
"EmotionalDamage",
|
||||
"MiniMuxerSwift",
|
||||
@@ -83,7 +84,6 @@ let package = Package(
|
||||
"SideKit",
|
||||
"KeychainAccess",
|
||||
"SemanticVersion",
|
||||
// .product(name: "CrashReporter", package: "PLCrashReporter"),
|
||||
.product(name: "libimobiledevice", package: "iMobileDevice.swift"),
|
||||
.product(name: "Roxas", package: "Roxas"),
|
||||
.product(name: "RoxasUI", package: "Roxas"),
|
||||
@@ -166,6 +166,10 @@ let package = Package(
|
||||
.linkedFramework("UserNotifications", .when(platforms: [.iOS, .macCatalyst])),
|
||||
.linkedFramework("MobileCoreServices", .when(platforms: [.iOS, .macCatalyst])),
|
||||
.linkedLibrary("AppleArchive")
|
||||
],
|
||||
plugins: [
|
||||
.plugin(name: "IntentBuilderPlugin", package: "SwiftPMPlugins"),
|
||||
.plugin(name: "LoggerPlugin", package: "SwiftPMPlugins")
|
||||
]
|
||||
),
|
||||
|
||||
|
||||
@@ -13,23 +13,12 @@ import UserNotifications
|
||||
|
||||
import AltSign
|
||||
import SideStoreCore
|
||||
import SideStoreAppKit
|
||||
import EmotionalDamage
|
||||
import RoxasUIKit
|
||||
|
||||
extension AppDelegate {
|
||||
static let openPatreonSettingsDeepLinkNotification = Notification.Name(Bundle.Info.appbundleIdentifier + ".OpenPatreonSettingsDeepLinkNotification")
|
||||
static let importAppDeepLinkNotification = Notification.Name(Bundle.Info.appbundleIdentifier + ".ImportAppDeepLinkNotification")
|
||||
static let addSourceDeepLinkNotification = Notification.Name(Bundle.Info.appbundleIdentifier + ".AddSourceDeepLinkNotification")
|
||||
|
||||
static let appBackupDidFinish = Notification.Name(Bundle.Info.appbundleIdentifier + ".AppBackupDidFinish")
|
||||
|
||||
static let importAppDeepLinkURLKey = "fileURL"
|
||||
static let appBackupResultKey = "result"
|
||||
static let addSourceDeepLinkURLKey = "sourceURL"
|
||||
}
|
||||
|
||||
@UIApplicationMain
|
||||
final class AppDelegate: UIResponder, UIApplicationDelegate {
|
||||
final class AppDelegate: SideStoreAppDelegate {
|
||||
var window: UIWindow?
|
||||
|
||||
@available(iOS 14, *)
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
//
|
||||
// Proxy.swift
|
||||
// SideStore
|
||||
//
|
||||
// Created by Joseph Mattiello on 11/7/22.
|
||||
// Copyright © 2022 Riley Testut. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
public extension Consts {
|
||||
enum Proxy {
|
||||
static let address = "127.0.0.1"
|
||||
static let port = "51820"
|
||||
static let serverURL = "\(address):\(port)"
|
||||
}
|
||||
}
|
||||
@@ -9,6 +9,7 @@
|
||||
import EmotionalDamage
|
||||
import minimuxer
|
||||
import MiniMuxerSwift
|
||||
import SideStoreAppKit
|
||||
import RoxasUIKit
|
||||
import UIKit
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
import SideStoreCore
|
||||
import EmotionalDamage
|
||||
import SideStoreAppKit
|
||||
import UIKit
|
||||
|
||||
@available(iOS 13, *)
|
||||
|
||||
@@ -16,7 +16,7 @@ import AppCenterCrashes
|
||||
|
||||
private let appCenterAppSecret = "73532d3e-e573-4693-99a4-9f85840bbb44"
|
||||
|
||||
extension AnalyticsManager {
|
||||
public extension AnalyticsManager {
|
||||
enum EventProperty: String {
|
||||
case name
|
||||
case bundleIdentifier
|
||||
@@ -33,7 +33,7 @@ extension AnalyticsManager {
|
||||
case updatedApp(InstalledApp)
|
||||
case refreshedApp(InstalledApp)
|
||||
|
||||
var name: String {
|
||||
public var name: String {
|
||||
switch self {
|
||||
case .installedApp: return "installed_app"
|
||||
case .updatedApp: return "updated_app"
|
||||
@@ -41,7 +41,7 @@ extension AnalyticsManager {
|
||||
}
|
||||
}
|
||||
|
||||
var properties: [EventProperty: String] {
|
||||
public var properties: [EventProperty: String] {
|
||||
let properties: [EventProperty: String?]
|
||||
|
||||
switch self {
|
||||
@@ -66,13 +66,13 @@ extension AnalyticsManager {
|
||||
}
|
||||
}
|
||||
|
||||
final class AnalyticsManager {
|
||||
static let shared = AnalyticsManager()
|
||||
public final class AnalyticsManager {
|
||||
public static let shared = AnalyticsManager()
|
||||
|
||||
private init() {}
|
||||
}
|
||||
|
||||
extension AnalyticsManager {
|
||||
public extension AnalyticsManager {
|
||||
func start() {
|
||||
AppCenter.start(withAppSecret: appCenterAppSecret, services: [
|
||||
Analytics.self,
|
||||
@@ -11,7 +11,7 @@ import SideStoreCore
|
||||
import Intents
|
||||
|
||||
@available(iOS 14, *)
|
||||
final class IntentHandler: NSObject, RefreshAllIntentHandling {
|
||||
public final class IntentHandler: NSObject, RefreshAllIntentHandling {
|
||||
private let queue = DispatchQueue(label: "io.altstore.IntentHandler")
|
||||
|
||||
private var completionHandlers = [RefreshAllIntent: (RefreshAllIntentResponse) -> Void]()
|
||||
@@ -19,7 +19,7 @@ final class IntentHandler: NSObject, RefreshAllIntentHandling {
|
||||
|
||||
private var operations = [RefreshAllIntent: BackgroundRefreshAppsOperation]()
|
||||
|
||||
func confirm(intent: RefreshAllIntent, completion: @escaping (RefreshAllIntentResponse) -> Void) {
|
||||
public func confirm(intent: RefreshAllIntent, completion: @escaping (RefreshAllIntentResponse) -> Void) {
|
||||
// Refreshing apps usually, but not always, completes within alotted time.
|
||||
// As a workaround, we'll start refreshing apps in confirm() so we can
|
||||
// take advantage of some extra time before starting handle() timeout timer.
|
||||
@@ -53,7 +53,7 @@ final class IntentHandler: NSObject, RefreshAllIntentHandling {
|
||||
}
|
||||
}
|
||||
|
||||
func handle(intent: RefreshAllIntent, completion: @escaping (RefreshAllIntentResponse) -> Void) {
|
||||
public func handle(intent: RefreshAllIntent, completion: @escaping (RefreshAllIntentResponse) -> Void) {
|
||||
completionHandlers[intent] = { response in
|
||||
// Ignore .ready response from confirm() timeout.
|
||||
guard response.code != .ready else { return }
|
||||
@@ -8,8 +8,8 @@
|
||||
|
||||
import AVFoundation
|
||||
|
||||
final class BackgroundTaskManager {
|
||||
static let shared = BackgroundTaskManager()
|
||||
public final class BackgroundTaskManager {
|
||||
public static let shared = BackgroundTaskManager()
|
||||
|
||||
private var isPlaying = false
|
||||
|
||||
@@ -39,7 +39,7 @@ final class BackgroundTaskManager {
|
||||
}
|
||||
}
|
||||
|
||||
extension BackgroundTaskManager {
|
||||
public extension BackgroundTaskManager {
|
||||
func performExtendedBackgroundTask(taskHandler: @escaping ((Result<Void, Error>, @escaping () -> Void) -> Void)) {
|
||||
func finish() {
|
||||
player.stop()
|
||||
17
Sources/SideStoreAppKit/Consts/Consts+Proxy.swift
Normal file
17
Sources/SideStoreAppKit/Consts/Consts+Proxy.swift
Normal file
@@ -0,0 +1,17 @@
|
||||
//
|
||||
// Proxy.swift
|
||||
// SideStore
|
||||
//
|
||||
// Created by Joseph Mattiello on 11/7/22.
|
||||
// Copyright © 2022 Joseph Mattiello. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
public extension Consts {
|
||||
enum Proxy {
|
||||
public static let address = "127.0.0.1"
|
||||
public static let port = "51820"
|
||||
public static let serverURL = "\(address):\(port)"
|
||||
}
|
||||
}
|
||||
@@ -20,7 +20,7 @@ import SideKit
|
||||
import SideStoreCore
|
||||
import RoxasUIKit
|
||||
|
||||
extension AppManager {
|
||||
public extension AppManager {
|
||||
static let didFetchSourceNotification = Notification.Name("io.altstore.AppManager.didFetchSource")
|
||||
static let didUpdatePatronsNotification = Notification.Name("io.altstore.AppManager.didUpdatePatrons")
|
||||
|
||||
@@ -29,7 +29,7 @@ extension AppManager {
|
||||
}
|
||||
|
||||
@available(iOS 13, *)
|
||||
final class AppManagerPublisher: ObservableObject {
|
||||
public final class AppManagerPublisher: ObservableObject {
|
||||
@Published
|
||||
fileprivate(set) var installationProgress = [String: Progress]()
|
||||
|
||||
@@ -41,8 +41,8 @@ private func == (lhs: OperatingSystemVersion, rhs: OperatingSystemVersion) -> Bo
|
||||
lhs.majorVersion == rhs.majorVersion && lhs.minorVersion == rhs.minorVersion && lhs.patchVersion == rhs.patchVersion
|
||||
}
|
||||
|
||||
final class AppManager {
|
||||
static let shared = AppManager()
|
||||
public final class AppManager {
|
||||
public static let shared = AppManager()
|
||||
|
||||
private(set) var updatePatronsResult: Result<Void, Error>?
|
||||
|
||||
@@ -116,7 +116,7 @@ final class AppManager {
|
||||
}
|
||||
}
|
||||
|
||||
extension AppManager {
|
||||
public extension AppManager {
|
||||
func update() {
|
||||
DatabaseManager.shared.persistentContainer.performBackgroundTask { context in
|
||||
#if targetEnvironment(simulator)
|
||||
@@ -275,7 +275,7 @@ extension AppManager {
|
||||
}
|
||||
}
|
||||
|
||||
extension AppManager {
|
||||
public extension AppManager {
|
||||
func fetchSource(sourceURL: URL,
|
||||
managedObjectContext: NSManagedObjectContext = DatabaseManager.shared.persistentContainer.newBackgroundContext(),
|
||||
dependencies: [Foundation.Operation] = [],
|
||||
@@ -662,9 +662,9 @@ extension AppManager {
|
||||
}
|
||||
}
|
||||
|
||||
extension AppManager {
|
||||
public extension AppManager {
|
||||
@discardableResult
|
||||
func backgroundRefresh(_ installedApps: [InstalledApp], presentsNotifications: Bool = false, completionHandler: @escaping (Result<[String: Result<InstalledApp, Error>], Error>) -> Void) -> BackgroundRefreshAppsOperation {
|
||||
public func backgroundRefresh(_ installedApps: [InstalledApp], presentsNotifications: Bool = false, completionHandler: @escaping (Result<[String: Result<InstalledApp, Error>], Error>) -> Void) -> BackgroundRefreshAppsOperation {
|
||||
let backgroundRefreshAppsOperation = BackgroundRefreshAppsOperation(installedApps: installedApps)
|
||||
backgroundRefreshAppsOperation.resultHandler = completionHandler
|
||||
backgroundRefreshAppsOperation.presentsFinishedNotification = presentsNotifications
|
||||
@@ -11,16 +11,16 @@ import Foundation
|
||||
|
||||
import SideStoreCore
|
||||
|
||||
extension AppManager {
|
||||
public extension AppManager {
|
||||
struct FetchSourcesError: LocalizedError, CustomNSError {
|
||||
var primaryError: Error?
|
||||
public private(set) var primaryError: Error?
|
||||
|
||||
var sources: Set<Source>?
|
||||
var errors = [Source: Error]()
|
||||
public private(set) var sources: Set<Source>?
|
||||
public private(set) var errors = [Source: Error]()
|
||||
|
||||
var managedObjectContext: NSManagedObjectContext?
|
||||
public private(set) var managedObjectContext: NSManagedObjectContext?
|
||||
|
||||
var errorDescription: String? {
|
||||
public var errorDescription: String? {
|
||||
if let error = primaryError {
|
||||
return error.localizedDescription
|
||||
} else {
|
||||
@@ -41,7 +41,7 @@ extension AppManager {
|
||||
}
|
||||
}
|
||||
|
||||
var recoverySuggestion: String? {
|
||||
public var recoverySuggestion: String? {
|
||||
if let error = primaryError as NSError? {
|
||||
return error.localizedRecoverySuggestion
|
||||
} else if errors.count == 1 {
|
||||
@@ -51,16 +51,16 @@ extension AppManager {
|
||||
}
|
||||
}
|
||||
|
||||
var errorUserInfo: [String: Any] {
|
||||
public var errorUserInfo: [String: Any] {
|
||||
guard let error = errors.values.first, errors.count == 1 else { return [:] }
|
||||
return [NSUnderlyingErrorKey: error]
|
||||
}
|
||||
|
||||
init(_ error: Error) {
|
||||
public init(_ error: Error) {
|
||||
primaryError = error
|
||||
}
|
||||
|
||||
init(sources: Set<Source>, errors: [Source: Error], context: NSManagedObjectContext) {
|
||||
public init(sources: Set<Source>, errors: [Source: Error], context: NSManagedObjectContext) {
|
||||
self.sources = sources
|
||||
self.errors = errors
|
||||
managedObjectContext = context
|
||||
@@ -65,7 +65,7 @@ final class MyAppsViewController: UICollectionViewController {
|
||||
super.init(coder: aDecoder)
|
||||
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(MyAppsViewController.didFetchSource(_:)), name: AppManager.didFetchSourceNotification, object: nil)
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(MyAppsViewController.importApp(_:)), name: AppDelegate.importAppDeepLinkNotification, object: nil)
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(MyAppsViewController.importApp(_:)), name: SideStoreAppDelegate.importAppDeepLinkNotification, object: nil)
|
||||
}
|
||||
|
||||
override func viewDidLoad() {
|
||||
@@ -1171,7 +1171,7 @@ private extension MyAppsViewController {
|
||||
// Make sure left UIBarButtonItem has been set.
|
||||
loadViewIfNeeded()
|
||||
|
||||
guard let url = notification.userInfo?[AppDelegate.importAppDeepLinkURLKey] as? URL else { return }
|
||||
guard let url = notification.userInfo?[SideStoreAppDelegate.importAppDeepLinkURLKey] as? URL else { return }
|
||||
|
||||
sideloadApp(at: url) { _ in
|
||||
guard url.isFileURL else { return }
|
||||
@@ -58,7 +58,7 @@ final class NewsViewController: UICollectionViewController {
|
||||
required init?(coder: NSCoder) {
|
||||
super.init(coder: coder)
|
||||
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(NewsViewController.importApp(_:)), name: AppDelegate.importAppDeepLinkNotification, object: nil)
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(NewsViewController.importApp(_:)), name: SideStoreAppDelegate.importAppDeepLinkNotification, object: nil)
|
||||
}
|
||||
|
||||
override func viewDidLoad() {
|
||||
@@ -33,8 +33,8 @@ enum AuthenticationError: LocalizedError {
|
||||
}
|
||||
|
||||
@objc(AuthenticationOperation)
|
||||
final class AuthenticationOperation: ResultOperation<(ALTTeam, ALTCertificate, ALTAppleAPISession)> {
|
||||
let context: AuthenticatedOperationContext
|
||||
public final class AuthenticationOperation: ResultOperation<(ALTTeam, ALTCertificate, ALTAppleAPISession)> {
|
||||
public let context: AuthenticatedOperationContext
|
||||
|
||||
private weak var presentingViewController: UIViewController?
|
||||
|
||||
@@ -56,7 +56,7 @@ final class AuthenticationOperation: ResultOperation<(ALTTeam, ALTCertificate, A
|
||||
|
||||
private var submitCodeAction: UIAlertAction?
|
||||
|
||||
init(context: AuthenticatedOperationContext, presentingViewController: UIViewController?) {
|
||||
public init(context: AuthenticatedOperationContext, presentingViewController: UIViewController?) {
|
||||
self.context = context
|
||||
self.presentingViewController = presentingViewController
|
||||
|
||||
@@ -67,7 +67,7 @@ final class AuthenticationOperation: ResultOperation<(ALTTeam, ALTCertificate, A
|
||||
progress.totalUnitCount = 4
|
||||
}
|
||||
|
||||
override func main() {
|
||||
public override func main() {
|
||||
super.main()
|
||||
|
||||
if let error = context.error {
|
||||
@@ -45,23 +45,23 @@ private let ReceivedApplicationState: @convention(c) (CFNotificationCenter?, Uns
|
||||
}
|
||||
|
||||
@objc(BackgroundRefreshAppsOperation)
|
||||
final class BackgroundRefreshAppsOperation: ResultOperation<[String: Result<InstalledApp, Error>]> {
|
||||
let installedApps: [InstalledApp]
|
||||
public final class BackgroundRefreshAppsOperation: ResultOperation<[String: Result<InstalledApp, Error>]> {
|
||||
public let installedApps: [InstalledApp]
|
||||
private let managedObjectContext: NSManagedObjectContext
|
||||
|
||||
var presentsFinishedNotification: Bool = false
|
||||
public var presentsFinishedNotification: Bool = false
|
||||
|
||||
private let refreshIdentifier: String = UUID().uuidString
|
||||
private var runningApplications: Set<String> = []
|
||||
|
||||
init(installedApps: [InstalledApp]) {
|
||||
public init(installedApps: [InstalledApp]) {
|
||||
self.installedApps = installedApps
|
||||
managedObjectContext = installedApps.compactMap { $0.managedObjectContext }.first ?? DatabaseManager.shared.persistentContainer.newBackgroundContext()
|
||||
|
||||
super.init()
|
||||
}
|
||||
|
||||
override func finish(_ result: Result<[String: Result<InstalledApp, Error>], Error>) {
|
||||
public override func finish(_ result: Result<[String: Result<InstalledApp, Error>], Error>) {
|
||||
super.finish(result)
|
||||
|
||||
scheduleFinishedRefreshingNotification(for: result, delay: 0)
|
||||
@@ -75,7 +75,7 @@ final class BackgroundRefreshAppsOperation: ResultOperation<[String: Result<Inst
|
||||
}
|
||||
}
|
||||
|
||||
override func main() {
|
||||
public override func main() {
|
||||
super.main()
|
||||
|
||||
guard !installedApps.isEmpty else {
|
||||
@@ -146,10 +146,10 @@ private extension BackupAppOperation {
|
||||
}
|
||||
|
||||
var backupResponseObserver: NSObjectProtocol!
|
||||
backupResponseObserver = NotificationCenter.default.addObserver(forName: AppDelegate.appBackupDidFinish, object: nil, queue: nil) { [weak self] notification in
|
||||
backupResponseObserver = NotificationCenter.default.addObserver(forName: SideStoreAppDelegate.appBackupDidFinish, object: nil, queue: nil) { [weak self] notification in
|
||||
self?.timeoutTimer?.invalidate()
|
||||
|
||||
let result = notification.userInfo?[AppDelegate.appBackupResultKey] as? Result<Void, Error> ?? .failure(OperationError.unknownResult)
|
||||
let result = notification.userInfo?[SideStoreAppDelegate.appBackupResultKey] as? Result<Void, Error> ?? .failure(OperationError.unknownResult)
|
||||
self?.finish(result)
|
||||
|
||||
NotificationCenter.default.removeObserver(backupResponseObserver!)
|
||||
@@ -16,10 +16,10 @@ private extension URL {
|
||||
#endif
|
||||
}
|
||||
|
||||
extension FetchTrustedSourcesOperation {
|
||||
struct TrustedSource: Decodable {
|
||||
var identifier: String
|
||||
var sourceURL: URL?
|
||||
public extension FetchTrustedSourcesOperation {
|
||||
public struct TrustedSource: Decodable {
|
||||
public var identifier: String
|
||||
public var sourceURL: URL?
|
||||
}
|
||||
|
||||
private struct Response: Decodable {
|
||||
@@ -28,8 +28,8 @@ extension FetchTrustedSourcesOperation {
|
||||
}
|
||||
}
|
||||
|
||||
final class FetchTrustedSourcesOperation: ResultOperation<[FetchTrustedSourcesOperation.TrustedSource]> {
|
||||
override func main() {
|
||||
public final class FetchTrustedSourcesOperation: ResultOperation<[FetchTrustedSourcesOperation.TrustedSource]> {
|
||||
public override func main() {
|
||||
super.main()
|
||||
|
||||
let dataTask = URLSession.shared.dataTask(with: .trustedSources) { data, response, error in
|
||||
@@ -9,11 +9,11 @@
|
||||
import Foundation
|
||||
import RoxasUIKit
|
||||
|
||||
class ResultOperation<ResultType>: Operation {
|
||||
public class ResultOperation<ResultType>: Operation {
|
||||
var resultHandler: ((Result<ResultType, Error>) -> Void)?
|
||||
|
||||
@available(*, unavailable)
|
||||
override func finish() {
|
||||
public override func finish() {
|
||||
super.finish()
|
||||
}
|
||||
|
||||
@@ -30,12 +30,12 @@ class ResultOperation<ResultType>: Operation {
|
||||
}
|
||||
}
|
||||
|
||||
class Operation: RSTOperation, ProgressReporting {
|
||||
let progress = Progress.discreteProgress(totalUnitCount: 1)
|
||||
public class Operation: RSTOperation, ProgressReporting {
|
||||
public let progress = Progress.discreteProgress(totalUnitCount: 1)
|
||||
|
||||
private var backgroundTaskID: UIBackgroundTaskIdentifier?
|
||||
|
||||
override var isAsynchronous: Bool {
|
||||
public override var isAsynchronous: Bool {
|
||||
true
|
||||
}
|
||||
|
||||
@@ -45,7 +45,7 @@ class Operation: RSTOperation, ProgressReporting {
|
||||
progress.cancellationHandler = { [weak self] in self?.cancel() }
|
||||
}
|
||||
|
||||
override func cancel() {
|
||||
public override func cancel() {
|
||||
super.cancel()
|
||||
|
||||
if !progress.isCancelled {
|
||||
@@ -53,7 +53,7 @@ class Operation: RSTOperation, ProgressReporting {
|
||||
}
|
||||
}
|
||||
|
||||
override func main() {
|
||||
public override func main() {
|
||||
super.main()
|
||||
|
||||
let name = "com.altstore." + NSStringFromClass(type(of: self))
|
||||
@@ -67,7 +67,7 @@ class Operation: RSTOperation, ProgressReporting {
|
||||
}
|
||||
}
|
||||
|
||||
override func finish() {
|
||||
public override func finish() {
|
||||
guard !isFinished else { return }
|
||||
|
||||
super.finish()
|
||||
@@ -13,14 +13,14 @@ import Network
|
||||
import AltSign
|
||||
import SideStoreCore
|
||||
|
||||
class OperationContext {
|
||||
public class OperationContext {
|
||||
var error: Error?
|
||||
|
||||
var presentingViewController: UIViewController?
|
||||
|
||||
let operations: NSHashTable<Foundation.Operation>
|
||||
|
||||
init(error: Error? = nil, operations: [Foundation.Operation] = []) {
|
||||
public init(error: Error? = nil, operations: [Foundation.Operation] = []) {
|
||||
self.error = error
|
||||
|
||||
self.operations = NSHashTable<Foundation.Operation>.weakObjects()
|
||||
@@ -29,12 +29,12 @@ class OperationContext {
|
||||
}
|
||||
}
|
||||
|
||||
convenience init(context: OperationContext) {
|
||||
public convenience init(context: OperationContext) {
|
||||
self.init(error: context.error, operations: context.operations.allObjects)
|
||||
}
|
||||
}
|
||||
|
||||
final class AuthenticatedOperationContext: OperationContext {
|
||||
public final class AuthenticatedOperationContext: OperationContext {
|
||||
var session: ALTAppleAPISession?
|
||||
|
||||
var team: ALTTeam?
|
||||
@@ -42,7 +42,7 @@ final class AuthenticatedOperationContext: OperationContext {
|
||||
|
||||
weak var authenticationOperation: AuthenticationOperation?
|
||||
|
||||
convenience init(context: AuthenticatedOperationContext) {
|
||||
public convenience init(context: AuthenticatedOperationContext) {
|
||||
self.init(error: context.error, operations: context.operations.allObjects)
|
||||
|
||||
session = context.session
|
||||
@@ -48,7 +48,7 @@ private struct OTAUpdate {
|
||||
}
|
||||
|
||||
@available(iOS 14, *)
|
||||
final class PatchAppOperation: ResultOperation<Void> {
|
||||
public final class PatchAppOperation: ResultOperation<Void> {
|
||||
let context: PatchAppContext
|
||||
|
||||
var progressHandler: ((Progress, String) -> Void)?
|
||||
@@ -66,7 +66,7 @@ final class PatchAppOperation: ResultOperation<Void> {
|
||||
progress.totalUnitCount = 100
|
||||
}
|
||||
|
||||
override func main() {
|
||||
public override func main() {
|
||||
super.main()
|
||||
|
||||
if let error = context.error {
|
||||
@@ -98,7 +98,7 @@ final class PatchAppOperation: ResultOperation<Void> {
|
||||
} receiveValue: { _ in }
|
||||
}
|
||||
|
||||
override func cancel() {
|
||||
public override func cancel() {
|
||||
super.cancel()
|
||||
|
||||
cancellable?.cancel()
|
||||
@@ -27,7 +27,7 @@ extension PatchViewController {
|
||||
}
|
||||
|
||||
@available(iOS 14.0, *)
|
||||
final class PatchViewController: UIViewController {
|
||||
public final class PatchViewController: UIViewController {
|
||||
var patchApp: AnyApp?
|
||||
var installedApp: InstalledApp?
|
||||
|
||||
@@ -57,7 +57,7 @@ final class PatchViewController: UIViewController {
|
||||
@IBOutlet private var cancelBarButtonItem: UIBarButtonItem!
|
||||
@IBOutlet private var cancelButton: UIButton!
|
||||
|
||||
override func viewDidLoad() {
|
||||
public override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
|
||||
isModalInPresentation = true
|
||||
@@ -81,7 +81,7 @@ final class PatchViewController: UIViewController {
|
||||
update()
|
||||
}
|
||||
|
||||
override func viewWillAppear(_ animated: Bool) {
|
||||
public override func viewWillAppear(_ animated: Bool) {
|
||||
super.viewWillAppear(animated)
|
||||
|
||||
if installedApp != nil {
|
||||
@@ -12,7 +12,7 @@ import Foundation
|
||||
import AltSign
|
||||
import SideStoreCore
|
||||
|
||||
final class RefreshGroup: NSObject {
|
||||
public final class RefreshGroup: NSObject {
|
||||
let context: AuthenticatedOperationContext
|
||||
let progress = Progress.discreteProgress(totalUnitCount: 0)
|
||||
|
||||
@@ -30,7 +30,7 @@ final class RefreshGroup: NSObject {
|
||||
private let dispatchGroup = DispatchGroup()
|
||||
private var operations: [Foundation.Operation] = []
|
||||
|
||||
init(context: AuthenticatedOperationContext = AuthenticatedOperationContext()) {
|
||||
public init(context: AuthenticatedOperationContext = AuthenticatedOperationContext()) {
|
||||
self.context = context
|
||||
|
||||
super.init()
|
||||
@@ -38,7 +38,7 @@ final class RefreshGroup: NSObject {
|
||||
|
||||
/// Used to keep track of which operations belong to this group.
|
||||
/// This does _not_ add them to any operation queue.
|
||||
func add(_ operations: [Foundation.Operation]) {
|
||||
public func add(_ operations: [Foundation.Operation]) {
|
||||
for operation in operations {
|
||||
dispatchGroup.enter()
|
||||
|
||||
@@ -56,7 +56,7 @@ final class RefreshGroup: NSObject {
|
||||
self.operations.append(contentsOf: operations)
|
||||
}
|
||||
|
||||
func set(_ result: Result<InstalledApp, Error>, forAppWithBundleIdentifier bundleIdentifier: String) {
|
||||
public func set(_ result: Result<InstalledApp, Error>, forAppWithBundleIdentifier bundleIdentifier: String) {
|
||||
results[bundleIdentifier] = result
|
||||
|
||||
switch result {
|
||||
@@ -67,7 +67,7 @@ final class RefreshGroup: NSObject {
|
||||
}
|
||||
}
|
||||
|
||||
func cancel() {
|
||||
public func cancel() {
|
||||
operations.forEach { $0.cancel() }
|
||||
}
|
||||
}
|
||||
@@ -12,6 +12,7 @@ import RoxasUIKit
|
||||
import AltSign
|
||||
import SideStoreCore
|
||||
|
||||
|
||||
@objc(ResignAppOperation)
|
||||
final class ResignAppOperation: ResultOperation<ALTApplication> {
|
||||
let context: InstallAppOperationContext
|
||||
@@ -76,7 +76,7 @@ final class SettingsViewController: UITableViewController {
|
||||
required init?(coder aDecoder: NSCoder) {
|
||||
super.init(coder: aDecoder)
|
||||
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(SettingsViewController.openPatreonSettings(_:)), name: AppDelegate.openPatreonSettingsDeepLinkNotification, object: nil)
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(SettingsViewController.openPatreonSettings(_:)), name: SideStoreAppDelegate.openPatreonSettingsDeepLinkNotification, object: nil)
|
||||
}
|
||||
|
||||
override func viewDidLoad() {
|
||||
33
Sources/SideStoreAppKit/SideStoreAppDelegate.swift
Normal file
33
Sources/SideStoreAppKit/SideStoreAppDelegate.swift
Normal file
@@ -0,0 +1,33 @@
|
||||
//
|
||||
// SideStoreAppDelegate.swift
|
||||
// AltStore
|
||||
//
|
||||
// Created by Riley Testut on 5/9/19.
|
||||
// Copyright © 2019 Riley Testut. All rights reserved.
|
||||
//
|
||||
|
||||
import AVFoundation
|
||||
import Intents
|
||||
import UIKit
|
||||
import UserNotifications
|
||||
|
||||
import AltSign
|
||||
import SideStoreCore
|
||||
import EmotionalDamage
|
||||
import RoxasUIKit
|
||||
|
||||
open class SideStoreAppDelegate: UIResponder, UIApplicationDelegate {
|
||||
|
||||
}
|
||||
|
||||
public extension SideStoreAppDelegate {
|
||||
static let openPatreonSettingsDeepLinkNotification = Notification.Name(Bundle.Info.appbundleIdentifier + ".OpenPatreonSettingsDeepLinkNotification")
|
||||
static let importAppDeepLinkNotification = Notification.Name(Bundle.Info.appbundleIdentifier + ".ImportAppDeepLinkNotification")
|
||||
static let addSourceDeepLinkNotification = Notification.Name(Bundle.Info.appbundleIdentifier + ".AddSourceDeepLinkNotification")
|
||||
|
||||
static let appBackupDidFinish = Notification.Name(Bundle.Info.appbundleIdentifier + ".AppBackupDidFinish")
|
||||
|
||||
static let importAppDeepLinkURLKey = "fileURL"
|
||||
static let appBackupResultKey = "result"
|
||||
static let addSourceDeepLinkURLKey = "sourceURL"
|
||||
}
|
||||
@@ -1,4 +0,0 @@
|
||||
import Foundation
|
||||
import UIKit
|
||||
|
||||
public final class SideStoreAppKit { }
|
||||
@@ -18,7 +18,7 @@ extension TabBarController {
|
||||
}
|
||||
}
|
||||
|
||||
final class TabBarController: UITabBarController {
|
||||
public final class TabBarController: UITabBarController {
|
||||
private var initialSegue: (identifier: String, sender: Any?)?
|
||||
|
||||
private var _viewDidAppear = false
|
||||
@@ -26,12 +26,12 @@ final class TabBarController: UITabBarController {
|
||||
required init?(coder aDecoder: NSCoder) {
|
||||
super.init(coder: aDecoder)
|
||||
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(TabBarController.openPatreonSettings(_:)), name: AppDelegate.openPatreonSettingsDeepLinkNotification, object: nil)
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(TabBarController.importApp(_:)), name: AppDelegate.importAppDeepLinkNotification, object: nil)
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(TabBarController.presentSources(_:)), name: AppDelegate.addSourceDeepLinkNotification, object: nil)
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(TabBarController.openPatreonSettings(_:)), name: SideStoreAppDelegate.openPatreonSettingsDeepLinkNotification, object: nil)
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(TabBarController.importApp(_:)), name: SideStoreAppDelegate.importAppDeepLinkNotification, object: nil)
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(TabBarController.presentSources(_:)), name: SideStoreAppDelegate.addSourceDeepLinkNotification, object: nil)
|
||||
}
|
||||
|
||||
override func viewDidAppear(_ animated: Bool) {
|
||||
public override func viewDidAppear(_ animated: Bool) {
|
||||
super.viewDidAppear(animated)
|
||||
|
||||
_viewDidAppear = true
|
||||
@@ -48,13 +48,13 @@ final class TabBarController: UITabBarController {
|
||||
}
|
||||
}
|
||||
|
||||
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
|
||||
public override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
|
||||
guard let identifier = segue.identifier else { return }
|
||||
|
||||
switch identifier {
|
||||
case "presentSources":
|
||||
guard let notification = sender as? Notification,
|
||||
let sourceURL = notification.userInfo?[AppDelegate.addSourceDeepLinkURLKey] as? URL
|
||||
let sourceURL = notification.userInfo?[SideStoreAppDelegate.addSourceDeepLinkURLKey] as? URL
|
||||
else { return }
|
||||
|
||||
let navigationController = segue.destination as! UINavigationController
|
||||
@@ -76,7 +76,7 @@ final class TabBarController: UITabBarController {
|
||||
}
|
||||
}
|
||||
|
||||
override func performSegue(withIdentifier identifier: String, sender: Any?) {
|
||||
public override func performSegue(withIdentifier identifier: String, sender: Any?) {
|
||||
guard _viewDidAppear else {
|
||||
initialSegue = (identifier, sender)
|
||||
return
|
||||
@@ -92,7 +92,7 @@ extension TabBarController {
|
||||
if let navigationController = presentedViewController as? UINavigationController,
|
||||
let sourcesViewController = navigationController.viewControllers.first as? SourcesViewController {
|
||||
if let notification = (sender as? Notification),
|
||||
let sourceURL = notification.userInfo?[AppDelegate.addSourceDeepLinkURLKey] as? URL {
|
||||
let sourceURL = notification.userInfo?[SideStoreAppDelegate.addSourceDeepLinkURLKey] as? URL {
|
||||
sourcesViewController.deepLinkSourceURL = sourceURL
|
||||
} else {
|
||||
// Don't dismiss SourcesViewController if it's already presented.
|
||||
Reference in New Issue
Block a user