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。