diff --git a/AltStore.xcodeproj/project.pbxproj b/AltStore.xcodeproj/project.pbxproj index a67b1764..874a5cc7 100644 --- a/AltStore.xcodeproj/project.pbxproj +++ b/AltStore.xcodeproj/project.pbxproj @@ -128,6 +128,7 @@ BFB11692229322E400BB457C /* DatabaseManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFB11691229322E400BB457C /* DatabaseManager.swift */; }; BFB1169B2293274D00BB457C /* JSONDecoder+ManagedObjectContext.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFB1169A2293274D00BB457C /* JSONDecoder+ManagedObjectContext.swift */; }; BFB1169D22932DB100BB457C /* Apps-Staging.json in Resources */ = {isa = PBXBuildFile; fileRef = BFB1169C22932DB100BB457C /* Apps-Staging.json */; }; + BFB3645A2325985F00CD0EB1 /* FindServerOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFB364592325985F00CD0EB1 /* FindServerOperation.swift */; }; BFB4323F22DE852000B7F8BC /* UpdateCollectionViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = BFB4323E22DE852000B7F8BC /* UpdateCollectionViewCell.xib */; }; BFB6B21B23186D640022A802 /* NewsItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFB6B21A23186D640022A802 /* NewsItem.swift */; }; BFB6B21E231870160022A802 /* NewsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFB6B21D231870160022A802 /* NewsViewController.swift */; }; @@ -404,6 +405,7 @@ BFB11691229322E400BB457C /* DatabaseManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DatabaseManager.swift; sourceTree = ""; }; BFB1169A2293274D00BB457C /* JSONDecoder+ManagedObjectContext.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "JSONDecoder+ManagedObjectContext.swift"; sourceTree = ""; }; BFB1169C22932DB100BB457C /* Apps-Staging.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = "Apps-Staging.json"; sourceTree = ""; }; + BFB364592325985F00CD0EB1 /* FindServerOperation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FindServerOperation.swift; sourceTree = ""; }; BFB4323E22DE852000B7F8BC /* UpdateCollectionViewCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = UpdateCollectionViewCell.xib; sourceTree = ""; }; BFB6B21A23186D640022A802 /* NewsItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NewsItem.swift; sourceTree = ""; }; BFB6B21D231870160022A802 /* NewsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NewsViewController.swift; sourceTree = ""; }; @@ -1003,6 +1005,7 @@ BF770E5722BC3D0F002A40FE /* OperationGroup.swift */, BF770E5322BC044E002A40FE /* AppOperationContext.swift */, BFE6326B22A86FF300F30809 /* AuthenticationOperation.swift */, + BFB364592325985F00CD0EB1 /* FindServerOperation.swift */, BFC1F38C22AEE3A4003AC21A /* DownloadAppOperation.swift */, BFDB6A0722AAED73007EA6D6 /* ResignAppOperation.swift */, BFDB6A0E22AB2776007EA6D6 /* SendAppOperation.swift */, @@ -1467,6 +1470,7 @@ BFE6326C22A86FF300F30809 /* AuthenticationOperation.swift in Sources */, BFB6B220231870B00022A802 /* NewsCollectionViewCell.swift in Sources */, BFDB6A0522A9AFB2007EA6D6 /* Fetchable.swift in Sources */, + BFB3645A2325985F00CD0EB1 /* FindServerOperation.swift in Sources */, BFD2479F2284FBD000981D42 /* UIColor+AltStore.swift in Sources */, BFDB5B1622EE90D300F74113 /* Date+RelativeDate.swift in Sources */, BFF0B69023219C6D007A79E1 /* PatreonComponents.swift in Sources */, diff --git a/AltStore/Managing Apps/AppManager.swift b/AltStore/Managing Apps/AppManager.swift index 0b113968..426f89b7 100644 --- a/AltStore/Managing Apps/AppManager.swift +++ b/AltStore/Managing Apps/AppManager.swift @@ -175,17 +175,6 @@ private extension AppManager { // Authenticate -> Download (if necessary) -> Resign -> Send -> Install. let group = group ?? OperationGroup() - - guard let server = ServerManager.shared.discoveredServers.first(where: { $0.isPreferred }) ?? ServerManager.shared.discoveredServers.first else { - DispatchQueue.main.async { - group.completionHandler?(.failure(ConnectionError.serverNotFound)) - } - - return group - } - - group.server = server - var operations = [Operation]() @@ -200,6 +189,18 @@ private extension AppManager } operations.append(authenticationOperation) + /* Find Server */ + let findServerOperation = FindServerOperation(group: group) + findServerOperation.resultHandler = { (result) in + switch result + { + case .failure(let error): group.error = error + case .success(let server): group.server = server + } + } + findServerOperation.addDependency(authenticationOperation) + operations.append(findServerOperation) + for app in apps { @@ -213,7 +214,7 @@ private extension AppManager guard let resignedApp = self.process(result, context: context) else { return } context.resignedApp = resignedApp } - resignAppOperation.addDependency(authenticationOperation) + resignAppOperation.addDependency(findServerOperation) progress.addChild(resignAppOperation.progress, withPendingUnitCount: 20) operations.append(resignAppOperation) @@ -246,12 +247,13 @@ private extension AppManager { // App is not yet installed (or we're forcing it to download a new version), so download it before resigning it. - let downloadOperation = DownloadAppOperation(app: app) + let downloadOperation = DownloadAppOperation(app: app, context: context) downloadOperation.resultHandler = { (result) in guard let app = self.process(result, context: context) else { return } context.app = app } progress.addChild(downloadOperation.progress, withPendingUnitCount: 40) + downloadOperation.addDependency(findServerOperation) resignAppOperation.addDependency(downloadOperation) operations.append(downloadOperation) } diff --git a/AltStore/Operations/DownloadAppOperation.swift b/AltStore/Operations/DownloadAppOperation.swift index 60e68b4a..903336e9 100644 --- a/AltStore/Operations/DownloadAppOperation.swift +++ b/AltStore/Operations/DownloadAppOperation.swift @@ -15,6 +15,7 @@ import AltSign class DownloadAppOperation: ResultOperation { let app: AppProtocol + let context: AppOperationContext private let bundleIdentifier: String private let sourceURL: URL @@ -22,9 +23,11 @@ class DownloadAppOperation: ResultOperation private let session = URLSession(configuration: .default) - init(app: AppProtocol) + init(app: AppProtocol, context: AppOperationContext) { self.app = app + self.context = context + self.bundleIdentifier = app.bundleIdentifier self.sourceURL = app.url self.destinationURL = InstalledApp.fileURL(for: app) @@ -38,6 +41,12 @@ class DownloadAppOperation: ResultOperation { super.main() + if let error = self.context.error + { + self.finish(.failure(error)) + return + } + print("Downloading App:", self.bundleIdentifier) func finishOperation(_ result: Result) diff --git a/AltStore/Operations/FindServerOperation.swift b/AltStore/Operations/FindServerOperation.swift new file mode 100644 index 00000000..3eb0ef4b --- /dev/null +++ b/AltStore/Operations/FindServerOperation.swift @@ -0,0 +1,51 @@ +// +// FindServerOperation.swift +// AltStore +// +// Created by Riley Testut on 9/8/19. +// Copyright © 2019 Riley Testut. All rights reserved. +// + +import Foundation +import Roxas + +@objc(FindServerOperation) +class FindServerOperation: ResultOperation +{ + let group: OperationGroup + + init(group: OperationGroup) + { + self.group = group + + super.init() + } + + override func main() + { + super.main() + + if let error = self.group.error + { + self.finish(.failure(error)) + return + } + + if let server = ServerManager.shared.discoveredServers.first(where: { $0.isPreferred }) + { + // Preferred server. + self.finish(.success(server)) + } + else if let server = ServerManager.shared.discoveredServers.first + { + // Any available server. + self.finish(.success(server)) + } + else + { + // No servers. + self.finish(.failure(ConnectionError.serverNotFound)) + } + } +} +