Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save CanTheAlmighty/fabdef60994171859a90acfc43b9d1d0 to your computer and use it in GitHub Desktop.
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.
//
// 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)
}
}
}
//
// 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