Updated on June 13, 2017 – Swift 3.0, Xcode 8
Code re-use is a powerful factor, nevertheless it’s not all the time straightforward to tug off. We attempt for it although, because in the long run, it makes maintaining the code far, far simpler than if we simply settled for copying and pasting.
With the introduction of dynamic frameworks in iOS eight, a world of risk opened up for iOS developers to realize some fairly cool re-use situations, one in every of which we’re going to dive into at present.
Not only can we share code between tasks, we will also share Core Data fashions between tasks by utilizing frameworks!
Maybe you’re engaged on an iOS + Mac app combination and the info model for each is equivalent. Perhaps you’re building several iOS apps which have totally different consumer interfaces however share some underlying persistence-layer fashions. Regardless of the case may be, wouldn’t it’s awesome to design the Core Data model as soon as and share it between your tasks?
Instance state of affairs
Our working instance for this walkthrough will be the following:
Our workforce is building an iOS app and a Mac app and the underlying knowledge model can be precisely the same between them. The only distinction between the apps would be the goal platform.
The app will goal automotive lovers all over the place – we’ll empower automotive fanatics to manage of a record of their favorite automobiles.
We’ll be creating two Xcode tasks during this walkthrough: One would be the framework and might be referred to as “CarKit”. The other can be a single view iOS software. We gained’t truly dive into the Mac challenge, but one might think about the method being very comparable for importing CarKit into the Mac software when it got here time to build that one.
I’m providing a accomplished CarKit + Carz package deal so that you can take a look at over at GitHub:
Let’s get began!
Creating a Swift framework challenge
To get started with creating a Swift framework, start with Xcode’s New Venture dialog (File -> New -> Undertaking…). Sometimes we stay within the realm of the “iOS Application” venture templates, however should you click “Framework & library”, you’ll see the option to create a new Cocoa Contact Framework:
In maintaining with Apple’s “___Kit” theme, we’ll identify our framework “CarKit”:
Add a knowledge model file
Once the framework challenge has been created, we’re set to drop in a new Data Model file from Xcode’s new file dialog (File -> New -> File…). Choose Core Data, after which Data Model:
Give the info model file a identify that appears to suit your state of affairs. For our instance, let’s identify it “CarModel”:
Add mannequin attributes
Next it’s time to truly add attributes to the model. Since our theme is automobiles here, we’ll stick with three easy attributes: yr, make, and mannequin:
Create NSManagedObject subclass
With the mannequin attributes all configured, it’s time to create an NSManagedObject subclass. This can make consuming the model a lot easier in shopper purposes. I’ve truly written up a full walk via on creating an NSManagedObject subclass in Swift as there are some nuances. Be happy to learn up on that for those who so want!
Be absolutely positive to mark your NSManagedObject subclass and its properties public – otherwise, the shopper app gained’t be capable of see the category or its properties:
As I point out in Implement NSManagedObject Subclass in Swift, it is advisable set the Module property within the Data Model Inspector to be CarKit (which is identical as the “Current Project Module” choice for this example):
Build and examine outputs
We’ve obtained a framework, and we’ve received a Data Model with attributes and an NSManagedObject subclass all appropriately carried out. Now it’s time to build the venture and inspect the output of the construct!
Command + B to build, and then head up to the File menu and choose Undertaking Settings:
Within the Challenge Settings space that seems, click on the small grey arrow beneath the “Derived Data” section:
Next, find the derived knowledge folder on your undertaking. It ought to be named the same as your undertaking with a set of random characters after. Typically there might be multiple folders that could possibly be your venture. You possibly can take a look at the last modified date to assist figure you figure out which one was most lately constructed and choose that one.
Increase the Construct folder right down to Build -> Products -> Debug-iphonesimulator. There you must see the CarKit.framework artifact, and within it, every part that’s needed to be able to utilize the info mannequin in a shopper software. Awesome!
Observe: This framework isn’t production-ready. It’s a little extra involved to create a framework that one can run on a gadget / cross validation when submitting to the app store. The event of the framework stays the same, however the build phases and procedures have to be modified to make it “universal”. Slightly than overly complicate this walkthrough, I like to recommend reviewing “Universal Cocoa Contact Frameworks for iOS 8 – (Remix) by @kodmunki to create a “universal” framework capable of being run within the simulator and on iOS units.
Creating the framework-dependent app
With the framework built, it’s time to create the iOS app that may make the most of that framework and its packaged belongings! Begin a new challenge from File -> New -> Undertaking and choose “Single View Application”. I’ll identify our instance app “Carz”. Make sure that “Use Core Data” is selected so that you simply get the boilerplate Core Data code put into your undertaking by Xcode:
Remove Xcode-generated .xcdatamodeld file
When you select “Use Core Data” within the venture creation window, Xcode routinely generates some boilerplate code, which we would like. Nevertheless it also provides us a “Carz.xcdatamodeld” file, which we won’t need as a result of we’ll use the model that’s found in CarKit. Remove the “Carz.xcdatamodeld” file that Xcode supplies for you:
Acquire framework Bundle Identifier
Talking of utilizing the CarKit Core Data mannequin, we’re now ready to configure that piece of the app. To do that half, you’ll need to know the Bundle Identifier from your framework challenge. To seek out out what it is, bounce again over to the framework venture, click the top-level node within the venture navigator, click on on the framework goal identify, and look underneath the Basic tab of the venture configuration. There you’ll discover the Bundle Identifier, which you’ll be able to copy to your clipboard:
Exchange managedObjectModel property initialization
Out of the box, Xcode generates some code to help locate your Core Data model file. The boilerplate managedObjectModel property appears like this:
lazy var managedObjectModel: NSManagedObjectModel =
Nevertheless, this gained’t work for us, as a result of we’re going to use the info model from CarKit, and CarKit is just not within the mainBundle(). For this reason we jumped over and copied the Bundle Identifier for CarKit in the earlier step. To find the info mannequin file in that bundle, you’ll substitute the managedObjectModel initialization step to the following (for CarKit):
lazy var managedObjectModel: NSManagedObjectModel =
let modelURL = carKitBundle!.url(forResource: “CarModel”, withExtension: “momd”)!
Recall that “CarModel” is the identify of the Core Data mannequin we created for the framework in CarKit. We simply search for that artifact by calling URLForResource:withExtension: on the carKitBundle to initialize an NSManagedObjectModel instance.
Add CarKit framework to undertaking and embed binary
Now it’s time to truly deliver in the framework for use inside our app. I sometimes open up a Finder window and drag over a copy of the framework (on this case, the CarKit.framework file) into my venture. Be happy to arrange it into a “lib” folder.
Assuming that you simply undergo all the required steps to make the framework production-ready, you’ll need to embed the binary and make sure that it’s referenced within the “Linked Frameworks and Libraries” portion of your undertaking configuration:
Taking the mannequin out for a check drive (pun meant)
It’s easy enough to attempt issues out by writing a simple little snippet of code within the AppDelegate:
func software(_ software: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool
// Override level for personalisation after software launch.
let newCar = NSEntityDescription.insertNewObject(forEntityName: “Car”, into: self.managedObjectContext!) as! Automotive
newCar.yr = 2015
newCar.make = “Tesla”
newCar.model = “S”
let fetchRequest = NSFetchRequest print(automobiles, terminator: “”) return true
let automobiles = (attempt! self.managedObjectContext?.fetch(fetchRequest)) as! [Car]
print(automobiles, terminator: “”)
This code simply obtains a new Automotive object, units some properties, and saves it all with the managedObjectContext occasion that’s configured within the AppDelegate.
Then it goes and performs a fetch request to grab all the Automotive objects and prints them. The results? See for your self:
This walkthrough guided you through the process of creating a framework for the aim of sharing a Core Data mannequin with multiple tasks. My hope is that you simply’re now empowered to make use of _re_use by using Swift frameworks to share even parts of your persistence layer!