Realtime adalah kerangka kerja ORM yang membuat pembuatan struktur basis data yang kompleks sederhana.
Struktur model yang dapat diskalakan sederhana
File
Koleksi
Referensi
Ui, bentuk
Database Firebase Realtime sepenuhnya didukung dan digunakan dalam produksi. Jika Anda menggunakan API Clean Firebase, realtime dapat membantu membuat aplikasi lebih cepat, dengan ini menerapkan struktur yang kompleks untuk menyimpan data, untuk memperbarui UI menggunakan perilaku reaktif. Realtime menyediakan lalu lintas data ringan, inisialisasi data yang malas, distribusi data yang baik.
FoundationDB didukung, tetapi dengan beberapa keterbatasan, karena FDB tidak memiliki mekanisme pengamatan asli.
Di AppDelegate dalam func application(_:didFinishLaunchingWithOptions:) Anda harus memanggil kode di bawah ini, untuk mengonfigurasi lingkungan kerja. Sekarang untuk kebijakan cache adalah nilai yang valid case .noCache, .persistance saja. Cache dalam memori belum diimplementasikan.
func application ( _ application : UIApplication , didFinishLaunchingWithOptions launchOptions : [ UIApplicationLaunchOptionsKey : Any ] ? ) -> Bool {
/// ...
/// initialize Realtime
RealtimeApp . initialize ( ... )
///...
return true
} Untuk membuat struktur data model apa pun yang dapat Anda buat dengan subklassing Object . Anda dapat mendefinisikan properti anak menggunakan kelas:
Object ;ReadonlyProperty , Property , Reference , Relation , ReadonlyFile , File ;References , Values , AssociatedValues , dan sebagainya; Jika Anda menggunakan properti malas, Anda perlu menerapkan fungsi kelas lazyPropertyKeyPath(for:) . (Tolong beritahu saya jika Anda tahu bagaimana menghindarinya, tanpa mewarisi nsObject). Fungsi ini menyerukan setiap subkelas, oleh karena itu Anda tidak perlu memanggil implementasi super. Contoh: class User : Object {
lazy var name : Property < String > = " name " . property ( in : self )
lazy var age : Property < Int > = " age " . property ( in : self )
lazy var photo : File < UIImage ? > = " photo " . file ( in : self , representer : . png )
lazy var groups : References < RealtimeGroup > = " groups " . references ( in : self , elements : . groups )
lazy var scheduledConversations : Values < Conversation > = " scheduledConversations " . values ( in : self )
lazy var ownedGroup : Relation < RealtimeGroup ? > = " ownedGroup " . relation ( in : self , " manager " )
override class func lazyPropertyKeyPath ( for label : String ) -> AnyKeyPath ? {
switch label {
case " name " : return User . name
case " age " : return User . age
case " photo " : return User . photo
case " groups " : return User . groups
case " ownedGroup " : return User . ownedGroup
case " scheduledConversations " : return User . scheduledConversations
default : return nil
}
}
}
let user = User ( in : Node ( key : " user_1 " ) )
user . name <== " User name "
user . photo <== UIImage ( named : " img " )
let transaction = user . save ( in : . root )
transaction . commit ( with : { state , err in
/// process error
} )ReadOnlyProperty - Properti yang disimpan hanya untuk nilai apa pun.
Properti - Properti tersimpan untuk nilai apa pun.
Referensi - Menyimpan referensi pada nilai database apa pun. Tidak menyiratkan integritas referensial. Gunakan jika catatan tidak akan dihapus atau alasan lain yang tidak memerlukan integritas referensial.
Relasi - Menyimpan referensi pada nilai basis data apa pun.
ReadOnlyFile - Properti yang disimpan oleh Readonly untuk file dalam penyimpanan firebase.
File - Properti tersimpan untuk file di Firebase Storage.
Semua properti mengadopsi fitur @propertyWrapper , tetapi sementara Swift adalah akses yang tidak didukung ke self di properti malas khusus, dengan cara ini untuk mendefinisikan properti yang umumnya tidak berguna.
class Some : Object {
lazy var array : Values < Object > = " some_array " . values ( in : self )
lazy var references : References < Object > = " some_linked_array " . references ( in : self , elements : . linkedObjects )
lazy var dictionary : AssociatedValues < Object > = " some_dictionary " . dictionary ( in : self , keys : . keyObjects )
} Beberapa operasi koleksi yang dapat berubah dapat memerlukan Negara Bagian isSynced . Untuk mencapai fungsi ini menggunakan fungsi func runObserving() atau mengatur properti keepSynced: Bool ke true .
(Terdistribusi) Referensi adalah array yang menyimpan objek sebagai referensi. Elemen sumber harus ditemukan dalam referensi yang sama. Pada penyisipan objek ke array ini membuat tautan pada objek samping.
Nilai (eksplisit) adalah array yang menyimpan objek berdasarkan nilai itu sendiri lokasi. Awalan 'Eksplisit' digunakan dalam koleksi yang menyimpan elemen tanpa tampilan koleksi.
References , Values yang bermutasi:
do {
let transaction = Transaction ( )
...
let element = Element ( )
try array . write ( element : element , in : transaction )
try otherArray . remove ( at : 1 , in : trasaction )
transaction . commit { ( err ) in
// process error
self . tableView . reloadData ( )
}
} catch let e {
// process error
}(Eksplisit) AssociatedValues adalah kamus di mana kunci adalah referensi, tetapi nilai adalah objek. On Save Value Membuat Tautan pada Objek Kunci Sisi.
AssociatedValues Mutasi:
do {
let transaction = Transaction ( )
...
let element = Element ( )
try dictionary . write ( element : element , key : key , in : transaction )
try otherDictionary . remove ( by : key , in : transaction )
transaction . commit { ( err ) in
// process error
}
} catch let e {
// process error
}MapRealTimecollection adalah koleksi abadi yang mendapat elemen dari fungsi peta. Ini adalah hasil dari X.LazyMap (_ Transform :) Metode, di mana x adalah apa pun realtimecollection.
let userNames = Values < User > ( in : usersNode ) . lazyMap { user in
return user . name
}<== - operator penugasan. Dapat digunakan untuk menetapkan (atau untuk mengambil) nilai ke (dari) properti realtime apa pun.==== ,! !=== - Operator perbandingan. Dapat digunakan untuk membandingkan sifat realtime di mana nilainya sesuai dengan protokol Equatable .?? - Operator infix, yang melakukan operasi koalesking nil, mengembalikan nilai yang dibungkus dari properti realtime atau nilai default.<- - Operator awalan. Dapat digunakan untuk mengonversi instance Closure, Assign jenis untuk penutupan eksplisit atau mundur.Transaksi - Objek yang berisi semua informasi tentang transaksi tulis. Hampir semua perubahan data melakukan menggunakan objek ini. Operasi yang paling bisa berubah hanya mengambil transaksi sebagai parameter, tetapi untuk membuat operasi kompleks khusus Anda dapat menggunakan metode ini:
/// adds operation of save RealtimeValue as single value as is
func set < T > ( _ value : T , by node : Node ) where T : RealtimeValue & RealtimeValueEvents
/// adds operation of delete RealtimeValue
func delete < T > ( _ value : T ) where T : RealtimeValue & RealtimeValueEvents
/// adds operation of update RealtimeValue
func update < T > ( _ value : T ) where T : ChangeableRealtimeValue & RealtimeValueEvents & Reverting
/// method to merge actions of other transaction
func merge ( _ other : Transaction )Untuk detail lebih lanjut lihat Proyek Contoh.
SinglesectionTableViewDelegate - Menyediakan sumber data bagian tunggal untuk UITableView dengan pembaruan otomatis. SectionEdTableViewDelegate - Menyediakan sumber data yang dibagi untuk UITableView dengan pembaruan otomatis. CollectionViewDelegate - Menyediakan sumber data untuk UICollectionView dengan pembaruan otomatis.
delegate . register ( UITableViewCell . self ) { ( item , cell , user , ip ) in
item . bind (
user . name , { cell , name in
cell . textLabel ? . text = name
} ,
{ err in
print ( err )
}
)
}
delegate . bind ( tableView )
delegate . tableDelegate = self
// data
users . changes
. listening (
onValue : { [ weak tableView ] ( e ) in
guard let tv = tableView else { return }
switch e {
case . initial : tv . reloadData ( )
case . updated ( let deleted , let inserted , let modified , let moved ) :
tv . beginUpdates ( )
tv . insertRows ( at : inserted . map ( { IndexPath ( row : $0 , section : 0 ) } ) , with : . automatic )
tv . deleteRows ( at : deleted . map ( { IndexPath ( row : $0 , section : 0 ) } ) , with : . automatic )
tv . reloadRows ( at : modified . map ( { IndexPath ( row : $0 , section : 0 ) } ) , with : . automatic )
moved . forEach { from , to in
tv . moveRow ( at : IndexPath ( row : from , section : 0 ) , to : IndexPath ( row : to , section : 0 ) )
}
tv . endUpdates ( )
}
} ,
onError : onError
)
. add ( to : listeningCollector ) Tersedia sebagai modul terpisah dengan dukungan Combine .
class User : Object {
var name : Property < String >
var age : Property < Int >
}
class FormViewController : UIViewController {
var form : Form < User >
override func viewDidLoad ( ) {
super . viewDidLoad ( )
let name = Row < TextCell , Model > . inputRow (
" input " ,
title : Localized . name ,
keyboard : . name ,
placeholder : . inputPlaceholder ( Localized . name ) ,
onText : { $0 . name <== $1 }
)
name . onUpdate { ( args , row ) in
args . view . textField . text <== args . model . name
}
let age = Row < TextCell , Model > . inputRow (
" input " ,
title : Localized . age ,
keyboard : . numberPad ,
placeholder : requiredPlaceholder ,
onText : { $0 . age <== $1 }
)
age . onUpdate { ( args , row ) in
args . view . textField . text <== args . model . age
}
let button : Row < ButtonCell , Model > = Row ( reuseIdentifier : " button " )
button . onUpdate { ( args , row ) in
args . view . titleLabel . text = Localized . login
}
button . onSelect { [ unowned self ] ( _ , row ) in
self . submit ( )
}
let fieldsSection : StaticSection < Model > = StaticSection ( headerTitle : nil , footerTitle : nil )
fieldsSection . addRow ( name )
fieldsSection . addRow ( age )
let buttonSection : StaticSection < Model > = StaticSection ( headerTitle : nil , footerTitle : nil )
buttonSection . addRow ( button )
form = Form ( model : User ( ) , sections : [ fieldsSection , buttonSection ] )
form . tableView = tableView
form . tableDelegate = self
}
}Untuk menerima perubahan pada tingkat penggunaan objek yang sesuai dengan protokol ini. Ini memiliki antarmuka RXSWIFT yang serupa.
public protocol Listenable {
associatedtype OutData
/// Disposable listening of value
func listening ( _ assign : Assign < OutData > ) -> Disposable
}Tambahkan argumen debug 'realtime_crash_on_error' disahkan pada peluncuran, untuk menangkap kesalahan internal.
Juga ada modul nodejs, dibuat untuk aplikasi vue.js. Kode sumber yang dapat Anda temukan di folder js .
Objek realtime tidak boleh dilewatkan di antara utas.
Untuk menjalankan proyek contoh, klon repo, dan menjalankan pod install dari direktori contoh terlebih dahulu.
Xcode 9+, Swift 4.1+.
Swiftpm
. package ( url : " https://github.com/k-o-d-e-n/realtime.git " , . branch ( " master " ) )Realtime tersedia melalui cocoapods. Untuk menginstalnya, cukup tambahkan baris berikut ke podfile Anda:
pod 'Realtime' pod 'RealtimeForm/Combine' , :git => 'https://github.com/k-o-d-e-n/Realtime.git' , :branch => 'master' Koryttsev Denis, [email protected]
Twitter: @k_o_d_e_n
Realtime tersedia di bawah lisensi MIT. Lihat file lisensi untuk info lebih lanjut.