Feathers: Klien iOS

Dibuat pada 4 Nov 2015  ·  30Komentar  ·  Sumber: feathersjs/feathers

Feathers API sangat mudah untuk diajak bicara. Klien iOS asli akan luar biasa dan @corymsmith telah melakukan beberapa

  • Komunikasi layanan melalui REST mirip dengan feathers-rest/client
  • Komunikasi layanan melalui Websocket mirip dengan feathers-socket-commons/client
  • Otentikasi mirip dengan bulu-otentikasi/klien

    • Metode authenticate yang mengautentikasi terhadap server dan menyimpan JWT di suatu tempat

    • Metode logout yang menghancurkan JWT yang disimpan

    • Lihat dokumen untuk info selengkapnya tentang alur autentikasi.

  • Kait yang mirip dengan kait bulu

    • Kemampuan untuk mendaftarkan rantai kait before dan after untuk mengubah data atau parameter kueri

bulu-klien adalah modul konsolidasi untuk semua modul di atas. Ini agar kami dapat membuat bundel mandiri untuk orang-orang tanpa pemuat modul JS. Saya tidak berpikir kita perlu melakukan ini untuk iOS. Semua modul klien ini harus dibundel di dalam satu klien iOS.

Kami memiliki repositori dengan beberapa kode awal yang disiapkan untuk ini jika ada yang ingin mengatasinya.

Help Wanted

Komentar yang paling membantu

Ya saya setuju. Saya melakukan flip-flop begitu saya menyadari bahwa jauh lebih mudah untuk membuat ekstensi dari panggilan balik daripada yang tidak dijanjikan.

Semua 30 komentar

:+1:

:100:% ingin ini / turun untuk membantu dalam beberapa cara

Mungkin @corymsmith dapat memposting apa yang dia punya dan kemudian kita dapat memutuskan ke mana harus pergi dari sana @startupthekid. Akan senang membantu!

Saya baru saja menambahkan implementasi awal dengan dukungan REST untuk 'find' dan 'get', akan mudah untuk menambahkan 'update' 'remove', dll. Saya menulis ulang ini untuk menggunakan NSURLSession vs menggunakan dependensi eksternal seperti AlamoFire, dll https:// github.com/feathersjs/feathers-ios

Saya sudah memiliki beberapa kode untuk Primus / Socket.io tetapi perlu dimigrasikan ke basis kode ini

Ini manis! Cukup bersemangat.

Ya ini memang terlihat cukup mengagumkan. Saya telah membangun sesuatu yang analog di aplikasi saya dan saya memiliki beberapa hal yang baik untuk dipertimbangkan saat membangun klien ini.

1) Swift vs Objective-C.

Objective-C jelas lebih dinamis dan ada banyak hal yang dapat Anda lakukan dengannya dalam hal pengiriman dinamis, metode swizzling, dll yang tidak dapat Anda lakukan di Swift. Namun apa yang Anda dapatkan di Swift adalah keamanan tipe.

Pertimbangkan metode protokol bulu berikut:

- (void)find:(NSDictionary *)params completion:(FeathersFindCompletionBlock)completionHandler;

Sebagai pengembang iOS utama, yang paling saya khawatirkan adalah jenis model apa yang dikembalikan ini. Blok penyelesaian mengembalikan array tetapi tanpa spesifikasi tipe, saya tidak tahu apakah itu mengembalikan JSON atau array model atau bahkan keduanya.

Pertimbangkan metode yang sama tetapi di Swift

func find<T: FeathersModel>(parameters: [String: AnyObject], completionHandler handler: ([T], NSError?) -> Void)

Sekarang sebagai konsumen fungsi, saya dapat secara langsung menentukan model apa yang harus dikembalikan dalam penangan penyelesaian tanpa menyandikan pengetahuan itu ke dalam layanan.

Protokol FeathersModel dapat terlihat seperti:

protocol FeathersModel {
    init?(dictionary: [String: AnyObject])
    static func JSONKeysByPropertyKey() -> [String: String]
}

