Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
How to write and use an asynchronous operation
import Foundation
class AsyncOperation: Operation {
enum State: String {
case isReady, isExecuting, isFinished
}
override var isAsynchronous: Bool {
return true
}
var state = State.isReady {
willSet {
willChangeValue(forKey: state.rawValue)
willChangeValue(forKey: newValue.rawValue)
}
didSet {
didChangeValue(forKey: oldValue.rawValue)
didChangeValue(forKey: state.rawValue)
}
}
override var isExecuting: Bool {
return state == .isExecuting
}
override var isFinished: Bool {
return state == .isFinished
}
override func start() {
guard !self.isCancelled else {
state = .isFinished
return
}
state = .isExecuting
main()
}
}
final class FetchOperation: AsyncOperation {
private(set) var dataFetched: Data?
private let session = URLSession(configuration: .default)
private var dataTask: URLSessionDataTask?
override func main() {
let url = URL(string: "https://jsonplaceholder.typicode.com/users")!
dataTask = session.dataTask(with: url) { [weak self] (data, _, _) in
guard let `self` = self else { return }
// We could improve this fallback with a Result enum
guard
!self.isCancelled,
let data = data else {
self.state = .isFinished
return
}
self.dataFetched = data
self.state = .isFinished
}
dataTask?.resume()
}
}
@robwithhair

This comment has been minimized.

Copy link

@robwithhair robwithhair commented Jun 1, 2018

Is this thread safe? I'm reading lots about thread safety of writing to state. I'm bit confused.

@badrinathvm

This comment has been minimized.

Copy link

@badrinathvm badrinathvm commented Oct 1, 2018

yea facing same issue.

@MarcoSantarossa

This comment has been minimized.

Copy link
Owner Author

@MarcoSantarossa MarcoSantarossa commented Feb 8, 2019

@robwithhair/@badrinathvm so far I didn't encounter thread problems. I should investigate about this issue.

@MarcoSantarossa

This comment has been minimized.

Copy link
Owner Author

@MarcoSantarossa MarcoSantarossa commented Feb 22, 2019

Looking around, I think we could use an internal GCD queue to update the state with a sync work. I will update this code asap.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment