in dit deel zullen we behandelen:
- Wat is Realmswift
- het creëren van een Complex Realm Model
- waarom we @objc en dynamic gebruiken in eigenschap
- To-One en to-Many Relatie In Realm
- Hoe aangepaste enum In Realm
- op te slaan Wat is RealmOptional en hoe Swift optionele atomaire eigenschap
- op te slaan Hoe werkt Computed Property als Transient Property in realm
- indexeren voor prestatiewinst
- Wat is linking object in realm
- complexe predicaat queries
- CRUD operatie
- Wat zijn live resultaten in realm
- dingen vermeden wanneer Realm-objecten wijzigen
li>
Realm is een platformonafhankelijke mobiele objectdatabase. Het is zeer snel, performant en makkelijk te gebruiken in vergelijking met Core Data en Sqlite. Het maakt gebruik van het opslagmechanisme om object op te slaan als JSON op de schijf in vergelijking met kerngegevens die Sqlite gebruikt als backend. Het is geschreven in cross-platform C++ dus het werkt precies op dezelfde manier op Android, iOS, macOS of een ander platform.
RealmSwift
de Meeste van de wereld is open-source, maar de geheime saus achter Realm ‘ s platform is de Kern van de DB-engine geschreven vanuit het niets in C++. RealmSwift is een wrapper rond de Objective – C Realm framework en Objective-C Realm framework is een wrapper rond Realm Core DB engine.
aan de slag
In deze tutorial zullen we aan deze modellen werken zoals getoond in Figuur 1
gebruiker → het is een model dat gebruikersinformatie bevat waarin userId
het primair is. Het heeft ook een To-one relatie met paspoort model en To-vele relaties met Todo taken. (Gebruiker kan alleen passport hebben en veel todo taken hebben)
Passport → het model bevat paspoortinformatie van een gebruiker en heeft ook een reverse back link van User
object.
Todo → het model bevat taken van een gebruiker en heeft ook een reverse back link van User
object.
Gebruiker een Model
Zoals getoond in Figuur 2 wordt gemaakt door Gebruiker een model en voegt daar een paar eigenschappen:
- Eerste we erven
User
klasse vanObject
waardoor hetRealm Object
. Realm-objecten zijn in principe een standaard datamodel, net als elk ander standaard datamodel dat u hebt gedefinieerd in uw apps. Het enige verschil is dat ze ondersteund worden door de doorzettingsvermogen en vermogens van het rijk. Door te kijken naar alleObject
class Realm zijn in staat om uw schema af te leiden. Elk model dat je wilt aanhouden moet je erven van Object class. -
firstName
slaat de voornaam van de gebruiker op alsString
. AangezienRealmSwift
een wrapper is rond de Objective-C Realm framework types zoals String, Date en Data zijn subklassen van NSObject in Objective-C, dus je kunt ze ook objecttypes in Swift beschouwen. In aanvulling op deze @objc betekent dat u wilt uw Swift code (klasse, methode, eigenschap, enz.) zichtbaar zijn vanuit Objective-C terwijl dynamisch betekent dat u Objective-C dynamic dispatch wilt gebruiken. Om eenvoudige Swift objectopslag in database Realm te maken, gebruikt Objective-C dynamic dispatch-functie om onder de motorkap te werken -
userId
slaat de gebruikers-id op die als primaire sleutel fungeert. U kunt een van de eigenschappen van uw object als primaire sleutel instellen. Meestal is een eigenschap die zich uniek identificeert, dat is een primaire kandidaat voor een primaire sleutel. Het helpt u een snelle lookup of object bewerken in een database. Zoals getoond in Figuur 2 maken weuserId
primaire sleutel doorprimarykey
statische functie te overschrijven. De standaard implementatie van deze methode geeft nul terug. OpmerkinguserId
fungeert als een Objective C primitive int type omdat het een wrapper is rond Objective C Realm -
passport
property slaat de gebruikerspaspoort informatie op die een ander Realm Object is. We creëerden een relatie met het Paspoortmodel. To-one relatie / object link, waarbij een realm object naar een ander realm object wijst. Wanneer u een relatie met een ander Realm-object maakt, moet de eigenschap ervan van een optioneel type zijn. In passport variable pointer reference ofPassport
object zal -
privateUserType
is de wrapper eigenschap vanUserType
aangezien UserType swift enum is, kunnen we niet direct op Realm opslaan. Alle case-waarden zouden een impliciet toegewezen ruwe waarde hebben die overeenkomt met de naam van de case. U zult deze ruwe waarde gebruiken om de enum opties te behouden alsInt
in Realm. Maar de cliënt heeft toegang tot de berekende enum-eigenschap en onder de motorkap enum ruwe waarde/atomaire waarde wordt opgeslagen in een database die niet zichtbaar is voor de cliënt. - String, NSDate, en nsdata eigenschappen kunnen worden gedeclareerd als optioneel of niet-optioneel met behulp van de standaard Swift syntaxis.Optionele numerieke types worden gedeclareerd met RealmOptional. Aangezien RealmSwift is wrapper rond Objective C Realm En er is geen optionele Int in Objective C dat is waarom Realm creëerde het type RealmOptional voor deze scenario ‘ s. Alle Objective C primitieve type vereisen in Swift met optionele moet je RealmOptional gebruiken . Opmerking: RealmOptional properties kan niet worden gedeclareerd als dynamisch en @objc trefwoord omdat generieke eigenschappen niet kunnen worden weergegeven in de Objective C runtime, die wordt gebruikt voor dynamische verzending van dynamische eigenschappen, en moet altijd worden gedeclareerd met let. Omdat het Realm klasse heeft het alle functies die Realm persist object hebben. Zoals getoond in Figuur 2
isEmailSubscriptionEnable
declareren we alsRealmOptional
Bool betekent dat het nihil kan zijn die we met let hebben gebruikt omdat het een referentietype is en we willen niet dat het adres in de toekomst verandert. - zoals getoond in Figuur 2 kan de gebruiker veel todo ‘ s hebben, wat een verzameling van Realm todo-objecten is . Maak een lijst als Realm-klasse om de verzameling van de realm-object-instanties vast te houden. We creëerden To-Many relatie met het Todo-model. Aan-veel relatie, waarin een rijk object verwijzen naar collectie van rijk object. Als u een normale Swift-array gebruikt om Realm-collectie van objecten op te slaan, krijgt u een uitzondering. Opmerking: zoals RealmOptional lijst kan niet worden verklaard als dynamisch en @objc trefwoord, omdat het een Realm klasse met alle ingebouwde functies. Lijst is zeer vergelijkbaar met Array voor ingebouwde methoden en toegang tot objecten met behulp van geïndexeerde subscripting. Lijst zoals u ziet is getypt en alle objecten moeten van hetzelfde type zijn
-
isUserHasTodos
is een berekende Swift-eigenschap en zal niet opslaan in realm-database die retourneert als de gebruiker bepaalde taken moet uitvoeren of niet. - tot slot maken we
userId
enfirstName
als geïndexeerde eigenschappen. DoorindexedProperties
statische methode te overschrijven, bieden we een reeks eigenschappen in String vorm. We doen geïndexeerd op eigenschappen verbeteren van de toegang keer wanneer het filtreren of het opvragen van de database
Paspoort Model
Zoals getoond in Figuur 3 geven we gemaakt Paspoort model met de weinige eigenschappen
-
passportNumber
slaat de gegevens van het Paspoort enexpiryDate
slaat de vervaldatum van het paspoort willen we deze eigenschappen te bewaren, dat is de reden waarom wij gebruik@objc
metdynamic
zoekwoord te vertellen rijk doe je onder de motorkap magic - Wij gemaakt
passport
woning opUser
model wat betekent datUser
object hebben hunpassport
verwijzing naar het object wat als we willen paspoort object ook weten welke gebruiker heeft dit paspoort / een verwijzing naar de gebruiker in verband met dit paspoort. We maakten de backlinks met behulp van LinkingObjects, wat betekent dat weofUser
property in Passport aangemaakt hebben die een referentie hebben van alle gebruikersobjecten die Passport object toewijzen in zijnpassport
property. In Core Data wordt het genoemd als inverse relatie. Het is een dynamische collectie die je vertelt wie linkt naar het huidige object.
As shown in Figure 4 we created Todo
Realm model with has a backlink to the all the users pointing to particular task .
Hebben We gedaan met het model / schema van schepping en nu is het tijd om te doen werkelijke CRUD operatie
Object Toevoegen aan de Realm
We voor het eerst duidelijk een concept dan zullen we in staat zijn om gemakkelijk object toevoegen in Realm
Zoals getoond in Figuur 5 hebben we beginnen met het krijgen van een exemplaar van de standaard Realm
door initialiseren zonder enige argumenten. De enige manier om toegang te krijgen tot de database via realm instance. Een instance Realm
(ook wel “A Realm” genoemd) vertegenwoordigt een Realm database.Realms kunnen worden opgeslagen op schijf (zie init(path:)
) of in het geheugen (zie Configuration
) die we zullen zien in aankomende delen. Realm
instances zijn niet thread veilig en kunnen niet gedeeld worden over threads of verzendwachtrijen. U moet een nieuwe instantie construeren voor elke thread waarin een rijk zal worden benaderd.
Zoals getoond in Figuur 5 want het is een vers-app en geen object opgeslagen in de database realm.isEmpty
geeft als resultaat true betekent database is leeg gedrukt op de console
Zoals getoond in Figuur 6 hebben we uitgevoerd aantal taken
- Wij voor de aanleg van
Realm
database - Gemaakt
Passport
en drie taken als eentodos
- aangemaakt
User
object en wijs paspoort en todos toe. Naast deze geïnitialiseerde Realm optionele eigenschap dieisEmailSubscriptionEnable
enUsertype
enum met gold lidmaatschap
zoals getoond in Figuur 6 realm database nog steeds leeg en inverse relatie/ Linking object werkt ook niet omdat we deze objecten niet toegevoegd aan het realm. Realm objecten (User,Passport,Todo)kunnen worden geïnstalleerd en gebruikt als onbeheerde objecten (dat wil zeggen nog niet toegevoegd aan een Realm) net als gewone Swift objecten. Om stellingen van objecten die worden beheerd door het Rijk moet u ze toevoegen in Realm
Zoals getoond in Figuur 7 zijn we eindelijk object invoegen in het Gebied database. We hebben cascading insert in de DB uitgevoerd.
Opmerking: alle wijzigingen aan een object (toevoeging, wijziging en verwijdering) moeten worden uitgevoerd binnen een schrijftransactie.Realm write operaties zijn synchroon en blokkeren, niet asynchroon. Als thread a een schrijfoperatie start, dan start thread B een schrijfoperatie op hetzelfde gebied voordat thread A klaar is, thread A moet zijn transactie beëindigen en committen voordat thread B ‘ s schrijfoperatie plaatsvindt. Schrijfbewerkingen verversen altijd automatisch zodat er geen raceconditie wordt aangemaakt. Schrijfbewerking kan fouten veroorzaken zoals een tekort aan schijfruimte
- We hebben gebruiker toegevoegd aan uw Realm, en omdat het verwijst naar passport en todos, worden deze objecten ook toegevoegd aan het Realm.
- door unmanaged object toe te voegen aan realm hebben we deze objecten nu gemanaged zoals getoond in de console werken onze backlinks. Nu passport kan toegang gebruiker object ook. Nu is onze database niet meer leeg
- we voegen uiteindelijk object in de database in omdat we object invoegen dat we moeten toevoegen in het schrijftransactieblok en we toevoegen aan het realm door de methode toevoegen te gebruiken op Realm instance. Nu Als een apart object met dezelfde primaire sleutel van de Gebruiker met
userId = 1
geprobeerd moet worden toegevoegd als een apart object naar het Rijk, een uitzondering zal worden geactiveerd
Check Object Fysiek Opslaan
Door het uitvoeren van deze opdracht op debugger output krijg je het adres van rijk bestand waarin uw gegevens worden opgeslagen
Open
default.realm
in het Rijk Studio
Rijk Studio is onze premiere developer tool, gebouwd, zodat u kunt eenvoudig beheren van de Gebieds Database en Rijk Platform. Met Realm Studio kunt u lokale en gesynchroniseerde Realms openen en bewerken en elk Realm-Objectservervoorbeeld beheren. Download het nu voor Mac, Windows of Linux.
Zoals getoond in Figuur 10 gegevens eigenlijk opgeslagen. U kunt zich afvragen Article
en Person
class ook daar omdat in sommige van mijn project class modellen persoon en artikel maken. Wanneer de toepassing wordt uitgevoerd, Introspecteert Realm alle klassen in uw app en frameworks en vindt hij die klassen die de objectklasse van Realm subklassen. Het beschouwt de lijst van deze klassen als uw gegevensschema dat op schijf of in het geheugen zal worden gehandhaafd.
Ophalen Object van het Gebied
Het proces van het ophalen van alle Gebruikers records van het Rijk heeft de volgende taken
- Wij voor de aanleg van de Gebieds Database en het kan gooit: Een
NSError
als het Rijk kan niet worden geïnitialiseerd. Standaard rijk wordt gecreëerd wanneer we belleninit()
zonder parameter - Genoemd objecten methode op het Gebied database waarin alle objecten van een bepaald type opgeslagen in de wereld en het zal de terugkeer van de Resultaten met alle objecten, zoals weergegeven in Figuur 11
- Geprint object op de console om gegevens te valideren is er en het Koppelen van objecten fijn werken
We opgehaald Gebruiker neem op van zijn primaire sleutel die ook een geïndexeerde eigenschap is, dus we krijgen het optionele gebruikersobject omdat object met deze primaire sleutel mogelijk niet bestaat. Primaire sleutel kan zijn Int
of String
de aanbeveling is om String.
te gebruiken.Zodra een primaire sleutelwaarde is ingesteld op een specifiek object, kan deze nooit worden gewijzigd.
Zoals aangegeven zijn wij gefilterd met behulp van een aantal Predicaat Hier zijn de lijst van de operatoren die we gebruikt
- filter → overeenkomt met de waarden gelijk aan
- filter niet hoofdlettergevoelig → overeenkomt met de waarden die gelijk is aan het negeren van behuizing
- IN {1,2,3} filter → overeenkomt met de waarde uit een lijst met waarden.
- filter → komt overeen als de voornaam waarde begint met een.
- filter → wedstrijden als de voornaam waarde conatins met li.
- Predicaat met Paspoort object dat we willen filter Gebruiker die het nummer van je paspoort == ‘pass1’
- Predicaat met Todos object dat we willen filter Gebruiker die een tdodo bevat details == ‘Nodig ot maken RxSwift blog’
Voor de geavanceerde query ‘ s is Het sterk aanbevolen om te zien https://academy.realm.io/posts/nspredicate-cheatsheet/ dit NSPredicate cheatsheet
Opmerking: Wat u verwijzen als “tijdelijke (berekend) eigenschappen”, Rijk verwijst als “genegeerd eigenschappen”. Dit zijn eigenschappen die voor het grootste deel worden genegeerd door Realm, zodat ze niet worden opgeslagen in het db-bestand, kunnen worden gemuteerd buiten write transacties, enz.Dit betekent echter ook dat ze niet profiteren van veel van de mogelijkheden van niet-genegeerde eigenschappen, zoals queries. (querying for Realm objects can only be done with non-computed, Realm-persisted properties)
As shown in Figure 14 we sorted results with the firstName
property on User model
Live resultaten
laatste onderwerp bij ophalen vanuit Realm sectie
Realm result sets retourneren altijd de laatste up-to-date gegevens. Gegevens in de resultaten zijn nooit verouderd. Dit betekent dat u nooit hoeft te herladen resultaten van de schijf of een of andere manier handmatig vernieuwen in het geheugen gegevens.
zoals getoond in figuur 15 kregen we de nieuwe gebruiker en we hebben niet opgehaald met behulp van realm.objects
methode in plaats daarvan worden nieuw toegevoegd object gepresenteerd op de variabele gebruikers . Als u van de achtergrond van kerngegevens komt, moet u het object opnieuw ophalen van de stack
lezen en schrijven kan gebeuren op verschillende plekken in het project, op verschillende threads, van verschillende processen, of, wanneer u het Realm-Platform gebruikt, van overal ter wereld. Elke klasse in de app kan zich richten op de zakelijke logica en vergeet het begrip van verouderde of gecached gegevens, omdat Realm objecten zijn altijd up-to-date.
Wijzigen Object Op Gebied
Zoals getoond in figuur 16 zijn we het wijzigen van de primaire sleutel en krijgen we een “Primaire sleutel kan niet worden gewijzigd nadat een object is geplaatst.”uitzondering omdat we primaire sleutel niet kunnen updaten . Vanuit Realm Docs wordt de primaire sleutel toegevoegd aan een Realm, de primaire sleutel kan niet worden gewijzigd. Oplossing → Verwijder en plaats het object of zie deze vraag in stackoverflow
Zoals getoond in Figuur 17 u niet kunt wijzigen object opgehaald van het rijk buiten schrijven transactie-blok als u probeert te wijzigen van buiten krijgt u de uitzondering “‘Probeert te wijzigen object buiten een schrijven transactie — oproep beginWriteTransaction op een RLMRealm eerste aanleg.”
As shown in Figure 18 as we modify object in write
transaction block it will persist that object into the disk as well as shown in Figure 19 default.realm
file now has a updated firstName
value of User
in het Laatste voorbeeld is zeer interessant voerden wij de volgende taken uitvoeren om update gebruiker met de newUser
- We krijgen de Gebruiker met de primaire sleutel
userId
1 - nieuwe
User
met dezelfde primaire sleutel - Op een schrijven transactie noemen we toevoegen batch update methode met update = true het zal de gebruiker bijwerken met primaire sleutel = 1 . If update = false it will throw an exception since two objects can’t have same primary key as shown in Figure 20 and 21
Delete Object From Realm
Any objects currently linken naar de verwijderde zal hun linking eigenschap op nul zetten. Als deze objecten zijn gekoppeld vanuit een lijst-eigenschappen, worden ze verwijderd uit de lijsten in kwestie.
As shown in Figure 22 and 23 we deleted User object having firstName == ‘ali new User’
As shown in Figure 24 we empty Realm database using deleteAll()
method in realm object. Zoals weergegeven in Figuur realm.isEmpty
geeft als resultaat true
Soms moet je een soort van hiërarchie tussen Rijk objecten, net zoals je gewend bent te doen met Swift klassen. Helaas ondersteunt Realm momenteel geen object overerving out of the box . tijdelijke: https://forum.realm.io/t/inheritance-with-realm-confusion/153
Useful Links
https://www.raywenderlich.com/9220-realm-tutorial-getting-started
https://www.appcoda.com/realm-database-swift/
https://realm.io/docs/swift/latest/#to-many-relationships
https://realm.io/docs/swift/latest/#optional-properties
https://academy.realm.io/posts/nspredicate-cheatsheet/
https://academy.realm.io/posts/nspredicate-cheatsheet/