ios - Core Data validation: from Objective-C to Swift -



ios - Core Data validation: from Objective-C to Swift -

i'm building dummy ios project in order understand how implement validation in core info swift. core info model of project has 1 entity called person contains 2 attributes: firstname , lastname. project based on swift but, in order start it, i'm using objective-c define nsmanagedobject subclass:

person.h

@interface person : nsmanagedobject @property (nonatomic, retain) nsstring *firstname; @property (nonatomic, retain) nsstring *lastname; @end

person.m

@implementation person @dynamic firstname; @dynamic lastname; -(bool)validatefirstname:(id *)iovalue error:(nserror **)outerror { if (*iovalue == nil || [*iovalue isequaltostring: @""]) { if (outerror != null) { nsstring *errorstr = nslocalizedstringfromtable(@"first name can't empty", @"person", @"validation: first name error"); nsdictionary *userinfodict = @{ nslocalizeddescriptionkey : errorstr }; nserror *error = [[nserror alloc] initwithdomain:@"domain" code: 101 userinfo: userinfodict]; *outerror = error; } homecoming no; } homecoming yes; } @end

person-bridging-header.h

#import "person.h"

in core info model editor, i've set entity class within info model inspector indicated:

class: person

the first time launch project, create instance of person in appdelegate application:didfinishlaunchingwithoptions: method next code:

if !nsuserdefaults.standarduserdefaults().boolforkey("isnotinitialload") { allow person = nsentitydescription.insertnewobjectforentityforname("person", inmanagedobjectcontext: managedobjectcontext!) person person.firstname = "john" person.lastname = "doe" var error: nserror? if !managedobjectcontext!.save(&error) { println("unresolved error \(error), \(error!.userinfo)") abort() } nsuserdefaults.standarduserdefaults().setbool(true, forkey: "isnotinitialload") nsuserdefaults.standarduserdefaults().synchronize() }

the project has 1 uiviewcontroller next code:

class viewcontroller: uiviewcontroller { var managedobjectcontext: nsmanagedobjectcontext! var person: person! override func viewdidload() { super.viewdidload() //fetch person object var error: nserror? allow fetchrequest = nsfetchrequest(entityname: "person") allow array = managedobjectcontext.executefetchrequest(fetchrequest, error:&error) if array == nil { println("unresolved error \(error), \(error!.userinfo)") abort() } person = array![0] person } @ibaction func changefirstname(sender: anyobject) { //generate random firstname allow array = ["john", "jimmy", "james", "johnny", ""] person.firstname = array[int(arc4random_uniform(uint32(5)))] var error: nserror? if !managedobjectcontext.save(&error) { println("unresolved error \(error), \(error!.userinfo)") homecoming } //if success, display new person's name println("\(person.firstname)" + " " + "\(person.lastname)") } }

changefirstname: linked uibutton. therefore, whenever click on button, new string randomly generated , assigned person.firstname. if new string empty, validatefirstname:error: generates nserror , save operation fails.

this works great but, in order have pure swift project, i've decided delete person.h, person.m , person-bridging-header.h , replace them single swift file:

class person: nsmanagedobject { @nsmanaged var firstname: string @nsmanaged var lastname: string func validatefirstname(iovalue: anyobject, error: nserrorpointer) -> bool { if iovalue as? string == "" { if error != nil { allow mybundle = nsbundle(forclass: self.dynamictype) allow errorstring = mybundle.localizedstringforkey("first name can't empty", value: "validation: first name error", table: "person") allow userinfo = nsmutabledictionary() userinfo[nslocalizedfailurereasonerrorkey] = errorstring userinfo[nsvalidationobjecterrorkey] = self var validationerror = nserror(domain: "domain", code: nsmanagedobjectvalidationerror, userinfo: userinfo) error.memory = validationerror } homecoming false } homecoming true } }

in core info model editor, i've changed entity class within info model inspector indicated:

class: person.person //<project name>.person

the problem project crashes whenever phone call changefirstname:. weirdest thing if set breakpoint within validatefirstname:, can see method never called.

what doing wrong?

i little bit guessing here, (id *)iovalue parameter mapped swift as

iovalue: autoreleasingunsafemutablepointer<anyobject?>

therefore swift variant should like

func validatefirstname(iovalue: autoreleasingunsafemutablepointer<anyobject?>, error: nserrorpointer) -> bool { if allow firstname = iovalue.memory as? string { if firstname == "" { // firstname empty string // ... } } else { // firstname nil (or not string) // ... } homecoming true }

update swift 2:

func validatefirstname(iovalue: autoreleasingunsafemutablepointer<anyobject?>) throws { guard allow firstname = iovalue.memory as? string firstname != "" else { // firstname nil, empty, or not string allow errorstring = "first name can't empty" allow userdict = [ nslocalizeddescriptionkey: errorstring ] throw nserror(domain: "domain", code: nsmanagedobjectvalidationerror, userinfo: userdict) } // firstname non-empty string }

as @santaclaus correctly noticed, validation function must throw error if validation fails.

ios objective-c validation core-data swift

Comments

Popular posts from this blog

Delphi change the assembly code of a running process -

json - Hibernate and Jackson (java.lang.IllegalStateException: Cannot call sendError() after the response has been committed) -

C++ 11 "class" keyword -