refactor to SideStoreAppKit

This commit is contained in:
Joe Mattiello
2023-03-01 19:09:33 -05:00
parent df5b0c3af1
commit c28a45f100
92 changed files with 145 additions and 120 deletions

View File

@@ -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")
]
),

View File

@@ -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, *)

View File

@@ -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)"
}
}

View File

@@ -9,6 +9,7 @@
import EmotionalDamage
import minimuxer
import MiniMuxerSwift
import SideStoreAppKit
import RoxasUIKit
import UIKit

View File

@@ -8,6 +8,7 @@
import SideStoreCore
import EmotionalDamage
import SideStoreAppKit
import UIKit
@available(iOS 13, *)

View File

@@ -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,

View File

@@ -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 }

View File

@@ -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()

View 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)"
}
}

View File

@@ -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

View File

@@ -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

View File

@@ -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 }

View File

@@ -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() {

View File

@@ -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 {

View File

@@ -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 {

View File

@@ -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!)

View File

@@ -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

View File

@@ -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()

View File

@@ -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

View File

@@ -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()

View File

@@ -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 {

View File

@@ -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() }
}
}

View File

@@ -12,6 +12,7 @@ import RoxasUIKit
import AltSign
import SideStoreCore
@objc(ResignAppOperation)
final class ResignAppOperation: ResultOperation<ALTApplication> {
let context: InstallAppOperationContext

View File

@@ -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() {

View 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"
}

View File

@@ -1,4 +0,0 @@
import Foundation
import UIKit
public final class SideStoreAppKit { }

View File

@@ -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.