Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import UIKit
- import Foundation
- import PlaygroundSupport
- import AVFoundation
- PlaygroundPage.current.needsIndefiniteExecution = true
- class AsyncOperation: Operation {
- internal enum State {
- case pending, executing, finished
- }
- private var managedKeyPaths: [KeyPath<AsyncOperation, Bool>] {
- return [\AsyncOperation.isExecuting, \AsyncOperation.isFinished]
- }
- internal var state = State.pending {
- willSet { managedKeyPaths.forEach { willChangeValue(for: $0) } }
- didSet { managedKeyPaths.forEach { didChangeValue(for: $0) } }
- }
- override var isAsynchronous: Bool {
- return true
- }
- override var isExecuting: Bool {
- return state == .executing
- }
- override var isFinished: Bool {
- return state == .finished
- }
- }
- extension Operation {
- func cancelRecursively() {
- cancel()
- dependencies.forEach { $0.cancelRecursively() }
- }
- }
- extension Array where Element: Operation {
- func cancel() {
- self.forEach { $0.cancel() }
- }
- }
- extension Array where Element: Operation {
- func join() {
- zip(self, self[1...]).forEach { $0.1.addDependency($0.0) }
- }
- }
- extension ArraySlice where Element: Operation {
- func cancel() {
- self.forEach { $0.cancel() }
- }
- }
- extension OperationQueue {
- func addWithDependencies(_ op: Operation) {
- addOperation(op)
- op.dependencies.forEach { self.addWithDependencies($0) }
- }
- func addLinearSteps(_ ops: [Operation]) {
- guard let target = ops.last else { return }
- addWithDependencies(target)
- }
- }
- class GuidingOperation: AsyncOperation, AVSpeechSynthesizerDelegate {
- let text: String
- let talk: AVSpeechSynthesizer
- func speechSynthesizer(_ synthesizer: AVSpeechSynthesizer, didFinish utterance: AVSpeechUtterance) {
- state = .finished
- }
- func speechSynthesizer(_ synthesizer: AVSpeechSynthesizer, didCancel utterance: AVSpeechUtterance) {
- state = .finished
- }
- init(text: String, talk: AVSpeechSynthesizer) {
- self.text = text
- self.talk = talk
- super.init()
- }
- override func cancel() {
- super.cancel()
- talk.stopSpeaking(at: .word)
- }
- override func start() {
- guard !isCancelled else {
- state = .finished
- return
- }
- state = .executing
- talk.delegate = self
- speak()
- }
- func speak() {
- let utterance = AVSpeechUtterance(string: text)
- talk.speak(utterance)
- }
- }
- let talk = AVSpeechSynthesizer()
- let guide1 = GuidingOperation(text: "However, GCD offers a better alternative as of iOS 5", talk: talk)
- let guide2 = GuidingOperation(text: "One of the most common mistakes even experienced iOS/Mac developers make is", talk: talk)
- let guide = [guide1, guide2]
- guide.join()
- OperationQueue.main.addLinearSteps(guide)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement