Datavalidering med kjernedata Avanserte begrensninger

I den forrige veiledningen lærte du hvordan du definerer vanlige begrensninger i datamodellen. I denne veiledningen viser jeg deg hvordan du kan definere mer avanserte begrensninger i koden.

1. Prosjektoppsett

Last ned prosjektet vi opprettet i den forrige opplæringen fra GitHub, og åpne den i Xcode. Åpen AppDelegate.swift og oppdater implementeringen av søknad (_: didFinishLaunchingWithOptions) som vist under.

Funk Application (Application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool hvis la enheten = NSEntityDescription.entityForName ("User", inManagedObjectContext: self.managedObjectContext) // Opprett administrert objekt la bruker = NSManagedObject enhet: enhet, insertIntoManagedObjectContext: self.managedObjectContext) // Populere Managed Object user.setValue (44, forKey: "age") user.setValue ("Bart", forKey: "first") user.setValue ("Jacobs", forKey : "last") user.setValue ("[email protected]", forKey: "email") gjør prøv user.validateForInsert () catch let validationError = feil som NSError print (validationError) returner sann

Hvis du kjører programmet i simulatoren eller på en fysisk enhet, bør ingen feil kastes. Med andre ord, det administrerte objektet vi lager i søknad (_: didFinishLaunchingWithOptions) bestått validering for innføring i programmets vedvarende butikk.

2. Subclassing NSManagedObject

For å validere verdien av et attributt i kode, må vi opprette en NSManagedObject underklasse. Velge Ny> Fil ... fra Xcode er Fil menyen og velg Kjernedata> NSManagedObject-underklasse mal fra listen over maler.

Velg datamodellen for prosjektet og kontroller enhetene du vil opprette en NSManagedObject underklasse.

Kryss av Bruk skalaregenskaper for primitive datatyper, Fortell Xcode hvor du vil lagre filene for underklassene, og klikk Skape.

3. Eiendomsgodkjenning

For å validere egenskapen til et foretak, implementerer du en metode som tar følgende format, validere(_ :). Metoden skal være en kaste-metode. Hvis valideringen mislykkes, kastes en feil, og underretter Core Data om at verdien for eiendommen er ugyldig.

I eksemplet nedenfor har jeg implementert en valideringsmetode for først eiendom av Bruker enhet. Legg til følgende utdrag til User.swift.

importere CoreData import Foundation class Bruker: NSManagedObject let errorDomain = "UserErrorDomain" enum UserErrorType: Int tilfelle InvalidFirst func validateFirst (verdi: AutoreleasingUnsafeMutablePointer) kaster var feil: NSError? = nil; hvis la først = value.memory som? String if first == "" let errorType = UserErrorType.InvalidFirst error = NSError (domene: errorDomain, kode: errorType.rawValue, userInfo: [NSLocalizedDescriptionKey: "Fornavnet kan ikke være tomt."]) errorType = UserErrorType.InvalidFirst error = NSError (domene: errorDomain, kode: errorType.rawValue, userInfo: [NSLocalizedDescriptionKey: "Fornavnet kan ikke være tomt."]) hvis la feil = feil kaste feil

Valideringsmetoden aksepterer en parameter av typen AutoreleasingUnsafeMutablePointer. Hva er det? Ikke la typen av parameteren skremme deg. Som navnet på typen indikerer, vil AutoreleasingUnsafeMutablePointer strukturen er en mutable peker. Det peker på en objektreferanse. Vi kan få tilgang til verdien som pekeren peker gjennom hukommelse eiendom.

Som jeg nevnte for et øyeblikk, validateFirst (_ :) Metoden kaster. Hvis verdien som er levert til oss, ikke er gyldig, kaster vi en feil. Ved å kaste en feil informerer vi Core Data om at det administrerte objektet er ugyldig.

I det neste eksemplet implementerer jeg en valideringsmetode for e-postegenskapen til Bruker klasse. Vi benytter et vanlig uttrykk for å validere verdien av e-post eiendom.

func validateEmail (verdi: AutoreleasingUnsafeMutablePointer) kaster var feil: NSError? = null hvis la email = value.memory som? String let regex = "^. + @ ([A-Za-z0-9 -] + \\.) + [A-Za-z] 2 [A-Za-z] * $" la predikat = NSPredicate (format: "SELF MATCHES% @", regex) hvis! Predicate.evaluateWithObject (email) la errorType = UserErrorType.InvalidEmail error = NSError (domene: errorDomain, kode: errorType.rawValue, userInfo: [NSLocalizedDescriptionKey: "E-postadressen adressen er ugyldig. "]) ellers let errorType = UserErrorType.InvalidEmail error = NSError (domene: errorDomain, kode: errorType.rawValue, userInfo: [NSLocalizedDescriptionKey:" Epostadressen er ugyldig. "]) = feil kaste feil

Selv om du kan endre verdien av eiendommen i en valideringsmetode, fraråder Apple dette. Hvis du endrer verdien som leveres til deg i en valideringsmetode, kan minnestyring gå haywire. Med det for øye blir data-valideringstrømmen veldig enkel. Bekreft verdien av eiendommen og kaste en feil hvis den er ugyldig. Det er så enkelt.

Endre verdiene til attributter i søknad (_: didFinishLaunchingWithOptions) og kjør programmet i simulatoren. Hvis verdiene du skrev inn, er ugyldige, bør en feil kastes.

4. Objekt validering

De NSManagedObject klassen avslører tre ekstra kroker underklasser kan overstyre for data validering:

  • validateForInsert ()
  • validateForUpdate ()
  • validateForDelete ()

Disse metodene påberopes av Core Data på det administrerte objektet før du setter inn, oppdaterer eller sletter den tilsvarende posten i den vedvarende butikken. Hver av disse metodene kaster. Hvis en feil blir kastet, blir den tilsvarende innsatsen, oppdateringen eller slettet avbrutt.

Selv om fordelene disse krokene har over eiendomsvalideringsmetodene vi diskuterte tidligere, er kanskje ikke umiddelbart åpenbare, de er uvurderlige i flere scenarier. Tenk deg at en brukeroppføring ikke kan slettes så lenge den har en eller flere notatposter tilknyttet den. I så fall kan du overstyre validateForDelete () metode i Bruker klasse.

overstyr func validateForDelete () kaster prøv super.validateForDelete () var feil: NSError? = nil hvis la notater = notater if notes.count> 0 let errorType = UserErrorType.OneOrMoreNotes error = NSError (domene: errorDomain, kode: errorType.rawValue, userInfo: [NSLocalizedDescriptionKey: "En bruker med notater kan ikke slettes ..." ]) hvis la feil = feil kaste feil

Legg merke til at vi bruker overstyring søkeord og påkalle validateForDelete () implementering av superklassen øverst. Hvis brukeroppføringen er knyttet til en eller flere notatposter, kastes en feil, og forhindrer at brukeroppføringen slettes.

5. Hvilket alternativ skal du bruke?

Datavalidering er et viktig aspekt ved enhver applikasjon som fungerer med data. Core Data gir utviklere flere APIer for å implementere data validering. Men du lurer kanskje på hvilket alternativ, eller alternativer som skal brukes i søknaden din.

Dette avhenger av dine preferanser og kravene til prosjektet. For en enkel datamodell med vanlige begrensninger, kan alternativene datamodellen tilbyr, være tilstrekkelig. Når det er sagt, foretrekker noen utviklere å beholde valideringslogikken i modellklassen, det vil si i NSManagedObject klasser. Fordelen er at logikken for en bestemt modellklasse ligger på ett sted.

For mer komplisert valideringslogikk, tilpassede valideringsmetoder for egenskaper eller validateForInsert (), validateForUpdate (), og validateForDelete () kroker anbefales. De legger til kraft og fleksibilitet for å motvirke validering, og du har også den fordelen at modelllaget inneholder valideringslogikken.

Det er viktig å forstå at data validering består av to aspekter, logikken for data validering og når data validering skal utføres. Modelllaget har ansvaret for datavalidering. Kontrolleren har ansvaret for å bestemme når datavalidering skal utføres, for eksempel når brukeren tapper en knapp for å opprette en konto. Dette er en subtil men viktig forskjell.

Sist men ikke minst, unngå å sette data validering logikk i kontrolleren lag. Det unødvendig clutters opp kontrollerne av prosjektet ditt, og det fører vanligvis til kode duplisering.

Konklusjon

Kjerne data gjør data validering enkelt og grei. Datamodellen hjelper deg med vanlige begrensninger, men rammen viser også flere avanserte APIer for tilpasset datavalidering.