Bir mobil uygulama geliştiricisiyseniz, belki de anında düzen ve mantık değişiklikleri yapmak için çevrimiçi geliştirme esnekliğini ve hipotez testlerini saniyeler içinde çalıştırma ve sonuçları daha da hızlı işleme becerisini hayal ettiniz mi?

Mobil geliştiricilere, uygulamaların yayınlanma ve güncellenme hızının, kullanıcılara ne kadar çabuk ulaştıklarıyla doğrudan ilişkili olduğuna inanmaları öğretilir. App Store denetleme süresi sinir bozucu derecede uzun olabilir. Bir Yazılım Geliştirme Kiti (SDK) oluşturmak daha da yavaş olacaktır çünkü ihtiyaçlarınızı başka birinin ürün geliştirme ve yayınlama döngülerine uydurmanız gerekir. Hipotezleri hiç test etmemek için iyi bir bahane olabilir.

Bu blog gönderisinde, konunun üzerinden geçeceğiz ve belirli sorunları çözmek için nasıl kullanıldığını ve bize ne gibi yararlar sağladığını açıklayarak Arka Uç Güdümlü Geliştirme adımlarında size yol göstereceğiz. Bu gönderi için malzemeler MovilePay örneğindeki kaynaktan alınmıştır. Orijinal metnin yazarı Rodrigo Maximo'dur.

Arka Uç Odaklı Geliştirme Nedir?

Arka uç odaklı geliştirme (veya Arka Uç Odaklı Geliştirme veya Arka Uç Odaklı Kullanıcı Arabirimi veya Sunucu Odaklı Kullanıcı Arabirimi), sunucu yanıtlarına dayalı ön uç uygulamaları geliştirme kavramıdır. Sunucunun yanıtlarına göre ekranlar ve akış değişir.

Mobil uygulamalar oluşturma işinin büyük kısmı genellikle bir kullanıcı arayüzü oluşturmakla ilişkilidir: kullanıcının etkileşimde bulunduğu öğeleri ekranlara yerleştirmek, böylece bir veya başka bir eylemi hızlı bir şekilde gerçekleştirebilir. Bu bileşenlerin bazıları API yükleriyle doldurulur: tipik olarak ilkel türlere (tamsayılar, booleanlar, dizeler) veya uygulama iş süreçlerine sahip JSON.

Ekranları uygulamaya yönelik geleneksel yaklaşımın bazı dezavantajları vardır, çünkü uygulama tarafında çok fazla iş mantığı olabilir ve kodun bakımı daha zor hale gelir:

  • Birçok platform için aynı koda ihtiyacınız var (Android, iOS, Web, vb.). Bu yaklaşım, hata ve uyumsuzluk olasılığını artıran platformlar arası uyumluluğu korumayı zorlaştırır;
  • Bir mobil uygulamanın her güncellemesi veya modifikasyonu, kodun değiştirilmesi gereğini ima eder ve bu da App Store'da uygulamaların daha uzun süre yayınlanmasına yol açar;
  • Dijitalde A/B testi daha zordur. Önemli ürün bilgilerini anlamak için kavramları test etmek ve kullanıcılardan veri toplamak daha zordur;
  • İş mantığının çoğu uygulama tarafında olduğundan, kodun bakımı ve bakımı daha zordur.

Arka uç odaklı geliştirme bu sorunları çözmek için geldi.

Aşağıdaki senaryoyu göz önünde bulundurun (örnek iOS uygulamasına dayalıdır, ancak başka herhangi bir ön uç projesine kolayca çevrilebilir):

Scenario for backend driven development

 {
    "pageTitle" : "Gösterici Başlık" ,
    "kutular" : [
        {
            "type ": "bigBlue" ,
            “başlık” : “Güzel kutu” ,
            "altyazı" : " Kutunun alt yazısı"
        } ,
        {
            "type ": "smallRed" ,
            “başlık” : “Harika kutu”
        } ,
        {
            "type ": "dikdörtgenYeşil" ,
            “başlık” : “İnanılmaz kutu” ,
            "altyazı" : " Kutunun alt yazısı" ,
            "sayı" : 10
        }
    ]
}

