MKDataDetector
Swift 中自然语言文本数据检测的简单便利包装,用于组织数据提取和处理。
用途
MKDataDetector
简化了 NSDataDetector
并在此基础上增加了有效使用信息的功能。
要求
- Swift 3.1+
- macOS 10.9+
- iOS 8.0+
安装
有多种安装选项可供选择。
CocoaPods (推荐)
要通过CocoaPods安装,请将以下行添加到您的 Podfile
pod 'MKDataDetector'
Carthage
要通过Carthage安装,请将以下行添加到您的 Cartfile 中,并包含您可能希望使用的框架特定版本
github "mayankk2308/mkdatadetector-swift"
手动
- 在您的项目目录中创建一个子模块:
git submodule add https://github.com/mayankk2308/mkdatadetector-swift.git
- 打开子模块目录,并将 .xcodeproj 文件拖入您的项目。
- 将 MKDataDetector.framework 添加到您的目标配置文件的 链接二进制与应用程序库 构建阶段。
- 现在,您可以通过导入框架来使用该框架。
使用说明
MKDataDetectorService
作为一组扩展被打包,以隔离开其以下功能
- 日期 - 日期提取
- 地址 - 地址提取
- 链接 - 链接提取
- 电话号码 - 电话号码检测
- 交通信息 - 飞行信息提取等
除了提取这些功能外,该框架还提供了便利的函数来操作和组织这些数据。
要导入和使用 MKDataDetectorService
类,请在您的 .swift
文件中添加以下语句
import MKDataDetector
您可以将基本功能作为 String
的扩展来使用
let testString: String = "sampleText"
// extract Dates
if let dates: [Date] = testString.dates {
print(dates)
}
// extract Links
if let links: [URL] = testString.links {
print(links)
}
类似的扩展还包括地址、交通和电话号码。为了获得更多相关信息,您可能需要初始化服务。
初始化
您可以这样声明实例
let dataDetectorService: MKDataDetectorService = MKDataDetectorService()
结果处理
返回一个通用的AnalysisResult
结构集用于提取/分析结果。还包括一个名为ResultType
的枚举,用于识别结果。
AnalysisResult
包含5个字段
- 源(《source》)- 检测到的数据来源/原始完整的《String》字符串
- 匹配范围(《rangeInSource》)- 匹配字符串在原始字符串中的《NSRange》范围
- 数据字符串(《dataString》)- 匹配的《data》子字符串
- 数据类型(《dataType》)- 返回数据的《ResultType》类型
- 数据(《data》)- 从源输入中提取的《T》数据
通用结构对每种结果类型都有一个typealias
DateAnalysisResult
- 用于《AnalysisResult》 URLAnalysisResult
- 用于《AnalysisResult》 AddressAnalysisResult
- 用于《AnalysisResult》 PhoneNumberAnalysisResult
- 用于《AnalysisResult》 TransitAnalysisResult
- 用于《AnalysisResult》
地址和交通信息的结果是结构(),通过
AddressInfo
和TransitInfo
别名。使用与关联字典键关联的《Address》和《Transit》结构,信息查找变得简单。例如,要访问提取的地址中的邮编,只需使用键Address.zip
。
实现
要从某些文本(《String》)中提取日期
if let results = dataDetectorService.extractDates(withTextBody: sampleTextBody) {
for result in results {
print(result.source)
print(result.data)
// do some stuff
}
}
对于给定的《textBody》,dataDetectorService
返回一个DateAnalysisResult
对象的数组。
要从多个文本源(《[String]》)中提取日期
if let combinedResults = dataDetectorService.extractDates(withTextBodies: [sampleText, sampleText, ...]) {
for individualResults in combinedResults {
for result in individualResults {
print(result.source)
print(result.data)
// do some stuff
}
}
}
对于给定的《textBodies》,dataDetectorService
返回一个[DateAnalysisResult]
对象的数组。
提取过程对其他类型的数据特征(如电话号码、地址、链接等)也是一致的。
在需要使用多个ResultType
进行检测的情况下,可以使用以下实现
if let results = dataDetectorService.extractInformation(fromTextBody textBody: String, withResultTypes: .date, .address ...) {
for result in results {
switch result.dataType {
case .date:
// force cast as DateAnalysisResult - create and save events, etc.
case .address:
// force cast as AddressAnalysisResult - get location, etc.
.
.
// for all result types you are concerned with, i.e, your input parameters
}
}
}
还包括从多个文本体中提取多个类型的一个实现。
其他功能
MKDataDetector
还提供方便的辅助函数来使用检测到的信息。
要从有效的《String》地址中检索精确的《location information》
dataDetectorService.extractLocation(fromAddress: sampleText) { location in
if extractedLocation = location {
// CLLocation object available, requires importing 'CoreLocation'
}
}
或者,如果您已经有了《AddressAnalysisResult》
dataDetectorService.extractLocation(fromAnalysisResult: sampleAnalysisResult) { location in
if extractedLocation = location {
// CLLocation object available, requires importing 'CoreLocation'
}
}
对于《calendar integration》,您可以从《DateAnalysisResult》轻松创建《EKEvent》。
let event: EKEvent = dataDetectorService.generateEvent(fromEventStore: sampleEventStore, withAnalysisResult: sampleResult)
有一个名为 withEndDate 的参数未在上图中显示,该参数是可选的。未提供值的情况下,事件默认在一个小时后结束。
还有一个更通用的事件生成器可以使用,如果需要100%的事件命名一致性,可能会更受欢迎。需要对从 DateAnalysisResult
对象中自动处理事件名称进行更多测试。
给定一组检索到的 AnalysisResult<T>
(任何提取操作的默认结果类型),您可以生成 彩色属性文本
if let attributedText = dataDetectorService.attributedText(fromAnalysisResults: sampleResults, withColor: UIColor.blue.cgcolor) {
// set UI component
}
未来版本中将包含更多便利功能。
示例
考虑以下输入
let meeting: String = "Meeting at 9pm tomorrow"
let party: String = "Party next Friday at 8pm"
使用 dataDetectorService
提取日期,我们为 meeting
获得了以下输出
source
= "Meet at 9pm tomorrow"sourceInRange
= 匹配 "at 9pm tomorrow" 的NSRange
dataString
= 匹配子串 "at 9pm tomorrow"data
= 相应的Date
对象,指定相对于设备当前日期/时间的源日期
对于 party
,输出类似
source
= "Party next Friday at 8pm"sourceInRange
= 匹配 "next Friday at 8pm" 的NSRange
dataString
= 匹配子串 "next Friday at 8pm"data
= 相应的Date
对象,指定相对于设备当前日期/时间的源日期
对于其他类型的数据特征,输出格式也将统一,其中 data
字段在每个情况下都返回适当类型的对象。
您可以轻松地使用这些数据,例如,通过生成一个事件
let meetingEvent = dataDetectorService.generateEvent(withEventStore: someEventStore, withAnalysisResult: meetingAnalysisResult)
// creates an event detailing a meeting for 9pm tomorrow, lasting an hour
let partyEvent = dataDetectorService.generateEvent(withEventStore: someEventStore, withAnalysisResult: partyAnalysisResult)
// creates an event detailing a party at 8pm next Friday, lasting an hour
假设 meeting
文本嵌入在一个名为 meetingLabel
的 UILabel
中。它还被扩展以添加 " and next Friday at 5pm"。您可以更新标签以显示检测到的文本的多个部分
if let attributedText = dataDetectorService.attributedText(withAnalysisResults: meetingAnalysisResult, withColor: UIColor.purple.cgcolor) {
meetingLabel.attributedText = attributedText
}
meetingLabel
现在将以紫色(此处加粗)显示原始文本和检测到的信息:"Meet at 9pm tomorrow and next Friday at 5pm"。
限制
Apple 的 NSDataDetector
文档指出,该类目前可以匹配日期、地址、链接、电话号码和交通信息,但不能匹配其他现有属性,如语法和拼写。
此外,NSDataDetector
也不检测
- 地址的 名称、职位、组织 与 电话号码 组件,尽管原始 API 中提供了相同的键
- 交通信息的 航空公司名称 组件,尽管原始 API 中提供了此键
联系
您可以联系
- Mayank Kumar - 通过 电子邮件 或 LinkedIn
- Jeet Parte - 通过 电子邮件
有关任何咨询或社区相关的问题。
许可证
本项目可在 MIT 许可证下使用。