在我的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];
}
请建议。
答案 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)
由于上述解决方案均不适用于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.com或http://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)
}