SwiftyData 0.1.1

SwiftyData 0.1.1

测试已测试
languages语言 SwiftSwift
许可证 MIT
发布上次发布2016 年 10 月
SPM支持 SPM

Ahmed Onawale维护。



SwiftyData

一个 Swift Core Data 包装器,提供用于与托管对象和托管对象上下文交互的便捷 API。

目录

要求

  • iOS 8.0+
  • Xcode 7+

安装

手动安装

如果您不希望使用上述任何一种依赖管理器,您可以将 SwiftyData 手动集成到项目中。

入门

使用 SwiftyData 在文件顶部导入 SwiftyData

import SwiftyData

class Person: NSManagedObject {
    @NSManaged var name: String
    @NSManaged var age: Int64
}

如果您的模型名称与您的类名称不同,您应该覆盖 NSManagedObjectentityName 属性,并返回类的模型名称。

extension Person {
    override class var entityName: String {
        return "Human"
    }
}

可选地,您可以采用和遵循 KeyCodeable 协议,这样您就可以使用枚举来表示您的属性,并确保类型安全。

extension Person: KeyCodeable {
    enum Key: String {
        case name
        case age
    }
}

创建

// Create a Person
let person = Person.create() // No casting needed, just create!
person.name = "Foo"
person.age = 18

// Or you can just create with properties:
let person = Person.create([.name: "Foo", .age: 18])

// You can also create multiple instances all at once.
let people = Person.bulkCreate([.name: "Foo", .age: 19],
                                [.name: "Bar", .age: 29],
                                [.name: "Baz", .age: 32])

使用 NSManagedObjectContext

let context = NSManagedObjectContext.defaultContext()
context.create(Person)
context.create(Person.self, properties: [.name: "Foo", .age: 18])

所有在 NSManagedObject 子类上可用的方法也都在 NSManagedObjectContext 上可用。不同之处在于上下文接受一个作为第一个参数的类名称,在它上执行操作。

获取和设置属性

// Returns a dictionary of [String: AnyObject]
person.get([.name, .age])

// Set properties to new value
person.set([.name: "Bar", .age: 20])

删除

// Deletes person
person.destroy()

// Deletes all Person
Person.destroyAll()

保存

将对象或对象保存到持久存储库中。如果保存成功返回True,否则返回False。如果没有需要保存的更改在NSManagedObjectContext中,也返回False

// Saves person
let person = Person.create()
person.save() // true
person.save() // false
person.name = "Foo"
person.save() // true

// Same as calling
Person.save()

重新加载

// Reloads person properties from the persistence store
let person = Person.create([.name: "Foo", .age: 18])
person.save()
person.set([.name: "Bar", .age: 20])
person.name // Baz
person.age // 20
person.reload()
person.name // Foo
person.age // 18

更新或插入

如果已经存在具有所提供属性的现有对象,则返回该对象,否则使用提供的属性创建一个新的对象。

Person.bulkCreate([.name: "Foo", .age: 19], [.name: "Bar", .age: 29])
Person.count() // returns 2
Person.upsert([.name: "Foo", .age: 19])
Person.count() // returns 2
Person.upsert([.name: "Baz", .age: 32])
Person.count() // returns 3

查找

// Find all Person
// Returns an array of all person
Person.findAll()

// Find by id
let id = person.objectID
Person.findById(id)

// Find by NSURL
let url = perosn.objectID.URIRepresentation()
Person.findByNSURL(url)

查找单个

// Finds one Person whose name is Foo
Person.findOne(where: [.name: "Foo"])

// You can a NSPredicate format string and arguments
// Finds one Person whose age is less than 20
Person.findOne(where: "age < %@", arguments: 20)

// Or you can just drop in a NSPredicate
// Finds one Person whose age is greater than 18
let predicate = NSPredicate(format: "age > 18")
Person.findOne(where: predicate)

查询

// Finds all Person less than 30 years old
let lessThan30 = Person.find(where: "age < 30")

// Finds Person named Foo that has age 18
let foo = Person.find(where: "name == %@ AND age == %@", arguments: "Foo", 18)

// Finds Person named Bar that has age 20
let bar = Person.find(where: [.name: "Bar", .age: 20])

// Finds all Person greater than 18 years old
let predicate = NSPredicate(format: "age > 18")
let greaterThan18 = Person.find(where: predicate)

排序

// Finds all Person and sort by name: ascending
Person.find(where: [:], sort: [.name: .ASC])

