Pêşveçûna serîlêdanê li ser SwiftUI. Beş 1: Dataflow û Redux

Pêşveçûna serîlêdanê li ser SwiftUI. Beş 1: Dataflow û Redux

Piştî ku beşdarî rûniştina Dewleta Yekîtiyê ya li WWDC 2019 bûm, min biryar da ku ez di nav SwiftUI de kûrahiyek kûr bikim. Min gelek wext bi wê re xebitand û naha dest bi pêşxistina serîlêdanek rastîn kir ku dikare ji gelek bikarhêneran re kêrhatî be.

Min jê re got MovieSwiftUI - ev serîlêdanek e ji bo lêgerîna fîlimên nû û kevn, û hem jî berhevkirina wan di berhevokê de bi karanîna TMDB API. Min her gav ji fîlman hez kir û tewra pargîdaniyek ku di vî warî de dixebitî jî ava kir, her çend demek berê. Pargîdanî bi zorê nedihat binavkirin, lê serîlêdan bû!

Em bînin bîra xwe: ji bo hemî xwendevanên "Habr" - dema ku hûn beşdarî qursek Skillbox-ê bi karanîna koda danasînê ya "Habr" têne qeyd kirin 10 rubleyan dakêşin.

Skillbox pêşniyar dike: Kursa perwerdehiya serhêl "Pîşesaziya Java Developer".

Ji ber vê yekê MovieSwiftUI dikare çi bike?

  • Bi API-ê re têkilî dike - hema hema her serîlêdana nûjen vê yekê dike.
  • Daneyên asynkron li ser daxwazan bar dike û JSON di modela Swift de bi kar tîne pars dike Codable.
  • Wêneyên ku li ser daxwazê ​​hatine barkirin nîşan dide û wan vedişêre.
  • Vê sepanê ji bo iOS, iPadOS, û macOS ji bo bikarhênerên van OS-an UX-a çêtirîn peyda dike.
  • Bikarhêner dikare daneyan biafirîne û navnîşên fîlimên xwe biafirîne. Serlêdan daneyên bikarhênerê hilîne û sererast dike.
  • Nêrîn, pêkhate û model bi karanîna nimûneya Redux bi zelalî têne veqetandin. Herikîna daneyê li vir yekalî ye. Ew dikare bi tevahî cached, nûvekirin û ji nû ve were nivîsandin.
  • Serlêdan hêmanên bingehîn ên SwiftUI, TabbedView, SegmentedControl, NavigationView, Form, Modal, hwd bikar tîne. Di heman demê de ew dîtinên xwerû, tevger, UI / UX jî peyda dike.

Pêşveçûna serîlêdanê li ser SwiftUI. Beş 1: Dataflow û Redux
Di rastiyê de, anîmasyon bêkêmasî ye, GIF-ê piçek zirav derket

Xebata li ser sepanê gelek ezmûn da min û bi giştî ezmûnek erênî bû. Min karîbû serîlêdanek bi tevahî fonksiyonel binivîsim, di meha îlonê de ez ê wê çêtir bikim û di AppStore-ê de biweşînim, hevdem digel berdana iOS 13.

Redux, BindableObject û EnvironmentObject

Pêşveçûna serîlêdanê li ser SwiftUI. Beş 1: Dataflow û Redux

Nêzîkî du sal in ez bi Redux re dixebitim, ji ber vê yekê ez pê re bi rêkûpêk jêhatî me. Bi taybetî, ez wê di pêşiyê de ji bo bikar tînim Bersivkirin malper, û her weha ji bo pêşxistina sepanên xwemalî iOS (Swift) û Android (Kotlin).

Min tu carî poşman nebû ku Redux wekî mîmariya herikîna daneyê ji bo avakirina serîlêdanek SwiftUI hilbijart. Di dema karanîna Redux-ê di serîlêdana UIKit-ê de beşên herî dijwar ev e ku bi firotgehê re dixebitin û daneyan digirin û vedigirin û nexşeya wan bi dîtinên / pêkhateyên we re nexşe dikin. Ji bo kirina vê yekê, min neçar ma ku celebek pirtûkxaneyek girêdanan biafirînim (bi karanîna ReSwift û ReKotlin). Baş dixebite, lê pir pir kod. Mixabin, ew ne (hîn) çavkaniyek vekirî ye.

