One of the news of iOS8 is that we can now simply create framework to separate, organize and reuse our code (it wasn’t impossible before but it was more complex).
In some simple steps we will see how to create a version of our PopDatePicker (see A simple iOS PopDatePicker) built as a separate framework.
Create the workspace
In XCode create a new workspace named “PopDatePickerWorkSpace”
Then add to it the project PopDatePickerApp of the previous article:
Now you have a workspace containing one project:
Create the framework
Now create a new project from the template “Cocoa Touch Framework”:
Click Next:
And then tell XCode to add the new project to the Workspace PopDatePickerWorkSpace, Group: PopDatePickerWorkSpace.
Now your workspace should appear as in the figure:
Move the code
Then we must move all the code related to the PopDatePicker widget inside the new framework. Drag and drop the 3 files:
- PopDatePicker.swift
- PopDateViewController.swift
- PopDateViewController.xib
from the project PopDatePickerApp to the PopDatePicker project:
Then delete them from the PopDatePickerApp project:
Include the framework in the app
Select the target of the app (PopDatePickerApp) and in the tab “General” section “Embedded Binaries” click the “+” button to add the framework PopDatePicker to the app:
At the top of the ViewController.swift file in the app add the import command:
1 |
import PopDatePicker |
And then … crash!
If you clean the project, start the app and tap on the date text field the app … just crashes! Why?
The error is:
1 |
'NSInternalInconsistencyException', reason: 'Could not load NIB in bundle: 'NSBundle <...> (loaded)' with name 'PopDateViewController' |
Remember the line to load the Xib file in PopDateViewController.swift?
1 2 3 4 |
override convenience init() { self.init(nibName: "PopDateViewController", bundle: nil) } |
The nil parameter says: “search this Xib in the main bundle”. But now we are in a separate bundle, not the main!
The Fix
To fix the bug just indicate that the Xib is in our sub-bundle, the one with bundle identifier “it.tabasoft.PopDatePicker”:
1 2 3 |
let frameworkBundleID = "it.tabasoft.PopDatePicker" let frameworkBundle = NSBundle(identifier: frameworkBundleID) self.init(nibName: "PopDateViewController", bundle: frameworkBundle) |
And the bug is fixed.
Compatibility
Probably we don’t want to use frameworks if we deploy also for iOS7. But, just in case, begin to know them waiting for the moment we will drop iOS7 compatibility (not so near future).
The code of the entire project, as usual, can be found in my GitHub Repository.
Downloaded from github, give error at import PopDatePicker – No such module ‘PopDatePicker’
Which version of XCode are you using? And note that it is a workspace. You have to open the PopDatePickerWorkSpace.xcworkspace file (not the xcodeproj inside folders).
Very helpful. Thanks!
Now that I’ve done both of these tutorials, how do I implement and use the PopDatePicker?