Alanları görüntülemek ve metin ve görsel bilgileri görüntülemek için tüm iş mantığı sunucu tarafında birleştirilir ve özetlenir, bu API'yi işlemek için birden fazla arabirime olan ihtiyacı ortadan kaldırır. Sunucu daha sonra iş mantığını uygular ve sonuçlarını JSON biçiminde bir API yanıtı oluşturmak için kullanır.

Örnekte, ekranda blokları görüntülemek için ("bigBlue", "smallRed" ve "rectangleGreen"), her alandan ek bilgiler kullanılır. İlginç bir şekilde, "kutular" değişkeni, arka ucun sunucunun verdiği kadar çok bloğu işlemesine izin verir.

Bu durumda A / B testini nasıl yapabileceğinizi muhtemelen tahmin ettiniz mi? Sunucu, yalnızca "bigBlue" bloklarını görüntülemek için belirli kullanıcıları seçebilir, diğerleri ise üç blok tipini de görebilir. Ayrıca blokların ekranda görüntülenme sırasını değiştiren A/B testleri de yapabilirsiniz.

Sunucuya Dayalı Geliştirme için başka bir kullanım durumu, bir uygulamanın arayüzünde değişiklik yapmaktır. Örneğin uygulamadaki header'ları değiştirmemiz gerekiyorsa basitçe sunucunun verdiği cevabı değiştirmemiz yeterlidir. Alt yazıların ve blokların görüntülenme sırasını değiştirmek de kolaydır. Bu durumda, AppStore'da yeni bir uygulama sürümü yayınlamanız gerekmez.

Making changes to the interface in backend driven development

 {
    "pageTitle" : "Gösterici Başlık" ,
    "kutular" : [
        {
            "type ": "dikdörtgenYeşil" ,
            “başlık” : “Başka bir başlık” ,
            “altyazı” : “Başka bir altyazı” ,
            "sayı" : 100
        } ,
        {
            "type ": "smallRed" ,
            “başlık” : “Farklı başlık”
        }
        {
            "type ": "bigBlue" ,
            "başlık" : "Arka Uç Yönelimli" ,
            "altyazı" : "Geliştirme"
        }
    ]
}

İki kere düşün

Backend Driven Development yaklaşımını kullanırken akılda tutulması gereken birkaç şey vardır. İlk olarak, ne derece esnekliğe ihtiyacınız var?

Deneyim ve araştırmaya dayanarak, orta esnekliğin optimal olduğunu düşünüyoruz.

Bir aşırı uçtan diğerine acele etmemelisiniz. Büyük miktarda özgürlük, gelişiminizin geri ödemesini olumsuz yönde etkileyebilir. Özellikle cihaz özellikleri veya ekran boyutu kontrolünüz dışında olduğu için her şeyi öngöremezsiniz. Son olarak, çok kafa karıştırıcı ve aşırı yüklenmiş uygulama tarafı sunum mantığıyla karşılaşıyorsunuz. Ayrıca, tasarım ekibinizin gelecekte yapmak isteyebileceği her şeyi tahmin edemezsiniz. Bu nedenle, uygulama kodunda hala değişiklik yapmanız gerekir ve test sırasında hedefe ulaşmak için çok sayıda karmaşık yol keşfedilecektir.

Sonuç olarak, çoğu durumda HTML'nin sahip olduğu esnekliğe ihtiyacınız olmayacak. Bu nedenle Backend-Driven Development fikrini kullanan ekranlar ve sunucu çözümleri geliştirmeden önce, olası tüm seçenekleri düşünmenizi öneririz.

Süper Uygulama Oluşturma, Movile Tech Case

Muhtemelen süper uygulama konseptine aşinasınız ve WeChat gibi bir uygulamayı duymuşsunuzdur. WeChat, Çin'de geliştirilen ve dünya çapında son derece popüler hale gelen bir mobil mesajlaşma platformu ve sosyal ağdır.

Böyle bir uygulama, birkaç tekrar eden hizmeti tek bir yerde toplamayı ve kullanıcılara günlük yaşamlarındaki çevrimiçi sorguların çoğuna tek bir erişim noktası sunmayı amaçlamaktadır. Bu, yazılım geliştirmenin kutsal kâsesidir: her şeyin göründüğü gibi görünmesini sağlamak için birçok işlevi bir araya getirmek.e, kullanıcılara karmaşık sorulara basit cevaplar ve büyük sorunlara çözümler sunar.

