O Real em tempo é o ORM Framework que torna a criação de estruturas complexas de banco de dados é simples.
Estrutura de modelo escalável simples
Arquivos
Coleções
Referências
UI, forma
O banco de dados em tempo real do Firebase é totalmente suportado e usa a produção. Se você usar a API Clean FireBase, o RealTime pode ajudar a criar o aplicativo mais rápido, para aplicar estruturas complexas para armazenar dados, para atualizar a interface do usuário usando comportamentos reativos. O RealTime fornece tráfego de dados leves, inicialização preguiçosa dos dados, boa distribuição de dados.
A FundaçãoDB é suportada, mas com algumas limitações, porque o FDB não possui mecanismos de observação nativos.
No aplicativo AppDelegate in func application(_:didFinishLaunchingWithOptions:) Você deve ligar para o código abaixo, para configurar o ambiente de trabalho. Agora, para a política de cache, é válido valores case .noCache, .persistance Somente. O cache na memória ainda não foi implementado.
func application ( _ application : UIApplication , didFinishLaunchingWithOptions launchOptions : [ UIApplicationLaunchOptionsKey : Any ] ? ) -> Bool {
/// ...
/// initialize Realtime
RealtimeApp . initialize ( ... )
///...
return true
} Para criar qualquer estrutura de dados de modelo que você possa fazer com Object Subclassing. Você pode definir propriedades infantis usando classes:
Object ;ReadonlyProperty , Property , Reference , Relation , ReadonlyFile , File ;References , Values , AssociatedValues e assim por diante; Se você usar propriedades preguiçosas, precisa implementar a função de classe lazyPropertyKeyPath(for:) . (Por favor, diga -me se você souber como evitá -lo, sem herdar o NSObject). Essa função exigia cada subclasse, portanto, você não precisa de chamada de super implementação. Exemplo: 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 - Propriedade armazenada READONLY por qualquer valor.
Propriedade - Propriedade armazenada para qualquer valor.
Referência - Referência de armazenamento em qualquer valor do banco de dados. Não implica integridade referencial. Use -o se o registro não for removido ou outro motivo que não precisa de integridade referencial.
Relacionamento - armazena referência em qualquer valor do banco de dados.
READONLYFILE - Propriedade armazenada READONLY para arquivo no Firebase Storage.
Arquivo - Propriedade armazenada para arquivo em armazenamento de Firebase.
Todas as propriedades adotam o recurso @propertyWrapper , mas, embora Swift não tenha acesso a self em propriedades preguiçosas personalizadas, dessa maneira para definir propriedades geralmente inúteis.
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 )
} Algumas operações mutáveis de coleções podem exigir um estado isSynced . Para alcançar esse estado, use func runObserving() Função ou Definir Propriedade keepSynced: Bool como true .
(Distribuído) Referências é uma matriz que armazena objetos como referências. Os elementos de origem devem localizar na mesma referência. Na inserção do objeto para essa matriz, cria link no objeto lateral.
(Explícito) Os valores são a matriz que armazena objetos por valor em si. O prefixo 'explícito' é usado na coleção que armazena elementos sem exibição de coleção.
References , Values mutações:
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
}(Explictic) AssociatedValues é o dicionário em que as chaves são referências, mas os valores são objetos. On Save Value cria link no objeto de chave lateral.
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 é uma coleção imutável que obtém elementos da função do mapa. Este é o resultado do X.LazyMap (_ Método :), onde X é qualquer Realtimecollection.
let userNames = Values < User > ( in : usersNode ) . lazyMap { user in
return user . name
}<== - Operador de atribuição. Pode usar para atribuir (ou recuperar) valor para (de) qualquer propriedade em tempo real.==== ,! !=== - Operadores de comparação. Pode usar para comparar quaisquer propriedades em tempo real em que seus valores estão em conformidade com o protocolo Equatable .?? - Operador de infix, que executa uma operação de coalescação de NIL, retornando o valor embrulhado de uma propriedade em tempo real ou um valor padrão.<- prefixo. Pode usar para converter a instância do Closure, Assign tipos para fechamento explícito ou atrasado.Transação - Objeto que contém todas as informações sobre transações de gravação. Quase todas as alterações de dados executam o desempenho usando este objeto. As operações mais mutáveis apenas tomam a transação como parâmetro, mas para criar operações complexas personalizadas, você pode usar esses métodos:
/// 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 )Para mais detalhes, consulte Exemplo de projeto.
SingleSectionTableViewDelegate - Fornece uma fonte de dados de seção única para o UitableView com atualização automática. SectionTableViewDelegate - Fornece fonte de dados seccionada para UIDEVIEW com atualização automática. CollectionViewDelegate - fornece fonte de dados para uicollectionView com atualização automática.
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 ) Disponível como módulo separado com suporte 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
}
}Para receber alterações no nível local, use objetos que estejam em conformidade com este protocolo. Possui interface rxswift semelhante.
public protocol Listenable {
associatedtype OutData
/// Disposable listening of value
func listening ( _ assign : Assign < OutData > ) -> Disposable
}Adicionar argumento de debug 'RealTime_Crash_on_error' passou no lançamento, para capturar erros internos.
Também existe módulo NodeJS, criado para o aplicativo Vue.js. Código fonte que você pode encontrar na pasta js .
Objetos em tempo real não devem passar entre os threads.
Para executar o projeto de exemplo, clone o repo e execute pod install no diretório Exemplo primeiro.
Xcode 9+, Swift 4.1+.
Swiftpm
. package ( url : " https://github.com/k-o-d-e-n/realtime.git " , . branch ( " master " ) )O tempo real está disponível através de Cocoapods. Para instalá -lo, basta adicionar a seguinte linha ao seu 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
O Real em tempo está disponível sob a licença do MIT. Consulte o arquivo de licença para obter mais informações.