^Ini sangat mirip dengan implementasi Swift dari Mantle yang secara mengejutkan sulit untuk ditiru (yang saya temukan saat membuat Blueprint ). Alih-alih membangun kerangka pemetaan objek sendiri, sesuatu seperti ObjectMapper , yang memiliki ekstensi Alamofire , akan menjadi pilihan yang bagus.

Kemudian metode protokol layanan dapat terlihat seperti:

func find<T: Mappable>(parameters: [String, AnyObject], completionHandler handler: ([T], NSError?) -> Void

dimana implementasinya akan dilakukan dengan menggunakan Alamofire .

Alamorfire.Manager.request(.GET, "\(self.baseURL)\(self.queryString(parameters))").responseArray { (response: Response<[T], NSError>) in
    if case let .Failure(error) = response.result {
        handler([], error)
    } else if case let .Success(value) = response.result {
        handler(value, nil)
    }
}

Alamofire.Manager didasarkan pada NSURLSession sehingga tidak akan jauh berbeda dengan menggunakan NSURLSession secara manual.

2) Fungsional vs panggilan balik

Saya penggemar berat ReactiveCocoa dan acara pemodelan (terutama acara jaringan) seperti Signal s dan SignalProducer s. Saya tidak tahu apakah versi reaktif dari protokol metode harus menjadi cara de facto untuk melakukannya atau submodule ( pod Feathers/ReactiveCocoa ) yang dapat digunakan pengguna akhir jika mereka memilihnya.

Saya telah menulis beberapa ekstensi reaktif untuk ekstensi ObjectMapper di Alamofire yang terlihat seperti ini:

    func rac_Object<T: Mappable>(queue: dispatch_queue_t? = nil, keyPath: String? = nil) -> SignalProducer<T, NSError> {
        return SignalProducer { observer, disposable in
            self.responseObject(queue, keyPath: keyPath) { (response: Response<T, NSError>) in
                if case let .Failure(error) = response.result {
                    observer.sendFailed(error)
                } else if case let .Success(value) = response.result {
                    observer.sendNext(value)
                    observer.sendCompleted()
                }
            }
        }
    }

    func rac_ObjectArray<T: Mappable>(queue: dispatch_queue_t? = nil, keyPath: String? = nil) -> SignalProducer<[T], NSError> {
        return SignalProducer { observer, disposable in
            self.responseArray(queue, keyPath: keyPath) { (response: Response<[T], NSError>) in
                if case let .Failure(error) = response.result {
                    observer.sendFailed(error)
                } else if case let .Success(value) = response.result {
                    observer.sendNext(value)
                    observer.sendCompleted()
                    }
            }
        }
    }

Menggunakan pola ini membuatnya sangat mudah untuk sesuatu seperti ini:

if let service = FeathersService.services["users"] {
    let user: User = service.get("someID").then(self.validateSession())
}

dari pada

service.get("someID") { result, error in
    if error != nil {
        print("ERROR ABANDON SHIP")
    } else {
        self.verifySession()
    }
}

3) Pengambilan jaringan vs sumber lain

Salah satu hal yang paling saya suka tentang bulu di backend saya, terutama feathers-mongoose , adalah bahwa saya menemukan pada layanan users dan model yang benar diambil secara otomatis, sama dengan create , dll.

Untuk itu, apa yang saya yakini akan membuat klien ios super kuat dan pada akhirnya menyebabkan orang menggunakannya adalah kemampuan untuk tidak hanya mengambil dari layanan Node.js tetapi dari kerangka kerja persistensi lokal, apakah itu CoreData atau Realm atau beberapa opsi ke-3 .

Sekali lagi di sinilah Swift dapat benar-benar membantu karena pemrograman berorientasi protokol sangat kuat. Tujuannya menurut saya adalah untuk mempertahankan desain seperti yang dibuat oleh @corymsmith , dengan satu objek Feathers tempat layanan terdaftar dan satu kelas FeathersService yang mengimplementasikan protokol layanan.

enum ServiceType<T> {
    case Remote(NSURL, String)
    case Realm(T.Type)
    case CoreData(entityName: String)
}
protocol ServiceProtocol {

    typealias Model

    var type: ServiceType<Model> { get set }


    init(type: ServiceType<Model>)
}

Dan kemudian untuk setiap jenis dukungan (Realm, CoreData), cukup tambahkan ekstensi:

extension ServiceProtocol where T: Object { } //Realm

Saya belum cukup menemukan desain protokol untuk menentukan kelas model apa yang dikaitkan dengan layanan dan apakah itu harus dilakukan berdasarkan fungsi berdasarkan fungsi dengan obat generik atau jika ServiceProtocol harus menjadi batasan tipe generik.

Memikirkannya lagi, enum terkait akan terlihat lebih seperti:

enum ServiceType<Model> {
    case Realm(modelClass: Model.Type)
    case Remote(modelClass: Model.Type, baseURL: String, servicePath: String)
    case CoreData(modelClass: Model.Type, entityName: String)
}

@startupthekid Setuju

@corymsmith pasti ada banyak cara berbeda untuk melakukan ini. Ketika saya membangunnya untuk salah satu aplikasi saya, saya mengalami beberapa masalah dengan generik Swift dan layanan penyimpanan.

Misalnya saya menetapkan layanan saya sebagai:

enum Service<Model> {
    case Realm(Model.Type)
    case Network(Model.Type, NSURL, String)
}

tetapi di manajer layanan saya (sama dengan Feathers.h), kamus yang menyimpan layanan harus bertipe [String: Service<T>] mana semua T s harus sama (tidak bisa simpan keduanya Service<User> dan Service<Post> misalnya.
Solusi saya hanya untuk mendefinisikan BaseModel dan memiliki jenis penyimpanan menjadi [String: Service<BaseModel>] yang tidak bagus tapi _shrug_.

Masalah lain yang saya temukan adalah bagaimana tepatnya menerapkan metode protokol yang berbeda untuk kasus enum yang berbeda. Pikiran awal saya adalah menggunakan ekstensi:

extension Service where Self == .Realm {

}

tetapi saya segera mengetahui bahwa Anda hanya dapat membatasi kelas dan protokol (dan juga tidak ada generik variadik di Swift seperti di C++ :-1 :). Kasus yang lebih buruk itu bisa saja hanya sebuah saklar:

extension Service {
    func find(parameters: [String: AnyObject]? = nil) -> SignalProducer<Model, NSError> {
        switch self {
            case let .Realm(model): //do something
            case let .Network(model, URI, servicePath): //do something else
        }
    }
}

@corymsmith @daffl hanya untuk referensi, apa yang akhirnya saya lakukan di aplikasi saya adalah membuat protokol:

protocol ServiceType {
    typealias Model

    func get(id: String) -> SignalProducer<Model, NSError>
}

dan kemudian untuk setiap jenis pengambilan sumber daya (Jaringan, Realm, dll), saya membuat satu implementasi struct konkret jadi saya berakhir secara keseluruhan dengan dua struct, RealmService , dan NetworkService , keduanya menerapkan ServiceProtocol .

struct RealmService<T: Object>: ServiceType {
    func get(id: String) -> SignalProducer<T, NSError> {
        return SignalProducer { observer, disposable in
            Persistence.sharedStack.fetch(T).filter(NSPredicate {
                if let object = $0.0 as? BaseModel where object.id == id {
                    return true
                }
                return false
            })
        }
    }
}

Saya melakukannya dengan cara ini karena setiap metode terpisah untuk mendapatkan data mungkin perlu memberikan batasan pada tipe terkait Model .

Maka saya hanya bisa melakukan:

let userRealmService = RealmService<User.self>()
userRealmService.get("someID")

@startupthekid Maaf kami agak gagal dalam hal ini. @corymsmith dan saya sangat sibuk dan lebih fokus pada React Native akhir-akhir ini, jadi saya akhirnya punya waktu untuk meninjau semua komentar Anda secara memadai. Saya bukan pengembang iOS jadi saya harus membaca banyak untuk memahami apa yang Anda bicarakan. Saya telah memperbarui deskripsi dengan persyaratan tingkat tinggi untuk apa yang mungkin ingin kami terapkan.

@corymsmith dan saya mengobrol sedikit tentang ini kemarin dan mungkin masuk akal untuk menulis ini di Swift dan kemudian memiliki beberapa header penghubung jika diperlukan, namun karena Swift tidak mendukung generik variadik, itu mungkin membuatnya sedikit rumit. Jadi sekarang saya mengatakan itu, mungkin Obj-C dengan bridging header ke Swift. Pasti ada beberapa pekerjaan yang harus dilakukan di sini kalian berdua akan lebih baik untuk membuat panggilan itu.

Saya pikir Anda sangat ingin melakukan sesuatu yang mirip dengan ReactiveCocoa. Kami berencana membuat klien JS opsional juga reaktif . Ini menyediakan antarmuka yang sangat bersih.

Sejauh dukungan Realm berjalan, idealnya itu harus seperti sebuah plugin. Saya cenderung membuat penyimpanan default untuk hal-hal seperti, katakanlah token auth atau data model Anda, dalam memori. Saya pikir pengembang harus dapat melakukan sesuatu seperti feathers.use() untuk CoreData, SQLite, atau Realm (selama Anda telah menautkan Perpustakaan, kami tidak menggabungkannya dengan jelas). Proses pemikiran saya di sini adalah bahwa itu tidak akan memaksa siapa pun ke dalam mesin penyimpanan tertentu, dan itu berada di dalam memori secara default akan memungkinkan orang untuk membuat prototipe barang dengan sangat cepat tanpa harus melakukan penautan atau apa pun.

Mengizinkan orang untuk hanya menyimpan sesuatu dalam memori mungkin merupakan ide bodoh di iOS, tetapi menjaga agar tetap fleksibel dan opsional adalah kunci kebahagiaan pengembang, meskipun itu sedikit lebih berhasil bagi kami. Jadi, bahkan jika kita perlu menggunakan datastore secara default, Anda harus dapat menukar, CoreData, Realm, SQLite hanya dengan beberapa baris.

Karena @corymsmith dan saya sangat sibuk dengan RN, @startupthekid jika Anda memiliki waktu dan motivasi untuk mengerjakan ini, Anda dapat sepenuhnya memimpin dan kami akan dengan senang hati mendukung Anda dengan tinjauan PR, pengujian, dan diskusi arsitektur. Beri tahu saya dan kami akan memberi Anda akses baca/tulis ke repo. :senyum:

Dengan tidak adanya ini, saya telah menggunakan Moya , yang fantastis tetapi ada beberapa hal yang saya tidak suka tentang itu, hal utama yang menurut saya bulu dapat sangat ditingkatkan: target titik akhir.

Singkatnya, Moya adalah lapisan abstraksi di Alamofire dan untuk setiap jenis permintaan yang Anda inginkan, Anda membuat enum terkait yang terlihat seperti:

enum API {
    case CreateUser(User)
    case UpdateUser(User)
    case CreatePost(postName: String, postImage: UIImage)
}

Yang berarti jika Anda ingin mendukung find , get , put , dll, itu adalah target terpisah untuk masing-masing dan itu menjadi rumit dengan cepat. Bahkan untuk aplikasi kecil yang sedang saya kerjakan sekarang saya memiliki 18 kasing terpisah. Saya akhirnya membuat protokol dan meniru perilaku bulu:

protocol CRUD {
    typealias Model
    func create() -> SignalProducer<Model, Types.Error>
    static func find(parameters: [NSObject: AnyObject]?) -> SignalProducer<[Model], Types.Error>
    static func get(id: String) -> SignalProducer<Model, Types.Error>
    func update() -> SignalProducer<Model, Types.Error>
    remove() -> SignalProducer<Model, Types.Error>
}

Saya menggunakan protokol ini pada model dan kelas model tetapi hal yang sama akan bekerja pada objek layanan.

Ada juga beberapa hal baik yang dilakukan Moya, yang akan lebih berjangka panjang untuk proyek ini, seperti menghentikan permintaan dukungan.

Hal-hal yang harus didukung:

  • Komunikasi layanan melalui REST mirip dengan feathers-rest/client
  • Komunikasi layanan melalui Websocket mirip dengan feathers-socket-commons/client
  • Otentikasi mirip dengan bulu-otentikasi/klien
  • Metode otentikasi yang mengautentikasi terhadap server dan menyimpan JWT di suatu tempat
  • Metode logout yang menghancurkan JWT yang disimpan
  • Lihat dokumen untuk info selengkapnya tentang alur autentikasi.
  • Kait yang mirip dengan kait bulu
  • Kemampuan untuk mendaftar sebelum dan sesudah rantai kait untuk mengubah data atau parameter kueri

Oke jadi ini hanya beberapa pemikiran awal yang saya miliki (saya juga sudah lama tidak melihat repo ini):

1) Layanan harus (kebanyakan) dibuat secara otomatis.