Geçmişte MovilePay, geliştirilmiş bir sürümünü geliştirme süreci bu makalede açıklanan süper bir uygulamanın geliştirilmesinde yer aldı. Ekibin yeni hizmetleri test edebileceği ve kullanımlarında ortak bir zemin bulabileceği bir test ve doğrulama merkezi olması gerekiyordu.

MovilePay, kodda hızla değişiklik yapabilen bir uygulama oluştururken sorun yaşadı. Birçok hizmet ve hizmeti test etmeyi ve görüntülenen bilgilere dayalı olarak kullanıcı davranışı üzerine araştırma yapmayı ve hipotezleri test etmeyi gerektiriyordu. MovilePay, özellikleri hızlı bir şekilde açıp kapatabilmek istedi. Bu koşullar altında, her değişiklik için bir sürüm ile geleneksel yaklaşımı kullanmak imkansızdı. Tüm bu noktalar ve karmaşık bir senaryo göz önünde bulundurularak Backend-Driven Development uygulanmasına karar verildi.

MovilePay, bu sorunu çözmek için kategori tabanlı bir ana ekran oluşturdu. Her bölümün widget adı verilen kendi öğeleri vardır. Bölümler, halihazırda uygulanmış herhangi bir hizmet için giriş noktalarını herhangi bir sırayla ve vurgulanan bireysel widget'ları gösterdi.

Bazen yalnızca bir hizmet görüntülendi. Diğer zamanlarda, şu anda neyin test edildiğine bağlı olarak üç tane vardı. MovilePay, herhangi bir kuralı uygulamaya kodlamak yerine seçimi sunucuya bıraktı. Sonuç olarak, uygulama yalnızca hizmetin giriş noktasının tanımını ve her bir belirli stilin nasıl oluşturulacağını bilir. Sunucuları, hangi hizmetlerin hangi sırayla oluşturulması gerektiğini söyler. İşte MovilePay uygulamasının görüntüleyebileceği bazı widget'lar.

Widgets that the MovilePay application

Widgets in MovilePay application

Widgets in MovilePay application

Widgets in MovilePay application

Bu nedenle, son derece uyarlanabilir bir ana ekran oluşturmak için, her biri bir widget listesi içeren bir bölüm listesiyle arka uçtan bir yanıt almamız gerekiyordu. Aşağıdaki, MovilePay uygulamasının ayrıştırması ve aşağıdaki örnekteki gibi bir ana ekran oluşturması gereken bir JSON yanıtı örneğidir.

Parsing and creating a home screen

 [
    {
        "başlık" : "Bölüm 1" ,
        "widget'lar" : [
            {
                "tanımlayıcı" : "COLLECTION_WIDGET" ,
                "içerik" : [
                    {
                        "başlık" : "Başlık A" ,
                        "resim" : "A" ,
                        "renk" : "sarı"
                    } ,
                    {
                        "başlık" : "Başlık B" ,
                        "resim" : "B" ,
                        "renk" : "mavi"
                    } ,
                    {
                        "başlık" : "Başlık C" ,
                        "resim" : "C" ,
                        "renk" : "kırmızı"
                    } ,
                    {
                        "başlık" : "Başlık D" ,
                        "resim" : "D" ,
                        "renk" : "mor"
                    } ,
                    {
                        "başlık" : "Başlık E" ,
                        "resim" : "E" ,
                        "renk" : "yeşil"
                    }
                ]
            } ,
            {
                "tanımlayıcı" : "IMAGES_WIDGET" ,
                "içerik" : [
                    {
                        "image" : "Resim" ,
                        "renk" : "yeşil"
                    } ,
                    {
                        "image" : "Resim" ,
                        "renk" : "mavi"
                    } ,
                    {
                        "image" : "Resim" ,
                        "renk" : "turuncu"
                    }
                ]
            } ,
            {
                "tanımlayıcı" : "COLLECTION_WIDGET" ,
                "içerik" : [
                    {"başlık" : "Başlık E" , "resim" : "E" , "renk" : "yeşil" } , { "başlık" : "Başlık F" , "resim" : "F" , "renk" : "mor " } , { "başlık" : "Başlık G" , "resim" : "G" , "renk" : "kırmızı" } , { "başlık" : "Başlık H" , "resim" : "H" , "renk " : "mavi" } , { "başlık" : "Başlık H" , "resim" : "Y" , "renk" : "sarı" } ] } ] } , { "başlık" : "Bölüm 2" , "widget'lar " : [ { "tanımlayıcı" : "HÜCRELER_WIDGET" , "içerik" : [ { "başlık" : "Hücre 1" , "renk" : "kırmızı" } , { "başlık" : "Hücre 2" , "renk" : "mor" } , { "başlık" : "Hücre 3" , "renk" : "sarı" } , { "başlık" : "Hücre 4" , "renk" : "mavi" } , { "başlık" : "Hücre 5" , "renk" : "koyu yeşil" } ] } ] } ]

