mirror of
https://github.com/SideStore/SideStore.git
synced 2026-02-09 06:43:25 +01:00
110 lines
2.9 KiB
Swift
110 lines
2.9 KiB
Swift
//
|
|
// Operation.swift
|
|
// AltStore
|
|
//
|
|
// Created by Riley Testut on 6/7/19.
|
|
// Copyright © 2019 Riley Testut. All rights reserved.
|
|
//
|
|
|
|
import Foundation
|
|
import Roxas
|
|
|
|
class ResultOperation<ResultType>: Operation
|
|
{
|
|
var resultHandler: ((Result<ResultType, Error>) -> Void)?
|
|
|
|
// Should only be set by subclasses
|
|
var localizedFailure: String?
|
|
|
|
@available(*, unavailable)
|
|
override func finish()
|
|
{
|
|
super.finish()
|
|
}
|
|
|
|
func finish(_ result: Result<ResultType, Error>)
|
|
{
|
|
guard !self.isFinished else { return }
|
|
|
|
var result = result
|
|
|
|
if self.isCancelled
|
|
{
|
|
result = .failure(OperationError.cancelled)
|
|
}
|
|
else if case .failure(let nsError as NSError) = result, let localizedFailure, nsError.localizedFailure == nil {
|
|
// Error doesn't have its own localizedFailure, so we give it the Operation's (if it exists)
|
|
let error = nsError.withLocalizedFailure(localizedFailure)
|
|
result = .failure(error)
|
|
}
|
|
|
|
// Diagnostics: perform verbose logging of the operations only if enabled (so as to not flood console logs)
|
|
if UserDefaults.standard.isVerboseOperationsLoggingEnabled {
|
|
// diagnostics logging
|
|
let resultStatus = String(describing: result).prefix("success".count).uppercased()
|
|
print("\n ====> OPERATION: `\(type(of: self))` completed with: \(resultStatus) <====\n\n" +
|
|
" Result: \(result)\n")
|
|
}
|
|
|
|
self.resultHandler?(result)
|
|
|
|
super.finish()
|
|
}
|
|
}
|
|
|
|
class Operation: RSTOperation, ProgressReporting
|
|
{
|
|
let progress = Progress.discreteProgress(totalUnitCount: 1)
|
|
|
|
private var backgroundTaskID: UIBackgroundTaskIdentifier?
|
|
|
|
override var isAsynchronous: Bool {
|
|
return true
|
|
}
|
|
|
|
override init()
|
|
{
|
|
super.init()
|
|
|
|
self.progress.cancellationHandler = { [weak self] in self?.cancel() }
|
|
}
|
|
|
|
override func cancel()
|
|
{
|
|
super.cancel()
|
|
|
|
if !self.progress.isCancelled
|
|
{
|
|
self.progress.cancel()
|
|
}
|
|
}
|
|
|
|
override func main()
|
|
{
|
|
super.main()
|
|
|
|
let name = "com.altstore." + NSStringFromClass(type(of: self))
|
|
self.backgroundTaskID = UIApplication.shared.beginBackgroundTask(withName: name) { [weak self] in
|
|
guard let backgroundTask = self?.backgroundTaskID else { return }
|
|
|
|
self?.cancel()
|
|
|
|
UIApplication.shared.endBackgroundTask(backgroundTask)
|
|
self?.backgroundTaskID = .invalid
|
|
}
|
|
}
|
|
|
|
override func finish()
|
|
{
|
|
guard !self.isFinished else { return }
|
|
|
|
super.finish()
|
|
|
|
if let backgroundTaskID = self.backgroundTaskID
|
|
{
|
|
UIApplication.shared.endBackgroundTask(backgroundTaskID)
|
|
self.backgroundTaskID = .invalid
|
|
}
|
|
}
|
|
}
|