- μ¬λ¬κ°μ§μ κ³ΌμΌ μ£Όμ€λ₯Ό λ§λ€λλ§λ€ κ³ΌμΌ μ°½κ³ μ μ¬κ³ λ₯Ό κ΄λ¦¬νκ³ , μ΄λ₯Ό UIλ‘ λ³΄μ¬μ£Όλ μ±μ λλ€.
1. νμ
2. μμλ
3. νμλΌμΈ
6. μ°Έκ³ λ§ν¬
μ μ¬ | λ―Έλ |
---|---|
![]() |
|
@ash-youu | @leegyoungmin |
-
2022.08.29
- 곡μλ¬Έμ νμ΅
-
2022.08.30
-
2022.08.31
- PR λ°μ‘ λ° κ³΅μλ¬Έμ νμ΅
-
2022.09.01
- STEP1
README.md
μμ± λ° κ³΅μλ¬Έμ νμ΅
- STEP1
-
2022.09.02
-
2022.09.05
- iOS UI μ±κ°λ° νμ΅
-
2022.09.06
-
2022.09.07
- STEP2
README.md
μμ± λ° PR λ°μ‘
- STEP2
-
2022.09.08
-
2022.09.12
- STEP3 UI μμ
- λ‘μ§ κ΅¬ν
-
2022.09.13
- STEP3 λ‘μ§ μμ
- STEP3 PR λ°μ‘
-
2022.09.15
- STEP3 리뷰μ λ°λ₯Έ 리ν©ν λ§ μ§ν
-
2022.09.16
- STEP3
README.md
μμ±
- STEP3
-
μ₯¬μ€λ©μ΄μ»€λ‘
makeJuice(juice:)
ν¨μ μ€νclass ViewController: UIViewController { private let maker = JuiceMaker() override func viewDidLoad() { super.viewDidLoad() for _ in 1...20 { if let juice = Juice.allCases.randomElement() { maker.makeJuice(juice: juice) } } } }
-
makeJuice(juice:)
λ°haveStock(of:, over:)
,increaseStock(of:, by:)
μ€λͺfunc makeJuice(juice: Juice) { let juiceNeedFruits = juice.needFruits let juiceNeedStocks = juice.needStocks do { try fruitStore.haveStock(of: juiceNeedFruits, over: juiceNeedStocks) fruitStore.increaseStock(of: juiceNeedFruits, by: juiceNeedStocks) print("μ£Όλ¬Ένμ \(juice.description) λμμ΅λλ€.") } catch StoreError.outOfStock { print("μ¬κ³ κ° λΆμ‘±ν©λλ€.") } catch { print("μ μ μλ μ€λ₯κ° λ°μνμμ΅λλ€.") } }
- μ΄ ν¨μλ μ£Όμ€λ₯Ό λ§λλ λͺ λ Ήμ λ΄λ¦¬λ ν¨μμ λλ€.
- μ΄ ν¨μμ κΈ°λ₯μ μ°½κ³ μ μ¬κ³ κ° μλμ§ νμΈ ν μλ€κ³ νλ¨νμ κ²½μ°μλ§ μ°½κ³ μ μ¬λ£λ₯Ό κ°μ Έμ μλ£λ₯Ό λ§λ€ λλ‘ μ€κ³νμμ΅λλ€.
- λ§μ½, μ¬κ³ κ° μκ±°λ λΆμ‘±ν κ²½μ°μλ μλ¬λ₯Ό λ°μμν€λλ‘ νμμ΅λλ€.
func haveStock(of fruits: [Fruit], over stocks: [Int]) throws { for (fruit, stock) in zip(fruits, stocks) { guard let remainStock = inventory[fruit], remainStock >= -stock else { throw StoreError.outOfStock } } }
haveStock(of:, over:)
μ μ£Όμ€λ₯Ό λ§λ€κΈ° μν΄μ νμν μ¬κ³ κ° μλμ§ νμΈνλ ν¨μμ λλ€.- μ΄ ν¨μλ₯Ό νμ©νμ¬μ μ¬κ³ κ° μλ κ²½μ°μ μλ¬λ₯Ό λ°μμν€λλ‘ κ΅¬ννμμ΅λλ€.
- λ§μ½, μ¬κ³ κ° μλ€λ©΄ ν¨μλ μ’
λ£λκ² λμ΄, μλ¬λ₯Ό λ°μμν€μ§ μκΈ° λλ¬Έμ
makeJuice(juice:)
ν¨μμ λ€μ κ΅¬λ¬Έμ΄ μ€νλκ² λ©λλ€.
func increaseStock(of fruits: [Fruit], by amounts: [Int]) { for (fruit, stock) in zip(fruits, amounts) { if let remainStock = inventory[fruit] { inventory.updateValue(remainStock + stock, forKey: fruit) } } }
increaseStock(of:, by:)
μ μ¬κ³ κ° μλ μ£Όμ€λ₯Ό μμ±νκΈ° μν΄μ μ¬λ£λ₯Ό κΊΌλ΄μ€λ κ³Όμ μ ννν ν¨μμ λλ€.- μ£Όμ€μ νμν μ¬λ£λ€κ³Ό μμ ν΅ν΄μ νμ¬ μ°½κ³ μ μ¬κ³ λ₯Ό μ€μ΄λ μν μ λ΄λΉνκ² λ©λλ€.
- λν, μ΄λ μμμ κ°μ΄ λ€μ΄μ€κ² λλ©΄, μ¬κ³ λ₯Ό μ¦κ°μν€λ ν¨μλ‘λ νμ©ν μ μμ΅λλ€.
- μλ£ μ£Όλ¬Έ λ° μ΄λ₯Ό ν΅ν΄μ λ³κ²½λ μ¬κ³ μ λν κ° λ°μ
- κ° λ²νΌμ κ°κ°μ μλ£λ₯Ό μ£Όλ¬Ένλ λ²νΌμ΄λ€.
- μ΄ λ²νΌμ λλ₯΄κ² λλ©΄, μ£Όμ€λ₯Ό λ§λ€ μ μλ μ¬κ³ λ₯Ό νμΈν ν μ£Όμ€λ₯Ό λ§λ€κ² λλ€.
- μ΄λ, μ£Όμ€λ₯Ό λ§λ€κ³ λ νμλ νμν μ¬κ³ λ€μ κ°μμν€κ² λλ€.
- λν, νλ©΄μ 보μ¬μ§λ λ°μ΄ν°λ λ°λ‘ μ λ°μ΄νΈκ° λλ€.
- λ
ΈμΉν κΈ°κΈ° μ€ν νλ©΄
- νλ²νΌ 보μ κΈ°κΈ° μ€ν μμ
- κ° νλ©΄μμ 'μ¬κ³ μμ ' νΉμ 'λ«κΈ°' λ²νΌμ λλ₯΄λ κ²½μ°, μ μ ν νλ©΄μΌλ‘ μ νλλ€.
- μ¬κ³ μμ νλ©΄μμ Stepperλ₯Ό μ΄μ©ν μλ λ³κ²½ μ λ©μΈ νλ©΄μμλ ν΄λΉ μλμΌλ‘ μ λ°μ΄νΈ λλ€.
- μ€ν λ μ΄μμμ ν΅ν΄ μμ΄ν κΈ°μ’ μ κΈ°κΈ°μμλ ν΅μΌλ νλ©΄μ΄ λ³΄μ¬μ§κ² λλ€.
makeJuice()
μμ juiceλ³ ν¨μ νΈμΆμ λν λ¬Έμ -
κ°λ³ 맀κ°λ³μλ₯Ό νμ©νλ λ°©λ²κ³Ό 리μ€νΈλ₯Ό λ°ννλ λ°©λ²
// Before func makeJuice(juice: Juice) { switch juice { ... case .strawberrybananaJuice: if fruitStore.checkStock(fruit: .strawberry, stock: -10) && fruitStore.checkStock(fruit: .banana, stock: -1) { fruitStore.changeStock(fruits: .strawberry, .banana, stocks: -10, -1) } case .mangokiwiJuice: if fruitStore.checkStock(fruit: .mango, stock: -2) && fruitStore.checkStock(fruit: .kiwi, stock: -1) { fruitStore.changeStock(fruits: .mango, .kiwi, stocks: -2, -1) } } } // After func makeJuice(juice: Juice) { let juiceNeedFruits = juice.needFruits let juiceNeedStocks = juice.needStocks do { try fruitStore.haveStock(of: juiceNeedFruits, over: juiceNeedStocks) fruitStore.increaseStock(of: juiceNeedFruits, by: juiceNeedStocks) } catch StoreError.outOfStock { print("μ¬κ³ κ° λΆμ‘±ν©λλ€.") } catch { print("μ μ μλ μ€λ₯κ° λ°μνμμ΅λλ€.") } }
-
Beforeκ³Ό κ°μ΄ νΈμΆ μ
juice
μ μΌμ΄μ€ λ³λ‘haveStock()
κ³ΌincreaseStock()
μ κ°κ° νΈμΆν΄μ€μΌ νμ¬ μ½λμ μ€λ³΅λκ° λμμ§λ λ¬Έμ κ° μμμ΅λλ€. -
Juice
νμ μμ μ£Όμ€ λ³λ‘ νμν κ³ΌμΌ(needFruits
)κ³Ό μλ(needStocks
)μ μ μΈνμ¬needFruitAndStock: [Fruit: Int]
μ Dictionary νμ μhaveStock()
κ³ΌincreaseStock()
λ΄λΆμμ νμ©νλ λ°©ν₯μΌλ‘ μμ νμμ΅λλ€.
-
-
κ°μ²΄μ μ±κΈν€νμ λν κ³ λ―Ό
- μ±κΈν€μ μ₯μ μλ ν λ²μ Instanceλ§ μμ±νμ¬μ λ©λͺ¨λ¦¬ λλΉλ₯Ό λ°©μ§ν μ μμ΅λλ€. λν, λ€λ₯Έ μμλ€κ³Ό 곡μ κ° μ½λ€λ μ₯μ μ΄ μμ΅λλ€.
- μ±κΈν€ μ¬μ©μ΄ μ λμ μΌλ‘ μ₯μ λ§ μλ κ²μ μλλλ€. μλ₯Ό λ€μ΄μ λ©μλμ λ³κ²½μ΄ μ΄λ£¨μ΄ μ§λ λ§λ€ μμ μ ν΄μΌ νλ λΆλΆμ΄ λ§μ΄ μκΈ΄λ€λμ§, λ§μ λ°μ΄ν°λ₯Ό 곡μ ν κ²½μ° λ€λ₯Έ ν΄λμ€μ Instanceλ€ κ° κ²°ν©λκ° λμμ§κ² λ©λλ€.
- λ€μν 쑰건과 νλ‘μ νΈμ λ°©ν₯μ±μ λν λ
Όμλ₯Ό νμ¬μ νμ₯μ±μ μκ°νμμ λ, μΆκ°μ μΈ μ°½κ³ Instanceκ° μμ±λκ³ , 1νΈμ , 2νΈμ λ±κ³Ό κ°μ νμ₯μμ κ²°ν©λκ° λμμ§ κ²μ΄λΌκ³ νλ¨νμ¬μ μ±κΈν€μ μ¬μ©νλ κ²λ³΄λ€λ
JuiceMaker
νμ μ΄FruitStore
νμ μ μμ νκ³ μλλ‘ νμμ΅λλ€.
-
NotificationCenter νμ© μ νλ‘νΌν° μ΄κΈ°κ° μ€μ μ΄ λΆκ°ν λ¬Έμ
class FruitStore { private var inventory: [Fruit: Int] = Fruit.beginningStock { didSet { NotificationCenter.default.post( name: Notification.Name.stockChanged, object: nil, userInfo: inventory ) } } }
FruitStore
μinventory
κ° λ³νλ₯Ό νλ‘νΌν° κ°μμ(didSet
) λ΄μ NotificationCenterλ₯Ό μ¬μ©ν΄JuiceMakerViewController
μ μ λ¬νλ λ°©μμ μ¬μ©νμ΅λλ€.- μ΄μ κ°μ΄ μ§ν μ
inventory
κ°μ΄ λ³ν λμλ§ NotificationCenterμpost
νκ² λμ΄λ§μλ μ₯¬μ€λ₯Ό λ§λ€μ΄ λλ €μ!
Viewμμ μ΄κΈ°κ°μ λ°μμ΄ μ΄λ €μ΄ λ¬Έμ κ° μμμ΅λλ€. - μ±μ΄ μλ‘ μΌμ§ λλ§λ€ κ³ΌμΌμ μλμ λͺ¨λ 10μΌλ‘ μ΄κΈ°νλκΈ° λλ¬Έμ View λ΄μμ κ³ΌμΌλ³
StockLabel
μ 10μΌλ‘ μ€μ νκ³ , μ΄νinventory
μ κ°μ΄ λ³κ²½λ λλ§λ€didSet
μ ν΅ν΄StockLabel.text
κ° μμ λ μ μλλ‘ νμ΅λλ€.
-
λ무 λ§μ
@IBOutlet
λ³μ μ μΈ- κΈ°μ‘΄μλ κ³ΌμΌλ³ μ¬κ³ λ μ΄λΈμ κ°λ³
@IBOultet
λ³μλ‘ μ μΈνμμ΅λλ€. - μ΄μ κ°μ΄ μμ±νκ² λλ κ²½μ°,
JuiceMakerViewController
μModifyViewController
ν΄λμ€μμ λͺ¨λ λ μ΄λΈμ λν λ³μλ₯Ό μ μΈνκ² λμ΄ λ무 λ§μ@IBOutlet
λ³μλ₯Ό μ μΈνκ² λλ λ¬Έμ κ° λ°μνμ΅λλ€. - λν,
forEach
λ¬Έμ ν΅ν΄ λ μ΄λΈμtext
κ°μ μ λ°μ΄νΈν λμλ λͺ¨λ κ°λ³ λ μ΄λΈμ μ·¨ν©ν΄ λ°°μ΄λ‘ μ¬μ μν΄μ£Όμ΄μΌ νλ λ¬Έμ κ° μμμ΅λλ€. @IBOutlet
μ ν΅ν΄ λ μ΄λΈμ λ³μλ₯Ό μ μΈν λ,[UILabel]
νμ μfruitLabels
λ‘ μ μΈλ μ μκ² νμκ³ ,forEach
λ¬Έμ ν΅ν΄ κ°μ μ λ°μ΄νΈν λμλ ν΄λΉ λ°°μ΄μ νμ©νλ λ°©λ²μΌλ‘ μμ νμμ΅λλ€.// Before @IBOutlet weak var strawberryStockLabel: UILabel! @IBOutlet weak var bananaStockLabel: UILabel! @IBOutlet weak var pineAppleStockLabel: UILabel! @IBOutlet weak var kiwiStockLabel: UILabel! @IBOutlet weak var mangoStockLabel: UILabel! // After @IBOutlet var fruitLabels: [UILabel]!
- κΈ°μ‘΄μλ κ³ΌμΌλ³ μ¬κ³ λ μ΄λΈμ κ°λ³
-
NotificationCenter
λ₯Ό ν΅ν μ΅μ λΉ ν¨ν΄κ³Ό μμ‘΄μ± μ£ΌμSTEP 2
μμ λ°μνμλ μ΄κΈ°ν λ¨κ³μμ νμ©ν μ μμλ λ¬Έμ μ λλ²μ§Έ νλ©΄μμ λ°μ΄ν°λ₯Ό μ λ¬νκ³ λκ°μ λ·° 컨νΈλ‘€λ¬κ° κ°μ λ°μ΄ν°λ₯Ό μ¬μ©νλ λ°μ λ¬Έμ κ° μμμ΅λλ€.- μ΄λ₯Ό ν΄κ²°νκΈ° μν΄μ μ§μ° μμ± νλ‘νΌν°λ₯Ό ν΅ν΄μ
JuiceMaker
μ μμ‘΄μ±μ μ£Όμ νμ¬μFruitStore
λ‘ μμ±λλ μΈμ€ν΄μ€λ₯ΌJuiceMakerViewController
κ° κ°μ§κ³ μλλ‘ κ΅¬ννμμ΅λλ€. - λν, μ΄λ₯Ό ν΅ν΄μ
ModifyViewController
μ λ°μ΄ν°λ₯ΌDelegate Pattern
μΌλ‘ λμ± μ½κ² λ°μ΄ν°λ₯Ό μ λ¬ν μ μλλ‘ νμμ΅λλ€. - μΆκ°μ μΌλ‘
Delegate
μμ μ μν νλ‘νΌν°λ₯Ό μ½κΈ° μ μ© νλ‘νΌν°λ‘ μ μ©νμ¬μModifyViewController
μμ μ§μ μ μΌλ‘ μμ νλ κ²μ λ°©μ§νκ³ μ νμμ΅λλ€. - μμ κ°μ μν©μμ
NotificationCenter
λ₯Ό νμ©νμ¬μFruitStore
μ μλ λ°μ΄ν° λ³κ²½μ κ΄μ°°νλ κ²μ λ°μ΄ν° λ³κ²½μ λ°λ₯Έ λ·°μ κ°±μ λ§ ν μ μκ² λλ κ²μ΄ μ₯μ μ΄λΌκ³ μκ°νμκ³ , μμ‘΄μ±μ μ£Όμ νμμ λμλ λ°μ΄ν°μ λ³κ²½μ κ΄μ°°νμ§ μμμ λ°μ΄ν° λ·°μ κ°±μ μ μ§μ μ μΌλ‘ ν΄μ€μΌ νμ§λ§, λλ²μ§Έ νλ©΄κ³Όμ λ°μ΄ν°λ₯Ό 곡μ ν μ μλ κ²μ΄ μ₯μ μ΄λΌκ³ μκ°νμμ΅λλ€. - μ ν¬λ μ΄μ κ°μ μν©μμ μ΄λ€ λ°©λ²μ΄ λ μ μ ν λ°©λ²μΈμ§μ λν΄μ κ³ λ―Όνκ² λμμ΅λλ€.
private let store = FruitStore() lazy var maker = JuiceMaker(store: store)
-
Delegate ν¨ν΄μ μ½κΈ° μ μ© νλ‘νΌν°
segue
λ₯Ό ν΅ν΄μ λ°μ΄ν°λ₯Ό μ λ¬ν λ,λλ²μ§Έ 뷰컨νΈλ‘€λ¬μ μΈμ€ν΄μ€μ 첫λ²μ§Έ λ·° 컨νΈλ‘€λ¬μstore
μ μ¬κ³ λ λ€λ₯Έ μΈμ€ν΄μ€κ° μμ±λκΈ° λλ¬Έμ νλ©΄μ΄Dismiss
λκΈ° μ μ λ°μ΄ν°λ₯Ό λ€μ λ겨μ λ³κ²½ν΄μ€μΌ νλ λ¨μ μ΄ μμμ΅λλ€.- μ ν¬λ νλ©΄μ΄ μ νλ λ λ°μ΄ν°λ₯Ό λ°μνλ κ²μ΄ μλλΌ μ¬μ©μμ μ΄λ²€νΈμ λ°λΌμ μ§μ μ μΌλ‘ λ³νλ₯Ό μ£Όκ³ μΆμμ΅λλ€. κ·Έλμ
Delegate Pattern
μ νμ©νμ¬μ λ°μ΄ν°μ λ³νλ₯Ό λ°μνκ³ , λλ²μ§Έ νλ©΄μ μ΄κΈ°κ°μ λ°μν μ μλλ‘ μ½κΈ°μ μ© νλ‘νΌν°λ₯Ό μ μνμμ΅λλ€. - μ²μ μ μ©ν λμλ λ¨μν
get
μ μ μ΄ λμμΌλκΉ μ½κΈ°μ μ©μΌλ‘ ꡬνμ νκ²μ΄λΌκ³ μκ°νμ¬μ μ΄μκ° λ°μνμμ΅λλ€. - νμ§λ§, λ©μλλ₯Ό μ μνλ κ²κ³Όλ λ¬λ¦¬, νλ‘νΌν°λ₯Ό μ μνκΈ° μν΄μλ μ½κΈ°μ μ© νλ‘νΌν°μλ μ΄λ€ κ²λ€μ΄ μκ³ , μ½κΈ°μ μ°κΈ°κ° λͺ¨λ κ°λ₯ν νλ‘νΌν°λ μ΄λ€ κ²λ€μ΄ μλμ§ μμμΌ νμ΅λλ€.
- μ΄μ λν΄μ 곡λΆν κ²°κ³Ό, νλ‘ν μ½μμμ
get, set
ν€μλλ μ½κΈ° μ μ©κ³Ό μ°κΈ°κ°λ₯μ λν κ²μ μ μλ§ νλ€λ κ²μ μμκ³ , μ μ₯ νλ‘νΌν°μ μ°μ° νλ‘νΌν°μμ μ½κΈ° μ μ© νλ‘νΌν°λ₯Ό μ μνλ λ°©λ²κ³Ό μ°κΈ° κ°λ₯ νλ‘νΌν°λ₯Ό μ μνλ λ°©λ²μ΄ μλ€λ κ²μ μμμ΅λλ€. - μ΄λ₯Ό λ°νμΌλ‘ μ°μ° νλ‘νΌν°μμμ μ½κΈ°μ μ© νλ‘νΌν°λ₯Ό μ μ©νμ¬μ λλ²μ§Έ λ·° 컨νΈλ‘€λ¬μμ μ½λ κ²λ§ κ°λ₯ν λ°μ΄ν°λ₯Ό μ λ¬ν μ μλλ‘ νμμ΅λλ€.
extension JuiceMakerViewController: ModifyStockDelegate { var inventory: [Fruit: Int] { get { return store.inventory } } func updateStock(by fruit: Fruit, to stock: Int) { store.inventory[fruit] = stock updateStockLabels() } }