Телефонные номера, обнаруженные с помощью NSDataDetector, не могут быть открыты с помощью openURL
Хорошо я пользуюсь NSDataDetector
для определения телефонных номеров, как это:
func matchesFor(type: NSTextCheckingResult.CheckingType) -> [String] {
do {
let nsstring = self as NSString
let detector = try NSDataDetector(types: type.rawValue)
let matches = detector.matches(in: self, options: [], range: NSRange(location: 0, length: nsstring.length))
return matches.map { nsstring.substring(with: $0.range) }
} catch {
return []
}
}
и он находит цифры. Но затем я пытаюсь открыть эти цифры следующим образом:
func makeACall(phoneNumber: String) {
if let url = URL(string: "tel://\(phoneNumber)"), UIApplication.shared.canOpenURL(url) {
UIApplication.shared.openURL(url)
}
}
и это не работает. Зачем?
Пример, который я имею в виду:
+48 576-786-987
Должен ли я что-то сделать с этим номером, чтобы использовать его для звонка?
2 ответа
Как сказал Юнь Чэнь, пробел - недопустимый символ в URL-адресе телефона.
Если вы используете URLComponents()
вместо URL(string:)
тогда все символы автоматически экранируются при необходимости. Пример:
let phoneNumber = "+48 576-786-987"
var urlcomps = URLComponents()
urlcomps.scheme = "tel"
urlcomps.host = phoneNumber
if let url = urlcomps.url, UIApplication.shared.canOpenURL(url) {
print("Calling:", url.absoluteString) // Calling: tel://+48%20576-786-987
UIApplication.shared.openURL(url)
}
Обратите внимание, что NSTextCheckingResult
имеет дополнительный phoneNumber
свойство, которое устанавливается при обнаружении телефонных номеров. Поэтому вы можете немного упростить код
extension String {
func phoneNumbers() -> [String] {
let detector = try! NSDataDetector(types: NSTextCheckingResult.CheckingType.phoneNumber.rawValue)
let matches = detector.matches(in: self, range: NSRange(location: 0, length: utf16.count))
return matches.flatMap { $0.phoneNumber }
}
}
NSDataDetector(types:)
может произойти сбой только для недопустимого типа, что может быть ошибкой программирования. Поэтому принудительная попытка здесь приемлема.