ios URL(字符串:)始终不起作用

Ank*_*ain 5 url nsurl url-encoding ios swift

let testurl = "http://akns-
images.eonline.com/eol_images/Entire_Site/2018029/rs_1024x759-
180129200032-1024.lupita-nyongo-angela-bassett-black-panther-
premiere.ct.012918.jpg?fit=inside|900:auto"

if let url = URL(string: testurl){
    print("valid")
}else {
   print("invalid")
}
Run Code Online (Sandbox Code Playgroud)

这将打印为无效的URL.但是在Web浏览器中显示图像.我已经看到很多方法,但它会抛出Apple警告使用stringByAddingPercentEncodingWithAllowedCharacters,这总是不起作用.

我更喜欢一个解决方案来清理网址而不编码完整的urlstring.在初始步骤对其进行编码可能是传递给外部库时的摩擦,外部库将重新编码URL并使其无效.

tho*_*b65 7

使用URLComponents,它将自动处理转义字符并正确编码网址.无需使用addingPercentEncoding

func computeURL() {
    let testurlStr = "http://akns-images.eonline.com/eol_images/Entire_Site/2018029/rs_1024x759-180129200032-1024.lupita-nyongo-angela-bassett-black-panther-premiere.ct.012918.jpg?fit=inside|900:auto"
    let components = transformURLString(testurlStr)

    if let url = components?.url {
        print("valid")
    } else {
        print("invalid")
    }
}

func transformURLString(_ string: String) -> URLComponents? {
    guard let urlPath = string.components(separatedBy: "?").first else {
        return nil
    }
    var components = URLComponents(string: urlPath)
    if let queryString = string.components(separatedBy: "?").last {
        components?.queryItems = []
        let queryItems = queryString.components(separatedBy: "&")
        for queryItem in queryItems {
            guard let itemName = queryItem.components(separatedBy: "=").first,
                  let itemValue = queryItem.components(separatedBy: "=").last else {
                    continue
            }
            components?.queryItems?.append(URLQueryItem(name: itemName, value: itemValue))
        }
    }
    return components!
}
Run Code Online (Sandbox Code Playgroud)


Ank*_*ain 7

我想我已经找到了答案。仍然会检查是否有任何副作用,欢迎评论:

let urlst = "http://akns-
images.eonline.com/eol_images/Entire_Site/2018029/rs_1024x759-
180129200032-1024.lupita-nyongo-angela-bassett-black-panther-
premiere.ct.012918.jpg?fit=inside|900:auto"
extension String {
 func getCleanedURL() -> URL? {
    guard self.isEmpty == false else {
        return nil
    }
    if let url = URL(string: self) {
        return url
    } else {
        if let urlEscapedString = self.addingPercentEncoding(withAllowedCharacters: CharacterSet.urlQueryAllowed) , let escapedURL = URL(string: urlEscapedString){
            return escapedURL
        }
    }
    return nil
 }
}
Run Code Online (Sandbox Code Playgroud)

这不会对完整的 URL 进行编码,而是仅对无效的查询字符进行编码(例如 url 中的“|”)。因此它仍然可以作为字符串或有效 URL 传递。

  • 最干净的方法是使用 URLComponents,正如我在回答中提到的...... (2认同)

Pra*_*iya 5

如果包含特殊字符,则必须使用URL编码才能从字符串构建URL。

为什么我们需要URL编码

这个答案

URI表示为字符序列,而不是八位字节序列。那是因为URI可能通过不通过计算机网络的方式“传输”,例如,打印在纸上,通过无线电读取等。

但是,对于包含非ASCII字符的原始字符序列,情况则更加困难。如果可能有多个[RFC2277],则传输旨在表示字符序列的八位位组序列的Internet协议有望提供某种方式来标识所使用的字符集。但是,当前在通用URI语法中没有提供完成此标识的规定。单个URI方案可能需要单个字符集,定义默认字符集或提供一种指示所使用字符集的方法。

在IOS SDK中,我们具有以下内容:

用户:URLUserAllowedCharacterSet
密码:URLPasswordAllowedCharacterSet
主机:URLHostAllowedCharacterSet
路径:URLPathAllowedCharacterSet
片段:URLFragmentAllowedCharacterSet
查询:URLQueryAllowedCharacterSet

您可以用来addingPercentEncoding(withAllowedCharacters:)正确编码字符串。

根据Apple文档,该方法的一个重要注意事项:

整个URL字符串不能进行百分比编码,因为每个URL组件都指定了一组不同的允许字符。例如,URL的查询组件允许使用“ @”字符,但是该字符必须在密码组件中进行百分比编码。

UTF-8编码用于确定正确的百分比编码字符。7位ASCII范围之外的allowedCharacters中的任何字符都将被忽略。

一个例子:

let encodedURL = testurl.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)
if let url = URL(string: finalUrl) {
    print("valid url")
} else {
    print("invalid url")
}
Run Code Online (Sandbox Code Playgroud)

我希望这是有帮助的。