SwiftUI เชชเชฐ เชเชชเซเชฒเชฟเช•เซ‡เชถเชจ เชตเชฟเช•เชพเชธ. เชญเชพเช— 1: เชกเซ‡เชŸเชพเชซเซเชฒเซ‹ เช…เชจเซ‡ เชฐเซ‡เชกเช•เซเชธ

SwiftUI เชชเชฐ เชเชชเซเชฒเชฟเช•เซ‡เชถเชจ เชตเชฟเช•เชพเชธ. เชญเชพเช— 1: เชกเซ‡เชŸเชพเชซเซเชฒเซ‹ เช…เชจเซ‡ เชฐเซ‡เชกเช•เซเชธ

WWDC 2019 เช–เชพเชคเซ‡ เชธเซเชŸเซ‡เชŸ เช‘เชซ เชง เชฏเซเชจเชฟเชฏเชจ เชธเชคเซเชฐเชฎเชพเช‚ เชนเชพเชœเชฐเซ€ เช†เชชเซเชฏเชพ เชชเช›เซ€, เชฎเซ‡เช‚ SwiftUI เชฎเชพเช‚ เชŠเช‚เชกเชพ เช‰เชคเชฐเชตเชพเชจเซเช‚ เชจเช•เซเช•เซ€ เช•เชฐเซเชฏเซเช‚. เชฎเซ‡เช‚ เชคเซ‡เชจเซ€ เชธเชพเชฅเซ‡ เช•เชพเชฎ เช•เชฐเชตเชพเชฎเชพเช‚ เช˜เชฃเซ‹ เชธเชฎเชฏ เชตเชฟเชคเชพเชตเซเชฏเซ‹ เช›เซ‡ เช…เชจเซ‡ เชนเชตเซ‡ เชเช• เชตเชพเชธเซเชคเชตเชฟเช• เชเชชเซเชฒเชฟเช•เซ‡เชถเชจ เชตเชฟเช•เชธเชพเชตเชตเชพเชจเซเช‚ เชถเชฐเซ‚ เช•เชฐเซเชฏเซเช‚ เช›เซ‡ เชœเซ‡ เชตเชชเชฐเชพเชถเช•เชฐเซเชคเชพเช“เชจเซ€ เชตเชฟเชถเชพเชณ เชถเซเชฐเซ‡เชฃเซ€ เชฎเชพเชŸเซ‡ เช‰เชชเชฏเซ‹เช—เซ€ เชฅเชˆ เชถเช•เซ‡.

เชฎเซ‡เช‚ เชคเซ‡เชจเซ‡ MovieSwiftUI เช•เชนเชฏเซเช‚ - เช† เชจเชตเซ€ เช…เชจเซ‡ เชœเซ‚เชจเซ€ เชซเชฟเชฒเซเชฎเซ‹ เชถเซ‹เชงเชตเชพเชจเซ€ เชธเชพเชฅเซ‡ เชธเชพเชฅเซ‡ เชคเซ‡เชจเซ‡ เชธเช‚เช—เซเชฐเชนเชฎเชพเช‚ เชเช•เชคเซเชฐเชฟเชค เช•เชฐเชตเชพ เชฎเชพเชŸเซ‡เชจเซ€ เชเชชเซเชฒเชฟเช•เซ‡เชถเชจ เช›เซ‡ TMDB API. เชฎเชจเซ‡ เชนเช‚เชฎเซ‡เชถเชพ เชซเชฟเชฒเซเชฎเซ‹ เชชเชธเช‚เชฆ เช›เซ‡ เช…เชจเซ‡ เช† เช•เซเชทเซ‡เชคเซเชฐเชฎเชพเช‚ เช•เชพเชฎ เช•เชฐเชคเซ€ เชเช• เช•เช‚เชชเชจเซ€ เชชเชฃ เชฌเชจเชพเชตเซ€ เช›เซ‡, เชœเซ‹เช•เซ‡ เช˜เชฃเชพ เชธเชฎเชฏ เชชเชนเซ‡เชฒเชพ. เช•เช‚เชชเชจเซ€เชจเซ‡ เชญเชพเช—เซเชฏเซ‡ เชœ เช เช‚เชกเซ€ เช•เชนเซ€ เชถเช•เชพเชฏ, เชชเชฐเช‚เชคเซ เชเชชเซเชฒเชฟเช•เซ‡เชถเชจ เชนเชคเซ€!

เช…เชฎเซ‡ เชฏเชพเชฆ เช•เชฐเชพเชตเซ€เช เช›เซ€เช: Habrเชจเชพ เชคเชฎเชพเชฎ เชตเชพเชšเช•เซ‹ เชฎเชพเชŸเซ‡ - Habr เชชเซเชฐเซ‹เชฎเซ‹ เช•เซ‹เชกเชจเซ‹ เช‰เชชเชฏเซ‹เช— เช•เชฐเซ€เชจเซ‡ เช•เซ‹เชˆเชชเชฃ เชธเซเช•เชฟเชฒเชฌเซ‹เช•เซเชธ เช•เซ‹เชฐเซเชธเชฎเชพเช‚ เชจเซ‹เช‚เชงเชฃเซ€ เช•เชฐเชคเซ€ เชตเช–เชคเซ‡ 10 เชฐเซ‚เชฌเชฒ เชกเชฟเชธเซเช•เชพเช‰เชจเซเชŸ.

เชธเซเช•เชฟเชฒเชฌเซ‹เช•เซเชธ เชญเชฒเชพเชฎเชฃ เช•เชฐเซ‡ เช›เซ‡: เชถเซˆเช•เซเชทเชฃเชฟเช• เช“เชจเชฒเชพเชˆเชจ เช•เซ‹เชฐเซเชธ "เชชเซเชฐเซ‹เชซเซ‡เชถเชจ เชœเชพเชตเชพ เชกเซ‡เชตเชฒเชชเชฐ".

เชคเซ‹ MovieSwiftUI เชถเซเช‚ เช•เชฐเซ€ เชถเช•เซ‡?

  • API เชธเชพเชฅเซ‡ เช•เซเชฐเชฟเชฏเชพเชชเซเชฐเชคเชฟเช•เซเชฐเชฟเชฏเชพ เช•เชฐเซ‡ เช›เซ‡ - เชฒเช—เชญเช— เช•เซ‹เชˆเชชเชฃ เช†เชงเซเชจเชฟเช• เชเชชเซเชฒเชฟเช•เซ‡เชถเชจ เช† เช•เชฐเซ‡ เช›เซ‡.
  • เชตเชฟเชจเช‚เชคเซ€เช“ เชชเชฐ เช…เชธเซเชฎเซ‡เชณ เชกเซ‡เชŸเชพ เชฒเซ‹เชก เช•เชฐเซ‡ เช›เซ‡ เช…เชจเซ‡ JSON เชจเซ‹ เช‰เชชเชฏเซ‹เช— เช•เชฐเซ€เชจเซ‡ เชธเซเชตเชฟเชซเซเชŸ เชฎเซ‹เชกเชฒเชฎเชพเช‚ เชชเชพเชฐเซเชธ เช•เชฐเซ‡ เช›เซ‡ เช•เซ‹เชกเซ‡เชฌเชฒ.
  • เชตเชฟเชจเช‚เชคเซ€ เชชเชฐ เชฒเซ‹เชก เช•เชฐเซ‡เชฒเซ€ เช›เชฌเซ€เช“ เชฌเชคเชพเชตเซ‡ เช›เซ‡ เช…เชจเซ‡ เชคเซ‡เชฎเชจเซ‡ เช•เซ‡เชถ เช•เชฐเซ‡ เช›เซ‡.
  • iOS, iPadOS เช…เชจเซ‡ macOS เชฎเชพเชŸเซ‡เชจเซ€ เช† เชเชชเซเชฒเชฟเช•เซ‡เชถเชจ เช† OS เชจเชพ เชตเชชเชฐเชพเชถเช•เชฐเซเชคเชพเช“ เชฎเชพเชŸเซ‡ เชถเซเชฐเซ‡เชทเซเช  UX เชชเซเชฐเชฆเชพเชจ เช•เชฐเซ‡ เช›เซ‡.
  • เชตเชชเชฐเชพเชถเช•เชฐเซเชคเชพ เชกเซ‡เชŸเชพ เชœเชจเชฐเซ‡เชŸ เช•เชฐเซ€ เชถเช•เซ‡ เช›เซ‡ เช…เชจเซ‡ เชคเซ‡เชฎเชจเซ€ เชชเซ‹เชคเชพเชจเซ€ เชฎเซ‚เชตเซ€ เชฒเชฟเชธเซเชŸ เชฌเชจเชพเชตเซ€ เชถเช•เซ‡ เช›เซ‡. เชเชชเซเชฒเชฟเช•เซ‡เชถเชจ เชตเชชเชฐเชพเชถเช•เชฐเซเชคเชพ เชกเซ‡เชŸเชพเชจเซ‡ เชธเชพเชšเชตเซ‡ เช›เซ‡ เช…เชจเซ‡ เชชเซเชจเชƒเชธเซเชฅเชพเชชเชฟเชค เช•เชฐเซ‡ เช›เซ‡.
  • Redux เชชเซ‡เชŸเชฐเซเชจเชจเซ‹ เช‰เชชเชฏเซ‹เช— เช•เชฐเซ€เชจเซ‡ เชฆเซƒเชถเซเชฏเซ‹, เช˜เชŸเช•เซ‹ เช…เชจเซ‡ เชฎเซ‰เชกเชฒ เชธเซเชชเชทเซเชŸ เชฐเซ€เชคเซ‡ เช…เชฒเช— เช•เชฐเชตเชพเชฎเชพเช‚ เช†เชตเซ‡ เช›เซ‡. เช…เชนเซ€เช‚ เชกเซ‡เชŸเชพเชจเซ‹ เชชเซเชฐเชตเชพเชน เชฆเชฟเชถเชพเชตเชฟเชนเซ€เชจ เช›เซ‡. เชคเซ‡ เชธเช‚เชชเซ‚เชฐเซเชฃเชชเชฃเซ‡ เช•เซ‡เชถเซเชก, เชชเซเชจเชƒเชธเซเชฅเชพเชชเชฟเชค เช…เชจเซ‡ เชซเชฐเซ€เชฅเซ€ เชฒเช–เซ€ เชถเช•เชพเชฏ เช›เซ‡.
  • เชเชชเซเชฒเชฟเช•เซ‡เชถเชจ SwiftUI, TabbedView, Segmented Control, NavigationView, Form, Modal, เชตเช—เซ‡เชฐเซ‡เชจเชพ เชฎเซ‚เชณเชญเซ‚เชค เช˜เชŸเช•เซ‹เชจเซ‹ เช‰เชชเชฏเซ‹เช— เช•เชฐเซ‡ เช›เซ‡. เชคเซ‡ เช•เชธเซเชŸเชฎ เชตเซเชฏเซ‚, เชนเชพเชตเชญเชพเชต, UI/UX เชชเชฃ เชชเซเชฐเชฆเชพเชจ เช•เชฐเซ‡ เช›เซ‡.

SwiftUI เชชเชฐ เชเชชเซเชฒเชฟเช•เซ‡เชถเชจ เชตเชฟเช•เชพเชธ. เชญเชพเช— 1: เชกเซ‡เชŸเชพเชซเซเชฒเซ‹ เช…เชจเซ‡ เชฐเซ‡เชกเช•เซเชธ
เชนเช•เซ€เช•เชคเชฎเชพเช‚, เชเชจเชฟเชฎเซ‡เชถเชจ เชธเชฐเชณ เช›เซ‡, GIF เชฅเซ‹เชกเซ‹ เช†เช‚เชšเช•เซ‹ เชฒเชพเช—เซเชฏเซ‹

เชเชช เชชเชฐ เช•เชพเชฎ เช•เชฐเชตเชพเชฅเซ€ เชฎเชจเซ‡ เช˜เชฃเซ‹ เช…เชจเซเชญเชต เชฎเชณเซเชฏเซ‹ เช…เชจเซ‡ เชเช•เช‚เชฆเชฐเซ‡ เชคเซ‡ เชธเช•เชพเชฐเชพเชคเซเชฎเช• เช…เชจเซเชญเชต เชนเชคเซ‹. เชนเซเช‚ เชเช• เชธเช‚เชชเซ‚เชฐเซเชฃ เช•เชพเชฐเซเชฏเชพเชคเซเชฎเช• เชเชชเซเชฒเชฟเช•เซ‡เชถเชจ เชฒเช–เชตเชพเชฎเชพเช‚ เชธเช•เซเชทเชฎ เชนเชคเซ‹, เชธเชชเซเชŸเซ‡เชฎเซเชฌเชฐเชฎเชพเช‚ เชนเซเช‚ เชคเซ‡เชจเซ‡ เชธเซเชงเชพเชฐเซ€เชถ เช…เชจเซ‡ เชคเซ‡เชจเซ‡ เชเชชเชธเซเชŸเซ‹เชฐเชฎเชพเช‚ เชชเซเชฐเช•เชพเชถเชฟเชค เช•เชฐเซ€เชถ, เชเช• เชธเชพเชฅเซ‡ iOS 13 เชจเชพ เชชเซเชฐเช•เชพเชถเชจ เชธเชพเชฅเซ‡.

Redux, BindableObject เช…เชจเซ‡ EnvironmentObject

SwiftUI เชชเชฐ เชเชชเซเชฒเชฟเช•เซ‡เชถเชจ เชตเชฟเช•เชพเชธ. เชญเชพเช— 1: เชกเซ‡เชŸเชพเชซเซเชฒเซ‹ เช…เชจเซ‡ เชฐเซ‡เชกเช•เซเชธ

เชนเซเช‚ เชฒเช—เชญเช— เชฌเซ‡ เชตเชฐเซเชทเชฅเซ€ Redux เชธเชพเชฅเซ‡ เช•เชพเชฎ เช•เชฐเซ€ เชฐเชนเซเชฏเซ‹ เช›เซเช‚, เชคเซ‡เชฅเซ€ เชนเซเช‚ เชคเซ‡เชฎเชพเช‚ เชชเซเชฐเชฎเชพเชฃเชฎเชพเช‚ เชธเชพเชฐเซ€ เชฐเซ€เชคเซ‡ เชตเชพเช•เซ‡เชซ เช›เซเช‚. เช–เชพเชธ เช•เชฐเซ€เชจเซ‡, เชนเซเช‚ เชคเซ‡เชจเซ‡ เชฎเชพเชŸเซ‡ เช…เช—เซเชฐเชญเชพเช—เชฎเชพเช‚ เช‰เชชเชฏเซ‹เช— เช•เชฐเซเช‚ เช›เซเช‚ เชชเซเชฐเชคเชฟเช•เซเชฐเชฟเชฏเชพ เชตเซ‡เชฌเชธเชพเช‡เชŸ, เชคเซ‡เชฎเชœ เชฎเซ‚เชณ iOS (Swift) เช…เชจเซ‡ Android (Kotlin) เชเชชเซเชฒเชฟเช•เซ‡เชถเชจ เชตเชฟเช•เชธเชพเชตเชตเชพ เชฎเชพเชŸเซ‡.

เชธเซเชตเชฟเชซเซเชŸเชฏเซเช†เชˆ เชเชชเซเชฒเซ€เช•เซ‡เชถเชจ เชฌเชจเชพเชตเชตเชพ เชฎเชพเชŸเซ‡ เชกเซ‡เชŸเชพ เชซเซเชฒเซ‹ เช†เชฐเซเช•เชฟเชŸเซ‡เช•เซเชšเชฐ เชคเชฐเซ€เช•เซ‡ เชฐเซ‡เชกเช•เซเชธเชจเซ‡ เชชเชธเช‚เชฆ เช•เชฐเชตเชพ เชฌเชฆเชฒ เชฎเชจเซ‡ เช•เซเชฏเชพเชฐเซ‡เชฏ เช…เชซเชธเซ‹เชธ เชฅเชฏเซ‹ เชจเชฅเซ€. UIKit เชเชชเซเชฒเชฟเช•เซ‡เชถเชจเชฎเชพเช‚ Redux เชจเซ‹ เช‰เชชเชฏเซ‹เช— เช•เชฐเชคเซ€ เชตเช–เชคเซ‡ เชธเซŒเชฅเซ€ เชชเชกเช•เชพเชฐเชœเชจเช• เชญเชพเช—เซ‹ เชธเซเชŸเซ‹เชฐ เชธเชพเชฅเซ‡ เช•เชพเชฎ เช•เชฐเซ‡ เช›เซ‡ เช…เชจเซ‡ เชกเซ‡เชŸเชพ เชฎเซ‡เชณเชตเชตเซ‹ เช…เชจเซ‡ เชชเซเชจเชƒเชชเซเชฐเชพเชชเซเชค เช•เชฐเชตเซ‹ เช…เชจเซ‡ เชคเซ‡เชจเซ‡ เชคเชฎเชพเชฐเชพ เชฆเซƒเชถเซเชฏเซ‹/เช˜เชŸเช•เซ‹เชฎเชพเช‚ เชฎเซ‡เชช เช•เชฐเชตเซ‹. เช† เช•เชฐเชตเชพ เชฎเชพเชŸเซ‡, เชฎเชพเชฐเซ‡ เช•เชจเซ‡เช•เซเชŸเชฐเซเชธเชจเซ€ เชเช• เชชเซเชฐเช•เชพเชฐเชจเซ€ เชฒเชพเช‡เชฌเซเชฐเซ‡เชฐเซ€ เชฌเชจเชพเชตเชตเชพเชจเซ€ เชนเชคเซ€ (ReSwift เช…เชจเซ‡ ReKotlin เชจเซ‹ เช‰เชชเชฏเซ‹เช— เช•เชฐเซ€เชจเซ‡). เชธเชพเชฐเซ€ เชฐเซ€เชคเซ‡ เช•เชพเชฎ เช•เชฐเซ‡ เช›เซ‡, เชชเชฐเช‚เชคเซ เช•เซ‹เชก เช˜เชฃเซ‹. เช•เชฎเชจเชธเซ€เชฌเซ‡, เชคเซ‡ (เชนเชœเซ เชธเซเชงเซ€) เช“เชชเชจ เชธเซ‹เชฐเซเชธ เชจเชฅเซ€.

เชธเชพเชฐเชพ เชธเชฎเชพเชšเชพเชฐ! SwiftUI เชธเชพเชฅเซ‡ เชšเชฟเช‚เชคเชพ เช•เชฐเชตเชพเชจเซ€ เชเช•เชฎเชพเชคเซเชฐ เชฌเชพเชฌเชคเซ‹ - เชœเซ‹ เชคเชฎเซ‡ Redux เชจเซ‹ เช‰เชชเชฏเซ‹เช— เช•เชฐเชตเชพเชจเซ€ เชฏเซ‹เชœเชจเชพ เช˜เชกเซ€ เชฐเชนเซเชฏเชพ เชนเซ‹เชต เชคเซ‹ - เชธเซเชŸเซ‹เชฐเซเชธ, เชธเซเชŸเซ‡เชŸเซเชธ เช…เชจเซ‡ เชฐเซ€เชกเซเชฏเซเชธเชฐ เช›เซ‡. @EnvironmentObjectเชจเซ‹ เช†เชญเชพเชฐ เชธเซเชตเชฟเชซเซเชŸเชฏเซเช†เชˆ เชฆเซเชตเชพเชฐเชพ เชธเซเชŸเซ‹เชฐ เชธเชพเชฅเซ‡เชจเซ€ เช•เซเชฐเชฟเชฏเชพเชชเซเชฐเชคเชฟเช•เซเชฐเชฟเชฏเชพเชจเซ€ เชธเช‚เชชเซ‚เชฐเซเชฃ เช•เชพเชณเชœเซ€ เชฒเซ‡เชตเชพเชฎเชพเช‚ เช†เชตเซ‡ เช›เซ‡. เชคเซ‡เชฅเซ€, เชธเซเชŸเซ‹เชฐ BindableObject เชฅเซ€ เชถเชฐเซ‚ เชฅเชพเชฏ เช›เซ‡.

เชฎเซ‡เช‚ เชเช• เชธเชฐเชณ เชธเซเชตเชฟเชซเซเชŸ เชชเซ‡เช•เซ‡เชœ เชฌเชจเชพเชตเซเชฏเซเช‚, SwiftUIFlux, เชœเซ‡ Redux เชจเซ‹ เชฎเซ‚เชณเชญเซ‚เชค เช‰เชชเชฏเซ‹เช— เชชเซ‚เชฐเซ‹ เชชเชพเชกเซ‡ เช›เซ‡. เชฎเชพเชฐเชพ เช•เชฟเชธเซเชธเชพเชฎเชพเช‚ เชคเซ‡ MovieSwiftUI เชจเซ‹ เชญเชพเช— เช›เซ‡. เชชเชฃ เชนเซเช‚ เชเช• เชชเช—เชฒเซเช‚ เชฆเซเชตเชพเชฐเชพ เชชเช—เชฒเซเช‚ เชŸเซเชฏเซเชŸเซ‹เชฐเซ€เชฏเชฒ เชฒเช–เซเชฏเซเช‚, เชœเซ‡ เชคเชฎเชจเซ‡ เช† เช˜เชŸเช•เชจเซ‹ เช‰เชชเชฏเซ‹เช— เช•เชฐเชตเชพเชฎเชพเช‚ เชฎเชฆเชฆ เช•เชฐเชถเซ‡.

เชคเซ‡ เช•เซ‡เชตเซ€ เชฐเซ€เชคเซ‡ เช•เชพเชฎ เช•เชฐเซ‡ เช›เซ‡?

final public class Store<State: FluxState>: BindableObject {
    public let willChange = PassthroughSubject<Void, Never>()
        
    private(set) public var state: State
    
    private func _dispatch(action: Action) {
        willChange.send()
        state = reducer(state, action)
    }
}

เชœเซเชฏเชพเชฐเซ‡ เชชเชฃ เชคเชฎเซ‡ เช•เซ‹เชˆ เช•เซเชฐเชฟเชฏเชพเชจเซ‡ เชŸเซเชฐเชฟเช—เชฐ เช•เชฐเซ‹ เช›เซ‹, เชคเซเชฏเชพเชฐเซ‡ เชคเชฎเซ‡ เช—เชฟเชฏเชฐเชฌเซ‹เช•เซเชธเชจเซ‡ เชธเช•เซเชฐเชฟเชฏ เช•เชฐเซ‹ เช›เซ‹. เชคเซ‡ เชเชชเซเชฒเชฟเช•เซ‡เชถเชจเชจเซ€ เชตเชฐเซเชคเชฎเชพเชจ เชธเซเชฅเชฟเชคเชฟ เช…เชจเซเชธเชพเชฐ เช•เซเชฐเชฟเชฏเชพเช“เชจเซเช‚ เชฎเซ‚เชฒเซเชฏเชพเช‚เช•เชจ เช•เชฐเชถเซ‡. เชคเซ‡ เชชเช›เซ€ เช•เซเชฐเชฟเชฏเชพเชจเชพ เชชเซเชฐเช•เชพเชฐ เช…เชจเซ‡ เชกเซ‡เชŸเชพ เช…เชจเซเชธเชพเชฐ เชจเชตเซ€ เชธเช‚เชถเซ‹เชงเชฟเชค เชธเซเชฅเชฟเชคเชฟ เชชเชฐเชค เช•เชฐเชถเซ‡.

เช เซ€เช• เช›เซ‡, เช•เชพเชฐเชฃ เช•เซ‡ เชธเซเชŸเซ‹เชฐ เช BindableObject เช›เซ‡, เชคเซ‡ SwiftUI เชจเซ‡ เชœเชพเชฃ เช•เชฐเชถเซ‡ เชœเซเชฏเชพเชฐเซ‡ PassthroughSubject เชฆเซเชตเชพเชฐเชพ เชชเซ‚เชฐเซ€ เชชเชพเชกเชตเชพเชฎเชพเช‚ เช†เชตเซ‡เชฒ willChange เชชเซเชฐเซ‹เชชเชฐเซเชŸเซ€เชจเซ‹ เช‰เชชเชฏเซ‹เช— เช•เชฐเซ€เชจเซ‡ เชคเซ‡เชจเซเช‚ เชฎเซ‚เชฒเซเชฏ เชฌเชฆเชฒเชพเชถเซ‡. เช† เชเชŸเชฒเชพ เชฎเชพเชŸเซ‡ เช›เซ‡ เช•เชพเชฐเชฃ เช•เซ‡ BindableObject เช PublisherType เชชเซเชฐเชฆเชพเชจ เช•เชฐเชตเซเช‚ เช†เชตเชถเซเชฏเช• เช›เซ‡, เชชเชฐเช‚เชคเซ เชชเซเชฐเซ‹เชŸเซ‹เช•เซ‹เชฒ เช…เชฎเชฒเซ€เช•เชฐเชฃ เชคเซ‡เชจเชพ เชธเช‚เชšเชพเชฒเชจ เชฎเชพเชŸเซ‡ เชœเชตเชพเชฌเชฆเชพเชฐ เช›เซ‡. เชเช•เช‚เชฆเชฐเซ‡, เช† Apple เชคเชฐเชซเชฅเซ€ เช–เซ‚เชฌ เชœ เชถเช•เซเชคเชฟเชถเชพเชณเซ€ เชธเชพเชงเชจ เช›เซ‡. เชคเชฆเชจเซเชธเชพเชฐ, เช†เช—เชพเชฎเซ€ เชฐเซ‡เชจเซเชกเชฐเชฟเช‚เช— เชธเชพเชฏเช•เชฒเชฎเชพเช‚, เชธเซเชตเชฟเชซเซเชŸเชฏเซเช†เชˆ เชฐเชพเชœเซเชฏเชจเชพ เชซเซ‡เชฐเชซเชพเชฐ เช…เชจเซเชธเชพเชฐ เชฎเช‚เชคเชตเซเชฏเซ‹เชจเชพ เชฎเซเช–เซเชฏ เชญเชพเช—เชจเซ‡ เชฐเซ‡เชจเซเชกเชฐ เช•เชฐเชตเชพเชฎเชพเช‚ เชฎเชฆเชฆ เช•เชฐเชถเซ‡.

เช–เชฐเซ‡เช–เชฐ, เช† เชธเซเชตเชฟเชซเซเชŸเชฏเซเช†เชˆเชจเซเช‚ เชนเซƒเชฆเชฏ เช…เชจเซ‡ เชœเชพเชฆเซ เช›เซ‡. เชนเชตเซ‡, เชฐเชพเชœเซเชฏเชฎเชพเช‚ เชธเชฌเซเชธเซเช•เซเชฐเชพเช‡เชฌ เช•เชฐเชจเชพเชฐ เช•เซ‹เชˆเชชเชฃ เชฆเซƒเชถเซเชฏเชฎเชพเช‚, เชฐเชพเชœเซเชฏเชฎเชพเช‚เชฅเซ€ เช•เชฏเซ‹ เชกเซ‡เชŸเชพ เชชเซเชฐเชพเชชเซเชค เชฅเชฏเซ‹ เช›เซ‡ เช…เชจเซ‡ เชถเซเช‚ เชฌเชฆเชฒเชพเชฏเซเช‚ เช›เซ‡ เชคเซ‡เชจเชพ เช†เชงเชพเชฐเซ‡ เชฆเซƒเชถเซเชฏ เชฐเซ‡เชจเซเชกเชฐ เช•เชฐเชตเชพเชฎเชพเช‚ เช†เชตเชถเซ‡.

class SceneDelegate: UIResponder, UIWindowSceneDelegate {
 
    var window: UIWindow?
 
 
    func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
        if let windowScene = scene as? UIWindowScene {
            let window = UIWindow(windowScene: windowScene)
            
            let controller = UIHostingController(rootView: HomeView().environmentObject(store))
            window.rootViewController = controller
            self.window = window
            window.makeKeyAndVisible()
        }
    }
}
 
struct CustomListCoverRow : View {
    @EnvironmentObject var store: Store<AppState>
    
    let movieId: Int
    var movie: Movie! {
        return store.state.moviesState.movies[movieId]
    }
    
    var body: some View {
        HStack(alignment: .center, spacing: 0) {
            Image(movie.poster)
        }.listRowInsets(EdgeInsets())
    }
}

เชœเซเชฏเชพเชฐเซ‡ เชเชชเซเชฒเชฟเช•เซ‡เชถเชจ เชถเชฐเซ‚ เชฅเชพเชฏ เช›เซ‡ เชคเซเชฏเชพเชฐเซ‡ เชธเซเชŸเซ‹เชฐเชจเซ‡ EnvironmentObject เชคเชฐเซ€เช•เซ‡ เช‡เชจเซเชœเซ‡เช•เซเชŸ เช•เชฐเชตเชพเชฎเชพเช‚ เช†เชตเซ‡ เช›เซ‡ เช…เชจเซ‡ เชชเช›เซ€ @EnvironmentObject เชจเซ‹ เช‰เชชเชฏเซ‹เช— เช•เชฐเซ€เชจเซ‡ เช•เซ‹เชˆเชชเชฃ เชฆเซƒเชถเซเชฏเชฎเชพเช‚ เชเช•เซเชธเซ‡เชธ เช•เชฐเซ€ เชถเช•เชพเชฏ เช›เซ‡. เชคเซเชฏเชพเช‚ เช•เซ‹เชˆ เชชเซเชฐเชฆเชฐเซเชถเชจ เชฆเช‚เชก เชจเชฅเซ€ เช•เชพเชฐเชฃ เช•เซ‡ เชตเซเชฏเซเชคเซเชชเชจเซเชจ เช—เซเชฃเชงเชฐเซเชฎเซ‹ เชเชกเชชเชฅเซ€ เชชเซเชจเชƒเชชเซเชฐเชพเชชเซเชค เช•เชฐเชตเชพเชฎเชพเช‚ เช†เชตเซ‡ เช›เซ‡ เช…เชฅเชตเชพ เชเชชเซเชฒเชฟเช•เซ‡เชถเชจเชจเซ€ เชธเซเชฅเชฟเชคเชฟเชฎเชพเช‚เชฅเซ€ เช—เชฃเชคเชฐเซ€ เช•เชฐเชตเชพเชฎเชพเช‚ เช†เชตเซ‡ เช›เซ‡.

เชœเซ‹ เชฎเซ‚เชตเซ€ เชชเซ‹เชธเซเชŸเชฐ เชฌเชฆเชฒเชพเชฏ เชคเซ‹ เช‰เชชเชฐเชจเซ‹ เช•เซ‹เชก เชˆเชฎเซ‡เชœ เชฌเชฆเชฒเซ‡ เช›เซ‡.

เช…เชจเซ‡ เช† เชตเชพเชธเซเชคเชตเชฎเชพเช‚ เชฎเชพเชคเซเชฐ เชเช• เชฒเชพเช‡เชจ เชธเชพเชฅเซ‡ เช•เชฐเชตเชพเชฎเชพเช‚ เช†เชตเซ‡ เช›เซ‡, เชœเซ‡เชจเซ€ เชฎเชฆเชฆเชฅเซ€ เชฆเซƒเชถเซเชฏเซ‹ เชฐเชพเชœเซเชฏ เชธเชพเชฅเซ‡ เชœเซ‹เชกเชพเชฏเซ‡เชฒเชพ เช›เซ‡. เชœเซ‹ เชคเชฎเซ‡ iOS เช…เชฅเชตเชพ เชคเซ‹ ReSwift เชธเชพเชฅเซ‡ เช•เชพเชฎ เช•เชฐเซเชฏเซเช‚ เช›เซ‡ เชœเซ‹เชกเชพเชตเชพ React เชธเชพเชฅเซ‡, เชคเชฎเซ‡ SwiftUI เชจเชพ เชœเชพเชฆเซเชจเซ‡ เชธเชฎเชœเซ€ เชถเช•เชถเซ‹.

เชนเชตเซ‡ เชคเชฎเซ‡ เช•เซเชฐเชฟเชฏเชพเชจเซ‡ เชธเช•เซเชฐเชฟเชฏ เช•เชฐเชตเชพเชจเซ‹ เชชเซเชฐเชฏเชพเชธ เช•เชฐเซ€ เชถเช•เซ‹ เช›เซ‹ เช…เชจเซ‡ เชจเชตเซ€ เชธเซเชฅเชฟเชคเชฟ เชชเซเชฐเช•เชพเชถเชฟเชค เช•เชฐเซ€ เชถเช•เซ‹ เช›เซ‹. เช…เชนเซ€เช‚ เชเช• เชตเชงเซ เชœเชŸเชฟเชฒ เช‰เชฆเชพเชนเชฐเชฃ เช›เซ‡.

struct CustomListDetail : View {
    @EnvironmentObject var store: Store<AppState>
 
    let listId: Int
    
    var list: CustomList {
        store.state.moviesState.customLists[listId]!
    }
    
    var movies: [Int] {
        list.movies.sortedMoviesIds(by: .byReleaseDate, state: store.state)
    }
    
    var body: some View {
        List {
            ForEach(movies) { movie in
                NavigationLink(destination: MovieDetail(movieId: movie).environmentObject(self.store)) {
                    MovieRow(movieId: movie, displayListImage: false)
                }
            }.onDelete { (index) in
               self.store.dispatch(action: MoviesActions.RemoveMovieFromCustomList(list: self.listId, movie: self.movies[index.first!]))
            }
        }
    }
}

เช‰เชชเชฐเชจเชพ เช•เซ‹เชกเชฎเชพเช‚, เชนเซเช‚ เชฆเชฐเซ‡เช• IP เชฎเชพเชŸเซ‡ SwiftUI เชคเชฐเชซเชฅเซ€ .onDelete เช•เซเชฐเชฟเชฏเชพเชจเซ‹ เช‰เชชเชฏเซ‹เช— เช•เชฐเซ€ เชฐเชนเซเชฏเซ‹ เช›เซเช‚. เช† เชธเซ‚เชšเชฟเชฎเชพเช‚เชจเซ€ เชชเช‚เช•เซเชคเชฟเชจเซ‡ เช•เชพเชขเซ€ เชจเชพเช–เชตเชพ เชฎเชพเชŸเซ‡ เชธเชพเชฎเชพเชจเซเชฏ iOS เชธเซเชตเชพเช‡เชช เชชเซเชฐเชฆเชฐเซเชถเชฟเชค เช•เชฐเชตเชพเชจเซ€ เชฎเช‚เชœเซ‚เชฐเซ€ เช†เชชเซ‡ เช›เซ‡. เชคเซ‡เชฅเซ€ เชœเซเชฏเชพเชฐเซ‡ เชตเชชเชฐเชพเชถเช•เชฐเซเชคเชพ เชกเชฟเชฒเซ€เชŸ เชฌเชŸเชจเชจเซ‡ เชธเซเชชเชฐเซเชถ เช•เชฐเซ‡ เช›เซ‡, เชคเซเชฏเชพเชฐเซ‡ เชคเซ‡ เช…เชจเซเชฐเซ‚เชช เช•เซเชฐเชฟเชฏเชพเชจเซ‡ เชŸเซเชฐเชฟเช—เชฐ เช•เชฐเซ‡ เช›เซ‡ เช…เชจเซ‡ เชฎเซ‚เชตเซ€เชจเซ‡ เชธเซ‚เชšเชฟเชฎเชพเช‚เชฅเซ€ เชฆเซ‚เชฐ เช•เชฐเซ‡ เช›เซ‡.

เช เซ€เช• เช›เซ‡, เช•เชพเชฐเชฃ เช•เซ‡ เชธเซ‚เชšเชฟเชจเซ€ เชฎเชฟเชฒเช•เชค BindableObject เชฐเชพเชœเซเชฏเชฎเชพเช‚เชฅเซ€ เชฒเซ‡เชตเชพเชฎเชพเช‚ เช†เชตเซ€ เช›เซ‡ เช…เชจเซ‡ เชคเซ‡เชจเซ‡ EnvironmentObject เชคเชฐเซ€เช•เซ‡ เช‡เชจเซเชœเซ‡เช•เซเชŸ เช•เชฐเชตเชพเชฎเชพเช‚ เช†เชตเซ€ เช›เซ‡, SwiftUI เชธเซ‚เชšเชฟเชจเซ‡ เช…เชชเชกเซ‡เชŸ เช•เชฐเซ‡ เช›เซ‡ เช•เชพเชฐเชฃ เช•เซ‡ ForEach เชฎเซ‚เชตเซ€เชเชจเซ€ เช—เชฃเชคเชฐเซ€ เช•เชฐเซ‡เชฒ เชชเซเชฐเซ‹เชชเชฐเซเชŸเซ€ เชธเชพเชฅเซ‡ เชธเช‚เช•เชณเชพเชฏเซ‡เชฒ เช›เซ‡.

เช…เชนเซ€เช‚ MoviesState เชฐเซ€เชกเซเชฏเซเชธเชฐเชจเซ‹ เชญเชพเช— เช›เซ‡:

func moviesStateReducer(state: MoviesState, action: Action) -> MoviesState {
    var state = state
    switch action {
    
    // other actions.
    
    case let action as MoviesActions.AddMovieToCustomList:
        state.customLists[action.list]?.movies.append(action.movie)
        
    case let action as MoviesActions.RemoveMovieFromCustomList:
        state.customLists[action.list]?.movies.removeAll{ $0 == action.movie }
        
    default:
        break
    }
    return state
}

เชœเซเชฏเชพเชฐเซ‡ เชคเชฎเซ‡ เช•เซ‹เชˆ เช•เซเชฐเชฟเชฏเชพ เชฎเซ‹เช•เชฒเซ‹ เช›เซ‹ เช…เชจเซ‡ เช‰เชชเชฐ เชœเชฃเชพเชตเซเชฏเชพ เชฎเซเชœเชฌ เชจเชตเซ€ เชธเซเชฅเชฟเชคเชฟ เชชเชฐเชค เช•เชฐเซ‹ เช›เซ‹ เชคเซเชฏเชพเชฐเซ‡ เชฐเซ€เชกเซเชฏเซเชธเชฐ เชเช•เซเชเชฟเช•เซเชฏเซเชŸ เชฅเชพเชฏ เช›เซ‡.

เชนเซเช‚ เชนเชœเซ€ เชตเชฟเช—เชคเชฎเชพเช‚ เชœเชˆเชถ เชจเชนเซ€เช‚ - เชธเซเชตเชฟเชซเซเชŸเชฏเซเช†เชˆ เช–เชฐเซ‡เช–เชฐ เช•เซ‡เชตเซ€ เชฐเซ€เชคเซ‡ เชœเชพเชฃเซ‡ เช›เซ‡ เช•เซ‡ เชถเซเช‚ เชชเซเชฐเชฆเชฐเซเชถเชฟเชค เช•เชฐเชตเซเช‚. เช†เชจเซ‡ เชตเชงเซ เชŠเช‚เชกเชพเชฃเชชเซ‚เชฐเซเชตเช• เชธเชฎเชœเชตเชพ เชฎเชพเชŸเซ‡, เชคเซ‡ เชฎเซ‚เชฒเซเชฏเชตเชพเชจ เช›เซ‡ เชกเซ‡เชŸเชพ เชซเซเชฒเซ‹ เชชเชฐ WWDC เชธเชคเซเชฐ เชœเซเช“ SwiftUI เชฎเชพเช‚. เชคเซ‡ เชถเชพ เชฎเชพเชŸเซ‡ เช…เชจเซ‡ เช•เซเชฏเชพเชฐเซ‡ เช‰เชชเชฏเซ‹เช— เช•เชฐเชตเซ‹ เชคเซ‡ เชชเชฃ เชตเชฟเช—เชคเชตเชพเชฐ เชธเชฎเชœเชพเชตเซ‡ เช›เซ‡ เชฐเชพเชœเซเชฏ, @Binding, ObjectBinding เช…เชจเซ‡ EnvironmentObject.

เชธเซเช•เชฟเชฒเชฌเซ‹เช•เซเชธ เชญเชฒเชพเชฎเชฃ เช•เชฐเซ‡ เช›เซ‡:

เชธเซ‹เชฐเซเชธ: www.habr.com

เชเช• เชŸเชฟเชชเซเชชเชฃเซ€ เช‰เชฎเซ‡เชฐเซ‹