Core Data is an object graph and persistence framework provided by Apple in the macOS and iOS operating systems. It allows data organized by the relational entity–attribute model to be serialized into XML, binary, or SQLite stores. The data can be manipulated using higher level objects representing entities and their relationships. Core Data manages the serialized version, providing object lifecycle and object graph management, including persistence. Core Data interfaces directly with SQLite, insulating the developer from the underlying SQL.
But Core Data is not easy for beginners. I design the framework to simplify these core data operations. You only use simple API to storage data in database.
The framework design dabase interface by Protocol-oriented programming. Follow the design pattern of interface dependence.The framework is easy to replace with realm、FMDB... for realisation layer by Inversion of Control.
Add swift package by xcode. Follow apple develop document for Adding Package Dependencies to Your App
swift package init --type executable
modify Package.swift
file
let package = Package(
name: "YourPorject",
products: [
.executable(name: "YourPorject", targets: ["YourPorject"]),
],
dependencies: [
// "from" is git tag
.package(url: "https://github.com/animeng/SimpleCoreData.git",from:"0.0.2")
],
targets: [
// Targets are the basic building blocks of a package. A target can define a module or a test suite.
.target(
name: "YourPorject",
dependencies: ["SimpleCoreData"]),
]
)
swift build
swift run
First you need create YourDatabase.xcdatamodeld
file and use the code to create dababase.
let database = CoreDataStorage(objectModelName: "YourDatabase", fileName: "testDatabase",bundle:nil)
if you use the framework only for ios 13.0 and you can use it by follows.
let database:some Storage = DBFactory.openDB(objectModelName: "YourDatabase", dbName: "testDatabase")
Detailed usage for reference SimpleCoredataExample
You need add entity in coredata model. Add Person
model and select model to codegen class definiton
extension Person {
public override var primeKey: String {
return self.uid ?? ""
}
}
Then you can insert data for Person
model
let user:Person = try! self.database.context.create()
user.name = "Andy"
database.context.saveData()
Fetch data from main thread
let request = FetchRequest<Person>(database.context).sorted(with: "name", ascending: true)
let filter = NSPredicate(format: "name = %@", name)
let result = try? database.context.fetch(request.filtered(with: filter))
print(result?.first)
Fetch data from background thread
self.database.backgroundOperation({ (context, _) in
let request = FetchRequest<Person>(context).sorted(with: "name", ascending: true)
let result = try? context.fetch(request)
print(result)
}) { (hasError) in
print(hasError?.localizedDescription ?? "error")
}
First you need query data by condition and remove
data by follows
if let result = fetchInMainThread(name: name) {
try database.context.remove(result)
try database.context.saveData()
}
You can Observer data changed by simple API.
let observal:CoreDataObservable<Person>? = CoreDataObservable<Person>(context: database.mainContext)
observal?.observer({ (persons) in
for person in persons {
switch person{
case .insert(let content):
print(content)
default:
break
}
}
})
Great than or equal to iOS 13.0
let observal = DBFactory.addObserver(database,type:Person.self)
observal.observer { (persons) in
for person in persons {
switch person{
case .insert(let content):
print("Insert: \(content)")
case .delete(let content):
print("Delete: \(content)")
case .update(let content):
print("Update: \(content)")
default:
break
}
}
}
You can open the example and refer to the explanation. The file structure is as follows:
SimpleCoreDataExample
├── Sources
│ └── SimpleCoreDataExample
│ ├── AppDelegate.swift
│ ├── SceneDelegate.swift
│ └── ViewController.swift
└── Package.swift
The framework has some issue and cann't be solved. The coredata object can not use relation object.
Entity method syncDictionary
only analysis simple object and cann't sync associate relation object. For example:
department:
{"name":"IT","office":"3-403"}
person:
{"name":"Lucas","job":"engineer","Department":{"name":"IT","office":"3-403"}}
use 'syncDictionary' and cann't analysis Department in person
@munger