FilterKit 是一个用 Swift 编写的组件,让您可以根据字典中列出的一组属性验证或筛选对象。它受到 MapBox 样式规范 中filter 元素的启发。它确保了与 iOS、macOS、tvOS、watchOS 和 Linux 的兼容性。还有一个小的桥梁,可以启用完整的(现在)Objective-C 兼容性。
本章复制并稍作改编自原始 MapBox filter 文档。
过滤器从一个属性字典中选择了特定特征。过滤器指定为一个以下形式的数组
["has", key] feature[key] 存在["!has", key] feature[key] 不存在["==", key, value] 等于: feature[key] = value["!=", key, value] 不等于: feature[key] ≠ value[">", key, value] 大于: feature[key] > value[">=", key, value] 大于等于: feature[key] ≥ value["<", key, value] 小于: feature[key] < value["<=", key, value] 小于等于: feature[key] ≤ value["in", key, v0, ..., vn] 集合包含: feature[key] ∈ {v0, ..., vn}["!in", key, v0, ..., vn] 集合排除: feature[key] ∉ {v0, ..., vn}["all", f0, ..., fn] 逻辑与: f0 ∧ ... ∧ fn["any", f0, ..., fn] 逻辑或: f0 ∨ ... ∨ fn["none", f0, ..., fn] 逻辑或非: ¬f0 ∧ ... ∧ ¬fnkey 必须是一个标识特征属性的字符串。
value(以及集合运算符的 v0、...、vn)必须是一个 String、Int、Double 或 Bool,以将其与属性值进行比较。
集合成员过滤器是一种紧凑且高效的方法,用于检查一个字段是否与多个值中的任何一个匹配。
比较和集合成员过滤器实现强类型比较;例如,以下所有操作都返回false:0 < "1"、2 == "2"、"true" in [true, false]。
"all"、"any" 和 "none" 过滤运算符用于创建复合过滤器。值 f0 ..., fn 必须是过滤表达式本身。
以下过滤器要求 road 属性等于 "street_major"、"street_minor" 或 "street_limited"。
["in", "road", "street_major", "street_minor", "street_limited"]组合过滤器 "all" 接受随后的三个其他过滤器,并要求它们都必须为真才能包含一个功能:一个功能必须有一个等于 "street_limited" 的 road,其 admin_level 必须大于或等于 3,并且 paved 不能为 false 或 2。您可以将组合过滤器更改为 "any",以允许包含符合这些标准中的任何标准的功能。
[
"all",
["==", "road", "street_limited"],
[">=", "admin_level", 3],
["!in", "paved", false, 2]
]首先,将 FilterKit 模块导入您的 Swift 类中使用 import FilterKit 或 Objective-C 中的一个使用 @import FilterKit;。
然后使用表示为字典的期望属性实例化 Filter 对象。在实例上调用 compile() 函数,提供包含过滤器的数组。
do {
let result = try Filter(properties: ["foo":"bar"]).compile(["all", ["==", "foo", "bar"]])
print("Result: \(result)")
} catch let error {
print(error.localizedDescription)
}或在 Objective-C 中
FILFilter *filter = [[FILFilter alloc] initWithProperties:@{@"foo": @"bar"}];
NSError *error;
FILFilterResult *result = [filter compileWithFilters:@[@"all", @[@"==", @"foo", @"bar"]] error:&error];
if(error != nil) {
NSLog(@"%@", error);
}
NSLog(@"Result: %d", result.valid);如果您需要了解如何解析 JSON 文件,请参阅包含在 Tests/FilterKitTests 子文件夹中的 FilterKitTests.swift 文件中的
parseFixture(_ named: String)函数。
由于编译器的差异,某些条件基于 Swift 版本或平台返回不同的结果。这可能是边缘情况,不应导致任何行为问题,但您应知道它们的存在。
以下是迄今为止已识别出的情况
1.09 == true 只有在 Swift ≥ 4 时才返回 false。1 == 1.0 在 Linux 上返回 false,而在 Apple 的平台上返回 true。1 == true 在 Linux 上返回 false,而在 Apple 的平台上返回 true。将 FilterKit Xcode 项目添加到您自己的项目中。然后将所需的 FilterKit-PLATFORM 框架添加到您应用程序目标的嵌入式二进制文件中。
在现有的 Package.swift 文件中,将以下行添加到 dependencies 数组的成员中。
.Package(url: "https://github.com/dimensiosrl/FilterKit.git", majorVersion: 1),完整的版本应该如下所示
import PackageDescription
let package = Package(
name: "Your App Name",
targets: [],
dependencies: [
.Package(url: "https://github.com/dimensiosrl/FilterKit.git", majorVersion: 1),
.Package(url: "https://github.com/example/another-dependancy.git", majorVersion: 2),
]
)测试套件在平台和目标之间共享,位于 Tests 文件夹中。在 Fixtures 子子文件夹中有许多 json 文件,代表不同的场景,这些场景将被解析并进行测试。
要在 macOS 上运行测试,您可以使用 Xcode 或在终端中使用以下命令
xcodebuild -project FilterKit.xcodeproj -scheme "FilterKit macOS" -enableCodeCoverage YES clean build test如果您想测试 Linux 并已安装 Docker,只需运行
docker-compose up它将拉取最新的 ibmcom/swift-ubuntu 映像,将项目文件夹挂载为 /FilterKit 并执行 swift package clean; swift test。
在两种情况下,输出将直接显示在终端上。
FilterKit遵循MIT许可证发布。有关详细信息,请参阅LICENSE。