
Day 52 of #100Days was the challenges to the Cupcake Corner app – an app that allows you to build a one-row order, encode it as JSON and submit it to an API with a URLSession. To allow the order to be passed around, it’s an @ObservedObject which meant that a few extra hoops needed to be jumped through to make it Codable.
1) Whitespace validation
The tutorial app validates the order address by checking that each field is not empty, but it can be fooled by just entering some spaces. The first challenge was to fix that.
The tutorial version of the app accomplished the checking with a computed property in the Order struct – which is a good place for it. Here it is:
var hasValidAddress: Bool {
if name.isEmpty || streetAddress.isEmpty || city.isEmpty || zip.isEmpty {
return false
}
return true
}
There’s no .isEmptyIfYouIgnoreWhiteSpace method, so I did this:
var hasValidAddress: Bool {
let trimmedName = name.trimmingCharacters(in: .whitespacesAndNewlines)
let trimmedStreetAddress = streetAddress.trimmingCharacters(in: .whitespacesAndNewlines)
let trimmedCity = city.trimmingCharacters(in: .whitespacesAndNewlines)
let trimmedZip = zip.trimmingCharacters(in: .whitespacesAndNewlines)
if trimmedName.isEmpty || trimmedStreetAddress.isEmpty || trimmedCity.isEmpty || trimmedZip.isEmpty {
return false
}
return true
}
2) Show an alert if the POST fails
In the tute version, this is just a print statement. This challenge just involves adding a second alert to the checkout view. Source
3) Change order to struct
This is a bit more complicated. A reason for preferring a struct is that all of the extra work we did to make the class Codable is eliminated. We need the thing being passed around to be an object because we want a reference type that can be mutated inside the view hierarchy, and because we want it to be an @Observed Object. The change proposed here is sort of the best of both worlds – have the object, but it’s sole property is the struct.
I created a wrapper class, with the struct as an @Published var.
class Wrapper: ObservableObject {
@Published var order = Order()
deinit {
}
}
Then I changed the Order class to a struct, removed @Published from all the properties and deleted the encode/decode code. Then in all the views, I had to go through and fix the names. I did not love the less readable names I was creating; for example wrapped.order.streetAddress instead of just order.streetAddress. But that all worked.
Leave a comment