A Framework to extend NSPersistentContainer with preloaded SQLite data. This supports both macOS for build phase and iOS for runtime.
- Preload multple records at build phase, then provide search experience to customers
Using Carthage:
$ cat Cartfile
github "riywo/PreloadedPersistentContainer"
$ carthage update
*** Fetching PreloadedPersistentContainer
*** Checking out PreloadedPersistentContainer at "v0.1.0"
*** xcodebuild output can be found in /var/folders/29/mmyrpb0d5g39glgdcv9x4z780000gn/T/carthage-xcodebuild.PBBnLr.log
*** Building scheme "PreloadedPersistentContainer iOS" in PreloadedPersistentContainer.xcodeproj
*** Building scheme "PreloadedPersistentContainer macOS" in PreloadedPersistentContainer.xcodeprojNow, you can use Framework:
./Carthage/Build
├── Mac
│ ├── PreloadedPersistentContainer.framework
│ └── PreloadedPersistentContainer.framework.dSYM
└── iOS
├── PreloadedPersistentContainer.framework
└── PreloadedPersistentContainer.framework.dSYM
File -> New -> Target -> macOS Command Line Tool
Add to Linked Frameworks and Libraries
Open file -> Show the File inspector (right pane) -> Check macOS CLI in Target Membership
4. Edit scheme of iOS App to add macOS CLI into its build targets before iOS App. Uncheck Parallelize Build.
Product -> Scheme -> Manage Schemes -> Edit Your iOS scheme -> Build -> Add macOS CLI -> Move it before iOS App -> Uncheck Parallelize Build
Open Buid Phases of your iOS App target -> Add Run script -> Move it after Compile Sources -> Paste command below
${BUILT_PRODUCTS_DIR}/../${CONFIGURATION}/YourMacOSCLIFramework with CLI is tricky. It requires additional steps to load Framework. See How to add a dynamic Swift framework to a Command Line Tool
In summary, because Swift stdlibs are already embedded in macOS Framework, you only need to do the steps below:
- Add
Runpath Search Paths$(PROJECT_DIR)/Carthage/Build/Mac/(to find Framework itself)$(PROJECT_DIR)/Carthage/Build/Mac/PreloadedPersistentContainer.framework/Versions/Current/Frameworks(to find Swift stdlibs)
- Add
User-Definedto dynamically link Swift stdlibsSWIFT_FORCE_DYNAMIC_LINK_STDLIB=YESSWIFT_FORCE_STATIC_LINK_STDLIB=NO
If this CLI runs on build phase of iOS App, it preloads SQLite files in you iOS App main bundle (Your.app/YourModel.sqlite*).
import CoreData
import PreloadedPersistentContainer
let container = NSPersistentContainer(name: "YourModel")
container.loadPersistentStoresWithPreload { (storeDescription, error) in
if let error = error {
fatalError("Failed to load store: \(error)")
}
}
let entity = YourEntity(context: container.viewContext)
entity.id = 1
try! container.viewContext.save()Maybe in AppDelegate.swift, replace loadPersistentStores() with loadPersistentStoresWithPreload().
Then, the bundled SQLite files (Your.app/YourModel.sqlite*) will be automatically read.
import CoreData
import PreloadedPersistentContainer
lazy var persistentContainer: NSPersistentContainer = {
let modelName = "YourModel"
let container = NSPersistentContainer(name: modelName)
container.loadPersistentStoresWithPreload(completionHandler: { (storeDescription, error) in
if let error = error as NSError? {
fatalError("Unresolved error \(error), \(error.userInfo)")
}
})
return container
}()Have fun!
- Creating Swift frameworks for iOS, OS X and tvOS with Unit Tests and Distributing via CocoaPods and Swift Package Manager
- Core Data: How to Preload Data and Use Existing SQLite Database
- Core Data: Automate master data preloading - The Cookbook
- How to add a dynamic Swift framework to a Command Line Tool