@escaping closures in SwiftUI

Updated:

@escaping closures in SwiftUI

When you want to download something from the Internet, we have to use asynchronous code. It runs from top to bottom immediately and then executes.

Compare regular function we will write the function it will run all those lines in our coed and then it will return as soon as it gets to the bottom. Those functions basically can return immediately.

But when we are going to a database to download data from the Internet, we’re going to create functions to go get that data but that data is not going to come back immediately. It’s going to take a couple seconds to go to the server get that data bring it back to our App

So, we can just immediately return out of this function and instead of immediately returning we need to handle this asynchronous code and we do that in swift with escaping closures

Basically, creating a function and then within that function we are passing another function as a parameter into the first function and this way we can call that second function when our code comes back from the database and when we want it to actually execute

import SwiftUI

// MARK: -  MODEL
struct DownloadResult {
let data: String
}

// typealias create shortcut DownloadResult return Void
typealias DownloadCompletion = (DownloadResult) -> ()

// MARK: -  VIEWMODEL
class EscapingViewModel: ObservableObject {
// MARK: -  PROPERTY
@Published var text: String = "Hello"
// MARK: -  INIT
// MARK: -  FUNCTION
func getData() {
  // text = downloadData()
  // downloadData2 { returnedData in
  // 	text = returnedData
  // }

  // downloadData3(forData: "Someting")

  // downloadData4 { [weak self] returnedData in
  // 	self?.text = returnedData

  // downloadData5 {[weak self] retrurnResult in
  // 	self?.text = retrurnResult.data
  // }

  downloadData6 {[weak self] retrurnResult in
    self?.text = retrurnResult.data
  }

}
// if we had a whole bunch of logic in this function it would run immediately line by line
// But there are times when this is not going to work
func downloadData() -> String {
  return "New data!"
}


// completionHandler which is then a function that we can call by calling completion handler
// and then padding in our new data2
func downloadData2(completionHandler: (_ data: String) -> Void) {

  completionHandler("New data2!")
  // Add Delay
  // DispatchQueue.main.asyncAfter(deadline: .now() + 2.0) {
  //
  // }
}

// -> () equal : return anything same as  -> Void
func downloadData3(forData data: String) -> () {
  print(data)
}

// when we add this @escaping it makes our code asynchronous which means it's not going to
// immediately execute and return
func downloadData4(completionHandler: @escaping (_ data: String) -> ()) {
  DispatchQueue.main.asyncAfter(deadline: .now() + 2.0) {
    completionHandler("New Data 4!")
  }
}

// short version of downloadData4 to use MODEL
func downloadData5(completionHandler: @escaping (DownloadResult) -> ()) {
  let result = DownloadResult(data: "New Data5!")
  DispatchQueue.main.asyncAfter(deadline: .now() + 2.0) {
    completionHandler(result)
  }
}

// short version of downloadData5 to use typealias
func downloadData6(completionHandler: @escaping DownloadCompletion) {
  let result = DownloadResult(data: "New Data5!")
  DispatchQueue.main.asyncAfter(deadline: .now() + 2.0) {
    completionHandler(result)
  }
}
}


struct ExcapingBootCamp: View {
// MARK: -  PROPERTY
@StateObject var vm = EscapingViewModel()
// MARK: -  BODY
var body: some View {
Text(vm.text)
  .font(.largeTitle)
  .fontWeight(.semibold)
  .foregroundColor(.blue)
  .onTapGesture {
    vm.getData()
  }
}
}

스크린샷

You do know this @escaping, you can actually get into downloading this data from the Internet finally and putting in into App


🗃 Reference

SwiftUI Thinking - https://www.youtube.com/watch?v=7gg8iBH2fg4&list=PLwvDm4VfkdpiagxAXCT33Rkwnc5IVhTar&index=21

Categories:

Updated:

Leave a comment