- 쥬스 주문
- 쥬스 주문 실패
- 재고 부족 Alert
- 재고 수정
- 닫기 버튼
class FruitLabel: UILabel {
var fruit: Fruits?
func setting() {
guard let fruit = self.fruit else {
return
}
text = FruitStore.shared.stock(fruit: fruit)?.description
}
}
- storyboard에서 사용할 수 있도록 UILabel, UIStepper, UIButton 하위 클래스를 생성했어요.
- FruitLabel의 text 값을 FruitStore에서 받아온 각 과일의 재고로 변경했어요.
- UIStepper에서도 동일하게 FruitStore의 값으로 초기화를 한 뒤 사용할 수 있도록 변경하였어요.
- UIButton의 경우에는 protocol을 이용하여 속성 값을 추가했어요.
- Object 별로 생성한 다음 custom class를 storyboard에서 매칭을 시켜줬어요
ViewController에서 모델의 데이터를 사용하기 위해서 데이터 전달하는 방법을 알아보았고 그 중에서도 Delegate를 이용한 데이터 전달로 해결을 했어요
// JuiceMakerViewController.swift
class JuiceMakerViewController: UIViewController {
override func viewDidLoad() {
FruitStore.shared.updateDelegate = self
}
}
extension JuiceMakerViewController: UpdateDelegate {
func updateLabel(fruit: Fruits) {
// ...
}
}
protocol UpdateDelegate: AnyObject {
func updateLabel(fruit: Fruits)
}
// FruitStore.swift
final class FruitStore {
weak var updateDelegate: UpdateDelegate?
func update(fruit: Fruits, quantity: Quantity) {
// ...
updateDelegate?.updateLabel(fruit: fruit)
}
}
Dictionary에서 값을 변경할 때, 우선적으로 key값이 있는지 확인하면서 Optional을 Unwrapping해야 하는데 !
를 사용하지 않는 방법에 대해서 고민했습니다
updateValue(_:forKey:) 공식문서를 보면 @discardableResult 키워드로 반환값을 사용하지 않아도 된다고 판단, guard문을 통해서 key값을 확인해서 새로운 값이 추가되지 않도록 하었습니다
func manageFruit(_ fruit: FruitsKind, quantity: Int) {
guard let stock = self.fruits[fruit] else {
return
}
self.fruits.updateValue(stock - quantity, forKey: fruit)
}
MVC 디자인 패턴을 사용할 때, Error의 핸들링(do-catch문)을 어떻게 처리를 해야 하나 고민을 했어요. Model에서 Error를 반환하였다면, Controller에서 확인하고 에러의 상황을 Alert으로 통해서 View에서 보이게 만들었어요.
// ViewController.swift
@IBAction func orderJuice(_ sender: UIButton) {
guard let juice = (sender as? MenuObject)?.juice else {
return
}
do {
try juiceMaker.make(juice: juice)
madeJuiceAlert(juice: juice)
} catch {
shortOfStockAlert(message: error.localizedDescription)
}
}