실시간은 복잡한 데이터베이스 구조의 생성을 간단하게 만드는 ORM 프레임 워크입니다.
간단한 확장 가능한 모델 구조
파일
컬렉션
참조
UI, 형태
Firebase Realtime Database는 완전히 지원되며 생산에 사용됩니다. Clean Firebase API를 사용하는 경우 Realtime은 복잡한 구조를 적용하여 데이터를 저장하고 반응성 동작을 사용하여 UI를 업데이트하기 위해 앱을 더 빨리 만들 수 있습니다. 실시간은 가벼운 데이터 트래픽, 게으른 데이터 초기화, 데이터 배포를 제공합니다.
FDB에는 기본 관찰 메커니즘이 없기 때문에 FoundationDB는 지원되지만 일부 제한 사항이 있습니다.
func application(_:didFinishLaunchingWithOptions:) 의 AppDelegate 에서 (_ : 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 등; Lazy Properties를 사용하는 경우 클래스 기능 lazyPropertyKeyPath(for:) 구현해야합니다. (nsobject를 물려받지 않고 그것을 피하는 방법을 알고 있는지 알려주세요). 이 기능은 각 서브 클래스에 대해 요청하므로 Call Super 구현이 필요하지 않습니다. 예: 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- 모든 값에 대해 Readonly 저장 속성.
속성 - 모든 값에 대해 저장된 속성.
참조 - 모든 데이터베이스 값에 대한 참조를 저장합니다. 참조 무결성을 의미하지 않습니다. 레코드가 제거되지 않거나 참조 무결성이 필요하지 않은 다른 이유가있는 경우 사용하십시오.
관계 - 모든 데이터베이스 값에 대한 참조를 저장합니다.
readonlyfile- 파일베이스 스토리지의 파일 용으로 Readonly 저장 속성.
파일 - 파일베이스 스토리지의 파일에 대한 저장된 속성.
모든 속성은 @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
(분산) 참조는 객체를 참조로 저장하는 배열입니다. 소스 요소는 동일한 참조로 찾아야합니다. 이 배열에 객체를 삽입하면 측면 객체에 링크가 생성됩니다.
(명시 적) 값은 객체를 그 자체로 값으로 저장하는 배열입니다. '명시 적'접두사는 컬렉션보기없이 요소를 저장하는 컬렉션에 사용됩니다.
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
}(명시 적) APTICATEVALUES 는 키가 참조 인 사전이지만 값은 객체입니다. 값 저장 값은 측면 키 객체에서 링크를 만듭니다.
AssociatedValues Mutating :
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 프로토콜을 준수하는 실시간 속성을 비교하는 데 사용할 수 있습니다.?? -Nil-Coalescing 작업을 수행하는 Infix 연산자, 실시간 속성 또는 기본값의 랩핑 된 값을 반환합니다.<- - 접두사 연산자. 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 용 단일 섹션 데이터 소스를 제공합니다. SectionEdTableViewDelegate- 자동 업데이트와 함께 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
}내부 오류를 포착하기 위해 Debug Argument 'Realtime_crash_on_error'가 출시 될 때 전달되었습니다.
vue.js 응용 프로그램 용으로 생성 된 nodejs 모듈도 있습니다. js 폴더에서 찾을 수있는 소스 코드.
실시간 객체는 스레드 사이를 전달해서는 안됩니다.
예제 프로젝트를 실행하려면 Repo를 복제하고 먼저 예제 디렉토리에서 pod install 실행하십시오.
Xcode 9+, Swift 4.1+.
Swiftpm
. package ( url : " https://github.com/k-o-d-e-n/realtime.git " , . branch ( " master " ) )실시간은 코코 포드를 통해 제공됩니다. 설치하려면 Podfile에 다음 줄을 추가하십시오.
pod 'Realtime' pod 'RealtimeForm/Combine' , :git => 'https://github.com/k-o-d-e-n/Realtime.git' , :branch => 'master' Koryttsev denis, [email protected]
트위터 : @K_O_D_E_N
MIT 라이센스에 따라 실시간이 가능합니다. 자세한 내용은 라이센스 파일을 참조하십시오.