Ghidul bazei de date Realm – Construirea unei aplicații Note în Swift pentru iOS

Dacă preferați videoclipurile în locul articolelor scrise, acest articol este o versiune scrisă a unui videoclip pe care l-am produs. Conținutul este identic.

Acest videoclip este primul dintr-o serie care sper că va servi pentru a vă învăța cum să folosiți cadrele și instrumentele iOS, cum ar fi Siri Shortcuts, CloudKit și altele. Dacă aveți un cadru sau o caracteristică specifică pe care ați dori să o vedeți acoperită în această serie, nu ezitați să îmi scrieți la jordanosterbergshadowsystemstech, sau pe Twitter @josterbe1.

Cuprins

  1. Introducere
  2. Instalarea dependențelor
  3. Modelul
  4. Implementarea Realm
  5. Concluzie

Fără alte introduceri, haideți să aruncăm o privire la aplicația pe care o vom construi în această serie….

Introducere

Lista de note a aplicației
Editarea unei note în mod individual

Avem lista noastră de note, iar atunci când atingem una, o putem citi și putem începe să o modificăm, sau să o ștergem. Destul de simplu. Veți observa, dacă descărcați proiectul de pornire, că notele nu persistă atunci când intrați și ieșiți din NoteDetailController atunci când apăsați pe nota „Apple Park Visit”. Adică, conținutul notei nu se salvează atunci când o editați.

Acesta este ceea ce vom construi în acest articol, folosind Realm Database. Folosesc Realm de doar aproximativ doi ani și consider că simplitatea sa depășește costul utilizării unei biblioteci terțe. De fapt, o folosesc în aplicația la care îmi petrec cel mai mult timp de dezvoltare personală (vezi https://countdowns.download) atât pe macOS, cât și pe iOS.

Instalarea dependențelor

Pentru a începe să folosim Realm, trebuie să îl instalăm folosind CocoaPods. CocoaPods, dacă nu știți, CocoaPods este un instrument de gestionare a dependențelor care este utilizat pe scară largă în spațiul iOS. Dacă nu aveți deja CocoaPods instalat pe Mac, puteți folosi comanda sudo gem install cocoapods pentru a începe. Acum, deschideți dosarul proiectului, precum și o fereastră Terminal în interiorul acelui director.

Tastați pod init, apoi open Podfile.

În interiorul „Podfile” nou creat, trebuie să scriem un text care va informa CocoaPods ce biblioteci doriți să instalați în proiectul dvs.

După # Pods for NotesApp, scrieți aceste două rânduri:

pod 'Realm', '~> 3.12.0'pod 'RealmSwift', '~> 3.12.0'

După ce ați scris aceste rânduri, Podfile-ul dvs. ar trebui să arate asemănător cu acesta:

platform :ios, '12.0'target 'NotesApp' do use_frameworks! # Pods for NotesApp pod 'Realm', '~> 3.12.0' pod 'RealmSwift', '~> 3.12.0' target 'NotesAppTests' do inherit! :search_paths end target 'NotesAppUITests' do inherit! :search_paths endend

Acum că am adăugat dependențele noastre, haideți să îi cerem lui CocoaPods să le instaleze cu pod install

Acest lucru va dura ceva timp atunci când folosiți CocoaPods pentru prima dată. Nu vă faceți griji, CocoaPods descarcă doar câteva componente inițiale. Acest lucru nu se va întâmpla de fiecare dată când pod install.

Fereastra Terminalului dvs. va arăta astfel după ce această comandă se termină de executat:

Fereastra Terminalului

După aceasta, dacă ați deschis deja NotesApp.xcodeproj, închideți din ea. Când utilizați CocoaPods, trebuie să utilizați fișierul .xcworkspace în loc de fișierul implicit .xcodeproj. Deschideți fișierul NotesApp.xcworkspace și mergeți la Note.swift.

The Model

Această clasă conține obiectul nostru Note model, care conține câteva proprietăți de bază:

class Note { var identifier: String var content: String var lastEdited: Date init( identifier: String = UUID().uuidString, content: String, lastEdited: Date = Date()) { self.identifier = identifier self.content = content self.lastEdited = lastEdited }}

Codul standard al modelului, nu se întâmplă nimic special aici.

Avem, de asemenea, o extensie a obiectului nostru Note în același fișier, care se subclasează ca protocol numit Writeable

extension Note: Writable { func write(dataSource: DataSource) { self.lastEdited = Date() dataSource.store(object: self) } func delete(dataSource: DataSource) { dataSource.delete(object: self) }}

În interiorul funcțiilor write și delete, veți observa că avem o proprietate DataSource. DataSource este un protocol generic pentru a ne ajuta să facem ca modificarea datelor să fie cât mai abstractă la nivelurile superioare ale codului nostru.

Iată definiția protocolului:

protocol DataSource { func store<T>(object: T) func delete<T>(object: T)}

Dacă nu sunteți familiarizați cu genericele, fiecare dintre funcțiile noastre are un parametru T care, în esență, înseamnă că poate fi orice tip de obiect. Acest lucru nu este folosit foarte mult în proiectul nostru, dar ar putea fi evoluat și folosit mai departe pentru a crea mai multe DataSources cu constrângeri diferite în legătură cu obiectele pe care le pot stoca.

Implementăm protocolul nostru DataSource în NoteDataSource. Nu este nimic special nici aici, în afară de un mic amănunt pe care aș dori să îl notez de dragul explicațiilor.

De fiecare dată când folosim obiecte store sau delete, folosim următorul apel la NotificationCenter:

NotificationCenter.default.post(name: .noteDataChanged, object: nil)// We also have this extension of Notification.Name to make sending and receiving this notification simple.extension Notification.Name { static let noteDataChanged = Notification.Name(rawValue: "noteDataChanged")}

În esență, de fiecare dată când orice notă este stocată sau ștearsă, informăm orice ascultători că datele noastre s-au schimbat, astfel încât aceștia să își poată actualiza interfața de utilizare în consecință.

După ce am eliminat toate fișierele și clasele noastre de model, să începem să implementăm Realm!

Implementarea Realm

Există trei pași pentru a integra Realm în proiectul nostru:

  1. Crearea obiectului Realm
  2. Facerea unei punți între obiectul nostru Realm și obiectul nostru primitiv Note
  3. Începeți să recuperați și să modificați datele cu Realm

Crearea obiectului Realm

Acest pas este relativ simplu. Să creăm un nou fișier Swift numit RealmNote.swift. În interiorul lui RealmNote.swift, importăm cadrul RealmSwift și creăm o declarație de clasă astfel:

import RealmSwiftclass RealmNote: Object {}

Vom subclasa clasa Object a Realm, care ne va permite să folosim RealmNote în funcțiile bazei de date Realm.

Acum, adăugați cele trei proprietăți pe care le avem în modelul nostru Note:

@objc dynamic var identifier: String = ""@objc dynamic var content: String = ""@objc dynamic var lastEdited: Date = Date()

Părțile @objc dynamic din declarația noastră de variabile expun proprietățile noastre la Objective-C, în care sunt scrise multe dintre straturile iOS ale Realm. De asemenea, permite Realm să asculte modificările aduse obiectelor noastre RealmNote.

Pentru a finaliza clasa noastră, suprascrieți class func primaryKey, care returnează un șir opțional (String?) cu valoarea „identifier”. Acest lucru informează Realm că cheia primară a RealmNote, o modalitate de a identifica în mod unic obiectele noastre, este stocată în proprietatea „identifier”.

După ce ați finalizat acești pași, RealmNote dvs. va arăta astfel:

class RealmNote: Object { @objc dynamic var identifier: String = "" @objc dynamic var content: String = "" @objc dynamic var lastEdited: Date = Date() override class func primaryKey() -> String? { return "identifier" }}

Asta este tot pentru primul pas.

Puntea dintre obiectul nostru Realm și obiectul nostru primitiv Note

Avem două obiecte model separate: Note și RealmNote. RealmNote este utilizat intern atunci când avem de-a face cu Realm, pentru a păstra stratul nostru de model decuplabil de interfața de utilizare. Prin utilizarea a două obiecte separate, am putea renunța la utilizarea Realm în viitor, dacă va fi nevoie.

În fișierul RealmNote.swift, creați o extensie a lui RealmNote:

extension RealmNote {}

Creăm acum un convenience init în interiorul extensiei, care primește un Note ca unică proprietate. Acest lucru ne va permite să creăm obiecte RealmNote folosind un obiect Note.

convenience init(note: Note) { self.init() self.identifier = note.identifier self.content = note.content self.lastEdited = note.lastEdited}

Genial, acum, pentru a termina RealmNote.swift, creați o variabilă Note în interiorul extensiei care se inițializează de la un RealmNote:

var note: Note { return Note(realmNote: self)}

Nu vă faceți griji dacă Xcode vă dă o eroare cu privire la inițializatorul Note, suntem pe cale să rezolvăm asta.

Direcționați-vă spre Note.swift, unde suntem pe cale să scriem cealaltă jumătate a punții noastre. Acest cod este, în esență, același lucru ca și extensia lui RealmNote.

extension Note { convenience init(realmNote: RealmNote) { self.init(identifier: realmNote.identifier, content: realmNote.content, lastEdited: realmNote.lastEdited) } var realmNote: RealmNote { return RealmNote(note: self) }}

Grea, acesta este pasul doi. Acum putem accesa un RealmNote de la un Note, iar un Note de la un RealmNote. Acest lucru înseamnă, de asemenea, că acest cod este perfect valabil:

Note(content: "Example").realmNote.note.realmNote.note.realmNote.note.realmNote// and so on...

Lăsând glumele la o parte, să terminăm aplicația noastră cu pasul trei.

Începeți să recuperați și să modificați datele cu Realm

Capitulați în NoteDataSource.swift, și import RealmSwift înainte de declarația clasei. Înainte de a modifica, șterge și prelua obiecte Realm, avem nevoie de o instanță a bazei de date Realm. Înlocuiți init-ul din NoteDataSource cu acest lucru:

var realm: Realminit() { // Load our data self.realm = try! Realm()}

Aceasta va crea o instanță a bazei de date Realm. În producție, probabil că nu veți dori să folosiți operatorul bang (!) atunci când creați instanța, deoarece aplicația dvs. se va bloca dacă baza de date nu este disponibilă.

În continuare, haideți să modificăm funcția store pentru a stoca efectiv obiecte în baza noastră de date.

Scrierea cu Realm este simplă:

try? self.realm.write {}

În interiorul acestui bloc de cod, putem actualiza obiectele din baza de date. Scrieți acest lucru:

self.realm.add(note.realmNote, update: true)

Aceasta va crea un nou RealmNote în baza de date sau va actualiza unul existent, dacă există unul. Asta este! Acum stocăm obiecte în baza de date Realm (apelarea funcției de scriere a notei este realizată în NoteDetailController.swift, dacă doriți să vedeți funcția care este utilizată efectiv pentru a realiza această scriere.)

Acum, haideți să scriem funcția noastră delete. Din cauza modului în care am scris puntea noastră (fără să consultăm Realm ori de câte ori creăm un RealmNote dintr-un Note), trebuie să preluăm obiectul direct din baza de date folosind identificatorul notei, mai degrabă decât folosind proprietatea realmNote a acesteia.

Acest lucru este simplu:

if let realmNote = self.realm.object(ofType: RealmNote.self, forPrimaryKey: note.identifier) {}

Aceasta îi cere lui Realm să recupereze un obiect RealmNote din baza de date, cu identificatorul, sau cheia primară, de note.identifier.

Acest lucru poate fi un pic ciudat. Din anumite motive, aplicația se blochează dacă folosim funcția tradițională write pe Realm. Ca o soluție alternativă, acest cod este perfect valabil și, în esență, îndeplinește aceeași sarcină ca și write:

self.realm.beginWrite()self.realm.delete(realmNote)try? self.realm.commitWrite()

Începem scrierea noastră, ștergem obiectul și confirmăm scrierea noastră.

Cu aceasta, am construit o aplicație de note funcțională!

Concluzie

Sper că v-a plăcut acest tutorial despre cum să folosiți baza de date Realm. M-am distrat foarte mult realizându-l și abia aștept să dezvolt această serie și să adaug mai multe caracteristici aplicației noastre de-a lungul timpului, cum ar fi Siri Shortcuts, CloudKit și multe altele. Vă mulțumim că ați citit.

Lasă un răspuns

Adresa ta de email nu va fi publicată.