ios URL(string: ) not working always

允我心安 提交于 2019-12-30 19:59:02

问题


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

This prints as an invalid URL. But shows the image in web browser. I have seen lot of methods but it throws Apple warning to use stringByAddingPercentEncodingWithAllowedCharacters and this doesn't work always.

I would prefer a solution to clean-up the url without encoding the complete urlstring. Encoding it at initial step can be a friction when passing to external libraries which will re-encode the url and make it invalid.


回答1:


Use URLComponents, it will handle escape characters automatically and encodes the url correct. no need to use 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!
}



回答2:


URL encoding is compulsory for building a URL from a string in case it contains special characters.

Why we need URL encoding

From this answer:

A URI is represented as a sequence of characters, not as a sequence of octets. That is because URI might be "transported" by means that are not through a computer network, e.g., printed on paper, read over the radio, etc.

And

For original character sequences that contain non-ASCII characters, however, the situation is more difficult. Internet protocols that transmit octet sequences intended to represent character sequences are expected to provide some way of identifying the charset used, if there might be more than one [RFC2277]. However, there is currently no provision within the generic URI syntax to accomplish this identification. An individual URI scheme may require a single charset, define a default charset, or provide a way to indicate the charset used.

In the IOS SDK we have the following:

User: URLUserAllowedCharacterSet
Password: URLPasswordAllowedCharacterSet
Host: URLHostAllowedCharacterSet
Path: URLPathAllowedCharacterSet
Fragment: URLFragmentAllowedCharacterSet
Query: URLQueryAllowedCharacterSet

You can use addingPercentEncoding(withAllowedCharacters:) to encode a string correctly.

One important note according to the apple docs for that method:

Entire URL strings cannot be percent-encoded, because each URL component specifies a different set of allowed characters. For example, the query component of a URL allows the “@” character, but that character must be percent-encoded in the password component.

UTF-8 encoding is used to determine the correct percent-encoded characters. Any characters in allowedCharacters outside of the 7-bit ASCII range are ignored.

An example:

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

I hope this is helpful.




回答3:


I think I have found my answer. Still will be checking for any side effects, comments are welcome:

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

This does not encode the complete URL but encodes only the invalid query characters (in eg url its '|'). Thus it can still be passed around as a string or a valid URL.




回答4:


Please replace your line with:

let  finalUrl = testurl.addingPercentEncoding( withAllowedCharacters: .urlUserAllowed)
if let url = URL(string: finalUrl){
    print("valid")
} else {
   print("invalid")
}


来源:https://stackoverflow.com/questions/48576329/ios-urlstring-not-working-always

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!