Swift: проверьте, содержит ли UISearchBar.text URL

Как я могу проверить, содержит ли UISearchBar.text URL-адрес? Я думал сделать что-то вроде этого:

if (searchBar.text == NSTextCheckingType.Link) {

}

но я получаю ошибку:

String is not convertible to NSObject

2 ответа

Решение

С Swift 3 вы можете использовать NSDataDetector, NSDataDetector имеет инициализатор под названием init(types:), init(types:) имеет следующую декларацию:

init(types checkingTypes: NSTextCheckingTypes) throws

Инициализирует и возвращает экземпляр детектора данных.

Чтобы создать детектор данных, который находит URL-адреса, вы должны передать NSTextCheckingResult.CheckingType.link в качестве параметра для init(types:),


#1. С помощью NSDataDetector а также NSRegularExpression "s enumerateMatches(in:options:range:using:) метод

Как подкласс NSRegularExpression, NSDataDetector имеет метод, называемый enumerateMatches(in:options:range:using:), enumerateMatches(in:options:range:using:) имеет следующую декларацию:

func enumerateMatches(in string: String, options: NSRegularExpression.MatchingOptions = [], range: NSRange, using block: (NSTextCheckingResult?, NSRegularExpression.MatchingFlags, UnsafeMutablePointer<ObjCBool>) -> Void)

Перечисляет строку, позволяющую блоку обрабатывать каждое совпадение регулярного выражения.

Код Playground ниже показывает, как использовать NSDataDetector а также enumerateMatches(in:options:range:using:) метод для того, чтобы обнаружить, если String содержит URL s:

import Foundation

let testString = " lorem http://www.yahoo.com ipsum google.fr"

do {
    let detector = try NSDataDetector(types: NSTextCheckingResult.CheckingType.link.rawValue)
    let range = NSRange(location: 0, length: testString.characters.count)
    let block = { (result: NSTextCheckingResult?, flags: NSRegularExpression.MatchingFlags, stop: UnsafeMutablePointer<ObjCBool>) -> Void in
        if let result = result, result.resultType == NSTextCheckingResult.CheckingType.link {
            print(result.url)
        }
    }
    detector.enumerateMatches(in: testString, options: [], range: range, using: block)
} catch {
    print(error)
}

/*
 prints:
 Optional(http://www.yahoo.com)
 Optional(http://google.fr)
 */

# 2. С помощью NSDataDetector а также NSRegularExpression "s matches(in:options:range:) метод

Как подкласс NSRegularExpression, NSDataDetector имеет метод, называемый matches(in:options:range:), matches(in:options:range:) имеет следующую декларацию:

func matches(in string: String, options: NSRegularExpression.MatchingOptions = [], range: NSRange) -> [NSTextCheckingResult]

Возвращает массив, содержащий все совпадения регулярного выражения в строке.

Это удобный метод, который вызывает enumerateMatches(in:options:range:using:) передавая соответствующую строку, параметры и диапазон.

Код Playground ниже показывает, как использовать NSDataDetector а также matches(in:options:range:) метод для того, чтобы обнаружить, если String содержит URL s:

import Foundation

let testString = " lorem http://www.yahoo.com ipsum google.fr"

do {
    let detector = try NSDataDetector(types: NSTextCheckingResult.CheckingType.link.rawValue)
    let range = NSRange(location: 0, length: testString.characters.count)
    let resultArray = detector.matches(in: testString, options: [], range: range)
    for result in resultArray {
        if result.resultType == NSTextCheckingResult.CheckingType.link {
            print(result.url)
        }
    }
} catch {
    print(error)
}

/*
 prints:
 Optional(http://www.yahoo.com)
 Optional(http://google.fr)
 */

Я улучшил Imanou PETITэто ответ.

Это позволяет вам извлекать несколько URL-адресов из строки.

extension String {
    var extractURLs: [NSURL] {
        var urls : [NSURL] = []
        var error: NSError?
        let detector = NSDataDetector(types: NSTextCheckingType.Link.rawValue, error: &error)

        var text = self

        detector!.enumerateMatchesInString(text, options: nil, range: NSMakeRange(0, count(text)), usingBlock: { (result: NSTextCheckingResult!, flags: NSMatchingFlags, stop: UnsafeMutablePointer<ObjCBool>) -> Void in
            //            println("\(result)")
            //            println("\(result.URL)")
            urls.append(result.URL!)
        })

        return urls
    }
}

Пример использования:

var urls = text.extractURLs
for url in urls {  
     // do stuff with your URL        
     if UIApplication.sharedApplication().canOpenURL(url) {
         UIApplication.sharedApplication().openURL(url)
         break
     }
}
Другие вопросы по тегам