Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/117.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios Swift中的URL验证_Ios_Swift - Fatal编程技术网

Ios Swift中的URL验证

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]*)|([-|_])*)+([\\.|/]

在我的Swift iOS项目中,我想在请求服务器之前检查url是否有效。我在前面的Objective C代码中检查了许多元素,如www、http、https等,以验证url是否正确。我们有类似的Swift代码吗

我期待像这样的Obj C方法

 - (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
return
false.