-
-
Save CanTheAlmighty/fabdef60994171859a90acfc43b9d1d0 to your computer and use it in GitHub Desktop.
Subclass of (NS)Operation to make it asynchronous in Swift 4, also providing a Block-based alternative.
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
// | |
// AsynchronousBlockOperation.swift | |
// | |
// Created by Jose Canepa on 12/13/17. | |
// Copyright © 2017 Jose Canepa. All rights reserved. | |
// | |
import Foundation | |
/// Block based version of the AsynchronousOperation | |
/// | |
/// Has the same qualities as the AsynchronousOperation, but with an implementation | |
/// closer to the one of a BlockOperation. | |
/// | |
/// Once the inner asynchronous operation is finished, call the finish() | |
/// on the block reference passed. Do not retain the passed block. | |
/// | |
final class AsynchronousBlockOperation : AsynchronousOperation | |
{ | |
private var block : (AsynchronousBlockOperation) -> () | |
init(_ block : @escaping (AsynchronousBlockOperation) -> ()) | |
{ | |
self.block = block | |
} | |
override func main() | |
{ | |
// If we were executing already | |
let wasExecuting = (state == .executing) | |
// Call our main to ensure we are not cancelled | |
super.main() | |
if !wasExecuting | |
{ | |
block(self) | |
} | |
} | |
} |
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
// | |
// AsynchronousOperation.swift | |
// | |
// Created by Vasily Ulianov on 09.02.17. | |
// Copyright © 2017 Vasily Ulianov. All rights reserved. | |
// | |
import Foundation | |
/// Subclass of `Operation` that add support of asynchronous operations. | |
/// ## How to use: | |
/// 1. Call `super.main()` when override `main` method, call `super.start()` when override `start` method. | |
/// 2. When operation is finished or cancelled call `finish()` | |
open class AsynchronousOperation: Operation | |
{ | |
public enum State : String | |
{ | |
case ready = "Ready" | |
case executing = "Executing" | |
case finished = "Finished" | |
fileprivate var keyPath: String { return "is" + self.rawValue } | |
} | |
override open var isAsynchronous : Bool { return true } | |
override open var isExecuting : Bool { return state == .executing } | |
override open var isFinished : Bool { return state == .finished } | |
public private(set) var state = State.ready | |
{ | |
willSet(n) | |
{ | |
willChangeValue(forKey: state.keyPath) | |
willChangeValue(forKey: n.keyPath) | |
} | |
didSet(o) | |
{ | |
didChangeValue(forKey: state.keyPath) | |
didChangeValue(forKey: o.keyPath) | |
} | |
} | |
override open func start() | |
{ | |
if self.isCancelled | |
{ | |
state = .finished | |
} | |
else | |
{ | |
state = .ready | |
main() | |
} | |
} | |
override open func main() | |
{ | |
if self.isCancelled | |
{ | |
state = .finished | |
} | |
else | |
{ | |
state = .executing | |
} | |
} | |
public func finish() | |
{ | |
guard state != .finished else { return } | |
state = .finished | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment