Mmepe ngwa na SwiftUI. Nkebi 1: Dataflow na Redux

Mmepe ngwa na SwiftUI. Nkebi 1: Dataflow na Redux

Mgbe m gachara nnọkọ steeti nke otu na WWDC 2019, ekpebiri m imikpu miri na SwiftUI. Ejila m oge dị ukwuu na-arụ ọrụ na ya ma malite ugbu a ịmepụta ezigbo ngwa nke nwere ike ịba uru maka ọtụtụ ndị ọrụ.

Akpọrọ m ya MovieSwiftUI - nke a bụ ngwa maka ịchọ ihe nkiri ọhụrụ na nke ochie yana iji nakọta ha na mkpokọta. TMDB API. Ahụrụ m ihe nkiri n'anya mgbe niile na ọbụna mepụta ụlọ ọrụ na-arụ ọrụ na mpaghara a, ọ bụ ezie na ogologo oge gara aga. Enwere ike ịkpọ ụlọ ọrụ ahụ jụụ, mana ngwa ahụ bụ!

Anyị na -echetara: maka ndị na-agụ Habr niile - ego 10 ruble mgbe ị na-edebanye aha na nkuzi Skillbox ọ bụla site na iji koodu mgbasa ozi Habr.

Skillbox na-atụ aro: Usoro nkuzi n'ịntanetị "Ọkachamara Java onye nrụpụta".

Yabụ kedu ihe MovieSwiftUI nwere ike ime?

  • Mmekọrịta na API - ihe fọrọ nke nta ka ọ bụrụ ngwa ọgbara ọhụrụ ọ bụla na-eme nke a.
  • Na-eburu data asynchronous na arịrịọ wee tụgharịa JSON n'ime ụdị Swift site na iji Codeable.
  • Na-egosi foto ndị ebukọrọ na arịrịọ ma chekwaa ha.
  • Ngwa a maka iOS, iPadOS na macOS na-enye UX kacha mma maka ndị ọrụ OS ndị a.
  • Onye ọrụ nwere ike ịmepụta data ma mepụta ndepụta ihe nkiri nke ha. Ngwa ahụ na-echekwa ma weghachi data onye ọrụ.
  • A na-ekewa elele, akụrụngwa na ụdị nke ọma site na iji ụkpụrụ Redux. Usoro data ebe a bụ unidirectional. Enwere ike ịchekwa ya nke ọma, weghachite ma degharịa ya.
  • Ngwa a na-eji ihe ndị bụ isi nke SwiftUI, TabbedView, SegmentedControl, NavigationView, Form, Modal, wdg. Ọ na-enyekwa echiche, mmegharị ahụ, UI/UX.

Mmepe ngwa na SwiftUI. Nkebi 1: Dataflow na Redux
N'ezie, animation ahụ dị nro, GIF tụgharịrị ntakịrị

Ịrụ ọrụ na ngwa ahụ nyere m ọtụtụ ahụmahụ na n'ozuzu ọ bụ ahụmahụ dị mma. Enwere m ike ide ngwa na-arụ ọrụ zuru oke, na Septemba m ga-emeziwanye ya ma bipụta ya na AppStore, n'otu oge na mwepụta nke iOS 13.

Redux, BindableObject na EnvironmentObject

Mmepe ngwa na SwiftUI. Nkebi 1: Dataflow na Redux

Mụ na Redux na-arụ ọrụ ihe dị ka afọ abụọ ugbu a, n'ihi ya, amachaghị m ya nke ọma. Karịsịa, m na-eji ya na frontend maka Emeghachi webụsaịtị, yana maka ịmepụta ngwa iOS (Swift) na gam akporo (Kotlin).

Ọ dịbeghị mgbe m kwakwara ụta maka ịhọrọ Redux ka ọ bụrụ usoro nhazi data maka iwulite ngwa SwiftUI. Akụkụ kacha sie ike mgbe ị na-eji Redux na ngwa UIKit na-arụ ọrụ na ụlọ ahịa ahụ na-enweta ma na-eweghachite data ma na-ese ya na echiche / akụkụ gị. Iji mee nke a, m ga-emepụta ụdị ọbá akwụkwọ nke njikọ (iji ReSwift na ReKotlin). Ọ na-arụ ọrụ nke ọma, mana ọtụtụ koodu. N'ụzọ dị mwute, ọ bụghị (ka) mepere emepe.

Ozi ọma! Naanị ihe ị ga-echegbu onwe gị na SwiftUI - ọ bụrụ na ị na-eme atụmatụ iji Redux - bụ ụlọ ahịa, steeti na ndị na-ebelata. SwiftUI na-elekọta mmekọrịta ya na ụlọ ahịa ahụ kpamkpam site na @EnvironmentObject. Yabụ, ụlọ ahịa na-amalite site na BindableObject.

Emepụtara m ngwugwu Swift dị mfe, SwiftUIFlux, nke na-enye isi ojiji nke Redux. N'ọnọdụ m ọ bụ akụkụ nke MovieSwiftUI. Mụ onwe m dere nkuzi nzọụkwụ site na nzọụkwụ, nke ga-enyere gị aka iji akụrụngwa a.

Olee otú ọ na-arụ ọrụ?

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)
    }
}

Mgbe ọ bụla ị kpalitere ihe, ị na-arụ ọrụ gearbox. Ọ ga-enyocha omume dịka ọnọdụ ngwa ugbu a siri dị. Ọ ga-eweghachite ọnọdụ ọhụrụ gbanwetụrụ dịka ụdị omume na data siri dị.

Ọ dị mma, ebe ụlọ ahịa bụ BindableObject, ọ ga-agwa SwiftUI mgbe uru ya gbanwere site na iji ihe ga-agbanwe ihe nke PassthroughSubject nyere. Nke a bụ n'ihi na BindableObject ga-ewetarịrị onye mbipụta, mana mmejuputa iwu ahụ bụ maka ijikwa ya. N'ozuzu, nke a bụ nnọọ ike ngwá ọrụ si Apple. N'ihi ya, na usoro ntụgharị na-esote, SwiftUI ga-enyere aka mee ka ahụ echiche dịka mgbanwe steeti siri dị.

N'ezie, nke a bụ obi na anwansi niile nke SwiftUI. Ugbu a, n'echiche ọ bụla nke na-edebanye aha na steeti, a ga-eme ka echiche ahụ dabere na data enwetara site na steeti na ihe gbanwere.

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())
    }
}

A na-agbanye ụlọ ahịa ahụ dị ka ihe gburugburu ebe obibi mgbe ngwa malitere wee nweta ya na nlele ọ bụla site na iji @EnvironmentObject. Enweghị ntaramahụhụ arụmọrụ n'ihi na a na-eweghachite ma ọ bụ gbakọọ akụrụngwa ewepụtara ngwa ngwa site na steeti ngwa.

Koodu dị n'elu na-agbanwe onyonyo ma ọ bụrụ na akwụkwọ mmado ihe nkiri gbanwere.

A na-eme nke a n'ezie na naanị otu ahịrị, site n'enyemaka nke echiche jikọtara na steeti. Ọ bụrụ na ị na-arụ ọrụ na ReSwift na iOS ma ọ bụ ọbụna jikọọ na React, ị ga-aghọta anwansi nke SwiftUI.

Ugbu a ị nwere ike ịnwa ịgbalite ihe omume ahụ wee bipụta steeti ọhụrụ. Nke a bụ ihe atụ dị mgbagwoju anya karị.

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!]))
            }
        }
    }
}

Na koodu dị n'elu, m na-eji .onDelete action sitere na SwiftUI maka IP ọ bụla. Nke a na-enye ohere ahịrị na ndepụta na-egosipụta nkịtị iOS swipe ihichapụ. Ya mere, mgbe onye ọrụ metụrụ bọtịnụ ihichapụ, ọ na-akpalite omume kwekọrọ ma wepụ ihe nkiri ahụ na listi ahụ.

Ọ dị mma, ebe ọ bụ na enwetara akụrụngwa ndepụta ahụ site na steeti BindableObject wee gbanye ya dị ka ihe EnvironmentObject, SwiftUI na-emelite ndepụta ahụ n'ihi na ejikọtara ForEach na ihe nkiri gbakọọ ihe nkiri.

Nke a bụ akụkụ nke ihe nbelata 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
}

A na-egbu onye nrụpụta ahụ mgbe izipu ihe wee weghachi steeti ọhụrụ, dịka ekwuru n'elu.

Agaghị m abanye n'ime nkọwa - ka SwiftUI si mara ihe ọ ga-egosipụta. Iji ghọta nke a nke ọma karị, ọ bara uru lelee nnọkọ WWDC na ntinye data na SwiftUI. Ọ na-akọwa n'ụzọ zuru ezu ihe mere na mgbe a ga-eji State, @Binding, ObjectBinding and EnvironmentObject.

Skillbox na-atụ aro:

isi: www.habr.com

Tinye a comment