// You can pass in an array of NSSortDescriptor
// Finds all Person and sort by name and age
let byName = NSSortDescriptor(key: "name", ascending: false)
let byAge = NSSortDescriptor(key: "age", ascending: true)
let sorted = Person.find(where: "age > %@", arguments: 10, sort: [byName, byAge])

限制

// Finds and return just two Person
let justTwo = Person.find(where: "age > 10", limit: 2)

分页或偏移

Person.bulkCreate([.name: "Foo", .age: 19], [.name: "Bar", .age: 29], [.name: "Baz", .age: 32])

Person.save() // If context is not saved, the fetchOffset property of NSFetchRequest is ignored.

// Returns an array of Person object skipping the first two result
let skipTwo = Person.find(where: "age > %@", arguments: 10, skip: 2)

如果不在NSManagedObject子类上调用保存,则跳过的参数将被忽略。

批量处理

// Returns a proxy object array of Person that transparently faults batches on demand.
Person.find(where: "age > %@", arguments: 10, batchSize: 2)

聚合

// Counts and return the number of Person
Person.count()

// You can supply a query to narrow down the objects to count
Person.count(where: "age < 30")

// You can also do this if you conform to KeyCodeable protocol
Person.count(where: [.name: "Foo"])

批量更新

对于所有符合所提供查询的托管对象进行批量更新。返回类型为NSBatchUpdateRequestResultType,默认为StatusOnlyResultType。

// Updates all Person whose name begins with fo to Foo
Person.update(where: "name BEGINSWITH[cd] %@", arguments: "fo", with: [.name: "Foo"])

// You can specify a result type you prefer. Here we are
// specifying a result type which returns the number of updated objects
let updatedCount = Person.update(where: "age < 30", with: [.age: 30], resultType: .UpdatedObjectsCountResultType) as? Int

// You can supply a NSPredicate if you like.
let age = NSPredicate(format: "age == 30")
let name = NSPredicate(format: "name == %@", "Foo")
let predicate = NSCompoundPredicate(andPredicateWithSubpredicates: [age, name])
Person.update(where: predicate, with:[.name: "Bar", .age: 19])

对于批量更新需要遵守KeyCodeable协议。

自定义SwiftyData

默认情况下,SwiftyData会将项目中目录下所有扩展名为xcdatamodeld的Model文件合并。因此,不管你给模型命名什么,或者是否有多个模型文件,它们都将被找到。

如果您不希望这种行为,您可以在AppDelegate中明确设置SwiftyData要使用的模型文件名,并且只会使用这个文件。

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
    SwiftyData.sharedData.modelName = "MyModel"
    return true
}

您可以在从AppDelegate的application didFinishLaunchingWithOptions方法返回之前设置一个数据库名,如果您不想使用默认的应用程序名称。

SwiftyData.sharedData.databaseName = "MyDatabase"

如果您不介意使用默认的,您也可以在从application didFinishLaunchingWithOptions方法返回之前设置一个自定义的托管对象上下文。

let context = NSManagedObjectContext(concurrencyType: ...)
SwiftyData.sharedData.managedObjectContext = context

关系

创建对象关系与设置它们的属性一样简单。考虑以下示例:

class Employee: Person {
    @NSManaged var employmentDate: NSDate
    @NSManaged var department: Department?
}

extension Employee {
    enum Key: String {
        case name, age, employmentDate, department
    }
}

class Department: NSManagedObject {
    @NSManaged var name: String
    @NSManaged var employees: [Employee]
}

extension Department: KeyCodeable {
    enum Key: String {
        case name, employees
    }

    override class var entityName: String {
        return "Organization"
    }
}
let employee = Employee.create([.employmentDate: NSDate()])
let department = Department.create([.name: "Accounting", .employees: []])

employee.department // nil
department.employees.isEmpty // true

employee.department = department

employee.department // returns department
department.employees.isEmpty // false

employee.destroy()
employee.save()

department.employees.isEmpty // true

// You can supply related objects during initialization if you want
let employees = (1...20).map { Employee.create([.employmentDate: NSDate(timeIntervalSinceNow: NSTimeInterval($0))]) }
let department = Department.create([.name: "Health", .employees: employees])

department.employees.count // 20
Employee.find(where: "department == %@", arguments: department).count // 20

路线图

  • Realm支持
  • JSON支持

许可

SwiftyData遵循MIT许可。有关更多信息,请参阅LICENSE.md文件。