Ayrıca arka uç odaklı geliştirme kullanılarak oluşturulabilecek bazı ekranları da inceleyeceğiz.

Home screens in backend-driven development

Esnek gezinme

MovilePay tarafından geliştirilen Süper Uygulama, amaçlanan yenilikçi olma hedefine ulaştı. MovilePay, hipotez testlerinden çok şey öğrendi, ancak özellikle iyi oldukları bir şey, ödeme işleme veya çeşitli hizmetler ve ürünler için ödeme işlemleridir. Sağladıkları herhangi bir hizmet için ödemeleri işleyebilecek bir ödeme uygulamasına sahiplerdi. MovilePay, birden fazla işlemi işleyerek ve tüketici davranışına ilişkin değerli bilgiler edinerek fiyatları aşağı çekebildiğinden, ödeme işlemlerini yönetme yeteneği önemli bir avantajdı.

MovilePay, Google Pay, Apple Pay veya VisaCheckout modelini temel alan ve diğer herhangi bir uygulamayla entegre edilebilecek bir ödeme SDK'sı geliştirmeye karar verdi.

Ancak, bir SDK üzerinde çalışmak, tipik geliştirme kalıplarını kullanarak çok az test etme yeteneği gerektirdiğinden, otomasyon gereklidir.

MovilePay ödemelerle ilgilendiğinden, akışların dönüşümü kritikti. MovilePay, dönüşüm hunisinin hiçbir aşamasında kullanıcılarını kaybetmeyi göze alamazdı. Bu nedenle, kullanıcı kaydından kart eklemeye ve ödemeye kadar tüm iş sürecini optimize etmek gerekliydi. Sunucuyu uygulamanın "navigatörü" haline getirerek Backend-Driven Development'ın tekrar kullanışlı olduğu yer burasıdır.

Optimizing the business process with BDD

MovilePay uygulama ekranlarının hiçbiri sırada hangi ekranın olduğunu bilmiyordu. Önceki ekran görevlerini tamamladıktan sonra, bir sonraki ekranın hangi ekranın görüntülenmesi gerektiğini döndürmekten sunucu sorumludur.

Rotalar, bir uygulamanın Yönlendirici olarak bilinen bir yapı aracılığıyla tanıyabileceği ve yanıt verebileceği eylemlerdi. Oturum açma mekanizması iki ayrı eylem dalı içeriyordu: biri sayfa başlığı için ve diğeri eylem ağacında karşılaşılan diğer öğeler (kullanıcı adı değişikliği veya yeni parola gibi) için. Yönlendirici bunları sunucuya göndererek işledi, ardından eylemlerini yorumladı ve bir sonraki ekranda hangi yorumların olması gerektiğini belirledi.

Stratejideki bu mütevazi değişiklik, düzene sokmaya izin verdi. MovilePay, kayıt formunu görüntülemek için birçok farklı yol denedi. Kartı eklemeden önce veya sonra ödeme ekranının gösterilmesinin tercih edilip edilmediğini test etmek mümkün oldu. Örneğin, MovilePay'in diğer ödeme seçeneklerine kıyasla dönüşüm oranını %30 artırabilmesinin nedenlerinden biri de budur.

