Kerangka kerja cepat yang terinspirasi oleh Sesi NSOperations Lanjutan WWDC 2015. Sebelumnya dikenal sebagai Operasi , yang dikembangkan oleh @Danthorpe dengan banyak bantuan dari komunitas kami yang fantastis.
| Sumber | Dimana menemukannya |
|---|---|
| Video sesi | pengembang.apple.com |
| Dokumentasi referensi lama tapi lebih lengkap | docs.danthorpe.me/operations |
| Dokumen referensi yang diperbarui tetapi belum lengkap | Prosedur.kit.run/development |
| Panduan Pemrograman | Operations.readme.io |
ProsedurKit mendukung semua platform Apple saat ini. Persyaratan minimumnya adalah:
Versi ProsedurEkit yang dirilis saat ini (5.1.0) mendukung Swift 4.2+ dan Xcode 10.1. Cabang development adalah Swift 5 dan Xcode 10.2 yang kompatibel.
ProsedurKit adalah kerangka kerja "multi-modul" (jangan repot-repot googling itu, saya baru saja mengada-ada). Yang saya maksud adalah bahwa proyek Xcode memiliki beberapa target/produk yang masing -masing menghasilkan modul Swift. Beberapa modul ini adalah cross-platform, yang lain berdedikasi, misalnya ProcedureKitNetwork vs ProcedureKitMobile .
Lihat Panduan Prosedur Instalasi.
Procedure adalah Foundation.Operation Subkelas Operasi. Ini adalah kelas abstrak yang harus disubkilasi.
import ProcedureKit
class MyFirstProcedure : Procedure {
override func execute ( ) {
print ( " Hello World " )
finish ( )
}
}
let queue = ProcedureQueue ( )
let myProcedure = MyFirstProcedure ( )
queue . add ( procedure : myProcedure )Poin utama di sini adalah:
Procedure subkelasexecute tetapi jangan hubungi super.execute()finish() setelah pekerjaan selesai, atau jika prosedur dibatalkan. Ini bisa dilakukan secara tidak sinkron.ProcedureQueue . Pengamat melekat pada subkelas Procedure . Mereka menerima panggilan balik ketika peristiwa siklus hidup terjadi. Acara siklus hidup adalah: melakukan lampirkan , akan mengeksekusi , melakukan eksekusi , membatalkan , akan menambahkan operasi baru , memang menambahkan operasi baru , akan selesai dan selesai .
Metode -metode ini ditentukan oleh protokol, sehingga kelas khusus dapat ditulis untuk menyesuaikan diri dengan banyak peristiwa. Namun, ada metode berbasis blok untuk menambahkan pengamat secara lebih alami. Misalnya, untuk mengamati ketika suatu prosedur selesai:
myProcedure . addDidFinishBlockObserver { procedure , errors in
procedure . log . info ( message : " Yay! Finished! " )
} Kerangka kerja ini juga menyediakan BackgroundObserver , TimeoutObserver dan NetworkObserver .
Lihat wiki di [[pengamat | pengamat]] untuk informasi lebih lanjut.
Kondisi dilampirkan pada subkelas Procedure . Sebelum suatu prosedur siap melaksanakannya akan secara tidak sinkron mengevaluasi semua kondisinya. Jika ada kondisi yang gagal, itu selesai dengan kesalahan alih -alih mengeksekusi. Misalnya:
myProcedure . add ( condition : BlockCondition {
// procedure will execute if true
// procedure will be ignored if false
// procedure will fail if error is thrown
return trueOrFalse // or throw AnError()
}Kondisi bisa saling eksklusif. Ini mirip dengan kunci yang ditahan mencegah operasi lain dengan pengecualian yang sama dieksekusi.
Kerangka kerja ini memberikan kondisi berikut: AuthorizedFor , BlockCondition , MutuallyExclusive , NegatedCondition NoFailedDependenciesCondition , SilentCondition dan UserConfirmationCondition (dalam ProsedurekitMobile ).
Lihat wiki di [[kondisi | kondisi]], atau panduan pemrograman lama tentang kondisi | Untuk informasi lebih lanjut.
Kemampuan mewakili kemampuan aplikasi untuk mengakses kemampuan perangkat atau akun pengguna, atau berpotensi segala jenis sumber daya yang terjaga keamanannya. Misalnya, layanan lokasi, wadah kit cloud, kalender dll atau layanan web. CapabiltiyProtocol menyediakan model terpadu untuk:
GetAuthorizationStatusProcedure ,AuthorizeCapabilityProcedureAuthorizedFor .Misalnya:
import ProcedureKit
import ProcedureKitLocation
class DoSomethingWithLocation : Procedure {
override init ( ) {
super . init ( )
name = " Location Operation "
add ( condition : AuthorizedFor ( Capability . Location ( . whenInUse ) ) )
}
override func execute ( ) {
// do something with Location Services here
finish ( )
}
} ProsedurKit memberikan kemampuan berikut: Capability.CloudKit Cloudkit dan Capability.Location .
Dalam operasi , (versi sebelumnya dari kerangka kerja ini), ada lebih banyak fungsionalitas (kalender, kesehatan, foto, buku alamat, dll), dan kami masih mempertimbangkan cara menawarkannya dalam prosedurKit .
Lihat wiki di [[kemampuan | kemampuan]], atau panduan pemrograman lama tentang kemampuan untuk informasi lebih lanjut.
Procedure memiliki fungsionalitas pencatatan internal sendiri yang terpapar melalui properti log :
class LogExample : Procedure {
override func execute ( ) {
log . info ( " Hello World! " )
finish ( )
}
}Lihat panduan pemrograman untuk informasi lebih lanjut tentang pencatatan dan mendukung kerangka log pihak ke -3.
Seringkali, prosedur membutuhkan dependensi untuk dieksekusi. Seperti khas dengan aplikasi berbasis asinkron/peristiwa, ketergantungan ini mungkin tidak diketahui pada waktu penciptaan. Sebaliknya mereka harus disuntikkan setelah prosedur diinisialisasi, tetapi sebelum dieksekusi. ProsedurKit mendukung ini melalui serangkaian protokol dan jenis yang bekerja bersama. Kami pikir pola ini bagus, karena mendorong komposisi prosedur tujuan tunggal kecil. Ini bisa lebih mudah untuk diuji dan berpotensi memungkinkan penggunaan kembali yang lebih besar. Anda akan menemukan injeksi ketergantungan yang digunakan dan didorong sepanjang kerangka kerja ini.
Bagaimanapun, pertama, nilai mungkin siap atau tertunda. Misalnya, ketika suatu prosedur diinisialisasi, ia mungkin tidak memiliki semua ketergantungannya, sehingga mereka berada dalam keadaan yang tertunda. Semoga mereka siap pada saat itu dieksekusi.
Kedua, jika suatu prosedur memperoleh ketergantungan yang diperlukan oleh prosedur lain, itu mungkin berhasil, atau mungkin gagal dengan kesalahan. Oleh karena itu ada jenis hasil sederhana yang mendukung ini.
Ketiga, ada protokol untuk menentukan sifat input dan output .
InputProcedure mengaitkan jenis Input . Subkelas Procedure dapat sesuai dengan ini untuk memungkinkan injeksi ketergantungan. Perhatikan, bahwa hanya satu properti input yang didukung, oleh karena itu, membuat tipe struct menengah untuk mengandung banyak dependensi. Tentu saja, properti input adalah tipe nilai yang tertunda.
OutputProcedure memperlihatkan jenis Output terkait melalui properti output , yang merupakan tipe hasil yang tertunda.
Menyatukan semuanya adalah satu set API pada InputProcedure yang memungkinkan dependensi rantai bersama -sama. Seperti ini:
import ProcedureKitLocation
// This class is part of the framework, it
// conforms to OutputProcedure
let getLocation = UserLocationProcedure ( )
// Lets assume we've written this, it
// conforms to InputProcedure
let processLocation = ProcessUserLocation ( )
// This line sets up dependency & injection
// it automatically handles errors and cancellation
processLocation . injectResult ( from : getLocation )
// Still need to add both procedures to the queue
queue . add ( procedures : getLocation , processLocation ) Di atas, diasumsikan bahwa tipe Input cocok dengan tipe Output , dalam hal ini, CLLocation . Namun, dimungkinkan juga untuk menggunakan penutupan untuk memijat tipe output ke tipe input yang diperlukan, misalnya:
import ProcedureKitLocation
// This class is part of the framework, it
// conforms to OutputProcedure
let getLocation = UserLocationProcedure ( )
// Lets assume we've written this, it
// conforms to InputProcedure, and
// requires a CLLocationSpeed value
let processSpeed = ProcessUserSpeed ( )
// This line sets up dependency & injection
// it automatically handles errors and cancellation
// and the closure extracts the speed value
processLocation . injectResult ( from : getLocation ) { $0 . speed }
// Still need to add both procedures to the queue
queue . add ( procedures : getLocation , processLocation ) Oke, jadi apa yang baru saja terjadi? Nah, API injectResult memiliki varian yang menerima penutupan trailing. Penutupan menerima nilai output, dan harus mengembalikan nilai input (atau melempar kesalahan). Jadi, { $0.speed } akan mengembalikan properti kecepatan dari instance CLLocation pengguna.
Hal penting yang perlu diperhatikan di sini adalah bahwa penutupan ini berjalan secara serempak. Jadi, yang terbaik adalah tidak menempatkan sesuatu yang berat di atasnya. Jika Anda perlu melakukan pemetaan data yang lebih kompleks, lihat TransformProcedure dan AsyncTransformProcedure .
Lihat Panduan Pemrograman tentang Hasil Suntikkan untuk informasi lebih lanjut.