Salah satu hal yang saya sukai tentang bulu adalah bahwa tergantung pada layanan DB saya, saya dapat membungkus model saya dalam panggilan ke feathers-mongoose atau apa pun yang Anda miliki. Itu berarti membuat paket terpisah seperti feathers-realm atau feathers-core-data yang akan diteruskan ke kelas model dan mengembalikan layanan.

Jika Anda ingin membuat layanan khusus, Anda cukup mewarisi dari kelas yang kami sediakan: Service . Atau mungkin bukan kelas tetapi protokol kecuali kita membutuhkan properti penyimpanan kelas.

2) DB sebagai plugin

Saya suka ide ini dan saya pikir itu agak perlu karena iOS adalah paradigma yang berbeda, semacam kombinasi dari feathers-client dan klien feathers npm. Layanan harus dapat a) membuat permintaan jaringan dan b) jika ada plugin db yang dikonfigurasi, bertahan/mengambil/menghapus dari layanan itu.

Pertimbangkan jika pengguna menggunakan Realm misalnya, ketika Anda memanggil create pertama-tama harus dibuat di jaringan dan kemudian mempertahankan model ke Realm SETELAH panggilan jaringan berhasil diselesaikan. Panggilan lain seperti find dapat berjalan secara paralel karena layanan harus segera mengembalikan model lokal sehingga pengguna memiliki salinan untuk dikerjakan.

