Convalida dei dati con i dati principali vincoli avanzati

Nel precedente tutorial, hai imparato come definire i vincoli comuni nel modello di dati. In questo tutorial, ti mostro come puoi definire i vincoli più avanzati nel codice.

1. Impostazione del progetto

Scarica il progetto che abbiamo creato nel precedente tutorial di GitHub e aprilo in Xcode. Aperto AppDelegate.swift e aggiornare l'implementazione di applicazione (_: didFinishLaunchingWithOptions) come mostrato di seguito.

func application (application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool if let = NSEntityDescription.entityForName ("User", inManagedObjectContext: self.managedObjectContext) // Crea oggetto gestito consenti user = NSManagedObject ( entity: entity, insertIntoManagedObjectContext: self.managedObjectContext) // Popola oggetto gestito user.setValue (44, forKey: "age") user.setValue ("Bart", forKey: "first") user.setValue ("Jacobs", forKey : "last") user.setValue ("[email protected]", forKey: "email") do try user.validateForInsert () catch let validationError = errore come stampa NSError (validationError) restituisce true

Se si esegue l'applicazione nel simulatore o su un dispositivo fisico, non devono essere generati errori. In altre parole, l'oggetto gestito in cui creiamo applicazione (_: didFinishLaunchingWithOptions) passa la convalida per l'inserimento nell'archivio permanente dell'applicazione.

2. Sottoclassi NSManagedObject

Per convalidare il valore di un attributo nel codice, dobbiamo creare un NSManagedObject sottoclasse. Scegliere Nuovo> File ... da Xcode's File menu e selezionare il Dati principali> Sottoclasse NSManagedObject modello dall'elenco di modelli.

Seleziona il modello dati del progetto e controlla le entità per le quali vuoi crearne uno NSManagedObject sottoclasse.

Dai un'occhiata Utilizzare le proprietà scalari per i tipi di dati primitivi, indicare a Xcode dove si desidera salvare i file per le sottoclassi e fare clic su Creare.

3. Convalida proprietà

Per convalidare la proprietà di un'entità, si implementa un metodo che assume il seguente formato, convalidare(_ :). Il metodo dovrebbe essere un metodo di lancio. Se la convalida fallisce, viene generato un errore, notificando al Core Data che il valore per la proprietà non è valido.

Nell'esempio seguente, ho implementato un metodo di convalida per primo proprietà del Utente entità. Aggiungi il seguente snippet a User.swift.

import CoreData import Foundation class Utente: NSManagedObject let errorDomain = "UserErrorDomain" enum UserErrorType: Int caso InvalidFirst func validateFirst (valore: AutoreleasingUnsafeMutablePointer) genera var error: NSError? = nulla; se let prima = valore.memory come? String if first == "" let errorType = UserErrorType.InvalidFirst error = NSError (domain: errorDomain, code: errorType.rawValue, userInfo: [NSLocalizedDescriptionKey: "Il nome non può essere vuoto."]) Else let errorType = UserErrorType.InvalidFirst error = NSError (domain: errorDomain, code: errorType.rawValue, userInfo: [NSLocalizedDescriptionKey: "Il nome non può essere vuoto."]) se let error = error throw error

Il metodo di convalida accetta un parametro di tipo AutoreleasingUnsafeMutablePointer. Cos'è quello? Non lasciare che il tipo del parametro ti spaventi. Come indica il nome del tipo, il AutoreleasingUnsafeMutablePointer la struttura è un puntatore mutevole. Punta a un riferimento all'oggetto. Possiamo accedere al valore a cui punta il puntatore memoria proprietà.

Come ho detto un momento fa, il validateFirst (_ :) il metodo sta lanciando. Se il valore che ci è stato consegnato non è valido, abbiamo generato un errore. Lanciando un errore, comunichiamo a Core Data che l'oggetto gestito non è valido.

Nel prossimo esempio, implemento un metodo di convalida per la proprietà email di Utente classe. Facciamo uso di un'espressione regolare per convalidare il valore del e-mail proprietà.

func validateEmail (valore: AutoreleasingUnsafeMutablePointer) genera var error: NSError? = nil se email = value.memory as? String let regex = "^. + @ ([A-Za-z0-9 -] + \\.) + [A-Za-z] 2 [A-Za-z] * $" let predicate = NSPredicate (formato: "SELF MATCHES% @", regex) if! Predicate.evaluateWithObject (email) let errorType = UserErrorType.InvalidEmail error = NSError (dominio: errorDomain, codice: errorType.rawValue, userInfo: [NSLocalizedDescriptionKey: "L'email l'indirizzo non è valido. "]) else let errorType = UserErrorType.InvalidEmail error = NSError (domain: errorDomain, code: errorType.rawValue, userInfo: [NSLocalizedDescriptionKey:" L'indirizzo email non è valido. "]) se l'errore = errore errore di lancio

Anche se è possibile modificare il valore della proprietà in un metodo di convalida, Apple scoraggia fortemente questo. Se modifichi il valore che ti è stato assegnato in un metodo di convalida, la gestione della memoria potrebbe andare in tilt. Con questo in mente, il flusso di convalida dei dati diventa molto semplice. Convalida il valore della proprietà e genera un errore se non è valido. È così semplice.

Modifica i valori degli attributi in applicazione (_: didFinishLaunchingWithOptions) ed esegui l'applicazione nel simulatore. Se i valori immessi non sono validi, è necessario generare un errore.

4. Validazione dell'oggetto

Il NSManagedObject classe espone tre ulteriori sottoclassi di hook che possono eseguire l'override per la convalida dei dati:

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

Questi metodi sono invocati da Core Data sull'oggetto gestito prima di inserire, aggiornare o eliminare il record corrispondente nell'archivio permanente. Ognuno di questi metodi sta lanciando. Se viene generato un errore, l'inserto, l'aggiornamento o l'eliminazione corrispondenti vengono interrotti.

Anche se il vantaggio che questi hook hanno sui metodi di convalida delle proprietà che abbiamo discusso in precedenza potrebbero non essere immediatamente evidenti, essi sono inestimabili in diversi scenari. Immagina che un record utente non possa essere cancellato a patto che abbia uno o più record di note associati. In tal caso, è possibile ignorare il validateForDelete () metodo nel Utente classe.

override func validateForDelete () genera try super.validateForDelete () var error: NSError? = nil se let notes = notes if notes.count> 0 let errorType = UserErrorType.OneOrMoreNotes error = NSError (domain: errorDomain, code: errorType.rawValue, userInfo: [NSLocalizedDescriptionKey: "Un utente con note non può essere cancellato ..." ]) se let error = error throw error

Nota che usiamo il oltrepassare parola chiave e invoca il validateForDelete () implementazione della superclasse in alto. Se il record dell'utente è legato a uno o più record di note, viene generato un errore, impedendo la cancellazione del record dell'utente.

5. Quale opzione dovresti usare?

La convalida dei dati è un aspetto importante di ogni applicazione che funziona con i dati. Core Data fornisce agli sviluppatori diverse API per l'implementazione della convalida dei dati. Ma potresti chiederti quale opzione, o opzioni, usare nella tua applicazione.

Questo dipende dalle tue preferenze e dai requisiti del progetto. Per un modello di dati semplice con vincoli comuni, le opzioni offerte dal modello di dati potrebbero essere sufficienti. Detto questo, alcuni sviluppatori preferiscono mantenere la logica di validazione nelle classi del modello, cioè nel NSManagedObject sottoclassi. Il vantaggio è che la logica per una particolare classe di modello si trova in un posto.

Per logica di convalida più complessa, metodi di convalida personalizzati per proprietà o validateForInsert (), validateForUpdate (), e validateForDelete () i ganci sono raccomandati Aggiungono potenza e flessibilità alla convalida degli oggetti e anche il vantaggio che il livello del modello include la logica di convalida.

È importante comprendere che la convalida dei dati consiste di due aspetti, la logica per la convalida dei dati e quando deve essere eseguita la convalida dei dati. Il livello del modello è responsabile della convalida dei dati. Il controllore ha il compito di decidere quando eseguire la convalida dei dati, ad esempio quando l'utente tocca un pulsante per creare un account. Questa è una differenza sottile ma importante.

Ultimo ma non meno importante, evitare di mettere la logica di convalida dei dati nel livello controller. Abbassa inutilmente i controller del progetto e di solito porta alla duplicazione del codice.

Conclusione

Core Data rende la convalida dei dati facile e immediata. Il modello dati ti aiuta con i vincoli comuni, ma il framework espone anche molte API più avanzate per la convalida dei dati personalizzati.