Skip to content

Latest commit

 

History

History
320 lines (232 loc) · 7.46 KB

CheatSheet.md

File metadata and controls

320 lines (232 loc) · 7.46 KB

CheatSheet

Use this cheatsheet for a fast review and training of AOperation features

subclass of Operation that added some features like conditions, observers, declarative Api, ... to it.

Use VoidOperation if you don't expect any result of your task and you just want it be done.

class MyVoidOperation: VoidOperation {
	override public func execute() {
		
		do {
			try doSomething()
			finish()
		}
		catch {
			finish(with: AOperationError(error))
		}
		
	}

}

Use ResultableOperation<Output> if you expect some resutl from your operation.

class MyVoidOperation: VoidOperation {
	override public func execute() {
		
		do {
			let result = try doSomething()
			finish(with: .success(result))
		}
		catch {
			finish(with: .failure(AOperationError(error)))
		}
		
	}

}

A Group Operation is an Operation that takes several operations as input and finishes only if all the given operations finish their execution.

let groupOperation = GroupOperation(operationA, operationB, operationC)

Ordered Group Operation is like a group operation whith the difference that the given operations execute in order.

let groupOperation = OrderedGroupOperation(operationA, operationB, operationC)

An Operation that wraps another operation.

class AuthorizedOperation: WrapperOperation<Void, (response: URLResponse, data: Data)> {
	
	init() {
		super.init { _ -> ResultableOperation<(response: URLResponse, data: Data)> in
			let url = URL(string: "A url string")!
			var request = URLRequest(url: url)
			request.allHTTPHeaderFields = 
			["Authorization" : "An authorization code"]
			return URLSessionTaskOperation.data(for: request)

		}
	}

}

You can also use WrapperOperation to wrap a chain of operations:

class ServiceOperation<Output: Decodable>: WrapperOperation<Void, Output> {
	init(url: URL) {
		super.init { (_) -> ResultableOperation<Output>? in
			return
			URlSessionTaskOperation.data(for: url)
			.deliver(to: ServicesErrorHandleOperation())
			.deliver(to: JSONDecoderOperation<Output>())
		}
	}
}

A protocol with methods for react to the changes of operation's lifecycle.

class SampleOperation: VoidOperation, AOperationDelegate {

	override public func execute() {
		// do some task
	}


	func operationDidStart(_ operation: AOperation) {
	}
	
	func operationDidFinish(_ operation: AOperation, with errors: [AOperationError]) {
	}

}

A protocol that declares an AOperation type that can receive input from a ResultableOperation or OperationPublisher.

Implementation

class ErrorHandleOperation: ResultableOperation<Data>, ReceiverOperation {

	public var receivedValue: Result<(data: Data, response: URLResponse), AOperationError>?
	
	public override func execute() {
		// do some task
	}

}

Usage

let url = URL(string: "https://ServerHost.com/userInfo")
URlSessionTaskOperation.data(for: url)
.deliver(to: ErrorHandleOperation())
.didFinish { result in

}

A protocol that operations conform to support attempts to recreate a finished operation.

Implementation

class FetchUserInfoOperation: VoidOperation, RetryableOperation {

	func new() -> Self {
		FetchUserInfoOperation() as! Self
	}
	
	public override func execute() {
		// do some task
	}

	
}

Usage

This protocl should be conformed if you want to use retryOnFailure method.

FetchUserInfoOperation()
.retryOnFailure({(numberOfRetries, error, retry) in
	retry(true)
}
.didFinish { result
//Update UI
}
.add(to: queue)

Or receive a sequence of values over time from a Combine upstream publishers.

subscriber =
		$searchedText
			.compactMap({$0})
			.deliver(to: SimpleMapOperation<String>(), on: queue)
			.retry(2)
			.receive(on: RunLoop.main)
			.catch({_ in Just("Helllo")})
			.sink(receiveValue: { (value) in

				//do something with received value
			
			})

A protocol that declares an operation type that should be unique. By adopting this protocol to an operation type you prevent that type from duplicate executation in same time.

class SampleOperation: VoidOperation, UniqueOperation {
	var uniqueId: String = "A Unique String"
}

A subclass of OperationQueue that implements a large number of "extra features" related to the AOperation class.

	let queue = AOperationQueue()
		let operation = SampleOperation()
	queue.addOperation(operation)

Another way of adding operation to queue:

SampleOperation()
.add(to: queue)

AOperationQueue.shared

A global instance of AOperationQueue that you can use it if you need.

	SampleOperation()
	.add(to: .shared)

AOperation supports declarative syntax.

URLSessionTaskOperation.data(for: url)
.conditions(UserAccessCondition())
.observers(TimeoutObserver(5))
.delvier(to: JsonDecoderOperation<[Comments]>)
.didFinish { result in
    // Update UI
}
.add(to: queue)

AOperation is fully compatible with Combine.

cancellable =
	$searchedText
	.throttle(for: 2, scheduler: RunLoop.main, latest: true)
	.compactMap({ (text) -> String? in
		return text?.replacingOccurrences(of: " ", with: "")
	})
	.filter({!$0.isEmpty})
	.removeDuplicates()
	.deliver(to: ModernFetchUserTimeLineOperation(), on: queue)
	.catch({ _ in Just([])})
	.assign(to: \.tweets, on: self)

A protocol for defining conditions that must be satisfied for an operation to begin execution.

struct UserAccessConditoin: AOperationCondition {
	static var isMutuallyExclusive: Bool = true
	
	let dependentOperation: AOperation? = RequestUserAccessOperation()
}

The protocol that types may conform if they wish to be notified of significant operation lifecycle events.

SampleOperation()
.didStart {
}
.didFinish { result in
}
.add(to: queue)

The type of error used in AOperation.

let error = AOperationError(receivedError)
self.finish(error)

A flag that if you turn it on, prints some message on debugger about operations lifecycle.

AOperation.Debugger.printOperationsState = true

See Also