3) Terminologi harus diubah sekitar

Sekali lagi karena iOS adalah binatang yang berbeda dari simpul, beberapa istilah harus diubah agar lebih akurat mewakili apa yang terjadi. app harus disebut seperti provider karena tidak digunakan dengan cara yang sama seperti di express.

Itu cukup banyak yang saya miliki untuk saat ini, saya harus lebih memikirkannya. Dan kita harus berdiskusi arsitektur sebelum kita mulai menulis kode apa pun. Secara pribadi saya pikir itu harus memodelkan model bulu yang ada semirip mungkin.

Dengan mengingat hal itu, Anda akan memiliki sesuatu seperti:

  • Penyedia (setara dengan feathers() )
  • Layanan (diakses melalui provider.service("serviceName") dan dibuat dengan provider.use )
  • Konfigurasi (seperti feathers-rest atau feathers-socketio ) yang Anda berikan ke penyedia

    • Konfigurasi juga bisa berupa protokol yang merinci cara mengatur, cara mengkonfigurasi rute, dll

  • Plugin (untuk penyedia db)

    • Benar-benar plugin hanyalah pembungkus layanan untuk model tertentu

Dan kerennya jika ini didistribusikan melalui Cocoapods, semua pembungkus db, konfigurasi, dan plugin dapat menjadi subspesifikasi:

pod 'Feathers'
pod 'Feathers/Realm'
pod 'Feathers/Rest'
pod 'Feathers/RX'
pod 'Feathers/ReactiveCocoa'

@startupthekid :+1: untuk semua itu dari saya. Bagaimana menurutmu @corymsmith?

Saya berpikir objek bulu alias penyedia akan terlihat seperti:

