WWDC 2019-แแ แแแแจแแ แแก แแแแแแแ แแแแแก แกแแกแแแแ แแแกแฌแ แแแแก แจแแแแแ, แแแแแแฌแงแแแขแ แฆแ แแแ แฉแแแแแแ SwiftUI. แแ แแแแ แแ แ แแแแแขแแ แ แแแกแแแ แแฃแจแแแแแจแ แแ แแฎแแ แแแแแฌแงแ แ แแแแฃแ แ แแแแแแแชแแแก แจแแแฃแจแแแแแ, แ แแแแแแช แจแแแซแแแแ แกแแกแแ แแแแแ แแงแแก แแแแฎแแแ แแแแแแ แคแแ แแ แกแแแฅแขแ แแกแแแแก.
แแ แแแก แแฃแฌแแแ MovieSwiftUI - แแก แแ แแก แแแแแแแชแแ แแฎแแแ แแ แซแแแแ แคแแแแแแแก แแแกแแซแแแแแ, แแกแแแ แแแแแฅแชแแแจแ แแแแ แจแแแ แแแแแแกแแแแก.
แจแแแแฎแกแแแแแ: "Habr"-แแก แงแแแแ แแแแแฎแแแแแกแแแแก - แคแแกแแแแแแแ 10 แ แฃแแแแแแ Skillbox-แแก แแแแแกแแแแ แแฃแ แกแแ แฉแแ แแชแฎแแแกแแก "Habr" แกแแ แแแแแแ แแแแแก แแแแแงแแแแแแ.
Skillbox แแแ แฉแแแ: แกแแแแแแแแแแแแแแ แแแแแแ แแฃแ แกแ
"แแ แแคแแกแแ Java Developer" .
แแแจ, แ แ แจแแฃแซแแแ MovieSwiftUI-แก?
- แฃแ แแแแ แแฅแแแแแแก API-แกแแแ - แแแแก แแแแแแแก แแแแฅแแแก แแแแแกแแแแ แ แแแแแแแแ แแแ แแแแแแแชแแ.
- แแขแแแ แแแแ แแกแแแฅแ แแแฃแแ แแแแแชแแแแแ แแแแฎแแแแแแแ แแ แแแแแแแแแแก JSON-แก Swift แแแแแแจแ แแแแแงแแแแแแ
แแแแแ แแแแแ . - แแฉแแแแแแก แแแแฎแแแแแ แฉแแขแแแ แแฃแ แกแฃแ แแแแแก แแ แฅแแจแแ แแแก แแแ.
- แแก แแแแแแแชแแ iOS-แแกแแแแก, iPadOS-แแกแแแแก แแ macOS-แแกแแแแก แฃแแ แฃแแแแแงแแคแก แกแแฃแแแแแกแ UX-แก แแ OS-แแแแก แแแแฎแแแ แแแแแแแกแแแแก.
- แแแแฎแแแ แแแแแก แจแแฃแซแแแ แแแแแชแแแแ แแแแแ แแ แแแ แแ แกแแแฃแแแ แ แคแแแแแแแก แกแแแแแก แจแแฅแแแ. แแแแแแแชแแ แแแแฎแแแก แแ แแฆแแแแแแก แแแแฎแแแ แแแแแก แแแแแชแแแแแก.
- แฎแแแแแ, แแแแแแแแแขแแแ แแ แแแแแแแแ แแจแแแ แแ แแแแแงแแคแแแแ Redux-แแก แแแแฃแจแแก แแแแแงแแแแแแ. แแแแแชแแแแ แแแแแแ แแฅ แชแแแแฎแ แแแแ. แแแกแ แกแ แฃแแแ แฅแแจแแ แแแ, แแฆแแแแแ แแ แแแแแฌแแ แ แจแแกแแซแแแแแแแ.
- แแแแแแแชแแ แแงแแแแแก SwiftUI, TabbedView, SegmentedControl, NavigationView, Form, Modal แแ แ.แจ. แซแแ แแแแ แแแแแแแแแขแแแก. แแก แแกแแแ แฃแแ แฃแแแแแงแแคแก แแแ แแแแฃแ แฎแแแแแก, แแแกแขแแแก, UI/UX.
แคแแฅแขแแแ แแแแ, แแแแแแชแแ แแแฃแแแ, GIF-แ แชแแขแ แฃแฎแแจแ แแฆแแแฉแแแ
แแแแแแแชแแแแ แแฃแจแแแแแ แแแแ แแแแแชแแแแแแ แแแแชแ แแ แแแแแแแแแแจแ แแก แแงแ แแแแแขแแฃแ แ แแแแแชแแแแแแ. แกแ แฃแแแ แคแฃแแฅแชแแแแแแฃแ แ แแแแแแแชแแแก แแแฌแแ แ แแแแแฎแแ แฎแ, แกแแฅแขแแแแแ แจแ แแแแแฃแแฏแแแแกแแ แแ แแแแแแแฅแแแงแแแ AppStore-แจแ, iOS 13-แแก แแแแแจแแแแแก แแแ แแแแแฃแ แแ.
Redux, BindableObject แแ EnvironmentObject
แแ แฃแแแ แแแแฎแแแแแแ แแ แ แฌแแแแ แแแฃแจแแแ Redux-แแแ, แแแแขแแ แจแแแแ แแแแ แแแ แแแ แแแชแแแแ แแแก. แแแ แซแแ, แแ แแแงแแแแ แแแก แฌแแแ แแฎแแ แแก
แแ แแกแแ แแก แแแแแแแ Redux-แแก แแ แฉแแแ, แ แแแแ แช แแแแแชแแแแ แแแแแแแก แแ แฅแแขแแฅแขแฃแ แ SwiftUI แแแแแแแชแแแก แจแแกแแฅแแแแแแ. UIKit แแแจแ Redux-แแก แแแแแงแแแแแแกแแก แงแแแแแแ แ แแฃแแ แแแฌแแแแ แแแฆแแแแแกแแแ แแฃแจแแแแ, แแแแแชแแแแแแก แแแฆแแแ แแ แแแซแแแแ แแ แแแแ แแแฎแแขแแ แแฅแแแแก แฎแแแแแแแ/แแแแแแแแแขแแแแแ. แแแแกแแแแแก แแ แฃแแแ แจแแแแฅแแแ แแแแแฅแขแแ แแแแก แแ แแแแแ แ แแแแแแแแแแ (ReSwift-แแกแ แแ ReKotlin-แแก แแแแแงแแแแแแ). แแแ แแแ แแฃแจแแแแก, แแแแ แแ แกแแแแแแ แแแแ แ แแแแ. แกแแแฌแฃแฎแแ แแ, แแก แแ แแ แแก (แฏแแ ) แฆแแ แฌแงแแ แ.
แฒแแ แแ แแแแแแ! แแ แแแแแ แแ, แ แแแแช แฃแแแ แแแแ แแแฃแแแ SwiftUI-แแ - แแฃ แแฅแแแ แแแแ แแแ Redux-แแก แแแแแงแแแแแแก - แแ แแก แแแฆแแแแแแ, แจแขแแขแแแ แแ แ แแแฃแฅแขแแ แแแ. แแแฆแแแแแกแแแ แฃแ แแแแ แแฅแแแแแแ แแแแแแแแ แแ แฃแแแแก SwiftUI-แแก แแแแ @EnvironmentObject-แแก แฌแงแแแแแแ. แแกแ แ แแ, แแแฆแแแแ แแฌแงแแแ BindableObject-แแ.
แแ แจแแแฅแแแแ แแแ แขแแแ Swift แแแแแขแ,
แ แแแแ แแฃแจแแแแก แแแ?
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-แแกแแแ. แจแแกแแแแแแกแแ, แ แแแแแ แแก แจแแแแแ แชแแแแจแ, SwiftUI แแแแแฎแแแ แแแแ แฎแแแแแแก แแแ แแฃแกแแก แแแแแแชแแแแจแ แแแแแแแ แแแแแก แชแแแแแแแแก แแแฎแแแแแ.
แกแแแแแแแแแแจแ, แแก แแ แแก SwiftUI-แแก แแแแแ แแฃแแ แแ แแแแแ. แแฎแแ, แแแแแกแแแแ แฎแแแจแ, แ แแแแแแช แฎแแแแแฌแแ แแแแ แกแแฎแแแแฌแแคแแก, แฎแแแ แแแแแแชแแแ แแแแก แแแฎแแแแแ, แแฃ แ แ แแแแแชแแแแแ แแแแฆแแแ แกแแฎแแแแฌแแคแแกแแแ แแ แ แ แจแแแชแแแแ.
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-แแก แแแแแงแแแแแแ. แแ แแ แกแแแแแก แจแแกแ แฃแแแแแก แฏแแ แแแ, แ แแแแแ แแแฆแแแฃแแ แแแแกแแแแแ แกแฌแ แแคแแ แแฆแแฅแแแแ แแ แแแแแแแแแแแ แแแแแชแฎแแแแก แแแแแแแ แแแแแแแ.
แแแแแ แแแชแแแฃแแ แแแแ แชแแแแก แกแฃแ แแแก, แแฃ แคแแแแแก แแแกแขแแ แ แแชแแแแแ.
แแ แแก แคแแฅแขแแแ แแแแ แแฎแแแแ แแ แแ แฎแแแแ แแแแแแแ, แ แแแแแก แแแฎแแแ แแแแแแช แฎแแแแแ แกแแฎแแแแฌแแคแแก แฃแแแแจแแ แแแแ. แแฃ แแฅแแแ แแฃแจแแแแแแ ReSwift-แแแ iOS-แแ แแ แแฃแแแแช
แแฎแแ แจแแแแซแแแแ แกแชแแแแ แแแฅแแแแแแแก แแแแฅแขแแฃแ แแแ แแ แแฎแแแ แแแแแแแ แแแแแก แแแแแฅแแแงแแแแ. แแฅ แแ แแก แฃแคแ แ แ แแฃแแ แแแแแแแแ.
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!]))
}
}
}
}
แแแแแ แแแชแแแฃแ แแแแจแ แแ แแแงแแแแ .onDelete แแแฅแแแแแแแก SwiftUI-แแแ แแแแแแฃแแ IP-แกแแแแก. แแก แกแแจแฃแแแแแแก แแซแแแแก แกแแแจแ แ แแแก แแฉแแแแแก แแแ แแแแฃแ แ 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
}
แ แแแฃแฅแขแแ แ แจแแกแ แฃแแแแฃแแแ, แ แแแแกแแช แแฅแแแ แแแแแแแแ แแแฅแแแแแแแก แแ แแแ แฃแแแแ แแฎแแ แแแแแแแ แแแแแก, แ แแแแ แช แแแแแ แแฆแแแแจแแ.
แแ แฏแแ แแ แจแแแแ แแแขแแแแแจแ - แ แแแแ แแชแแก SwiftUI แ แแแแฃแ แแ แ แ แฃแแแ แแฉแแแแแก. แแแแก แฃแคแ แ แฆแ แแแ แแแกแแแแแแ, แฆแแ แก
Skillbox แแแ แฉแแแ:
- แแ แแฅแขแแแฃแแ แแฃแ แกแ
"Mobile Developer PRO" .- แแแแแ แแ แแแแแแ แแฃแ แกแก
"แแแแแแแก แแแแแชแแแแ แแแแแแขแแแแกแ" .- แแ แฌแแแแแ แแ แแฅแขแแแฃแแ แแฃแ แกแ
"แแ แแแ PRO แแแ แแแแแแแแแ แ" .
แฌแงแแ แ: www.habr.com