Te whanaketanga tono i runga i te SwiftUI. Wāhanga 1: Dataflow me Redux
Whai muri i taku haerenga ki te huihuinga State of the Union i WWDC 2019, ka whakatau ahau ki te ruku hohonu ki SwiftUI. Kua roa ahau ki te mahi ki a ia, kua timata ahau ki te whakawhanake i tetahi tono tino whai hua ki te tini o nga kaiwhakamahi.
I tapaina e ahau ko MovieSwiftUI - he taupānga tenei mo te rapu kiriata hou me nga kiriata tawhito, me te kohi i roto i te kohinga ma te whakamahi TMDB API. He tino aroha ahau ki nga kiriata me te hanga i tetahi kamupene e mahi ana i tenei mara, ahakoa kua roa ke. Kaore e taea te kiia te kamupene he hauhautanga, engari ko te tono!
Ka whakamahara matou:mo nga kaipānui katoa o "Habr" - he utu mo te 10 rubles i te wa e whakauru ana ki tetahi akoranga Skillbox ma te whakamahi i te waehere whakatairanga "Habr".
Ka mahi tahi me te API - tata ki nga tono hou ka mahia tenei.
Ka utaina nga raraunga tukutahi i runga i nga tono ka poroporoaki i a JSON ki te tauira Swift ma te whakamahi Ka taea te tohu.
Ka whakaatu i nga whakaahua kua utaina i runga i te tono me te keteroki.
Ko tenei taupānga mo iOS, iPadOS, me te macOS e whakarato ana i te UX pai mo nga kaiwhakamahi o enei OS.
Ka taea e te kaiwhakamahi te whakaputa raraunga me te hanga i o raatau ake rarangi kiriata. Ko te tono ka whakaora me te whakahoki i nga raraunga kaiwhakamahi.
Ko nga tirohanga, nga waahanga me nga tauira ka tino wehea ma te whakamahi i te tauira Redux. Ko te rerenga raraunga kei konei he aronga kotahi. Ka taea te keteroki katoa, te whakahoki me te tuhirua.
Ka whakamahia e te tono nga waahanga taketake o SwiftUI, TabbedView, SegmentedControl, NavigationView, Puka, Modal, etc. Ka whakarato hoki i nga tirohanga ritenga, nga tohu, UI / UX.
Inaa, he maeneene te hākoritanga, he iti noa te ahua o te GIF
Ko te mahi i runga i te taupānga i homai he wheako nui ki a au me te katoa he wheako pai. I taea e au te tuhi i tetahi tono tino mahi, i te marama o Hepetema ka whakapai ake ahau ka whakaputa i te AppStore, i te wa ano me te tukunga o iOS 13.
Redux, BindableObject me EnvironmentObject
Kua rua tau ahau e mahi tahi ana me Redux inaianei, no reira kua tino mohio ahau ki tenei. Ina koa, ka whakamahia e au i te pito o mua mo tauhohe paetukutuku, me te whakawhanake i nga tono taketake iOS (Swift) me Android (Kotlin).
Kaore au i pouri ki te kowhiri i a Redux hei hoahoanga rerenga raraunga mo te hanga tono SwiftUI. Ko nga waahanga tino wero i te wa e whakamahi ana i a Redux i roto i te taupānga UIKit kei te mahi tahi me te toa me te tiki me te tiki raraunga me te mapi ki o tirohanga/waahanga. Ki te mahi i tenei, me hanga e ahau he momo whare pukapuka honohono (ma te whakamahi i a ReSwift me ReKotlin). He pai te mahi, engari he maha nga waehere. Kia aroha mai, kare ano i te puna tuwhera.
Rongo pai! Ko nga mea anake hei maaharahara ki a SwiftUI - mena ka whakamahere koe ki te whakamahi i a Redux - ko nga toa, whenua, me nga whakaheke. Ko te taunekeneke me te toa ka tino tiakina e SwiftUI na @EnvironmentObject. Na, ka timata te toa ki te BindableObject.
I hanga e ahau he kete Swift ngawari, SwiftUIFlux, e whakarato ana i te whakamahinga taketake o Redux. I taku keehi he waahanga o MovieSwiftUI. Ko ahau hoki tuhia he akoranga taahiraa-i-taahiraa, ka awhina koe ki te whakamahi i tenei waahanga.
Ka pēhea te mahi i te reira?
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)
}
}
I nga wa katoa ka timata koe i tetahi mahi, ka whakahohe koe i te pouaka. Ka arotakehia nga mahi i runga i te ahua o te tono o naianei. Ka hoki mai he ahua hou kua whakarereketia e ai ki te momo mahi me nga raraunga.
Na, i te mea he BindableObject te toa, ka whakamohio atu ki a SwiftUI ka huri ana te uara ma te whakamahi i te taonga willChange e whakaratohia ana e PassthroughSubject. Ko tenei na te mea me whakarato e te BindableObject he PublisherType, engari ko te whakatinana kawa te kawenga mo te whakahaere. I te katoa, he taputapu tino kaha tenei mai i a Apple. Na reira, i roto i te huringa taake e whai ake nei, ka awhina a SwiftUI ki te whakaputa i te tinana o nga tirohanga e ai ki nga huringa o te kawanatanga.
Inaa, koinei te ngakau me te makutu o SwiftUI. Inaianei, i roto i nga tirohanga katoa e ohauru ana ki tetahi kawanatanga, ka tukuna te tirohanga kia rite ki nga raraunga ka riro mai i te kawanatanga me nga mea kua rereke.
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())
}
}
Ka werohia te Toa hei EnvironmentObject ina timata te tono, ka uru atu ki tetahi tirohanga ma te whakamahi @EnvironmentObject. Karekau he whiunga mahi na te mea ka tere te tiki mai, ka tatauhia ranei nga taonga mai i te ahua tono.
Ko te waehere i runga ake ka huri i te ahua mena ka huri te panui kiriata.
Na ka mahia tenei ma te raina kotahi, me te awhina o nga tirohanga e hono ana ki te kawanatanga. Mena kua mahi koe me ReSwift i runga i te iOS, ara hono me React, ka mohio koe ki te makutu o SwiftUI.
Ka taea e koe te ngana ki te whakahohe i te mahi me te whakaputa i te ahua hou. Anei tetahi tauira uaua ake.
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!]))
}
}
}
}
I roto i te waehere i runga ake nei, kei te whakamahi ahau i te mahi .onDelete mai i SwiftUI mo ia IP. Ma tenei ka taea e te rarangi o te rarangi te whakaatu i te swipe noa a iOS ki te muku. Na ka pa te kaiwhakamahi ki te paatene muku, ka puta te mahi e rite ana, ka tangohia te kiriata mai i te rarangi.
Ana, i te mea i ahu mai te rarangi taonga mai i te ahua BindableObject ka werohia hei EnvironmentObject, ka whakahou a SwiftUI i te raarangi na te mea e hono ana a ForEach ki nga taonga kua tatauhia nga kiriata.
Anei tetahi waahanga o te MoviesState whakaiti:
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
}
Ka mahia te whakaheke i te wa e tukuna ana e koe he mahi me te whakahoki i tetahi ahuatanga hou, penei i te korero i runga ake nei.
Kaore au e korero mo nga korero - me pehea te mohio a SwiftUI ki nga mea hei whakaatu. Ki te tino mohio ki tenei, he mea utu tirohia te huihuinga WWDC mo te rerenga raraunga i roto i te SwiftUI. Ka whakamāramahia hoki te take me te wa hei whakamahi State, @Binding, ObjectBinding me EnvironmentObject.