element-ios/Riot/Modules/MatrixKit/Categories/NSString+MatrixKit.swift

60 lines
2.3 KiB
Swift

//
// Copyright 2024 New Vector Ltd.
// Copyright 2020 The Matrix.org Foundation C.I.C
//
// SPDX-License-Identifier: AGPL-3.0-only
// Please see LICENSE in the repository root for full details.
//
import Foundation
import MatrixSDK.MXLog
public extension NSString {
/// Gets the first URL contained in the string ignoring any links to hosts defined in
/// the `firstURLDetectionIgnoredHosts` property of `MXKAppSettings`.
/// - Returns: A URL if detected, otherwise nil.
@objc func mxk_firstURLDetected() -> NSURL? {
let hosts = MXKAppSettings.standard().firstURLDetectionIgnoredHosts ?? []
return mxk_firstURLDetected(ignoring: hosts)
}
/// Gets the first URL contained in the string ignoring any links to the specified hosts.
/// - Returns: A URL if detected, otherwise nil.
@objc func mxk_firstURLDetected(ignoring ignoredHosts: [String]) -> NSURL? {
guard let linkDetector = try? NSDataDetector(types: NSTextCheckingResult.CheckingType.link.rawValue) else {
MXLog.debug("[NSString+URLDetector]: Unable to create link detector.")
return nil
}
var detectedURL: NSURL?
// enumerate all urls that were found in the string to ensure
// detection of a valid link if there are invalid links preceding it
linkDetector.enumerateMatches(in: self as String,
options: [],
range: NSRange(location: 0, length: self.length)) { match, flags, stop in
guard let match = match else { return }
// check if the match is a valid url
let urlString = self.substring(with: match.range)
guard let url = NSURL(string: urlString) else { return }
// ensure the match is a web link
guard let scheme = url.scheme?.lowercased(),
scheme == "https" || scheme == "http"
else { return }
// discard any links to ignored hosts
guard let host = url.host?.lowercased(),
!ignoredHosts.contains(host)
else { return }
detectedURL = url
stop.pointee = true
}
return detectedURL
}
}