SwiftUI پر ایپلیکیشن ڈویلپمنٹ۔ حصہ 1: ڈیٹا فلو اور ریڈکس

SwiftUI پر ایپلیکیشن ڈویلپمنٹ۔ حصہ 1: ڈیٹا فلو اور ریڈکس

WWDC 2019 میں اسٹیٹ آف دی یونین سیشن میں شرکت کے بعد، میں نے SwiftUI میں گہرا غوطہ لگانے کا فیصلہ کیا۔ میں نے اس کے ساتھ کام کرنے میں کافی وقت صرف کیا ہے اور اب میں نے ایک حقیقی ایپلی کیشن تیار کرنا شروع کر دی ہے جو کہ صارفین کی وسیع رینج کے لیے مفید ہو سکتی ہے۔

میں نے اسے MovieSwiftUI کہا - یہ نئی اور پرانی فلموں کو تلاش کرنے کے ساتھ ساتھ انہیں ایک مجموعہ میں جمع کرنے کے لیے ایک ایپ ہے۔ TMDB API. میں نے ہمیشہ فلموں کو پسند کیا ہے اور یہاں تک کہ اس شعبے میں کام کرنے والی ایک کمپنی بھی بنائی ہے، حالانکہ بہت عرصہ پہلے۔ کمپنی کو شاید ہی ٹھنڈا کہا جا سکے، لیکن درخواست تھی!

ہم آپ کو یاد دلاتے ہیں: "Habr" کے تمام قارئین کے لیے - "Habr" پروموشنل کوڈ کا استعمال کرتے ہوئے کسی بھی Skillbox کورس میں داخلہ لینے پر 10 rubles کی رعایت۔

Skillbox تجویز کرتا ہے: تعلیمی آن لائن کورس "پیشہ جاوا ڈویلپر".

تو MovieSwiftUI کیا کر سکتا ہے؟

  • API کے ساتھ تعامل کرتا ہے - تقریبا کوئی بھی جدید ایپلی کیشن ایسا کرتی ہے۔
  • درخواستوں پر غیر مطابقت پذیر ڈیٹا لوڈ کرتا ہے اور JSON کو استعمال کرتے ہوئے Swift ماڈل میں پارس کرتا ہے۔ کوڈ ایبل.
  • درخواست پر بھری ہوئی تصاویر دکھاتا ہے اور انہیں کیش کرتا ہے۔
  • iOS، iPadOS اور macOS کے لیے یہ ایپ ان OS کے صارفین کے لیے بہترین UX فراہم کرتی ہے۔
  • صارف ڈیٹا تیار کر سکتا ہے اور اپنی فلم کی فہرستیں بنا سکتا ہے۔ ایپلیکیشن صارف کے ڈیٹا کو محفوظ اور بحال کرتی ہے۔
  • ریڈکس پیٹرن کا استعمال کرتے ہوئے آراء، اجزاء اور ماڈل واضح طور پر الگ کیے گئے ہیں۔ یہاں ڈیٹا کا بہاؤ یک طرفہ ہے۔ اسے مکمل طور پر کیش، بحال اور اوور رائٹ کیا جا سکتا ہے۔
  • ایپلی کیشن SwiftUI، TabbedView، SegmentedControl، NavigationView، Form، Modal، وغیرہ کے بنیادی اجزاء استعمال کرتی ہے۔ یہ حسب ضرورت نظارے، اشاروں، UI/UX بھی فراہم کرتا ہے۔

SwiftUI پر ایپلیکیشن ڈویلپمنٹ۔ حصہ 1: ڈیٹا فلو اور ریڈکس
دراصل، حرکت پذیری ہموار ہے، GIF تھوڑا سا جھٹکا لگا

ایپ پر کام کرنے سے مجھے کافی تجربہ ملا اور مجموعی طور پر یہ ایک مثبت تجربہ تھا۔ میں ایک مکمل طور پر فعال ایپلیکیشن لکھنے کے قابل تھا، ستمبر میں میں اسے بہتر بناؤں گا اور اسے ایپ اسٹور میں شائع کروں گا، بیک وقت iOS 13 کے اجراء کے ساتھ۔

Redux، BindableObject اور EnvironmentObject

SwiftUI پر ایپلیکیشن ڈویلپمنٹ۔ حصہ 1: ڈیٹا فلو اور ریڈکس

میں اب تقریباً دو سال سے Redux کے ساتھ کام کر رہا ہوں، اس لیے میں اس میں نسبتاً ماہر ہوں۔ خاص طور پر، میں اسے فرنٹ اینڈ میں استعمال کرتا ہوں۔ جواب دیں ویب سائٹ، نیز مقامی iOS (Swift) اور Android (Kotlin) ایپلی کیشنز تیار کرنے کے لیے۔

