SWIFT: Concurrency simplified


/ Published in: Objective C
Save to your folder(s)

This simple example shows how a customer can buy a ticket within a specific line but then payment can happen in parallel.


Copy this code and paste it in your HTML
  1. //
  2. // ViewController.swift
  3. // Concurrency
  4. //
  5. // Created by tommy trojan on 4/11/15.
  6. // Copyright (c) 2015 Skyground Media Inc. All rights reserved.
  7. //
  8. import Foundation
  9. import UIKit
  10.  
  11. class ViewController: UIViewController {
  12.  
  13. @IBOutlet weak var nextBuyerLbl: UILabel!
  14.  
  15. @IBOutlet weak var currentBuyerLbl: UILabel!
  16.  
  17. @IBOutlet weak var tapeRollLbl: UITextView!
  18.  
  19.  
  20. @IBOutlet weak var onAlphaSlider: UISlider!
  21.  
  22. @IBOutlet weak var resetBtn: UIButton!
  23.  
  24. @IBOutlet weak var buyBtn: UIButton!
  25.  
  26. let customers:Array<String> = ["Audrey", "B", "C", "D", "E"]
  27.  
  28. var currentIdx:Int = 0
  29.  
  30. var serial:dispatch_queue_t = dispatch_queue_create("com.test.serial", DISPATCH_QUEUE_SERIAL)
  31.  
  32. override func viewDidLoad() {
  33. super.viewDidLoad()
  34. // Do any additional setup after loading the view, typically from a nib.
  35. clearLabels()
  36. }
  37.  
  38. override func didReceiveMemoryWarning() {
  39. super.didReceiveMemoryWarning()
  40. }
  41.  
  42. override func viewDidAppear(animated: Bool) {
  43. buyTicket()
  44. }
  45.  
  46. @IBAction func onAlphaChanged(sender: AnyObject) {
  47.  
  48. }
  49.  
  50. @IBAction func onResetClicked(sender: AnyObject) {
  51.  
  52. }
  53.  
  54. @IBAction func onBuyClicked(sender: AnyObject) {
  55. buyTicket()
  56. }
  57.  
  58. func clearLabels(){
  59. updateLabels( "currentBuyerLbl", message: "")
  60. updateLabels( "tapeRollLbl", message: "")
  61. updateLabels( "nextBuyerLbl", message: "")
  62. }
  63.  
  64. //Serial task
  65. func buyTicket(){
  66. //Increment the index
  67. currentIdx++
  68. if(currentIdx == customers.count ){
  69. //Turn off the BUY button
  70. buyBtn.enabled = false
  71.  
  72. clearLabels()
  73.  
  74. updateLabels( "currentBuyerLbl", message: "No more customers.")
  75. }else{
  76. //Switch to new customer
  77. let customerName:String = customers[currentIdx]
  78.  
  79. dispatch_async(serial, {
  80. //Run simulator to resemble an HTTP request
  81. let num:Double = Simulator.sharedInstance.runSimulatorWithMinTime(2, maxTime: 5)
  82. //You cannot update the UIX from a background thread so you call this data back up the main UIX.
  83. dispatch_async(dispatch_get_main_queue(), { () -> Void in
  84. //Update the text label with the new async data
  85. self.updateLabels("currentBuyerLbl", message: "Current: " + self.customers[self.currentIdx])
  86.  
  87. self.updateLabels("tapeRollLbl", message: "\(customerName) bought tickets in \(num).")
  88.  
  89. var nextIdx:Int = self.currentIdx + 1
  90. self.updateLabels( "nextBuyerLbl", message: "Next:self. " + self.customers[nextIdx])
  91. })
  92. })
  93. //Customer Will Now Pay
  94. submitPayment(customerName)
  95. }
  96. }
  97.  
  98. //Parallel task
  99. func submitPayment(customerName:String){
  100. dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), { ()-> Void in
  101. //Run simulator to resemble an HTTP request
  102. let num:Double = Simulator.sharedInstance.runSimulatorWithMinTime(2, maxTime: 5)
  103. dispatch_async(dispatch_get_main_queue(), { () -> Void in
  104. //Update the text label with the new async data
  105. self.updateLabels("tapeRollLbl", message: "\(customerName) paid in \(num).")
  106. })
  107. })
  108. }
  109.  
  110. func updateLabels(label:String, message:String){
  111.  
  112. switch(label){
  113. case "currentBuyerLbl":
  114. currentBuyerLbl.text = message
  115. break
  116. case "nextBuyerLbl":
  117. nextBuyerLbl.text = message
  118. break
  119. case "tapeRollLbl":
  120. var oldMessage:String = tapeRollLbl.text
  121. var newMessage:String = "\(message) \n"
  122.  
  123. tapeRollLbl.text = oldMessage + newMessage
  124.  
  125. break
  126. default :
  127. break
  128. }
  129. }
  130. }
  131.  
  132. class Simulator {
  133.  
  134. class var sharedInstance: Simulator {
  135. struct Static {
  136. static let instance: Simulator = Simulator()
  137. }
  138. return Static.instance
  139. }
  140.  
  141. func runSimulatorWithMinTime( minTime:Int, maxTime:Int ) -> Double {
  142.  
  143. //Calculate random thread wait time
  144. let ms:Int = ( Int(rand()) % ((maxTime - minTime) * 1000) ) + (minTime * 1000)
  145.  
  146. let waitTime:Double = Double(ms) / 1000.0;
  147.  
  148. let timer:Void = NSThread.sleepForTimeInterval(waitTime)
  149.  
  150. println( "Simulator.runSimulatorWithMinTime:", waitTime )
  151. return waitTime
  152. }
  153.  
  154. }

Report this snippet


Comments

RSS Icon Subscribe to comments

You need to login to post a comment.