Reputation: 77
I am learning Swift on Udemy and JSON data parsing has me struggling. I have created two files WebService.swift
and OrderListViewModel.swift
. Former is... as name suggests implementing the data request (node.js) from Glitch while later is implementing View Model. Here are the files:
`WebService.swift`:
import Foundation
class Webservice {
func getAllOrders(completion: @escaping ([Order]?) -> ()) {
guard let url = URL(string: "https://island-bramble.glitch.me/orders") else {
completion(nil)
return
}
let task = URLSession.shared.dataTask(with: url) { data, response, error in
guard let data = data, error == nil else {
DispatchQueue.main.async {
completion(nil)
}
return
}
let orders = try? JSONDecoder().decode([Order].self, from: data)
DispatchQueue.main.async {
completion(orders)
}
}.resume()
}
}
I reasonably understand what's happening here. I am unable to understand the part that's happening below.
`OrderListViewModel.swift`:
import Foundation
class OrderListViewModel: ObservableObject {
var orders = [OrderViewModel]()
init() {
fetchOrders()
}
func fetchOrders() {
Webservice().getAllOrders { orders in
if let orders = orders {
self.orders = orders.map(OrderViewModel.init)
}
}
}
}
class OrderViewModel {
let id = UUID()
var order: Order
init (order: Order) {
self.order = order
}
var name: String {
return self.order.name
}
var size: String {
return self.order.size
}
var coffeeName: String {
return self.order.coffeeName
}
var total: Double {
return self.order.total
}
}
How is fetchOrders()
fetching orders
. More specifically how is this block of code (closure) fetching the orders
? Alternatively, if data fetched from remote server is passed as arguments to the callback function’s parameters how is below code retrieving it?
Webservice().getAllOrders { orders in
if let orders = orders {
self.orders = orders.map(OrderViewModel.init)
}
Upvotes: 2
Views: 94
Reputation: 123
You call a function
Webservice().getAllOrders
and pass a completion block
{ orders in
if let orders = orders {
self.orders = orders.map(OrderViewModel.init)
}
into it.
Completion block will receive value named orders
of type [Order]?
and if orders
is not nil
if let orders = orders
You can assign your class var orders
, which is declared here
var orders = [OrderViewModel]
to new array which in turn contains elements of type OrderViewModel
The latter is the result of
orders.map(OrderViewModel.init)
and this can also be written like
orders.forEach { order in
self.orders.append(OrderViewModel.init(order))
}
Upvotes: 1