Hello. Trying to wrap NSOperation and ran into a series of problems. I will describe the structure with which I am currently working. The project is based on the following PAT:
@available(OSX 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *)
public protocol ProducerTaskProtocol: Operation {
associatedtype Output
associatedtype Failure: Error
// MARK: -
typealias Produced = Result<Output, ProducerTaskProtocolError<Failure>>
var produced: Produced? { get }
// MARK: -
var conditions: [AnyTaskCondition] { get }
@discardableResult
func addCondition<C: TaskCondition>(_ condition: C) -> Self
// MARK: -
var observers: [Observer] { get }
@discardableResult
func addObserver<O: Observer>(_ observer: O) -> Self
// MARK: -
@discardableResult
func addDependency<T: ProducerTaskProtocol>(_ task: T) -> Self
@discardableResult
func addDependencies<T: ProducerTaskProtocol>(_ tasks: [T]) -> Self
// MARK: -
func willEnqueue()
// MARK: -
func execute()
// MARK: -
func finish(with produced: Produced)
func finished(with produced: Produced)
// MARK: -
func produce<T: ProducerTaskProtocol>(new task: T)
// MARK: -
func recieve(completion: @escaping (Produced) -> Void) -> Self
}
And the main class implements it:
@available(OSX 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *)
open class ProducerTask<Output, Failure: Error>: Operation, ProducerTaskProtocol {
// ...
}
In turn, the protocol is expanded as follows:
@available(OSX 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *)
public protocol ConsumerProducerTaskProtocol: ProducerTaskProtocol {
associatedtype Input
// MARK: -
typealias ProducingTask = ProducerTask<Input, Failure>
var producing: ProducingTask { get }
// MARK: -
typealias Consumed = ProducingTask.Produced
var consumed: Consumed? { get }
// MARK: -
func execute(with consumed: Consumed)
}
And implemented as:
@available(OSX 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *)
open class ConsumerProducerTask<Input, Output, Failure: Error>: ProducerTask<Output, Failure>, ConsumerProducerTaskProtocol {
// ...
}
And here a problem arises. I cannot storing various tasks, I can’t even pass them as an argument, in a similar way:
public init<T: ProducerTaskProtocol>(
name: String? = nil,
qos: QualityOfService = .default,
priority: Operation.QueuePriority = .normal,
underlyingQueue: DispatchQueue? = nil,
tasks: [T],
produced: ProducerTask<Output, Failure>
) {
// ...
}
Of course, here comes the thought of type-erasures, but how to do it? After all, the main protocol has a Self constraint - NSOperation.