Last active
March 14, 2024 19:36
-
-
Save voncannon/7fa4db1463270e9dfa996617b1ece5e4 to your computer and use it in GitHub Desktop.
Swift Async Operation
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
// | |
// AsyncOperation.swift | |
// TopoLock | |
// | |
// Created by VonCannon Tech, Inc. on 8/13/23. | |
// | |
import Foundation | |
//Originally taken fromm: https://gist.github.com/Sorix/57bc3295dc001434fe08acbb053ed2bc | |
class AsyncOperation: Operation { | |
public override var isAsynchronous: Bool { | |
return true | |
} | |
public override var isExecuting: Bool { | |
return state == .executing | |
} | |
public override var isFinished: Bool { | |
return state == .finished | |
} | |
public override func start() { | |
if self.isCancelled { | |
state = .finished | |
} else { | |
state = .ready | |
main() | |
} | |
} | |
open override func main() { | |
if self.isCancelled { | |
state = .finished | |
} else { | |
state = .executing | |
} | |
} | |
public func finish() { | |
state = .finished | |
} | |
// MARK: - State management | |
public enum State: String { | |
case ready = "Ready" | |
case executing = "Executing" | |
case finished = "Finished" | |
fileprivate var keyPath: String { return "is" + self.rawValue } | |
} | |
/// Thread-safe computed state value | |
public var state: State { | |
get { | |
stateQueue.sync { | |
return stateStore | |
} | |
} | |
set { | |
let oldValue = state | |
willChangeValue(forKey: state.keyPath) | |
willChangeValue(forKey: newValue.keyPath) | |
stateQueue.sync(flags: .barrier) { | |
stateStore = newValue | |
} | |
didChangeValue(forKey: state.keyPath) | |
didChangeValue(forKey: oldValue.keyPath) | |
} | |
} | |
private let stateQueue = DispatchQueue(label: "AsynchronousOperation State Queue", attributes: .concurrent) | |
/// Non thread-safe state storage, use only with locks | |
private var stateStore: State = .ready | |
} |
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
// | |
// TestAsyncOperation.swift | |
// TopoLock | |
// | |
// Created by bvc on 8/14/23. | |
// | |
import Foundation | |
class TestAsyncOperation: AsyncOperation { | |
override func main() { | |
super.main() | |
Task { | |
guard !self.isCancelled else { | |
return | |
} | |
await woot() | |
self.finish() | |
} | |
} | |
} | |
func woot() async { | |
// | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
A possible alternative that jrendel told me about: https://stackoverflow.com/a/73072799