kodeco.com Forums

Video Tutorial: Beginning Core Data Part 2: NSManagedObject Subclasses

Learn how to use NSManagedObject subclasses to make data objects easier to work with and more extensible, and explore the moving parts behind Core Data.


This is a companion discussion topic for the original entry at https://www.raywenderlich.com/3200-beginning-core-data/lessons/3

Hi Greg,
When generating NSManagedObject subclasses from a Core Data model, what things should I consider when deciding to check the ‘use scalar properties for primitive data types’ checkbox? I understand mechanically what the checkbox does, setting the attribute types to things like NSNumber and NSDate if not checked and to things like Bool, Int32 and NSTimeInterval if it is checked, but I don’t totally grasp the ramifications that’s going to have for me when working with the generated classes. Do you have any guidelines or thoughts on when you should check that box when generating?

Hi Jason, that’s a great question! For all-Swift projects, I definitely prefer the native types such as Bool and Int. That just means Core Data will handle the complexity of bridging to the actual data store while I get to write using native-feeling types in Swift.

For mixed projects that have more Objective-C, I’ll think about using the non-scalar properties. Objective-C will bridge Swift Int types and such automatically, but sometimes I like seeing the more Obj-C style types in there.

I don’t think there’s any runtime performance penalty or anything like that with either choice. For me, it’s just about the primary language and what’s more comfortable.

Thanks for the question and I hope this helps!

This does help, thanks, Greg. What threw me a bit was that Int32 types are generated instead of Swift “Int” types. Seems like you have to do some conversion no matter what if you’re working with Ints in your Swift code.

The other two things that the generator does when generating Swift subclasses is 1) always create optional types, which you mentioned in the video and 2) create NSSets for relationships rather than typed Sets. I’m manually changing these after generation, but, of course, my changes are overwritten when I re-generate as my model is still in a state of flux. Hopefully the support for both of these will be added at some point for Swift subclasses.

Hi,greg,i generating NSManagedObject subclasses ,but i can’t set the property. i just wanna access some json data and set the property. i don’t want to save the data to disk.how can i use the NSManagedObject as NSObject.i apprecaite any help

Hi Greg, at about 4:55 in the video you say you’re passing the managedObjectContext down the view stack. You’re doing this with a tabBarController, but how can i do the same thing to pass it to a tableViewController that is accessed directly from the root view controller?

(1) Navigation controller
(2) root view controller
(3) table view controller ← I want to use it here

Thanks,
Jim

Hey greg, enjoying your Core Data tutorials. As I work through the challenge I’m trying to complete the changes in tableView(_:cellForRowAtIndexPath:) in PeopleTableViewController.swift but am unable to figure it out. I downloaded both the ‘challenge finished’ and ‘uber challenge finished’ projects but don’t see any changes reflected in there.

I did change the declaration for ‘person’ at the top to from var people = NSManagedObject to:

var people = [Person]()

Any hints on what would need to be changed in cellForRowAtIndexPath?

Here’s the code:

` override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) → UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier(“PersonCell”, forIndexPath: indexPath)

let person = people[indexPath.row]
if let name = person.valueForKey("name") as? String {
  cell.textLabel?.text = name
}

return cell

}`

Ok, I got brave and just forged ahead and figured it out. I replaced the following…

if let name = person.valueForKey("name") as? String {
  cell.textLabel?.text = name
}

… with this. I like how concise it is.

cell.textLabel?.text = people[indexPath.row].name

Hi :slight_smile: … I’ve discovered some issue with addressLabel, which isn’t appearing on screen at all.
I’ve tried starter and completed projects for this part and they all behave the same, except completed version of challenge project … when I run this project addressLabel has appeared :slight_smile:

So, after some trying to solve this problem I’ve found that if in class ViewController in method viewDidLoad() where we setting up:
layout.itemSize = CGSize(width: self.view.bounds.size.width/2.0 - 16, height: 250)

we’ve to change the height to: 280, like so:

layout.itemSize = CGSize(width: self.view.bounds.size.width/2.0 - 16, height: 280).
As it is in completed challenge project for this part.

=> One more thing :wink: … in challenge documentation in page 4 there’re peace of code that shouldn’t be
(just before section “Implementing the Picker Delegate”; this is the same code which is in section “Showing The Image”, where it should be):

if let pictureData = person.picture {
cell.pictureImageView.image = UIImage(data: pictureData as Data)
}

I really didn’t get the purpose of making name attribute required Even If I am not giving the name I didn’t see any difference If I make it optional .