/*:#localized(key: "HopBackToMain")
 # The return trip: hop back to main

 Here's the pattern you'll use constantly. Heavy or slow work goes on a
 background queue with `async`. When it's done and you need to touch the UI,
 you `async` **back to the main queue**. Work out; result back.

 Remember the rule from earlier: **all UI updates must happen on the main
 thread.** Updating UI from a background thread is a classic, hard-to-spot
 bug. The hop back to main is how you obey the rule.
 */
//#-editable-code
import Foundation
import PlaygroundSupport

PlaygroundPage.current.needsIndefiniteExecution = true

func totalSales(for days: Int) -> Int {
    // Stand-in for slow work: adding up a big register tape.
    var total = 0
    for day in 1...days { total += day * 37 }
    return total
}

print("Crunching the numbers...")

DispatchQueue.global(qos: .userInitiated).async {
    // heavy: background
    let result = totalSales(for: 100_000)

    DispatchQueue.main.async {
        // Back on main: safe to update the "UI" (here, a print).
        print("Weekly total: \(result), updating the label now")
        PlaygroundPage.current.finishExecution()
    }
}
//#-end-editable-code
/*:#localized(key: "HopBackToMain-2")
 **Watch it run:** `Crunching the numbers...` prints immediately (the main
 thread never blocked), then the total appears once the background work
 finishes and hands the result back to main. In a real app that inner block
 would set a label's text or reload a table, and because it runs on the main
 queue, that's safe.
 
 Memorize this shape: `global().async { ...work... ;
 DispatchQueue.main.async { ...UI... } }`.

 [Previous](@previous)  |  page 6 of 9  |  [Next: Quality of Service: How Urgent Is This?](@next)
 */
