Skip to content

Instantly share code, notes, and snippets.

@egcode
Created May 12, 2022 00:57
Show Gist options
  • Save egcode/fc47d05ced92e7b189dc71fa0f4f5b9b to your computer and use it in GitHub Desktop.
Save egcode/fc47d05ced92e7b189dc71fa0f4f5b9b to your computer and use it in GitHub Desktop.
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
}
}
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
}
}
@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