PredicateFlow
编写令人惊叹的、强类型且易于阅读的NSPredicate。这个库允许你编写可流动的NSPredicate,而无需猜测属性名称、谓词操作或编写错误的参数类型。
支持的平台
- iOS 9.0+
- macOS 10.9+
- tvOS 9.0+
- watchOS 2.0+
安装
CocoaPods实际上是安装它的唯一方式。
Cocoapods
需要CocoaPods 0.39.0+版本来编译此库
-
在你的Podfile中添加
pod 'PredicateFlow'
并运行pod install
-
在Xcode中,点击文件列表中的你的项目,选择
TARGETS
下的目标,点击Build Phases
标签,然后点击左上角的加号创建一个新的Run Script
阶段 -
将新的
Run Script
阶段拖到Compile Sources
阶段之上和Check Pods Manifest.lock
之下,展开并粘贴以下脚本"$PODS_ROOT/Sourcery/bin/sourcery" --sources "$PODS_ROOT/PredicateFlow/PredicateFlow/Classes/Utils/" --sources "$SRCROOT" --templates "$PODS_ROOT/PredicateFlow/PredicateFlow/Templates/PredicateFlow.stencil" --output "$SRCROOT/PredicateFlow.generated.swift"
如果您正在使用 PredicateFlow-Realm,请替换上面的脚本为以下脚本
"$PODS_ROOT/Sourcery/bin/sourcery" --sources "$PODS_ROOT/PredicateFlow/PredicateFlow/Classes/Utils/" --sources "$SRCROOT" --sources "$PODS_ROOT/RealmSwift" --templates "$PODS_ROOT/PredicateFlow/PredicateFlow/Templates/PredicateFlow-Realm.stencil" --output "$SRCROOT/PredicateFlow.generated.swift"
仅限 Xcode 10,添加一个新的
输出文件
并粘贴以下内容$SRCROOT/PredicateFlow.generated.swift
-
构建您的项目。在 Finder 中,您现在将在
$SRCROOT
文件夹中看到一个PredicateFlow.generated.swift
文件,将PredicateFlow.generated.swift
文件拖入您的项目中,并取消勾选 如果需要则复制项目
提示: 将 *.generated.swift
模式添加到您的 .gitignore
文件中,以防止不必要的冲突。
用法
定义一个具有自身属性的类/结构体,实现 PredicateSchema
import PredicateFlow
class Dog: PredicateSchema {
private var name: String = ""
private var age: Int = 0
private var isHungry: Bool = false
private var owner: Person?
}
class Person: PredicateSchema {
enum Sex {
case male
case female
}
private var name: String = ""
private var birth: Date?
private var sex: Sex!
private var dogs: [Dog] = []
}
构建项目。PredicateFlow 将自动生成属性引用以构建谓词,并将它们放在结构体中。
// Generated using Sourcery 0.10.0 — https://github.com/krzysztofzablocki/Sourcery
// DO NOT EDIT
import PredicateFlow
/// The "Dog" Predicate Schema
internal struct DogSchema: GeneratedPredicateSchema {
private var compoundFieldBuilder: CompoundFieldBuilder
/// DO NOT USE THIS INIT DIRECTLY!
internal init(compoundFieldBuilder: CompoundFieldBuilder) {
self.compoundFieldBuilder = compoundFieldBuilder
}
/// "name" property
internal var name: StringPredicateProperty { return builder.string("name") }
/// "name" property for static access
internal static var name: StringPredicateProperty { return DogSchema().name }
// Other properties of Dog class autogenerated...
}
/// The "Person" Predicate Schema
internal struct PersonSchema: GeneratedPredicateSchema {
private var compoundFieldBuilder: CompoundFieldBuilder
/// DO NOT USE THIS INIT DIRECTLY!
internal init(compoundFieldBuilder: CompoundFieldBuilder) {
self.compoundFieldBuilder = compoundFieldBuilder
}
/// "name" property
internal var name: StringPredicateProperty { return builder.string("name") }
/// "name" property for static access
internal static var name: StringPredicateProperty { return PersonSchema().name }
// Other properties of Person class autogenerated...
}
要编写可流畅的 NSPredicate,只需写下
DogSchema.age.isEqual(10).query()
// or
// Vanilla mode:
// NSPredicate("age == %@", 10)
您也可以编写复合谓词,并使用深层字段
PredicateBuilder(DogSchema.age > 10)
.and(DogSchema.isHungry.isTrue)
.and(DogSchema.age.between(1, 10))
.and(DogSchema.owner.element().name == "Foo")
.or(DogSchema.owner.element().dogs.maxElements().age > 10)
.or(DogSchema.owner.element().dogs.anyElements().name == "Foo")
.build()
// Vanilla mode:
// NSPredicate("age > %@ AND isHungry == %@ AND age BETWEEN %@ AND owner.name == %@ OR [email protected] > %@ OR ANY owner.dogs.name == %@", 10, true, [1, 10], "Foo", 10, "Foo")
PredicateFlow 还可以构建 KeyPaths,您可以将其用作强类型之一。
DogSchema.age.keyPath()
DogSchema.owner.element().dogs.keyPath()
// Vanilla mode:
// "age"
// "owner.dogs"
PredicateFlow/Realm
如果您想在 Realm 中使用可流畅的和强类型的查询,请在您的 Podfile 中添加 两者 pod 'PredicateFlow'
和 pod 'PredicateFlow/Realm'
,然后运行 pod install
。
let realm = try! Realm()
realm.objects(Dog.self)
.filter(DogSchema.age.isGreater(than: 10))
.filter(DogSchema.isHungry.isTrue)
.sorted(DogSchema.age.ascending())
// Vanilla mode:
realm.objects(Dog.self)
.filter("age > %@", 10)
.filter("isHungry == %@", true)
.sorted("age", ascending: true)
贡献
PredicateFlow 是一个开源项目,因此欢迎贡献。您可以为问题或建议创建问题,并且您可以通过打开一个带有更改的 pull request 提议您自己的修复。
许可证
PredicateFlow 在 MIT 许可证下可用。有关更多信息,请参阅 LICENSE 文件。
致谢
此库由 Sourcery 支持。
作者
Andrea Del Fante, [email protected]