Contents

dataDetectorMatches(_:options:)

Searches for known data types in a string or a substring.

Declaration

func dataDetectorMatches(_ types: DataDetector.MatchType = .all, options: DataDetector.Options = DataDetector.Options()) -> some AsyncSequence<DataDetector.Match, Never>

Parameters

  • options:

    The DataDetector.Options to customize the search.

Return Value

An AsyncSequence of DataDetector/Match objects that match the provided string.

Discussion

DataDetection only searches for known data types in natural language text. There’s no guarantee that the framework can find a particular matching string in the data, especially in ambiguous cases. The scanner expects an input string in a person’s language and region, if supported. However, the framework may consider some additional languages and regions. Don’t use this functionality to validate form inputs such as email addresses, postal addresses, URLs, and so on.

The following example functions show how to scan for email addresses, links, calendar events, and measurements in strings.

import DataDetection

/// Returns the number of emails from example.com in the provided string.
func countExampleEmails(text: String) async -> Int {
    var countExampleEmails: Int = 0
    for await match in text.dataDetectorMatches([.emailAddress]) {
        if case let .emailAddress(email) = match.details {
            if email.emailAddress.hasSuffix("@example.com") {
                countExampleEmails += 1
            }
        }
    }
    return countExampleEmails
}

/// Returns an attributed string that highlights links, calendar events, and measurements the data detection finds in the provided string.
func underline(text: String) async -> AttributedString {
    var attributedText = AttributedString(text)
    for await match in text.dataDetectorMatches([.link, .calendarEvent, .measurement]) {
        if let range = match.range, let attributedRange = Range(range, in: attributedText) {
            var attributes = AttributeContainer ()
            switch match.preferredHighlightStyle {
            case .hidden:
                continue
            case .url:
                attributes.underlineColor = .linkColor
            default:
                let color = attributedText[attributedRange].foregroundColor ?? .textColor
                attributes.underlineColor = color.withAlphaComponent(0.26)
            }
            attributedText[attributedRange].mergeAttributes(attributes, mergePolicy: .keepNew)
        }
    }
    return attributedText
}