MKDataDetector 3.0.0

MKDataDetector 3.0.0

测试已测试
语言语言 SwiftSwift
许可 MIT
发布时间最后发布时间2019年6月
SPM支持 SPM

Mayank Kumar 维护。



  • Mayank Kumar 和 Jeet Parte 编写。

Header

MKDataDetector

Build Status Platform badge

Swift 中自然语言文本数据检测的简单便利包装,用于组织数据提取和处理。

用途

MKDataDetector 简化了 NSDataDetector 并在此基础上增加了有效使用信息的功能。

要求

  • Swift 3.1+
  • macOS 10.9+
  • iOS 8.0+

安装

有多种安装选项可供选择。

CocoaPods (推荐)

要通过CocoaPods安装,请将以下行添加到您的 Podfile

pod 'MKDataDetector'

Carthage

要通过Carthage安装,请将以下行添加到您的 Cartfile 中,并包含您可能希望使用的框架特定版本

github "mayankk2308/mkdatadetector-swift"

手动

  1. 在您的项目目录中创建一个子模块: git submodule add https://github.com/mayankk2308/mkdatadetector-swift.git
  2. 打开子模块目录,并将 .xcodeproj 文件拖入您的项目。
  3. MKDataDetector.framework 添加到您的目标配置文件的 链接二进制与应用程序库 构建阶段
  4. 现在,您可以通过导入框架来使用该框架。

使用说明

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

地址和交通信息的结果是结构(),通过AddressInfoTransitInfo别名。使用与关联字典键关联的《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 文本嵌入在一个名为 meetingLabelUILabel 中。它还被扩展以添加 " 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 中提供了此键

联系

您可以联系

有关任何咨询或社区相关的问题。

许可证

本项目可在 MIT 许可证下使用。