SwiftUI ನಲ್ಲಿ ಅಪ್ಲಿಕೇಶನ್ ಅಭಿವೃದ್ಧಿ. ಭಾಗ 1: ಡೇಟಾಫ್ಲೋ ಮತ್ತು ರಿಡಕ್ಸ್
WWDC 2019 ರಲ್ಲಿ ಸ್ಟೇಟ್ ಆಫ್ ಯೂನಿಯನ್ ಅಧಿವೇಶನದಲ್ಲಿ ಭಾಗವಹಿಸಿದ ನಂತರ, ನಾನು SwiftUI ಗೆ ಆಳವಾದ ಡೈವ್ ಮಾಡಲು ನಿರ್ಧರಿಸಿದೆ. ನಾನು ಅದರೊಂದಿಗೆ ಕೆಲಸ ಮಾಡಲು ಸಾಕಷ್ಟು ಸಮಯವನ್ನು ಕಳೆದಿದ್ದೇನೆ ಮತ್ತು ಈಗ ವ್ಯಾಪಕ ಶ್ರೇಣಿಯ ಬಳಕೆದಾರರಿಗೆ ಉಪಯುಕ್ತವಾದ ನೈಜ ಅಪ್ಲಿಕೇಶನ್ ಅನ್ನು ಅಭಿವೃದ್ಧಿಪಡಿಸಲು ಪ್ರಾರಂಭಿಸಿದೆ.
ನಾನು ಇದನ್ನು MovieSwiftUI ಎಂದು ಕರೆದಿದ್ದೇನೆ - ಇದು ಹೊಸ ಮತ್ತು ಹಳೆಯ ಚಲನಚಿತ್ರಗಳನ್ನು ಹುಡುಕುವ ಅಪ್ಲಿಕೇಶನ್ ಆಗಿದೆ, ಜೊತೆಗೆ ಅವುಗಳನ್ನು ಬಳಸಿಕೊಂಡು ಸಂಗ್ರಹಣೆಯಲ್ಲಿ ಸಂಗ್ರಹಿಸುತ್ತದೆ. TMDB API. ನಾನು ಯಾವಾಗಲೂ ಚಲನಚಿತ್ರಗಳನ್ನು ಪ್ರೀತಿಸುತ್ತೇನೆ ಮತ್ತು ಬಹಳ ಹಿಂದೆಯೇ ಈ ಕ್ಷೇತ್ರದಲ್ಲಿ ಕೆಲಸ ಮಾಡುವ ಕಂಪನಿಯನ್ನು ಸಹ ರಚಿಸಿದ್ದೇನೆ. ಕಂಪನಿಯನ್ನು ತಂಪಾಗಿ ಕರೆಯಲಾಗುವುದಿಲ್ಲ, ಆದರೆ ಅಪ್ಲಿಕೇಶನ್ ಆಗಿತ್ತು!
ನಾವು ನೆನಪಿಸುತ್ತೇವೆ:ಎಲ್ಲಾ Habr ಓದುಗರಿಗೆ - Habr ಪ್ರೊಮೊ ಕೋಡ್ ಬಳಸಿಕೊಂಡು ಯಾವುದೇ ಸ್ಕಿಲ್ಬಾಕ್ಸ್ ಕೋರ್ಸ್ಗೆ ದಾಖಲಾಗುವಾಗ 10 ರೂಬಲ್ ರಿಯಾಯಿತಿ.
API ನೊಂದಿಗೆ ಸಂವಹಿಸುತ್ತದೆ - ಯಾವುದೇ ಆಧುನಿಕ ಅಪ್ಲಿಕೇಶನ್ ಇದನ್ನು ಮಾಡುತ್ತದೆ.
ವಿನಂತಿಗಳ ಮೇಲೆ ಅಸಮಕಾಲಿಕ ಡೇಟಾವನ್ನು ಲೋಡ್ ಮಾಡುತ್ತದೆ ಮತ್ತು JSON ಅನ್ನು ಸ್ವಿಫ್ಟ್ ಮಾದರಿಯಲ್ಲಿ ಪಾರ್ಸ್ ಮಾಡುತ್ತದೆ ಕೋಡಬಲ್.
ವಿನಂತಿಯ ಮೇರೆಗೆ ಲೋಡ್ ಮಾಡಲಾದ ಚಿತ್ರಗಳನ್ನು ತೋರಿಸುತ್ತದೆ ಮತ್ತು ಅವುಗಳನ್ನು ಕ್ಯಾಶ್ ಮಾಡುತ್ತದೆ.
iOS, iPadOS ಮತ್ತು macOS ಗಾಗಿ ಈ ಅಪ್ಲಿಕೇಶನ್ ಈ OS ಗಳ ಬಳಕೆದಾರರಿಗೆ ಅತ್ಯುತ್ತಮ UX ಅನ್ನು ಒದಗಿಸುತ್ತದೆ.
ಬಳಕೆದಾರರು ಡೇಟಾವನ್ನು ರಚಿಸಬಹುದು ಮತ್ತು ತಮ್ಮದೇ ಆದ ಚಲನಚಿತ್ರ ಪಟ್ಟಿಗಳನ್ನು ರಚಿಸಬಹುದು. ಅಪ್ಲಿಕೇಶನ್ ಬಳಕೆದಾರರ ಡೇಟಾವನ್ನು ಉಳಿಸುತ್ತದೆ ಮತ್ತು ಮರುಸ್ಥಾಪಿಸುತ್ತದೆ.
Redux ಮಾದರಿಯನ್ನು ಬಳಸಿಕೊಂಡು ವೀಕ್ಷಣೆಗಳು, ಘಟಕಗಳು ಮತ್ತು ಮಾದರಿಗಳನ್ನು ಸ್ಪಷ್ಟವಾಗಿ ಪ್ರತ್ಯೇಕಿಸಲಾಗಿದೆ. ಇಲ್ಲಿ ಡೇಟಾ ಹರಿವು ಏಕಮುಖವಾಗಿದೆ. ಇದನ್ನು ಸಂಪೂರ್ಣವಾಗಿ ಕ್ಯಾಶ್ ಮಾಡಬಹುದು, ಮರುಸ್ಥಾಪಿಸಬಹುದು ಮತ್ತು ತಿದ್ದಿ ಬರೆಯಬಹುದು.
ಅಪ್ಲಿಕೇಶನ್ SwiftUI, TabbedView, SegmentedControl, NavigationView, Form, Modal, ಇತ್ಯಾದಿಗಳ ಮೂಲ ಘಟಕಗಳನ್ನು ಬಳಸುತ್ತದೆ. ಇದು ಕಸ್ಟಮ್ ವೀಕ್ಷಣೆಗಳು, ಗೆಸ್ಚರ್ಗಳು, UI/UX ಅನ್ನು ಸಹ ಒದಗಿಸುತ್ತದೆ.
ವಾಸ್ತವವಾಗಿ, ಅನಿಮೇಷನ್ ಮೃದುವಾಗಿರುತ್ತದೆ, GIF ಸ್ವಲ್ಪ ಜರ್ಕಿಯಾಗಿ ಹೊರಹೊಮ್ಮಿತು
ಅಪ್ಲಿಕೇಶನ್ನಲ್ಲಿ ಕೆಲಸ ಮಾಡುವುದು ನನಗೆ ಸಾಕಷ್ಟು ಅನುಭವವನ್ನು ನೀಡಿತು ಮತ್ತು ಒಟ್ಟಾರೆ ಇದು ಸಕಾರಾತ್ಮಕ ಅನುಭವವಾಗಿದೆ. ನಾನು ಸಂಪೂರ್ಣ ಕ್ರಿಯಾತ್ಮಕ ಅಪ್ಲಿಕೇಶನ್ ಅನ್ನು ಬರೆಯಲು ಸಾಧ್ಯವಾಯಿತು, ಸೆಪ್ಟೆಂಬರ್ನಲ್ಲಿ ನಾನು ಅದನ್ನು ಸುಧಾರಿಸುತ್ತೇನೆ ಮತ್ತು ಅದನ್ನು ಆಪ್ಸ್ಟೋರ್ನಲ್ಲಿ ಪ್ರಕಟಿಸುತ್ತೇನೆ, ಐಒಎಸ್ 13 ಬಿಡುಗಡೆಯೊಂದಿಗೆ ಏಕಕಾಲದಲ್ಲಿ.
ರಿಡಕ್ಸ್, ಬೈಂಡಬಲ್ ಆಬ್ಜೆಕ್ಟ್ ಮತ್ತು ಎನ್ವಿರಾನ್ಮೆಂಟ್ ಆಬ್ಜೆಕ್ಟ್
ನಾನು ಈಗ ಸುಮಾರು ಎರಡು ವರ್ಷಗಳಿಂದ Redux ನೊಂದಿಗೆ ಕೆಲಸ ಮಾಡುತ್ತಿದ್ದೇನೆ, ಆದ್ದರಿಂದ ನಾನು ತುಲನಾತ್ಮಕವಾಗಿ ಚೆನ್ನಾಗಿ ಪರಿಣತಿ ಹೊಂದಿದ್ದೇನೆ. ನಿರ್ದಿಷ್ಟವಾಗಿ, ನಾನು ಅದನ್ನು ಮುಂಭಾಗದಲ್ಲಿ ಬಳಸುತ್ತೇನೆ ಪ್ರತಿಕ್ರಿಯಿಸು ವೆಬ್ಸೈಟ್, ಹಾಗೆಯೇ ಸ್ಥಳೀಯ iOS (Swift) ಮತ್ತು Android (Kotlin) ಅಪ್ಲಿಕೇಶನ್ಗಳನ್ನು ಅಭಿವೃದ್ಧಿಪಡಿಸಲು.
SwiftUI ಅಪ್ಲಿಕೇಶನ್ ಅನ್ನು ನಿರ್ಮಿಸಲು ಡೇಟಾ ಹರಿವಿನ ಆರ್ಕಿಟೆಕ್ಚರ್ ಆಗಿ Redux ಅನ್ನು ಆಯ್ಕೆ ಮಾಡಿದ್ದಕ್ಕಾಗಿ ನಾನು ಎಂದಿಗೂ ವಿಷಾದಿಸಲಿಲ್ಲ. UIKit ಅಪ್ಲಿಕೇಶನ್ನಲ್ಲಿ Redux ಅನ್ನು ಬಳಸುವಾಗ ಅತ್ಯಂತ ಸವಾಲಿನ ಭಾಗಗಳೆಂದರೆ ಸ್ಟೋರ್ನೊಂದಿಗೆ ಕೆಲಸ ಮಾಡುವುದು ಮತ್ತು ಡೇಟಾವನ್ನು ಪಡೆಯುವುದು ಮತ್ತು ಹಿಂಪಡೆಯುವುದು ಮತ್ತು ಅದನ್ನು ನಿಮ್ಮ ವೀಕ್ಷಣೆಗಳು/ಘಟಕಗಳಿಗೆ ಮ್ಯಾಪಿಂಗ್ ಮಾಡುವುದು. ಇದನ್ನು ಮಾಡಲು, ನಾನು ಒಂದು ರೀತಿಯ ಕನೆಕ್ಟರ್ಸ್ ಲೈಬ್ರರಿಯನ್ನು ರಚಿಸಬೇಕಾಗಿತ್ತು (ReSwift ಮತ್ತು ReKotlin ಬಳಸಿ). ಉತ್ತಮವಾಗಿ ಕಾರ್ಯನಿರ್ವಹಿಸುತ್ತದೆ, ಆದರೆ ಸಾಕಷ್ಟು ಕೋಡ್. ದುರದೃಷ್ಟವಶಾತ್, ಇದು (ಇನ್ನೂ) ತೆರೆದ ಮೂಲವಲ್ಲ.
ಸಿಹಿ ಸುದ್ದಿ! SwiftUI ನೊಂದಿಗೆ ಚಿಂತಿಸಬೇಕಾದ ಏಕೈಕ ವಿಷಯಗಳು - ನೀವು Redux ಅನ್ನು ಬಳಸಲು ಯೋಜಿಸಿದರೆ - ಸ್ಟೋರ್ಗಳು, ಸ್ಟೇಟ್ಗಳು ಮತ್ತು ರಿಡ್ಯೂಸರ್ಗಳು. @EnvironmentObject ಗೆ ಧನ್ಯವಾದಗಳು SwiftUI ನಿಂದ ಸ್ಟೋರ್ನೊಂದಿಗಿನ ಸಂವಹನವನ್ನು ಸಂಪೂರ್ಣವಾಗಿ ನೋಡಿಕೊಳ್ಳಲಾಗಿದೆ. ಆದ್ದರಿಂದ, ಸ್ಟೋರ್ ಬೈಂಡಬಲ್ ಆಬ್ಜೆಕ್ಟ್ನೊಂದಿಗೆ ಪ್ರಾರಂಭವಾಗುತ್ತದೆ.
ನಾನು ಸರಳ ಸ್ವಿಫ್ಟ್ ಪ್ಯಾಕೇಜ್ ಅನ್ನು ರಚಿಸಿದ್ದೇನೆ, ಸ್ವಿಫ್ಟ್ ಯುಐಎಫ್ಲಕ್ಸ್, ಇದು 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)
}
}
ಪ್ರತಿ ಬಾರಿ ನೀವು ಕ್ರಿಯೆಯನ್ನು ಪ್ರಚೋದಿಸಿದಾಗ, ನೀವು ಗೇರ್ಬಾಕ್ಸ್ ಅನ್ನು ಸಕ್ರಿಯಗೊಳಿಸುತ್ತೀರಿ. ಇದು ಅಪ್ಲಿಕೇಶನ್ನ ಪ್ರಸ್ತುತ ಸ್ಥಿತಿಗೆ ಅನುಗುಣವಾಗಿ ಕ್ರಮಗಳನ್ನು ಮೌಲ್ಯಮಾಪನ ಮಾಡುತ್ತದೆ. ಇದು ಕ್ರಿಯೆಯ ಪ್ರಕಾರ ಮತ್ತು ಡೇಟಾಗೆ ಅನುಗುಣವಾಗಿ ಹೊಸ ಮಾರ್ಪಡಿಸಿದ ಸ್ಥಿತಿಯನ್ನು ಹಿಂತಿರುಗಿಸುತ್ತದೆ.
ಒಳ್ಳೆಯದು, ಸ್ಟೋರ್ ಬೈಂಡಬಲ್ ಆಬ್ಜೆಕ್ಟ್ ಆಗಿರುವುದರಿಂದ, ಪಾಸ್ಥ್ರೂ ಸಬ್ಜೆಕ್ಟ್ ಒದಗಿಸಿದ willChange ಆಸ್ತಿಯನ್ನು ಬಳಸಿಕೊಂಡು ಅದರ ಮೌಲ್ಯವು ಬದಲಾದಾಗ ಅದು SwiftUI ಗೆ ಸೂಚನೆ ನೀಡುತ್ತದೆ. ಏಕೆಂದರೆ BindableObject ಪಬ್ಲಿಷರ್ ಪ್ರಕಾರವನ್ನು ಒದಗಿಸಬೇಕು, ಆದರೆ ಪ್ರೋಟೋಕಾಲ್ ಅನುಷ್ಠಾನವು ಅದನ್ನು ನಿರ್ವಹಿಸುವ ಜವಾಬ್ದಾರಿಯನ್ನು ಹೊಂದಿದೆ. ಒಟ್ಟಾರೆಯಾಗಿ, ಇದು ಆಪಲ್ನಿಂದ ಅತ್ಯಂತ ಶಕ್ತಿಯುತ ಸಾಧನವಾಗಿದೆ. ಅಂತೆಯೇ, ಮುಂದಿನ ರೆಂಡರಿಂಗ್ ಚಕ್ರದಲ್ಲಿ, ಸ್ವಿಫ್ಟ್ಯುಐ ಸ್ಥಿತಿಯ ಬದಲಾವಣೆಗೆ ಅನುಗುಣವಾಗಿ ವೀಕ್ಷಣೆಗಳ ದೇಹವನ್ನು ನಿರೂಪಿಸಲು ಸಹಾಯ ಮಾಡುತ್ತದೆ.
ವಾಸ್ತವವಾಗಿ, ಇದು 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 ಬಳಸಿಕೊಂಡು ಯಾವುದೇ ವೀಕ್ಷಣೆಯಲ್ಲಿ ಪ್ರವೇಶಿಸಬಹುದು. ಯಾವುದೇ ಕಾರ್ಯಕ್ಷಮತೆಯ ದಂಡವಿಲ್ಲ ಏಕೆಂದರೆ ಪಡೆದ ಗುಣಲಕ್ಷಣಗಳನ್ನು ತ್ವರಿತವಾಗಿ ಹಿಂಪಡೆಯಲಾಗುತ್ತದೆ ಅಥವಾ ಅಪ್ಲಿಕೇಶನ್ ಸ್ಥಿತಿಯಿಂದ ಲೆಕ್ಕಹಾಕಲಾಗುತ್ತದೆ.
ಚಲನಚಿತ್ರ ಪೋಸ್ಟರ್ ಬದಲಾದರೆ ಮೇಲಿನ ಕೋಡ್ ಚಿತ್ರವನ್ನು ಬದಲಾಯಿಸುತ್ತದೆ.
ಮತ್ತು ಇದನ್ನು ವಾಸ್ತವವಾಗಿ ಕೇವಲ ಒಂದು ಸಾಲಿನೊಂದಿಗೆ ಮಾಡಲಾಗುತ್ತದೆ, ಅದರ ಸಹಾಯದಿಂದ ವೀಕ್ಷಣೆಗಳು ರಾಜ್ಯಕ್ಕೆ ಸಂಪರ್ಕ ಹೊಂದಿವೆ. ನೀವು iOS ನಲ್ಲಿ ReSwift ನೊಂದಿಗೆ ಕೆಲಸ ಮಾಡಿದ್ದರೆ ಅಥವಾ ಸಹ ಸಂಪರ್ಕ ರಿಯಾಕ್ಟ್ನೊಂದಿಗೆ, ನೀವು 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 ಸ್ಥಿತಿಯಿಂದ ಪಡೆಯಲಾಗಿದೆ ಮತ್ತು ಎನ್ವಿರಾನ್ಮೆಂಟ್ ಆಬ್ಜೆಕ್ಟ್ ಆಗಿ ಚುಚ್ಚಲಾಗುತ್ತದೆ, SwiftUI ಪಟ್ಟಿಯನ್ನು ನವೀಕರಿಸುತ್ತದೆ ಏಕೆಂದರೆ ForEach ಚಲನಚಿತ್ರಗಳ ಲೆಕ್ಕಾಚಾರದ ಆಸ್ತಿಯೊಂದಿಗೆ ಸಂಬಂಧ ಹೊಂದಿದೆ.
MoviesState reducer ನ ಭಾಗ ಇಲ್ಲಿದೆ:
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 ನಿಜವಾಗಿ ಏನನ್ನು ಪ್ರದರ್ಶಿಸಬೇಕೆಂದು ತಿಳಿದಿದೆ. ಇದನ್ನು ಹೆಚ್ಚು ಆಳವಾಗಿ ಅರ್ಥಮಾಡಿಕೊಳ್ಳಲು, ಇದು ಯೋಗ್ಯವಾಗಿದೆ ಡೇಟಾ ಹರಿವಿನ ಮೇಲೆ WWDC ಅಧಿವೇಶನವನ್ನು ವೀಕ್ಷಿಸಿ SwiftUI ನಲ್ಲಿ. ಏಕೆ ಮತ್ತು ಯಾವಾಗ ಬಳಸಬೇಕೆಂದು ಇದು ವಿವರವಾಗಿ ವಿವರಿಸುತ್ತದೆ ರಾಜ್ಯ, @ ಬೈಂಡಿಂಗ್, ಆಬ್ಜೆಕ್ಟ್ ಬೈಂಡಿಂಗ್ ಮತ್ತು ಎನ್ವಿರಾನ್ಮೆಂಟ್ ಆಬ್ಜೆಕ್ಟ್.