class Feathers() {
    static let singleton = Feathers()
    func service(serviceName: String) -> Service {}
}

Kemudian sebagai pengguna akhir yang akan Anda lakukan: Feathers.singleton.service('users').get(id, params)
Singleton tampaknya merupakan cara yang harus dilakukan agar penyedia utama selalu ada dalam memori. Saya tidak tahu apakah pengguna akan menggunakan (atau ingin?) kemampuan untuk membuat sub-aplikasi seperti yang mereka bisa di node.js. Sepertinya fitur yang tidak terlalu dibutuhkan?

@startupthekid , itulah yang saya dan @corymsmith pikirkan.

Dia sedang mengerjakan implementasi Android yang lebih lengkap sekarang yang mungkin akan berfungsi sebagai panduan yang layak untuk apa yang harus kita lakukan di iOS ketika kita tidak berurusan dengan bahasa yang dinamis.

@ekryski terdengar hebat. Saya akan senang membantu kapan pun saya bisa. Cukup sibuk bulan ini tetapi datang bulan depan saya akan memiliki banyak waktu luang untuk meretas.

@ekryski Saya pasti bisa memulainya malam ini, siapkan Pod dan yang lainnya jadi jika Anda ingin menambahkan saya sebagai kolaborator, itu akan luar biasa. Saya bisa memulainya dengan gaya bulu yang indah.

@startupthekid selesai! Menantikan untuk melihat apa yang Anda masak :senyum: Jika Anda masih ingat untuk melakukan PR, itu akan manis. Sebagian besar untuk visibilitas pada saat ini.

Ini mungkin pertanyaan bodoh, tetapi saya tidak pernah menjadi bagian dari repo yang bukan milik saya atau di mana saya adalah satu-satunya pengembang di dalamnya. Bagaimana Anda mengelola PR ketika Anda memiliki akses tulis ke repo? Buat cabang dan tarik permintaan untuk dikuasai?

@startupthekid Anda mengerti! Idealnya kami memiliki setidaknya satu orang meninjau PR satu sama lain. Ini adalah pemeriksaan kewarasan yang baik dan membuatnya setidaknya satu orang lain tahu apa yang sedang terjadi. @corymsmith akan menjadi orang terbaik untuk ditinjau tetapi saya akan melakukan yang terbaik untuk membantu juga.

Segera kami akan meresmikan bagaimana kami ingin melakukan rilis dan apa strategi percabangan yang harus dilakukan, tetapi untuk saat ini adalah musim yang cukup terbuka.

Coba saja dan pertahankan komitmen dan PR lebih kecil sehingga mudah ditinjau. Komit Anda akan muncul di saluran #aktivitas di Slack. Terkejut!

@ekryski Luar biasa! Hal cepat terakhir: biasanya saya membangun banyak barang saya secara Reaktif dengan ReactiveCocoa dari bawah ke atas, tetapi sepertinya opsi yang lebih baik adalah membuatnya dengan panggilan balik dan kemudian memiliki ekstensi reaktif yang dikemas sebagai subspesifikasi. Mungkin subspec janji untuk menggunakan PromiseKit. Apakah Anda akan memiliki preferensi tentang bagaimana Anda menginginkannya?

Benar-benar apa yang kita bicarakan di sini bukan hanya membangun iOS yang setara dengan Feathers tetapi juga kait, istirahat, socketio, dll. Dan saya penasaran karena kait di JS dapat mengembalikan janji tetapi juga menggunakan panggilan balik, sebagian besar karena JS 100x lebih dinamis daripada Swift.

Plus seperti yang saya katakan sebelumnya, feathers-ios adalah binatang yang menarik karena merupakan kombinasi fungsionalitas dari paket klien dan server.

Saya condong ke janji sebagai default dan ekstensi/plugin Reaktif nanti. Hal-hal panggilan balik di JS lebih untuk mendukung versi Feathers 1.x.

Pada kenyataannya, karena ini adalah platform yang berbeda, saya akan menggunakan apa pun yang akan menjadi yang paling umum/akrab bagi orang-orang di iOS. Jika janji cukup umum maka mari kita lakukan itu. Jika orang menganggap janji itu aneh maka mungkin panggilan balik lebih baik. Saya akan membiarkan Anda dan @corymsmith memutuskan.

