Advertisement
Guest User

Untitled

a guest
Jul 12th, 2018
75
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Swift 3.02 KB | None | 0 0
  1. import UIKit
  2. import Foundation
  3. import PlaygroundSupport
  4.  
  5. import AVFoundation
  6. PlaygroundPage.current.needsIndefiniteExecution = true
  7.  
  8.  
  9. class AsyncOperation: Operation {
  10.    
  11.     internal enum State {
  12.         case pending, executing, finished
  13.     }
  14.    
  15.     private var managedKeyPaths: [KeyPath<AsyncOperation, Bool>] {
  16.         return [\AsyncOperation.isExecuting, \AsyncOperation.isFinished]
  17.     }
  18.  
  19.     internal var state = State.pending {
  20.         willSet { managedKeyPaths.forEach { willChangeValue(for: $0) } }
  21.         didSet { managedKeyPaths.forEach { didChangeValue(for: $0) } }
  22.     }
  23.    
  24.     override var isAsynchronous: Bool {
  25.         return true
  26.     }
  27.    
  28.     override var isExecuting: Bool {
  29.         return state == .executing
  30.     }
  31.    
  32.     override var isFinished: Bool {
  33.         return state == .finished
  34.     }
  35. }
  36.  
  37. extension Operation {
  38.     func cancelRecursively() {
  39.         cancel()
  40.         dependencies.forEach { $0.cancelRecursively() }
  41.     }
  42. }
  43.  
  44. extension Array where Element: Operation {
  45.     func cancel() {
  46.         self.forEach { $0.cancel() }
  47.     }
  48. }
  49.  
  50. extension Array where Element: Operation {
  51.     func join() {
  52.         zip(self, self[1...]).forEach { $0.1.addDependency($0.0) }
  53.     }
  54. }
  55.  
  56. extension ArraySlice where Element: Operation {
  57.     func cancel() {
  58.         self.forEach { $0.cancel() }
  59.     }
  60. }
  61.    
  62. extension OperationQueue {
  63.     func addWithDependencies(_ op: Operation) {
  64.         addOperation(op)
  65.         op.dependencies.forEach { self.addWithDependencies($0) }
  66.     }
  67.    
  68.     func addLinearSteps(_ ops: [Operation]) {
  69.         guard let target = ops.last else { return }
  70.         addWithDependencies(target)
  71.     }
  72. }
  73.  
  74. class GuidingOperation: AsyncOperation, AVSpeechSynthesizerDelegate {
  75.     let text: String
  76.     let talk: AVSpeechSynthesizer
  77.    
  78.     func speechSynthesizer(_ synthesizer: AVSpeechSynthesizer, didFinish utterance: AVSpeechUtterance) {
  79.         state = .finished
  80.     }
  81.    
  82.     func speechSynthesizer(_ synthesizer: AVSpeechSynthesizer, didCancel utterance: AVSpeechUtterance) {
  83.         state = .finished
  84.     }
  85.    
  86.     init(text: String, talk: AVSpeechSynthesizer) {
  87.         self.text = text
  88.         self.talk = talk
  89.         super.init()
  90.     }
  91.    
  92.     override func cancel() {
  93.         super.cancel()
  94.         talk.stopSpeaking(at: .word)
  95.     }
  96.    
  97.     override func start() {
  98.         guard !isCancelled else {
  99.             state = .finished
  100.             return
  101.         }
  102.         state = .executing
  103.         talk.delegate = self
  104.         speak()
  105.     }
  106.    
  107.     func speak() {
  108.         let utterance = AVSpeechUtterance(string: text)
  109.         talk.speak(utterance)
  110.     }
  111. }
  112.  
  113. let talk = AVSpeechSynthesizer()
  114.  
  115. let guide1 = GuidingOperation(text: "However, GCD offers a better alternative as of iOS 5", talk: talk)
  116. let guide2 = GuidingOperation(text: "One of the most common mistakes even experienced iOS/Mac developers make is", talk: talk)
  117.  
  118. let guide = [guide1, guide2]
  119. guide.join()
  120.  
  121. OperationQueue.main.addLinearSteps(guide)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement