Did you know that you can tinker with Core Data inside of Swift playgrounds in Xcode? You can!
Jeremiah Jessel, author at http://www.learncoredata.com, wrote up an article in 2015 detailing how you can use the Core Data framework inside a playground. He shows how you can do everything from setting up the Core Data stack, to creating NSManagedObjects programmatically in code. Great stuff!
After I read his guide, I got to thinking: I wonder if you can take an .xcdatamodeld file created with Xcode’s Data Model designer and use it in a Playground….
The short answer is, kinda. You can’t use the .xcdatamodeld file (at least, I couldn’t find a way), BUT, you can use the compiled “momd” file that gets created when you build your app.
There’s at least two limitations / caveats I’ve come across as I’ve been playing with this concept:
No NSManagedObject subclasses
While you can create instances of the Entities in the model, if you’ve created
NSManagedObject subclasses for your Entities, you won’t be able to use those in the playground. You’d have to resort back to setting properties on your
NSManagedObject instances using
But this is a minor drawback, especially if you’re just wanting to tinker.
After you read the walkthrough, you’ll know how to get the model into your playground.
Here’s the deal though: If you ever make changes to your model, you’ll need to go through the steps necessary to re-add a freshly-compiled model to the playground’s Resources folder that includes the changes. This is because resources that are added to a playground are copied, not referenced.
I don’t think that’s a terrible draw-back, especially once you know how to do it.
So how do you do it? Here’s how:
Get started by adding a Data Model to your project. If you’ve got a project already going that uses Core Data, you probably already have a .xcdatamodeld file in your project. If you don’t, though, one is easily add-able from the File menu:
Add Data Model file (unless you already have one)
For my “smoke test”, just to see if it was possible, I left the default value for the model name as “Model.xcdatamodeld”.
Add entity with attribute
Once I had the data model added to the project, I went in and added an entity (named “Entity”) with an attribute (named “attribute” of type Integer 16):
Add a playground
Next up, I added a new playground to my project:
Build project; Locate “momd” file
With a playground and a data model has some structure to it, I built the project (CMD + B) so that the .xcdatamodeld file would be compiled into an “momd” file. It’s the momd file that needs to be added to the playground as a resource.
Show .app package contents
Drag “momd” file from Finder to playground Resources folder
Write Core Data code to use model
That’s it! Now that the “momd” file is in the playground’s Resources folder, you’re set to write code against it. You can insert
NSManagedObject instances, perform fetch requests, etc. Here’s an example that I wrote up:
Woohoo! I thought this was pretty cool.
Don’t forget: If you make updates to your model, you need to re-build your app, delete the “momd” folder from your playground’s resources, re-drag the freshly-compiled “momd” file to your playground again to work with the latest version of the model.
The other important question to ask, besides “I wonder if this is possible?” is “How is this useful?”
- Learning. Playgrounds in and of themselves make sense as a learning tool. How cool is it to be able to build the model you’re thinking of in the Xcode designer, import that into a playground, and tinker with it as a learning exercise??
- This could also be useful when you need to try out your data model but don’t really want to wire it up to an actual user interface yet. Strip away all the UI complexity and just work with the data model… in a playground! It just seems like a more elegant solution to the “print it out to the console” method of experimenting with the model.
- There might be situations when you’re building semi-complicated
NSPredicateinstances for a fetch request – why not get it working in a playground first, then migrate it over to your app? Just an idea!