Başka bir örnek, MovilePay'in sorunlarını çözmek için Arka Uç Güdümlü Geliştirmeyi nasıl kullandığıdır. harika olduğunu düşünüyoruzBu yaklaşımın pratikte nasıl uygulanacağını öğrenmek. Sana ne kadar kolay olduğunu göstereyim.

Aynı amaca ulaşmak için birçok alternatif yöntem vardır. MovilePay'in bunu iOS için nasıl yaptığını size göstereceğiz. İstenirse, bu konsept diğer herhangi bir ön uç platforma uygulanabilir.

MovilePay bunu uyguladığında, ek widget ekleme kolaylığı, kod okunabilirliği ve tek sorumluluk gibi gereksinimleri göz önünde bulundurdular. İşleri daha basit ve daha yerel hale getirmek için MovilePay, serileştirme için Codable API'yi kullanmaya karar verdi.

Widget'lar (iOS)

Esneklik açısından MovilePay, en iyi çözümün bir protokolle ayrıştırılması gereken widget'ları genelleştirmek olduğunu hissetti. MovilePay ayrıca hangi widget yapısının verilerin ayrıştırılacağını belirlemek için bir numaralandırma ayarlar.

 protokol Widget'ı : Çözülebilir { }

enum WidgetIdentifier : Dize , Çözülebilir {
    vaka başlığı = "BANNER"
    vaka koleksiyonu = "KOLEKSİYON"
    vaka listesi = "LİSTE"

    var metatype : Widget . Tür {
        kendini değiştir {
        durum . afiş :
            BannerWidget'ı döndür . öz
        durum . koleksiyon :
            CollectionWidget'ı döndürür . öz
        durum . liste :
            ListWidget'ı döndürür . öz
        }
    }
}

Widget protokolü tarafından uygulanan Çözülebilir protokol aracılığıyla Codable API'den yararlanıyorlar. Aşağıda bir widget yapısı tanımlama örneği verilmiştir.

 struct BannerWidget : Widget {
    özel izin imageURLString : Dize
}

struct CollectionWidget : Widget {

    struct Öğe : Çözülebilir {
        let imageURLString : Dize
        Let başlık : Dize
        alt yazı izin ver : Dize
    }

    let sectionTitle : Dize
    listeleyelim : [ Öğe ]
}

struct ListWidget : Widget {

    struct Öğe : Çözülebilir {
        let imageURLString : Dize
        Let text : Dize
    }

    let sectionTitle : Dize
    listeleyelim : [ Öğe ]
}

