Ios Swift中的URL验证
在我的Swift iOS项目中,我想在请求服务器之前检查url是否有效。我在前面的Objective C代码中检查了许多元素,如www、http、https等,以验证url是否正确。我们有类似的Swift代码吗 我期待像这样的Obj C方法Ios Swift中的URL验证,ios,swift,Ios,Swift,在我的Swift iOS项目中,我想在请求服务器之前检查url是否有效。我在前面的Objective C代码中检查了许多元素,如www、http、https等,以验证url是否正确。我们有类似的Swift代码吗 我期待像这样的Obj C方法 - (BOOL) validateUrl: (NSString *) candidate { NSString *urlRegEx = @"(http|https)://((\\w)*|([0-9]*)|([-|_])*)+([\\.|/]
- (BOOL) validateUrl: (NSString *) candidate {
NSString *urlRegEx =
@"(http|https)://((\\w)*|([0-9]*)|([-|_])*)+([\\.|/]((\\w)*|([0-9]*)|([-|_])*))+";
NSPredicate *urlTest = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", urlRegEx];
return [urlTest evaluateWithObject:candidate];
}
请提出建议。您可以使用该方法替换您的链接可能具有的任何特殊字符,然后您可以使用以下方法检查您的链接是否为有效url:
let link = "http://www.yourUrl.com".stringByRemovingPercentEncoding!.stringByAddingPercentEscapesUsingEncoding(NSUTF8StringEncoding)!
if let checkedUrl = NSURL(string: link) {
// you can use checkedUrl here
}
注意:NSURL(字符串:)仅用于Web链接。如果要为本地资源文件创建NSURL,则需要使用NSURL(fileURLWithPath:)我建议使用如下正则表达式。下面的模式对于url是正确的
let regex = NSRegularExpression(pattern: "/^(https?:\/\/)?([\da-z\.-]+)\.([a-z\.]{2,6})([\/\w \.-]*)*\/?$/",options: nil, error: nil)!
if regex.firstMatchInString(searchTerm!, options: nil, range: NSMakeRange(0, searchTerm!.length)) != nil {
println("not valid url ")
}
我对这里评级最高的答案有疑问。我认为这显然是错误的,原因有二: 首先,
stringByAddingPercentExcapedUsingEncoding
实际上会对有效URL进行双重编码,从而使其无效或至少与原始输入不同。如果输入字符串已经是正确编码的URL,那么您应该使用它
例如,http://foo.com/My%20Stuff/
将变为http://foo.com/My%2520Stuff/
这是不一样的。如果您将其馈送给NSURL,它实际上会将其解码为一个包含文本%
的URL
Second,NSURL
在识别错误输入方面非常糟糕。例如,当您给它一个类似x/3:()foo/blah
的东西时,它会愉快地返回一个非nil结果,这显然是错误的,并且不是有效的URL
我认为最好使用正则表达式。我认为没有任何基础可以正确地验证URL。 试试这个。
func validateUrl (urlString: String?) -> Bool {
let urlRegEx = "(http|https)://((\\w)*|([0-9]*)|([-|_])*)+([\\.|/]((\\w)*|([0-9]*)|([-|_])*))+"
return NSPredicate(format: "SELF MATCHES %@", urlRegEx).evaluateWithObject(urlString)
}
下面的代码检查了或,也检查了它,但如果没有http或https标记,它将无法工作。如果您错过了域名(本例中为谷歌),它将显示一个错误
func checkGivenUrl(userURL:String) -> Bool {
let userURL:String = userURL
do {
let checkReg = try NSRegularExpression(pattern: "(http|https)://([A-Z]|[a-z].)|([A-Z]|[a-z]|[0-9]+)*.([a-z]|[A-Z])", options: .CaseInsensitive)
if checkReg.firstMatchInString(userURL, options: .ReportCompletion, range: NSMakeRange(0, userURL.lengthOfBytesUsingEncoding(NSUTF8StringEncoding))) != nil {
if let url = NSURL(string: userURL) {
if UIApplication.sharedApplication().canOpenURL(url) {
return true
}
}
return false
}
}
catch
{
print("Error")
}
return false
}
函数调用如下
requestedURL = "http://google.com"
if checkGivenUrl(requestedURL!) == true {
performSegueWithIdentifier("gotoWebView", sender: self)
}
else{
let alert = UIAlertController(title: "Failed", message: "Enter a valid URL", preferredStyle: .Alert)
alert.addAction(UIAlertAction(title: "Dismiss", style: .Cancel, handler: nil))
self.presentViewController(alert, animated: true, completion: nil)
}
}
如果您发现任何不适合上述方法的测试用例,请进行评论。我将尝试解决它们:)我发现这很容易实现
func validateUrl() -> Bool {
let urlRegEx = "((\\w)*|([0-9]*)|([-|_])*)+([\\.|/]((\\w)*|([0-9]*)|([-|_])*))+"
return NSPredicate(format: "SELF MATCHES %@", urlRegEx).evaluate(with: self)
}
我觉得这很容易。如果你把它作为一个扩展或只是在课堂上,你可以说
func fooBar(textField: UITextField) {
if textField == someTextField {
if textField.text?.validateUrl() == true {
print("true")
} else {
print("false")
}
}
}
与其他答案非常相似tho,而且晚了几年
这不需要http部分,我觉得大多数用户不会像google.com或www.google.com那样麻烦地键入http或https
显然,你可以多做一点,检查他们是否放置了http,如果你真的想添加它,请自己添加。或者不添加,我有另一个解决方案。斯威夫特3
import Foundation
import UIKit
extension String {
var canOpenURL : Bool {
guard let url = NSURL(string: self) else {return false}
if !UIApplication.shared.canOpenURL(url as URL) {return false}
let regEx = "((https|http)://)((\\w|-)+)(([.]|[/])((\\w|-)+))+"
let predicate = NSPredicate(format:"SELF MATCHES %@", argumentArray:[regEx])
return predicate.evaluate(with: self)
}
}
它可以用作
if textField == someTextField {
if (self.textField.text?.canOpenURL)! {
//URL valid
}else {
//URL invalid
}
}
您可以使用正则表达式验证URL格式
(https?://(www.)?)?[-a-zA-Z0-9@:%._+~#=]{2,256}.[a-z]{2,6}b([-a-zA-Z0-9@:%_+.~#?&//=]*)
SWIFT 4:
func validateURL (urlString: String) -> Bool {
let urlRegEx = "(https?://(www.)?)?[-a-zA-Z0-9@:%._+~#=]{2,256}.[a-z]{2,6}b([-a-zA-Z0-9@:%_+.~#?&//=]*)"
let urlTest = NSPredicate(format:"SELF MATCHES %@", urlRegEx)
return urlTest.evaluate(with: urlString)
}
Swift 4.x 这涵盖了所有类型的验证,如子域,有或没有HTTP/HTTPS
func isValidUrl(url: String) -> Bool {
let urlRegEx = "^(https?://)?(www\\.)?([-a-z0-9]{1,63}\\.)*?[a-z0-9][-a-z0-9]{0,61}[a-z0-9]\\.[a-z]{2,6}(/[-\\w@\\+\\.~#\\?&/=%]*)?$"
let urlTest = NSPredicate(format:"SELF MATCHES %@", urlRegEx)
let result = urlTest.evaluate(with: url)
return result
}
希望这对您有用。Swift 5
由于上述解决方案在Swift 5中对我都不起作用,我最终为Swift 5编写了自己的正则表达式。这包括所有类型的验证,包括端口验证
func validateURL(url: String) -> Bool {
let regex = "http[s]?://(([^/:.[:space:]]+(.[^/:.[:space:]]+)*)|([0-9](.[0-9]{3})))(:[0-9]+)?((/[^?#[:space:]]+)([^#[:space:]]+)?(#.+)?)?"
let test = NSPredicate(format:"SELF MATCHES %@", regex)
let result = test.evaluate(with: url)
return result
}
这个简单的扩展使生活变得简单
extension String {
var isValidUrl: Bool {
let urlRegEx = "((?:http|https)://)?(?:www\\.)?[\\w\\d\\-_]+\\.\\w{2,3}(\\.\\w{2})?(/(?<=/)(?:[\\w\\d\\-./_]+)?)?"
return NSPredicate(format: "SELF MATCHES %@", urlRegEx).evaluate(with: self)
}
扩展字符串{
var Isvalidul:Bool{
让urlRegEx=“((?:http | https):/)(?:www\\)?[\\w\\d\\-\\+\\\.\\w{2,3}”)(/(?表示Swift 5.0
func validateUrl (urlString: String?) -> Bool {
let urlRegEx = "(http|https)://((\\w)*|([0-9]*)|([-|_])*)+([\\.|/]((\\w)*|([0-9]*)|([-|_])*))+"
return NSPredicate(format: "SELF MATCHES %@", urlRegEx).evaluate(with: urlString)
}
你以前做过什么?你也尝试过做同样的事情吗?我尝试过使用NSPredicate predicateWithFormat,但在Swift中无法实现。试试这个,嗨,我需要验证这个URL->h t p://192.168.1.146:8081/Myservelet/webserviceCea/?username=Stella请成员勾选解决问题的答案:-)你可能想解释一下rationale@Wain需要解释什么?NSURL已经进行了检查,并且只在给它一个有效字符串的情况下返回一个实例。不需要重新创建轮子。我没有说重新创建轮子,只需要描述它工作的原因,所以基本上你的注释在答案中。+1无论如何,但是解释增加了值。这是一个in回答正确。请参阅下面我的完整答案。此编译正确吗?它没有编译此代码。第1行中的生成错误-“行上的连续语句必须用分隔符分隔;"firebase.google.com返回false。你能帮我添加这个场景吗?你必须提到https://或http://然后它才会起作用。当我检查URL是否可以打开时需要协议。用Swift 5测试此代码,不幸的是stackoverflow.com.com
返回true
,而129.0.0.1
和ftp://129.0.0.1
returnfalse.