เรียลไทม์เป็นกรอบ ORM ที่ทำให้การสร้างโครงสร้างฐานข้อมูลที่ซับซ้อนนั้นง่าย
โครงสร้างโมเดลที่ปรับขนาดได้ง่าย
ไฟล์
ของสะสม
การอ้างอิง
ui, รูปแบบ
ฐานข้อมูล Firebase Realtime ได้รับการสนับสนุนอย่างเต็มที่และใช้งานในการผลิต หากคุณใช้ Clean Firebase API เรียลไทม์สามารถช่วยสร้างแอพได้เร็วขึ้นพร้อมใช้โครงสร้างที่ซับซ้อนเพื่อจัดเก็บข้อมูลเพื่ออัปเดต UI โดยใช้พฤติกรรมปฏิกิริยา เรียลไทม์ให้การรับส่งข้อมูลที่มีน้ำหนักเบาการเริ่มต้นข้อมูลขี้เกียจการกระจายข้อมูลที่ดี
รองพื้นได้รับการสนับสนุน แต่มีข้อ จำกัด บางประการเนื่องจาก FDB ไม่มีกลไกการสังเกตพื้นเมือง
ใน AppDelegate ใน func application(_:didFinishLaunchingWithOptions:) คุณต้องโทรไปด้านล่างเพื่อกำหนดค่าสภาพแวดล้อมการทำงาน ตอนนี้สำหรับนโยบายแคชเป็น case .noCache, .persistance เท่านั้น แคชในหน่วยความจำยังไม่ได้ใช้งาน
func application ( _ application : UIApplication , didFinishLaunchingWithOptions launchOptions : [ UIApplicationLaunchOptionsKey : Any ] ? ) -> Bool {
/// ...
/// initialize Realtime
RealtimeApp . initialize ( ... )
///...
return true
} ในการสร้างโครงสร้างข้อมูลแบบจำลองใด ๆ ที่คุณสามารถทำได้โดย Object ย่อย คุณสามารถกำหนดคุณสมบัติเด็กโดยใช้คลาส:
Object ;ReadonlyProperty , Property , Reference , Relation , ReadonlyFile , File ;References Values AssociatedValues และอื่น ๆ ; หากคุณใช้คุณสมบัติขี้เกียจคุณต้องใช้ฟังก์ชั่นคลาส lazyPropertyKeyPath(for:) (โปรดบอกฉันว่าคุณรู้ว่าหลีกเลี่ยงได้อย่างไรโดยไม่ต้องสืบทอด NSObject) ฟังก์ชั่นนี้เรียกว่าแต่ละคลาสย่อยดังนั้นคุณไม่จำเป็นต้องใช้การใช้งาน Super Call ตัวอย่าง: 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 - คุณสมบัติที่เก็บไว้อย่างเดียวสำหรับค่าใด ๆ
คุณสมบัติ - คุณสมบัติที่เก็บไว้สำหรับค่าใด ๆ
การอ้างอิง - เก็บข้อมูลอ้างอิงในค่าฐานข้อมูลใด ๆ ไม่ได้หมายความถึงความสมบูรณ์ของการอ้างอิง ใช้ถ้าบันทึกจะไม่ถูกลบออกหรือเหตุผลอื่น ๆ ที่ไม่จำเป็นต้องมีความสมบูรณ์ของการอ้างอิง
ความสัมพันธ์ - เก็บข้อมูลอ้างอิงในค่าฐานข้อมูลใด ๆ
ReadonlyFile - คุณสมบัติที่เก็บไว้อย่างเดียวสำหรับไฟล์ในที่เก็บข้อมูล Firebase
ไฟล์ - คุณสมบัติที่เก็บไว้สำหรับไฟล์ในที่เก็บข้อมูล Firebase
คุณสมบัติทั้งหมดใช้คุณสมบัติ @propertyWrapper แต่ในขณะที่ Swift ไม่ได้รับการสนับสนุนการเข้าถึง self ในคุณสมบัติขี้เกียจแบบกำหนดเองวิธีนี้ในการกำหนดคุณสมบัติโดยทั่วไปไร้ประโยชน์
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 )
} การดำเนินการที่ไม่แน่นอนของคอลเลกชันอาจต้องใช้รัฐ isSynced เพื่อให้ได้สถานะนี้ให้ใช้ฟังก์ชั่น func runObserving() หรือตั้งค่าคุณสมบัติ keepSynced: Bool เป็น true
(กระจาย) การอ้างอิง คืออาร์เรย์ที่เก็บวัตถุเป็นข้อมูลอ้างอิง องค์ประกอบแหล่งที่มาจะต้องค้นหาในการอ้างอิงเดียวกัน ในการแทรกวัตถุไปยังอาร์เรย์นี้จะสร้างลิงก์บนวัตถุด้านข้าง
(ชัดเจน) ค่า คืออาร์เรย์ที่เก็บวัตถุตามค่าในตำแหน่งของตัวเอง คำนำหน้า 'Explicit' ใช้ในการรวบรวมที่เก็บองค์ประกอบที่ไม่มีมุมมองการรวบรวม
References Values การกลายพันธุ์:
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
}(ชัดเจน) AssociatedValues เป็นพจนานุกรมที่มีการอ้างอิงคีย์ แต่ค่าเป็นวัตถุ ในการบันทึกค่าสร้างลิงก์บนวัตถุคีย์ด้านข้าง
AssociatedValues กลายพันธุ์:
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 เป็นคอลเลกชันที่ไม่เปลี่ยนรูปที่ได้รับองค์ประกอบจากฟังก์ชั่นแผนที่ นี่คือผลลัพธ์ของ x.lazymap (_ transform :) วิธีการโดยที่ x คือ realtimecollection ใด ๆ
let userNames = Values < User > ( in : usersNode ) . lazyMap { user in
return user . name
}<== - ตัวดำเนินการที่ได้รับมอบหมาย สามารถใช้เพื่อกำหนด (หรือเรียกคืน) ค่า (จาก) คุณสมบัติเรียลไทม์ใด ๆ==== ,! !=== - ตัวดำเนินการเปรียบเทียบ สามารถใช้เพื่อเปรียบเทียบคุณสมบัติเรียลไทม์ที่ค่าของพวกเขาสอดคล้องกับโปรโตคอล Equatable?? - ตัวดำเนินการ Infix ที่ดำเนินการ NIL-coalescing ส่งคืนค่าที่ห่อหุ้มของคุณสมบัติเรียลไทม์หรือค่าเริ่มต้น<- - ตัวดำเนินการคำนำหน้า สามารถใช้ในการแปลงอินสแตนซ์ของ Closure, Assign ประเภทเพื่อปิดหรือย้อนกลับอย่างชัดเจนการทำธุรกรรม - วัตถุที่มีข้อมูลทั้งหมดเกี่ยวกับธุรกรรมการเขียน การเปลี่ยนแปลงข้อมูลเกือบทั้งหมดดำเนินการโดยใช้วัตถุนี้ การดำเนินการที่ไม่แน่นอนที่สุดเพียงแค่ทำธุรกรรมเป็นพารามิเตอร์ แต่เพื่อสร้างการดำเนินการที่ซับซ้อนที่กำหนดเองคุณสามารถใช้วิธีนี้:
/// 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 )สำหรับรายละเอียดเพิ่มเติมดูตัวอย่างโครงการ
SinglesectionTableViewDelegate - จัดเตรียมแหล่งข้อมูลส่วนเดียวสำหรับ UITableView พร้อมการอัปเดตอัตโนมัติ SectreedTableViewDelegate - จัดเตรียมแหล่งข้อมูลที่แบ่งส่วนสำหรับ UITableView พร้อมการอัปเดตอัตโนมัติ CollectionViewDelegate - ให้แหล่งข้อมูลสำหรับ UICollectionView พร้อมการอัปเดตอัตโนมัติ
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 ) มีให้เป็นโมดูลที่คั่นด้วย 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
}
}เพื่อรับการเปลี่ยนแปลงในวัตถุที่ใช้ในระดับท้องถิ่นที่สอดคล้องกับโปรโตคอลนี้ มันมีอินเทอร์เฟซ RXSwift ที่คล้ายกัน
public protocol Listenable {
associatedtype OutData
/// Disposable listening of value
func listening ( _ assign : Assign < OutData > ) -> Disposable
}เพิ่มอาร์กิวเมนต์การดีบัก 'RealTime_crash_on_error' ผ่านการเปิดตัวเพื่อจับข้อผิดพลาดภายใน
ยังมีโมดูล NodeJS ที่สร้างขึ้นสำหรับแอปพลิเคชัน Vue.js ซอร์สโค้ดที่คุณสามารถพบได้ในโฟลเดอร์ js
วัตถุเรียลไทม์ไม่ควรผ่านระหว่างเธรด
ในการเรียกใช้โครงการตัวอย่างให้โคลน repo และเรียกใช้ pod install จากไดเรกทอรีตัวอย่างก่อน
Xcode 9+, Swift 4.1+
swiftpm
. package ( url : " https://github.com/k-o-d-e-n/realtime.git " , . branch ( " master " ) )เรียลไทม์มีให้บริการผ่าน cocoapods หากต้องการติดตั้งเพียงเพิ่มบรรทัดต่อไปนี้ลงใน PodFile ของคุณ:
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
เรียลไทม์พร้อมใช้งานภายใต้ใบอนุญาต MIT ดูไฟล์ใบอนุญาตสำหรับข้อมูลเพิ่มเติม