Son olarak, Decodeable tarafından verilen özel başlatmanın değiştirilmesi gerektiğinde herhangi bir parçacığı gerekli başlatma yöntemiyle yorumlayan bir tür silme olarak tanımlandı.

 son sınıf AnyWidget : Çözülebilir {

    özel numaralandırma Kodlama Anahtarları : Kodlama Anahtarı {
        vaka tanımlayıcısı
    }

    izin widget : Widget ?

    gerekli init ( kod çözücüden : Dekoder ) { atar
        yap {
            kapsayıcıya izin verin = kod çözücüyü deneyin . kapsayıcı ( keyedBy : CodingKeys . self )
            yazın = kapsayıcıyı deneyin . kod çözme ( WidgetIdentifier .self , forKey : . identifier )
            öz . widget = yazmayı deneyin . metatip . init ( 'den : kod çözücü )
        } yakalamak {
            öz . widget = sıfır
        }
    }
}

Bu silme türü, Widget'ın tanımlayıcısının ve onun "meta-type" özelliğinin şifresini çözmek ve ayrıştırılmış Widget'ın geri kalan verilerini ayrıştırmak için hangi pencere öğesi yapısının kullanılması gerektiğini belirlemek için kullanılır.

Tüm bunlar, aşağıdaki yapının, widget'larla ilgili tüm bilgileri içeren bir yanıtı ayrıştırabilmesiyle sonuçlanır. Benzersiz bir özelliği vardır: bir dizi Widget protokol türü ve yukarıda tanımlanan tür silmeyi kullanarak her Widget'ın şifresini çözebilir.

 struct HomeResponse : Çözülebilir {

    özel numaralandırma Kodlama Anahtarları : Kodlama Anahtarı {
        vaka widget'ları
    }

    let widget'ları : [ Widget ]

    init ( kod çözücüden : Dekoder ) { atar
        kapsayıcıya izin verin = kod çözücüyü deneyin . kapsayıcı ( keyedBy : CodingKeys . self )
        öz . widget'lar = kapsayıcıyı deneyin . kod çözme ( [ AnyWidget ] .self , forKey : .widgets)ss="belirteç noktalama">) . compactMap {$ 0. widget } } init ( widgets : [ Wdget ] ) { self . widget'lar = widget'lar } }

MovilePay, protokolü kullanmamak ve ayrıştırma için desteklenen her bir widget'ın bir dizisini döndürmek için arka uca güvenmek gibi başka seçenekleri de seçebilirdi. Ancak, protokol seçimimizin bakım ve okunabilirlik için en iyi seçim olduğunu gördük. Bu yaklaşım, yeni bir yapı oluşturmak ve her yeni bir pencere öğesi oluşturulması gerektiğinde enum'a vakalar eklemek için yeterliydi. Benzer bir durumda farklı bir sistemle HomeResponse tasarımının değiştirilmesi gerekir.

Aşağıda, bu modelin ayrıştıracağı olası bir JSON API yanıtı verilmiştir.

 {
    "widget'lar" : [
        {
            "tanımlayıcı" : "BANNER" ,
            "imageURLString" : "url_image_to_be_downloaded"
        } ,
        {
            "tanımlayıcı" : "KOLEKSİYON" ,
            "sectionTitle" : "Bölüm Başlığı" ,
            "liste" : [
                {
                    "imageURLString" : "url_image_to_be_downloaded" ,
                    "başlık" : "Başlık öğesi 1" ,
                    "altyazı" : "Altyazı öğesi 1"
                } ,
                {
                    "imageURLString" : "url_image_to_be_downloaded" ,
                    "başlık" : "Başlık öğesi 2" ,
                    "altyazı" : "Altyazı öğesi 2"
                } ,
                {
                    "imageURLString" : "url_image_to_be_downloaded" ,
                    "başlık" : "Başlık öğesi 3" ,
                    "altyazı" : "Altyazı öğesi 3"
                }
            ]
        } ,
        {
            "tanımlayıcı" : "LİSTE" ,
            "sectionTitle" : "Bölüm Başlığı" ,
            "liste" : [
                {
                    "imageURLString" : "url_image_to_be_downloaded" ,
                    "metin" : "Metin öğesi 1"
                } ,
                {
                    "imageURLString" : "url_image_to_be_downloaded" ,
                    "metin" : "Metin öğesi 2"
                } ,
                {
                    "imageURLString" : "url_image_to_be_downloaded" ,
                    "metin" : "Metin öğesi 3"
                }
            ]
        } ,
        {
            "tanımlayıcı" : "BANNER" ,
            "imageURLString" : "url_image_to_be_downloaded"
        }
    ]
}

Bu yaklaşım, MovilePay'in farklı kullanıcılara farklı hizmetler sunmasını, birçok görüntüleme seçeneğini test etmesini, hipotezler geliştirmesini ve hangi hizmet için hangi widget'ın kullanılacağını belirlemesini sağlayan Süper Uygulamanın geliştirilmesine çok yakındır. Ekran sıralama ve hizmet gruplamasındaki değişiklik, MovilePay'in daha önce yaptıklarına yakındı.

Navigasyon (iOS)

Widget sorununu çözdükten sonra MovilePay, navigasyonu benzer şekilde iyileştirmeye çalıştı. Widget protokolüyle aynı olan Eylem protokolünü oluşturdular.

Eylem, bazı MovilePay API'lerinin JSON yanıtında bir kimlik ve temsil ettiği sahnede görüntülenmesi gereken parametrelerle döndürülen yapılandırılmış bir nesnedir. Sonuç olarak, Eylem protokolü, yapılandırılmış nesnenin yapısını bozmaya yardımcı olmaktan sorumludur.

 protokol Eylem : Çözülebilir {
    func sahnesi ( ) - > UIViewController
}

enum ActionIdentifier : Dize , Çözülebilir {
    case home = "HOME"
    case screenOne = "SCREEN_ONE"
    case screenTwo = "EKRAN_İKİ"

    var metatype : Action . Tür {
        kendini değiştir {
        durum . ev :
            HomeAction'a geri dönün . öz
        durum . ekran biroken operatörü">: ScreenOneAction'ı döndür . self case.screenTwo : ScreenTwoAction'ı geri döndür . self } } } ham görüntüle

Eylem protokolü ile Widget protokolü arasındaki tek fark, Eylem tanımında her Eylem için uygun sahneyi döndüren bir yöntem sağlamamızdır. Örnek olarak, bu eylemlerin nasıl uygulandığına bir göz atın.

 struct HomeAction : Eylem {
    func sahnesi ( ) - > UIViewController {
        HomeCoordinator'a geri dönün . sahne ( )
    }
}

struct ScreenOneAction : Eylem {
    Let başlık : Dize

    func sahnesi ( ) - > UIViewController {
        ScreenOneCoordinator'a geri dönün . sahne ( başlık : öz . başlık )
    }
}

struct ScreenTwoAction : Eylem {
    Let başlık : Dize
    alt yazı izin ver : Dize

    func sahnesi ( ) - > UIViewController {
        ScreenTwoCoordinator'a geri dönün . sahne ( başlık : self . başlık , alt başlık : self . altyazı )
    }
}

Yukarıdaki örnek, oluşturulduğunda, Actions'ın sahnelerini başlatmak ve UIViewController'ı başlatmak için Coordinators yöntemini çağırmak için gerekli tüm özellikleri içermesi gerektiğini gösterir. Koordinatörler, bir UIViewController sağlayan yapılardır. Burada bahsedilecek bir şey var: MovilePay, Koordinatörler yapılarında, her aşama için bir UIViewController örneği oluşturmakla görevli statik bir sahne() yöntemiyle temsil edilen bir tasarım deseni kullanır.

 final sınıfı Ev Koordinatörü : Koordinatör {
    statik işlev sahnesi ( ) - > UIViewController {
        // ViewController'ı ve bu sahnenin tüm mimari bileşenlerini oluşturun...
        oluşturulanViewController'ı döndür
    }
}

final sınıfı ScreenOneCoordinator : Koordinatör {
    statik işlev sahnesi ( ) - > UIViewController {
        // ViewController'ı ve bu sahnenin tüm mimari bileşenlerini oluşturun...
        oluşturulanViewController'ı döndür
    }
}

final sınıfı ScreenTwoCoordinator : Koordinatör {
    statik işlev sahnesi ( ) - > UIViewController {
        // ViewController'ı ve bu sahnenin tüm mimari bileşenlerini oluşturun...
        oluşturulanViewController'ı döndür
    }
}

Ayrıca, seçilen mimari tasarım modeline (MVC, MVP, MVVM-C, VIPER-C, VIP veya sahneler oluşturmak ve bir sahneden diğerine geçmek için bir koordinatör kullanan başka herhangi bir mimari) rağmen, uygulamanın Eylem ve Arka Uç Odaklı Geliştirme oldukça uygundur.

Actions MovilePay bağlamı için, küçük bir uyarlamayla, widget'larla aynı türde silme kullandık.

 son sınıf AnyAction : Çözülebilir {

    özel numaralandırma Kodlama Anahtarları : Kodlama Anahtarı {
        vaka tanımlayıcısı
    }

    eyleme izin ver : Eylem ?

    gerekli init ( kod çözücüden : Dekoder ) { atar
        yap {
            kapsayıcıya izin verin = kod çözücüyü deneyin . kapsayıcı ( keyedBy : CodingKeys . self )
            yazın = kapsayıcıyı deneyin . kod çözme ( ActionIdentifier .self , forKey : . identifier )
            öz . eylem = türü deneyin . metatip . init ( 'den : kod çözücü )
        } yakalamak {
            öz . eylem = sıfır
        }
    }
}

Buradaki ilgili not, MovilePay'in tür silme kodunun kopyalanmasını önlemek için Generics tasarım modelini kullanabileceğidir. Ancak, yapmamayı seçtiler. Aşağıdaki, bir Eylem içeren bir yapı örneğidir.

 struct ResponseModelForActions : Çözülebilir {
    özel numaralandırma Kodlama Anahtarları"belirteç operatörü">: CodingKey { durum eylemi , metin } eyleme izin ver : Eylem ? let text : String init ( kod çözücüden : Decoder ) atar { let container = try decoder . kapsayıcı ( keyedBy : CodingKeys.self ) self . metin = kapsayıcıyı deneyin . kod çözme ( String.self , forKey: .text ) let anyAction = deneyelim mi? konteyner . kod çözme ( AnyAction.self , forKey : .action ) self . eylem = herhangi Eylem ?. eylem } }

Örneğin, ekranda bir UIButton oluşturmak için bir API tarafından sağlanan JSON olabilir. Kullanıcı bu düğmeye dokunduktan sonra işlenen eylem nesnesi, sağlanan eylemi gerçekleştirerek uygulamanın ana ekranı görüntülemesine neden olabilir.

 {
    "metin" : "Gösterici metin" ,
    "eylem" : {
        "tanımlayıcı" : "HOME_SCREEN"
    }
}

Tüm koordinatörlerin Actions nesnesi aracılığıyla yeni bir sahne almasına izin vermek için Koordinatör protokolünü genişleterek kolayca elde edildi.

Koordinatörün harekete geçmesine, yani bu eylem için bir sonraki UIViewController örneğini oluşturmasına ve ardından görüntülemesine izin verir.

 uzantı Koordinatörü {
    func sahnesi ( eylem kullanarak : Eylem ) - > UIViewController {
        dönüş eylemi . sahne ( )
    }
}

Sunucu uygulamasına ilişkin bir ipucu

Muhtemelen tüm bunların sunucu tarafında nasıl göründüğünü merak ediyorsunuzdur. Hizmetlerinizi ve temel yeteneklerinizi harici bilgilerle nasıl karıştırmayın? Yazılım geliştirmede başarının sırrı katmanlar halinde çalışmaktır.

Böylece, tüm karmaşık çekirdek hizmetlere ek olarak, MovilePay, diğer tüm hizmetleri soyutlayarak ve tüm uygulama mantığını uygulayarak, verileri ön uç tarafından beklenen yanıta dönüştüren sunucuya başka bir katman ekledi. Bu katmana BFF denir veya Ön Uç İçin Arka Uç, sistemin iki ayrı ve ilişkisiz ucu arasında iletişim sağlayan bir katmandır. Dizilerin, görüntülerin, akışların ve stil varyasyonlarının yapılandırıldığı ve uygulamalara gönderilmeden önce temel alınan verilere uygulandığı yerdir.

Sonuçlar

Arka Uç Odaklı yaklaşımı kullanmanın, makale boyunca açıklığa kavuşturmaya çalıştığımız çeşitli avantajları vardır. Ancak, bu sadece başka bir çözüm şablonu. Uygulama geliştirme için sihirli bir hap değil. Ayrıca uygulamanın kullanılacağı bağlam da göz önünde bulundurulmalıdır. Birden fazla platform için uygulamalar oluşturmanız mı gerekiyor? Ne tür testler yapmak istersiniz? Tüm ekranlar üzerinde tam kontrole mi ihtiyacınız var? Yükleriniz ne kadar büyük olacak? Bu görevleri yerine getirebilecek bir geliştirme ekibi de dahil olmak üzere bu projeyi yürütmek için yeterli kaynağınız var mı?

Her şeyden önce, ihtiyacınız olan esnekliğe her zaman dikkat etmelisiniz. Son derece çok yönlü UI bileşenleri oluşturmak veya standart olmayan yazı tipleri ve kenar boşlukları kullanmak, kod tabanını inanılmaz derecede karmaşık hale getirerek daha kötü bir kullanıcı deneyimine yol açabilir.

Çoğu proje bu tür bir esnekliğe ihtiyaç duymaz. Arka Uç Odaklı bir yaklaşım seçerken, böyle bir projeyi geliştirmek ve sürdürmek için finans şeklinde kaynaklara ve bir geliştirme ekibine sahip olup olmadığınızı ve uygulamanızın yükünü doğru bir şekilde hesaplayıp hesaplayamadığınızı göz önünde bulundurmak önemlidir.