@corymsmith saya akan mengatakan panggilan balik pasti yang paling umum; Saya tidak tahu banyak orang yang menggunakan PromiseKit. Tapi bermain advokat setan sebentar, jika seseorang melihat perpustakaan ini sudah akrab dengan bulu, mereka pasti sudah mengerti janji dan bagaimana bulu menggunakannya.

@ekryski baru saja mengeluarkan PR pertama saya. Itu sedikit miring karena saya harus meledakkan master, menjalankan instalasi pod baru untuk mendapatkan pengaturan yang benar, kemudian memaksa memperbarui master sehingga mereka memiliki riwayat yang sama, lalu mengeluarkan permintaan tarik. Seharusnya tidak perlu melakukan force push lagi, cukup dengan pengaturan awal Cocoapods dan repo yang sudah ada.
Apa yang Anda ingin saya lakukan dengan cabang yang tidak saya gunakan lagi seperti pods-integration ? Meninggalkan mereka atau memberi mereka kapak?

@startupthekid Saya telah membangun versi Android sejauh ini dengan panggilan balik tetapi sedang mempertimbangkan untuk beralih ke Janji atau berpotensi mendukung Observables menggunakan RXJava.

Saya pikir akan baik-baik saja untuk memulai dengan janji dan jika kita perlu menambahkan dukungan atau ekstensi panggilan balik maka kita bisa melakukannya.

Sejauh cabang lama Anda bisa memberikan kapak jika Anda sudah menggabungkannya atau Anda tidak menggunakannya lagi.

Saus yang luar biasa, terima kasih atas tanggapan cepatnya. Saya akan memiliki beberapa hal pendahuluan untuk Anda lihat sebentar lagi.

@startupthekid Jangan khawatir dan terima kasih banyak telah membantu!

Saya akan menggunakan PromiseKit karena ini yang paling banyak digunakan. Saya setuju untuk tidak melakukan apa pun dengan panggilan balik, menghilangkannya sepenuhnya hanya membuat hidup semua orang lebih mudah.

@startupthekid Inilah cara saya mendaftarkan layanan dan menyiapkan Socket.IO di Android:

Feathers.getInstance()
                .setBaseUrl("http://localhost:3030/")
                .configure(new FeathersSocketIO())
                .use("posts", Article.class);

        FeathersService<Article> articleService = Feathers.service("posts");

Jadi saya berpikir bahwa jika itu lebih akrab dan @corymsmith akan melakukan panggilan balik, mengapa kita tidak melakukannya untuk saat ini dan melihat bagaimana perkembangannya. Kami selalu dapat bermigrasi ke janji atau menambahkan ekstensi janji nanti. Saya tidak terlalu khawatir tentang orang-orang yang datang dari JS ke iOS atau Android dan menjadi persis sama. Hanya saja semua lib klien harus dalam semangat yang sama.

Ya saya setuju. Saya melakukan flip-flop begitu saya menyadari bahwa jauh lebih mudah untuk membuat ekstensi dari panggilan balik daripada yang tidak dijanjikan.

Oke. Mari kita tutup masalah ini dan kemudian masalah/diskusi berikut dapat terjadi baik pada bulu-ios repo dan slack. Saya mungkin mulai menyiapkan saluran terpisah, setidaknya untuk klien yang berbeda.

Masalah ini telah dikunci secara otomatis karena tidak ada aktivitas terbaru setelah ditutup. Silakan buka masalah baru dengan tautan ke masalah ini untuk bug terkait.

Apakah halaman ini membantu?
0 / 5 - 0 peringkat

Masalah terkait

harrytang picture harrytang  ·  3Komentar

perminder-klair picture perminder-klair  ·  3Komentar

rstegg picture rstegg  ·  3Komentar

jordanbtucker picture jordanbtucker  ·  4Komentar

codeus-de picture codeus-de  ·  4Komentar