Thursday, April 21, 2016

Core Data Type Safety With Swift

Brian King:

Xcode also supports Swift code generation, but I don’t think developers should use it. First off, the amount of code you have to write to use Core Data with Swift is less than with Objective-C, since there are not separate interface and implementation files and the property syntax is simpler. It’s not that hard to do by hand, as we’ll see. Second, types are so much more important in Swift, and NSManagedObject is actually incredibly smart when it comes to types and Swift.

[…]

By default, to-many relationships will be generated as NSSet?. But who can deal with typeless containers these days? Use the native Swift Set type instead.

[…]

If you’re using Core Data with Swift, I hope this inspires you to revisit you models and reduce the amount of force casting and optional unwrapping in your code.

In Xcode 7.3:

The NSManaged attribute can be used with methods as well as properties, for access to Core Data’s automatically generated Key-Value-Coding-compliant to-many accessors.

@NSManaged var employees: NSSet

@NSManaged func addEmployeesObject(employee: Employee)
@NSManaged func removeEmployeesObject(employee: Employee)
@NSManaged func addEmployees(employees: NSSet)
@NSManaged func removeEmployees(employees: NSSet)

These can be declared in your NSManagedObject subclass.

6 Comments RSS · Twitter

Saying that it's "safe to use Int for 32-bit integers and smaller" doesn't sit well with me at all. Declaring an NSInteger32AttributeType as an Int will cause a console warning about "Implicit coercion to 32 bits in the database is not recommended" when run on a 64 bit system.

The only time Int is both guaranteed to not crash and guaranteed to not discard quantities is when the the attribute is an NSInteger64AttributeType AND the code is running on a 64bit system.

Also, the quoted section (above) from the Xcode release notes may be a bit inaccurate. The inferred Objective-C selector for those add/remove methods seem to be incorrect unless the parameter is named value for the singular methods or values for the plural ones. Explicitly declaring the Objective-C selector may be another option, if you want to get really creative:

@NSManaged @objc(addEmployeesObject:) func increaseStaffRoster(byAdding employee: Employee)

@Trevor That’s a good point about Int. Thanks. It seems to me that, for the to-many accessors, the problem is that there should be a _ before the parameter name so that it doesn’t become part of the selector. It’s not clear to me why you are suggesting value/values.

The last time I encountered the problem, it seemed that "value" and "values" would result in a more accurate inferred selector, but now I'm not so sure.

I just went back to the code in question, changed `@NSManaged func addMembers(values: Set)` to `@NSManaged func addMembers(members: Set)` and it worked fine either way. Maybe it was a full moon or something...

@Trevor Thanks for checking. It makes sense that the parameter name wouldn’t matter. The Swift/Obj-C book matches the release notes. Regarding the _, I think I was momentarily confused about how external parameter names work with Objective-C.

[…] Core Data Type Safety With Swift […]

[…] Core Data Type Safety With Swift […]

Leave a Comment