مجھے SwiftUI ایپلیکیشن بنانے کے لیے ڈیٹا فلو فن تعمیر کے طور پر Redux کو منتخب کرنے پر کبھی افسوس نہیں ہوا۔ UIKit ایپ میں Redux کا استعمال کرتے وقت سب سے مشکل حصے اسٹور کے ساتھ کام کرنا اور ڈیٹا حاصل کرنا اور بازیافت کرنا اور اسے اپنے خیالات/اجزاء کے ساتھ نقشہ بنانا ہے۔ ایسا کرنے کے لیے، مجھے کنیکٹرز کی ایک قسم کی لائبریری بنانا پڑی (ReSwift اور ReKotlin کا ​​استعمال کرتے ہوئے)۔ اچھی طرح سے کام کرتا ہے، لیکن بہت زیادہ کوڈ۔ بدقسمتی سے، یہ (ابھی تک) اوپن سورس نہیں ہے۔

اچھی خبر! SwiftUI کے بارے میں فکر کرنے کی واحد چیزیں - اگر آپ Redux استعمال کرنے کا ارادہ رکھتے ہیں - اسٹورز، اسٹیٹس اور کم کرنے والے ہیں۔ @EnvironmentObject کی بدولت SwiftUI اسٹور کے ساتھ تعامل کا مکمل خیال رکھتا ہے۔ تو، اسٹور BindableObject سے شروع ہوتا ہے۔

میں نے ایک سادہ سوئفٹ پیکیج بنایا، SwiftUIFlux، جو 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)
    }
}

جب بھی آپ کوئی کارروائی شروع کرتے ہیں، آپ گیئر باکس کو چالو کرتے ہیں۔ یہ درخواست کی موجودہ حالت کے مطابق اعمال کا جائزہ لے گا۔ اس کے بعد یہ کارروائی کی قسم اور ڈیٹا کے مطابق ایک نئی ترمیم شدہ حالت واپس کر دے گا۔

ٹھیک ہے، چونکہ اسٹور ایک BindableObject ہے، یہ SwiftUI کو مطلع کرے گا جب پاس تھرو سبجیکٹ کے ذریعے فراہم کردہ willChange پراپرٹی کا استعمال کرتے ہوئے اس کی قدر میں تبدیلی آئے گی۔ اس کی وجہ یہ ہے کہ BindableObject کو ایک PublisherType فراہم کرنا ضروری ہے، لیکن پروٹوکول کا نفاذ اس کے انتظام کے لیے ذمہ دار ہے۔ مجموعی طور پر، یہ ایپل کا ایک بہت طاقتور ٹول ہے۔ اس کے مطابق، اگلے رینڈرنگ سائیکل میں، 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 کا استعمال کرتے ہوئے کسی بھی منظر میں قابل رسائی ہوتا ہے۔ کارکردگی کا کوئی جرمانہ نہیں ہے کیونکہ اخذ کردہ خصوصیات کو فوری طور پر بازیافت کیا جاتا ہے یا درخواست کی حالت سے شمار کیا جاتا ہے۔

اگر فلم کا پوسٹر تبدیل ہوتا ہے تو اوپر والا کوڈ تصویر کو تبدیل کرتا ہے۔

اور یہ دراصل صرف ایک سطر کے ساتھ کیا جاتا ہے، جس کی مدد سے خیالات کو ریاست سے جوڑا جاتا ہے۔ اگر آپ نے iOS یا یہاں تک کہ ReSwift کے ساتھ کام کیا ہے۔ متصل React کے ساتھ، آپ 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 ریاست سے اخذ کی گئی ہے اور اسے EnvironmentObject کے طور پر انجکشن کیا گیا ہے، SwiftUI فہرست کو اپ ڈیٹ کرتا ہے کیونکہ 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 اصل میں جانتا ہے کہ کیا ڈسپلے کرنا ہے۔ اس کو مزید گہرائی سے سمجھنے کے لئے، یہ قابل ہے ڈیٹا فلو پر WWDC سیشن دیکھیں SwiftUI میں۔ یہ بھی تفصیل سے بتاتا ہے کہ کیوں اور کب استعمال کرنا ہے۔ حالت، @Binding، ObjectBinding اور EnvironmentObject۔

Skillbox تجویز کرتا ہے:

ماخذ: www.habr.com

نیا تبصرہ شامل کریں