Swift: check if UISearchBar.text contains a url

孤者浪人 提交于 2019-12-20 04:15:06

问题


How can I check if UISearchBar.text contains a URL? I thought of doing something like this:

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

}

but I get the error:

String is not convertible to NSObject

回答1:


With Swift 3, you can use NSDataDetector. NSDataDetector has an initializer called init(types:). init(types:) has the following declaration:

init(types checkingTypes: NSTextCheckingTypes) throws

Initializes and returns a data detector instance.

In order to create a data detector that finds urls, you have to pass NSTextCheckingResult.CheckingType.link as the parameter for init(types:).


#1. Using NSDataDetector and NSRegularExpression's enumerateMatches(in:options:range:using:) method

As a subclass of NSRegularExpression, NSDataDetector has a method called enumerateMatches(in:options:range:using:). enumerateMatches(in:options:range:using:) has the following declaration:

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

Enumerates the string allowing the Block to handle each regular expression match.

The Playground code below shows how to use NSDataDetector and enumerateMatches(in:options:range:using:) method in order to detect if a String contains URLs:

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. Using NSDataDetector and NSRegularExpression's matches(in:options:range:) method

As a subclass of NSRegularExpression, NSDataDetector has a method called matches(in:options:range:). matches(in:options:range:) has the following declaration:

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

Returns an array containing all the matches of the regular expression in the string.

This is a convenience method that calls enumerateMatches(in:options:range:using:) passing the appropriate string, options, and range.

The Playground code below shows how to use NSDataDetector and matches(in:options:range:) method in order to detect if a String contains URLs:

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)
 */



回答2:


I enhanced Imanou PETIT's anwser.

This allows you to extract multiple URL's from a string.

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
    }
}

An example usage:

var urls = text.extractURLs
for url in urls {  
     // do stuff with your URL        
     if UIApplication.sharedApplication().canOpenURL(url) {
         UIApplication.sharedApplication().openURL(url)
         break
     }
}


来源:https://stackoverflow.com/questions/25572850/swift-check-if-uisearchbar-text-contains-a-url

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!