Nûçeyên baş! Tiştên ku hûn bi SwiftUI re xemgîn dibin - heke hûn plan dikin ku Redux bikar bînin - firotgeh, dewlet û kêmker in. Bi saya @EnvironmentObject danûstendina bi firotgehê re bi tevahî ji hêla SwiftUI ve tê girtin. Ji ber vê yekê, firotgeh bi BindableObject dest pê dike.

Min pakêtek Swift a hêsan çêkir, SwiftUIFlux, ku karanîna bingehîn a Redux peyda dike. Di doza min de ew beşek MovieSwiftUI ye. ez jî tutorial gav-bi-gav nivîsî, ku dê ji we re bibe alîkar ku hûn vê hêmanê bikar bînin.

Çawa dixebite?

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

Her gava ku hûn çalakiyek çêdikin, hûn gearboxê çalak dikin. Ew ê çalakiyan li gorî rewşa heyî ya serîlêdanê binirxîne. Dûv re ew ê li gorî celeb û daneya çalakiyê rewşek nû ya guhertî vegerîne.

Welê, ji ber ku firotgehek BindableObject e, ew ê SwiftUI agahdar bike dema ku nirxa wê bi karanîna taybetmendiya willChange ku ji hêla PassthroughSubject ve hatî guheztin biguhezîne. Ji ber vê yekê ye ku BindableObject divê PublisherType peyda bike, lê pêkanîna protokolê berpirsiyariya birêvebirina wê ye. Bi tevayî, ev amûrek pir bi hêz ji Apple ye. Li gorî vê yekê, di çerxa renderê ya paşîn de, SwiftUI dê bibe alîkar ku laşê nêrînan li gorî guheztina dewletê peyda bike.

Bi rastî, ev hemî dil û sêrbaziya SwiftUI ye. Naha, di her nêrînek ku ji dewletek re têkildar be, dê nêrîn li gorî kîjan daneyên ji dewletê têne wergirtin û çi guherî ye were pêşkêş kirin.

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

Dema ku serîlêdan dest pê dike Store wekî EnvironmentObject tê derzî kirin û dûv re bi karanîna @EnvironmentObject di her dîmenî de tê gihîştin. Cezayê performansê tune ji ber ku taybetmendiyên jêhatî zû ji rewşa serîlêdanê têne girtin an têne hesibandin.

Heke posterê fîlimê biguhere koda li jor wêneyê diguherîne.

Û ev bi rastî tenê bi yek rêzê, bi alîkariya wê nêrîn bi dewletê ve tê girêdan. Ger we bi ReSwift-ê re li ser iOS an tewra jî xebitî bihevgirêdan bi React re, hûn ê sêrbaziya SwiftUI fam bikin.

Naha hûn dikarin hewl bidin ku çalakiyê çalak bikin û dewleta nû biweşînin. Li vir mînakek tevlihevtir heye.

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

Di koda jorîn de, ez ji bo her IP-ê çalakiya .onDelete ji SwiftUI bikar tîne. Ev dihêle rêza di navnîşê de ji bo jêbirina swipe-ya normal ya iOS-ê nîşan bide. Ji ber vê yekê gava ku bikarhêner bişkojka jêbirinê dest pê dike, ew çalakiya têkildar dide destpêkirin û fîlimê ji navnîşê derdixe.

Welê, ji ber ku taybetmendiya navnîşê ji rewşa BindableObject-ê hatî derxistin û wekî EnvironmentObject tê derzî kirin, SwiftUI navnîşê nûve dike ji ber ku ForEach bi taybetmendiya fîlimên hesabkirî ve girêdayî ye.

Li vir beşek kêmkerê MoviesState ye:

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
}

Dema ku hûn çalakiyek dişînin û rewşek nû vedigerin, wekî ku li jor hatî destnîşan kirin, kêmker tê darve kirin.

Ez ê hîna bi hûrgulî neçim - SwiftUI bi rastî çawa dizane ku çi nîşan bide. Ji bo fêmkirina vê kûrtir, hêja ye danişîna WWDC li ser herikîna daneyê bibînin li SwiftUI. Ew jî bi hûrgulî rave dike ka çima û kengê bikar tîne Rewş, @Binding, ObjectBinding û EnvironmentObject.

Skillbox pêşniyar dike:

Source: www.habr.com

Add a comment