በWWDC 2019 የሕብረቱ ክፍለ ጊዜ ከተሳተፍኩ በኋላ፣ ወደ SwiftUI በጥልቀት ለመጥለቅ ወሰንኩ። ከእሱ ጋር በመስራት ብዙ ጊዜ አሳልፌያለሁ እና አሁን ለብዙ ተጠቃሚዎች ጠቃሚ ሊሆን የሚችል እውነተኛ መተግበሪያ ማዘጋጀት ጀመርኩ።
MovieSwiftUI ብዬ ጠራሁት - ይህ አዲስ እና አሮጌ ፊልሞችን ለመፈለግ እንዲሁም በስብስብ ውስጥ ለመሰብሰብ መተግበሪያ ነው
እኛ እናስታውስዎታለን- ለሁሉም የ "ሀብር" አንባቢዎች - የ "Habr" የማስተዋወቂያ ኮድን በመጠቀም በማንኛውም የ Skillbox ኮርስ ውስጥ ሲመዘገቡ የ 10 ሩብልስ ቅናሽ.
Skillbox ይመክራል፡ ትምህርታዊ የመስመር ላይ ኮርስ
"ሙያ ጃቫ ገንቢ" .
ስለዚህ MovieSwiftUI ምን ማድረግ ይችላል?
- ከኤፒአይ ጋር ይገናኛል - ማንኛውም ዘመናዊ መተግበሪያ ማለት ይቻላል ይህን ያደርጋል።
- በጥያቄዎች ላይ ያልተመሳሰለ ውሂብን ይጭናል እና JSONን በመጠቀም ወደ ስዊፍት ሞዴል ይተነዋል።
ተቀባይነት ያለው . - በተጠየቀ ጊዜ የተጫኑ ምስሎችን ያሳያል እና ይሸፍኗቸዋል።
- ይህ መተግበሪያ የiOS፣ iPadOS እና macOS ለእነዚህ ስርዓተ ክወናዎች ተጠቃሚዎች ምርጡን UX ያቀርባል።
- ተጠቃሚው ውሂብ ማመንጨት እና የራሳቸውን የፊልም ዝርዝሮች መፍጠር ይችላል። አፕሊኬሽኑ የተጠቃሚውን ውሂብ ያስቀምጣል እና ወደነበረበት ይመልሳል።
- እይታዎች፣ ክፍሎች እና ሞዴሎች የ Redux ስርዓተ-ጥለትን በመጠቀም በግልፅ ተለያይተዋል። እዚህ ያለው የውሂብ ፍሰት ባለአንድ አቅጣጫ ነው። ሙሉ በሙሉ መሸጎጫ፣ ወደነበረበት መመለስ እና ሊፃፍ ይችላል።
- አፕሊኬሽኑ የSwiftUI፣ TabbedView፣ SegmentedControl፣ NavigationView፣ Form፣ Modal፣ ወዘተ መሰረታዊ ክፍሎችን ይጠቀማል። እንዲሁም ብጁ እይታዎችን፣ የእጅ ምልክቶችን፣ UI/UXን ያቀርባል።
እንደ እውነቱ ከሆነ፣ እነማው ለስላሳ ነው፣ ጂአይኤፍ ትንሽ ገርሞታል።
በመተግበሪያው ላይ መሥራት ብዙ ልምድ ሰጠኝ እና በአጠቃላይ አዎንታዊ ተሞክሮ ነበር። ሙሉ በሙሉ የሚሰራ አፕሊኬሽን መፃፍ ችያለሁ፣ በሴፕቴምበር ላይ አሻሽየዋለሁ እና በAppStore ውስጥ አሳትመዋለሁ፣ በተመሳሳይ ጊዜ iOS 13 ከተለቀቀ በኋላ።
Redux፣ BindableObject እና EnvironmentObject
ከሬዱክስ ጋር ለሁለት ዓመታት ያህል እየሠራሁ ነው፣ ስለዚህ በአንፃራዊነት በደንብ ጠንቅቄአለሁ። በተለይም እኔ በግንባሩ ውስጥ እጠቀማለሁ
የስዊፍት UI መተግበሪያን ለመገንባት ሬዱክስን እንደ የውሂብ ፍሰት አርክቴክቸር በመምረጥ ተቆጭቼ አላውቅም። በ UIKit መተግበሪያ ውስጥ Reduxን ሲጠቀሙ በጣም ፈታኝ የሆኑት ክፍሎች ከመደብሩ ጋር እየሰሩ እና ውሂብን በማግኘት እና በማውጣት እና በእርስዎ እይታዎች/አካላት ላይ በማሳየት ላይ ናቸው። ይህንን ለማድረግ, የግንኙነት አይነት (ReSwift እና ReKotlin በመጠቀም) አይነት ቤተ-መጽሐፍት መፍጠር ነበረብኝ. በደንብ ይሰራል፣ ግን በጣም ብዙ ኮድ። እንደ አለመታደል ሆኖ (ገና) ክፍት ምንጭ አይደለም።
መልካም ዜና! ከSwiftUI ጋር መጨነቅ ያለብዎት ብቸኛው ነገር - Redux ለመጠቀም ካሰቡ - መደብሮች፣ ግዛቶች እና መቀነሻዎች ናቸው። ከሱቁ ጋር ያለው መስተጋብር ሙሉ በሙሉ በSwiftUI እንክብካቤ ይደረግለታል @EnvironmentObject እናመሰግናለን። ስለዚህ፣ ማከማቻ በBindableObject ይጀምራል።
ቀላል የስዊፍት ጥቅል ፈጠርኩ ፣
ይህ የሚሠራው እንዴት ነው?
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 ስለሆነ፣ በPassthroughSubject የቀረበ ንብረትን በመጠቀም እሴቱ ሲቀየር ለSwiftUI ያሳውቀዋል። ይህ የሆነበት ምክንያት BindableObject የአታሚ አይነት ማቅረብ ስላለበት ነው፣ ነገር ግን የፕሮቶኮሉ ትግበራ እሱን የማስተዳደር ሃላፊነት አለበት። በአጠቃላይ ይህ ከ 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ን በመጠቀም በማንኛውም እይታ ተደራሽ ይሆናል። የአፈጻጸም ቅጣት የለም ምክንያቱም የተገኙ ንብረቶች በፍጥነት ከመተግበሪያው ሁኔታ ስለሚመለሱ ወይም ስለሚሰላ።
የፊልም ፖስተር ከተቀየረ ከላይ ያለው ኮድ ምስሉን ይለውጠዋል.
እና ይሄ በእውነቱ በአንድ መስመር ብቻ ይከናወናል, በእነሱ እርዳታ እይታዎች ከግዛቱ ጋር የተገናኙ ናቸው. ከ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 እየተጠቀምኩ ነው። ይህ በዝርዝሩ ውስጥ ያለው ረድፍ ለመሰረዝ የተለመደውን የ iOS ሸርተቴ እንዲያሳይ ያስችለዋል። ስለዚህ ተጠቃሚው የመሰረዝ አዝራሩን ሲነካው ተጓዳኝ እርምጃውን ያስነሳል እና ፊልሙን ከዝርዝሩ ያስወግዳል.
እንግዲህ፣ የዝርዝር ንብረቱ ከBindableObject ግዛት የተገኘ እና እንደ ኢንቫይሮንመንትኦብጀክት የተወጋ በመሆኑ፣ ስዊፍት UI ዝርዝሩን ያዘምናል ምክንያቱም ForEach ከተሰላ ንብረት ጋር የተያያዘ ነው።
የፊልም ግዛት ቅነሳ አካል ይኸውና፡-
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 ይመክራል፡
- ተግባራዊ ኮርስ
"ሞባይል ገንቢ PRO" .- በመስመር ላይ ኮርስ ተተግብሯል
"Python ውሂብ ተንታኝ" .- የሁለት ዓመት ተግባራዊ ኮርስ
"እኔ የ PRO ድር ገንቢ ነኝ" .
ምንጭ: hab.com