Created
May 12, 2022 00:57
-
-
Save egcode/fc47d05ced92e7b189dc71fa0f4f5b9b to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Foundation | |
protocol OperationType { | |
var operationType: RequestOperationType { get } | |
} | |
public enum RequestOperationType: Int { | |
case blah | |
case devices | |
} | |
public class AsyncOperation: Operation { | |
enum State: String { | |
case ready, executing, finished | |
fileprivate var keyPath: String { | |
return "is" + rawValue.capitalized | |
} | |
} | |
var state = State.ready { | |
willSet { | |
willChangeValue(forKey: newValue.keyPath) | |
willChangeValue(forKey: state.keyPath) | |
} | |
didSet { | |
didChangeValue(forKey: oldValue.keyPath) | |
didChangeValue(forKey: state.keyPath) | |
} | |
} | |
} | |
extension AsyncOperation { | |
override public var isReady: Bool { | |
return super.isReady && state == .ready | |
} | |
override public var isExecuting: Bool { | |
return state == .executing | |
} | |
override public var isFinished: Bool { | |
return state == .finished | |
} | |
override public var isAsynchronous: Bool { | |
return true | |
} | |
override public func start() { | |
if isCancelled { | |
state = .finished | |
return | |
} | |
main() | |
state = .executing | |
} | |
override public func cancel() { | |
super.cancel() | |
state = .finished | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Foundation | |
public class ImageDownloadOperation: AsyncOperation { | |
private let completion: ((_ success:Bool, _ imageData:Data?) -> ())? | |
let url: String | |
public init(url:String, completion: ((_ success:Bool, _ imageData:Data?) -> ())?) { | |
self.completion = completion | |
self.url = url | |
super.init() | |
} | |
override public func main() { | |
if let someUrl = URL(string: self.url) { | |
var request = URLRequest(url: someUrl) | |
request.httpMethod = "GET" | |
let sessionConfig = URLSessionConfiguration.default | |
sessionConfig.timeoutIntervalForRequest = 20 | |
let session = URLSession(configuration: sessionConfig) | |
let task = session.dataTask(with: request) { (data, response, error) in | |
if let imdata = data, (response as? HTTPURLResponse)?.statusCode ?? -1 == 200 { | |
self.finishedRequest(success: true, imageData: imdata) | |
} else { | |
self.finishedRequest(success: false, imageData: nil) | |
} | |
} | |
task.resume() | |
} else { | |
Log.error("Unable to create url from string: \(self.url)") | |
self.finishedRequest(success: false, imageData: nil) | |
} | |
} | |
fileprivate func finishedRequest(success:Bool, imageData: Data?) { | |
self.state = .finished | |
if let complete = self.completion { | |
complete(success, imageData) | |
} else { | |
Log.debug("⛔️Completion block is required for ThumbnailDownloadOperation") | |
} | |
} | |
// MARK: - Debug description | |
override public var debugDescription: String { | |
return "\n<\nurl=\(self.url);\n>" | |
} | |
} | |
extension ImageDownloadOperation: OperationType { | |
var operationType: RequestOperationType { | |
return .devices | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@objcMembers public class OperationsManager: NSObject { | |
public static let shared = OperationsManager() | |
override init() { | |
super.init() | |
} | |
public lazy var requestsQueue:OperationQueue = { | |
var queue = OperationQueue() | |
queue.name = "Requests queue" | |
queue.maxConcurrentOperationCount = 5 | |
return queue | |
}() | |
// MARK: - Requests | |
public class func addOperation(operation: Operation) { | |
OperationsManager.shared.requestsQueue.addOperation(operation) | |
} | |
// public class func prioritizeThumbnailOperation(channelIDs:[String]) { | |
// if let ops = OperationsManager.shared.thumbnailDownloadQueue.operations as? [ThumbnailDownloadOperation] { | |
// for op in ops { | |
// op.queuePriority = .normal | |
// if channelIDs.contains(where: {$0 == op.deviceId}) { | |
// op.queuePriority = .veryHigh | |
// } | |
// } | |
// } | |
// } | |
public func isAllRequestFinished() -> Bool { | |
if self.requestsQueue.operationCount == 0 { | |
return true | |
} else { | |
return false | |
} | |
} | |
public func operationRequestTypeIsRunning(type:RequestOperationType) -> Bool { | |
for op in requestsQueue.operations { | |
if let o = op as? OperationType { | |
if o.operationType == type { | |
return true | |
} | |
} | |
} | |
return false | |
} | |
public func cancelOperationsWithType(type:RequestOperationType) { | |
for op in requestsQueue.operations { | |
if let o = op as? OperationType { | |
if o.operationType == type { | |
op.cancel() | |
} | |
} | |
} | |
} | |
@objc public func cancelAllOperations() { | |
self.requestsQueue.cancelAllOperations() | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment