Swift中的URL验证

时间:2015-03-17 17:38:16

标签: 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]*)|([-|_])*)+([\\.|/]((\\w)*|([0-9]*)|([-|_])*))+";
    NSPredicate *urlTest = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", urlRegEx]; 
    return [urlTest evaluateWithObject:candidate];
}

请建议。

12 个答案:

答案 0 :(得分:4)

您可以使用stringByAddingPercentEscapesUsingEncoding方法替换链接可能包含的任何特殊字符,然后您可以使用NSURL(string:)检查您的链接是否为有效网址,如下所示:

let link =  "http://www.yourUrl.com".stringByRemovingPercentEncoding!.stringByAddingPercentEscapesUsingEncoding(NSUTF8StringEncoding)!

if let checkedUrl = NSURL(string: link) {
    // you can use checkedUrl here
}

注意:NSURL(字符串:)仅适用于网络链接。如果要为本地资源文件创建NSURL,则需要使用NSURL(fileURLWithPath :)

答案 1 :(得分:4)

Swift 4.x

这涵盖了所有类型的验证,例如带有或不带有HTTP / HTTPS的子域

#include <vector>
#include <iostream>

struct xy
{

    std::size_t x, y;
};

constexpr std::size_t linear_extent(xy _)
{
    return _.y * _.x;
}

constexpr std::size_t linear_position(xy _, xy extent)
{
    return _.y * extent.x + _.x;
}

template<class T>
struct vector_2d
{
    vector_2d(xy size, T x = T())
    : extent_(size)
    , storage_(linear_extent(extent_), x)
    {

    }

    T& operator[](xy const& _)
    {
        return storage_[linear_position(_, extent_)];
    }

    T const& operator[](xy const& _) const
    {
        return storage_[linear_position(_, extent_)];
    }

    constexpr auto extent() const { return extent_; }

    xy extent_;
    std::vector<T> storage_;
};

template<class T>
std::ostream& operator<<(std::ostream& os, vector_2d<T> const& v)
{
    const char* sep = " [";
    os << "[";
    auto extent = v.extent();
    for(auto y = std::size_t(0) ; y < extent.y ; ++y)
    {
        os << sep;
        const char* sep2 = " ";
        for (auto x = size_t(0) ; x < extent.x ; ++x)
        {
            std::cout << sep2 << v[{x, y}];
            sep2 = ", ";
        }
        os << " ]";
        sep = "\n  [";
    }

    os << " ]";

    return os;
}


int main()
{
    auto v = vector_2d<int>({5, 5});
    v[{1, 3}] = 8;
    std::cout << v << std::endl;
}

希望这对您有用。

答案 2 :(得分:2)

试试这个。

func validateUrl (urlString: String?) -> Bool {
    let urlRegEx = "(http|https)://((\\w)*|([0-9]*)|([-|_])*)+([\\.|/]((\\w)*|([0-9]*)|([-|_])*))+"
    return NSPredicate(format: "SELF MATCHES %@", urlRegEx).evaluateWithObject(urlString)
}

答案 3 :(得分:1)

我的评分最高的答案在这里有问题。我认为这有两个原因:

首先stringByAddingPercentExcapedUsingEncoding实际上对有效网址进行编码,从而使其无效或至少与原始输入不同。如果输入字符串已经是正确编码的URL,那么您应该使用它。

例如,http://foo.com/My%20Stuff/将变为http://foo.com/My%2520Stuff/,但不一样。如果您将其提供给NSURL,它实际上会将其解码为包含文字%的网址。

第二NSURL在识别错误​​输入方面非常糟糕。例如,如果你给它x/3:()foo/blah这样的内容显然格式错误且不是有效的网址,那么它会愉快地返回一个非零结果。

我认为最好使用正则表达式。我认为 Foundation 中有任何可以正确验证网址的内容。

答案 4 :(得分:1)

我发现这很容易快速

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

非常类似于其他答案,而且已经很晚了

这不需要http部分,我觉得大多数用户都不会打扰输入http或https,例如http://www.google.com,而只是google.com或www.google.com

显然你可以加倍努力,检查他们是否做了http(s),如果你真的想添加它自己添加..或者不是

答案 5 :(得分:1)

雨燕5

由于上述解决方案均不适用于Swift 5,因此我最终为Swift 5编写了自己的REGEX。这涵盖了所有类型的验证,包括PORT

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
 }

答案 6 :(得分:1)

这种简单的扩展使生活变得轻松

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

}

答案 7 :(得分:0)

我建议使用这样的正则表达式。下面的模式对于网址是正确的。

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

答案 8 :(得分:0)

在对http://google.comhttp://www.google.com进行代码检查后,检查了http://9gag.com,但没有http或https标记,它无法正常工作。如果您错过了域名(在这种情况下为Google),则会显示错误。

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

如果您发现任何不适合上述方法的测试用例,请发表评论。我会尝试解决它们:)

答案 9 :(得分:0)

我有另一个解决方案。在Swift 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
    }
}

答案 10 :(得分:0)

您可以使用 Regex 来验证网址格式

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

答案 11 :(得分:0)

适用于 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)
    }