52: CupcakeCorner, part 4

그루두·2024년 6월 26일
0

100 days of SwiftUI

목록 보기
59/108

100 days of swiftui: 52

Challenge

  1. Our address fields are currently considered valid if they contain anything, even if it’s just only whitespace. Improve the validation to make sure a string of pure whitespace is invalid.
  2. If our call to placeOrder() fails – for example if there is no internet connection – show an informative alert for the user. To test this, try commenting out the request.httpMethod = "POST" line in your code, which should force the request to fail.
  3. For a more challenging task, try updating the Order class so it saves data such as the user's delivery address to UserDefaults. This takes a little thinking, because @AppStorage won't work here, and you'll find getters and setters cause problems with Codable support. Can you find a middle ground?

Solution

1. 주소에 공백 문자열 입력 방지하기

trimmingCharacters()로 빈 문자열이 아닌지 확인했다. 찾아보니, 만약 공백 문자열을 제출하면 trim 이후 빈 문자열을 반환한다고 해서 == ""로 빈 문자열을 확인했다.
trimmingCharacters(in:)

    var hasValidAddress: Bool {
        if name.isEmpty || streetAddress.isEmpty || city.isEmpty || zip.isEmpty || streetAddress.trimmingCharacters(in: .whitespacesAndNewlines) == "" {
                return false
        }
        return true
    }

깃헙 링크

2. placeOrder()가 실패할 경우 alert 나타내기

해당 함수에 이미 실패할 경우에 return을 하도록 설정되어 있어서, retrun 값을 성공했을 땐 true, 실패했을 땐 false로 설정했다. 그리고 placeOrder()를 실행한 후 return 값에 따라 alert 메시지를 변경했다.

                Button("Place Order") {
                    Task {
                        if !(await placeOrder()) {
                            confirmationMessage = "Failed to place order. Please check if you're in proper environment."
                            showingConfirmation = true
                        }
                    }
                }
    func placeOrder() async -> Bool{
        guard let encoded = try? JSONEncoder().encode(order) else {
            print("Error: Failed to encode order")
            return false
        }
        let url = URL(string: "https://reqres.in/api/cupcakes")!
        var request = URLRequest(url: url)
        request.setValue("application/json", forHTTPHeaderField: "Content-Type")
        request.httpMethod = "POST"
        do {
            let (data, _) = try await URLSession.shared.upload(for: request, from: encoded)
            let decodedOrder = try JSONDecoder().decode(Order.self, from: data)
            confirmationMessage = "Your order for \(decodedOrder.quantity) x \(Order.types[decodedOrder.type].lowercased()) cupcakes is on its way!"
            showingConfirmation = true
            return true
        } catch {
            print("Error: Get \(error.localizedDescription)")
            return false
        }
    }

깃헙 링크

3. user's delivery address를 Userdefaults에 저장하기

class가 만들어질 때(initializer) 이전의 값은 없었는지 확인하고 불러오고, 값이 바뀌면 바로 Userdefaults에 저장되도록 했다.


그래서 앱을 닫아도 주소 정보가 저장된다.

속성 정의:

    var name = "" {
        didSet {
            UserDefaults.standard.setValue(name, forKey: "Name")
        }
    }
    var streetAddress = "" {
        didSet {
            UserDefaults.standard.setValue(streetAddress, forKey: "StreetAddress")
        }
    }
    var city = "" {
        didSet {
            UserDefaults.standard.setValue(city, forKey: "City")
        }
    }
    var zip = "" {
        didSet {
            UserDefaults.standard.setValue(zip, forKey: "Zip")
        }
    }

initializer 정의:

    init() {
        self.name = UserDefaults.standard.string(forKey: "Name") ?? ""
        self.streetAddress = UserDefaults.standard.string(forKey: "StreetAddress") ?? ""
        self.city = UserDefaults.standard.string(forKey: "City") ?? ""
        self.zip = UserDefaults.standard.string(forKey: "Zip") ?? ""
    }

깃헙 링크

profile
계속 해보자

0개의 댓글

관련 채용 정보