// Start a new project
// Add a UILabel and UIButton to the default view controller
// connect the label to countLabel @IBOutlet
// connect the button to doFetch @IBAction
//
// each tap of the button will call fetch() in LoginManager.shared
// and use a 1-second delay to simulate fetching data from an API
class ViewController: UIViewController {
@IBOutlet var countLabel: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
// set the "callback" closure in LoginManager
LoginManager.shared.callback = { [weak self] str in
// safely unwrap self
guard let self = self else { return }
// we have to update UI elements on the main thread
DispatchQueue.main.async {
// set the returned str to countLabel's text
self.countLabel.text = str
}
}
}
@IBAction func doFetch(_ sender: Any) {
countLabel.text = "Calling API..."
LoginManager.shared.fetch()
}
}
class LoginManager {
static let shared = LoginManager()
// counter var
var myCounter: Int = 0
// closure for communication
var callback: ((String) -> ())?
func fetch() -> Void {
// increment the counter
myCounter += 1
// 1-second delay to simulate getting data from API
DispatchQueue.global(qos: .userInitiated).asyncAfter(deadline: .now() + 1, execute: {
// get a random number from 1 to 9999
let n = Int.random(in: 1...9999)
// use the closure to send it back as a string
self.callback?("API Count: \(self.myCounter) Random: \(n)")
})
}
}
Comments
0 B
|👍
/👎