如何在 Swift 2.0 中对 URL 使用 stringByAddingPercentEncodingWithAllowedCharacters()

How to use stringByAddingPercentEncodingWithAllowedCharacters() for a URL in Swift 2.0

我在 Swift 1.2

中使用这个
let urlwithPercentEscapes = myurlstring.stringByAddingPercentEscapesUsingEncoding(NSUTF8StringEncoding)

这现在给了我一个警告,要求我使用

stringByAddingPercentEncodingWithAllowedCharacters

我需要使用 NSCharacterSet 作为参数,但是参数太多了,我无法确定哪个会给我与之前使用的方法相同的结果。

我要用的例子URL会是这样

http://www.mapquestapi.com/geocoding/v1/batch?key=YOUR_KEY_HERE&callback=renderBatch&location=Pottsville,PA&location=Red Lion&location=19036&location=1090 N Charlotte St, Lancaster, PA

用于编码的 URL 字符集似乎包含设置 trim my URL。即

The path component of a URL is the component immediately following the host component (if present). It ends wherever the query or fragment component begins. For example, in the URL http://www.example.com/index.php?key1=value1, the path component is /index.php.

但是我不想 trim 它的任何方面。 当我使用我的字符串时,例如 myurlstring 它会失败。

但是用下面的时候就没有问题了。它用一些魔法对字符串进行了编码,我可以获得我的 URL 数据。

let urlwithPercentEscapes = myurlstring.stringByAddingPercentEscapesUsingEncoding(NSUTF8StringEncoding)

作为它

Returns a representation of the String using a given encoding to determine the percent escapes necessary to convert the String into a legal URL string

谢谢

这将取决于您的 url。如果您的 url 是一个路径,您可以使用字符集 url允许路径

let myFileString = "My File.txt"
if let urlwithPercentEscapes = myFileString.addingPercentEncoding(withAllowedCharacters: .urlPathAllowed) {
    print(urlwithPercentEscapes)  // "My%20File.txt"
}

Creating a Character Set for URL Encoding

urlFragmentAllowed

urlHostAllowed

urlPasswordAllowed

urlQueryAllowed

urlUserAllowed

您也可以创建自己的 url 字符集:

let myUrlString = "http://www.mapquestapi.com/geocoding/v1/batch?key=YOUR_KEY_HERE&callback=renderBatch&location=Pottsville,PA&location=Red Lion&location=19036&location=1090 N Charlotte St, Lancaster, PA"

let urlSet = CharacterSet.urlFragmentAllowed
                .union(.urlHostAllowed)
                .union(.urlPasswordAllowed)
                .union(.urlQueryAllowed)
                .union(.urlUserAllowed)

extension CharacterSet {
    static let urlAllowed = CharacterSet.urlFragmentAllowed
                                        .union(.urlHostAllowed)
                                        .union(.urlPasswordAllowed)
                                        .union(.urlQueryAllowed)
                                        .union(.urlUserAllowed)
}

if let urlwithPercentEscapes = myUrlString.addingPercentEncoding(withAllowedCharacters: .urlAllowed) {
    print(urlwithPercentEscapes)  // "http://www.mapquestapi.com/geocoding/v1/batch?key=YOUR_KEY_HERE&callback=renderBatch&location=Pottsville,PA&location=Red%20Lion&location=19036&location=1090%20N%20Charlotte%20St,%20Lancaster,%20PA"
}

另一种选择是use URLComponents to properly create your url

对于给定的 URL 字符串相当于

let urlwithPercentEscapes = myurlstring.stringByAddingPercentEscapesUsingEncoding(NSUTF8StringEncoding)

是字符集URLQueryAllowedCharacterSet

let urlwithPercentEscapes = myurlstring.stringByAddingPercentEncodingWithAllowedCharacters( NSCharacterSet.URLQueryAllowedCharacterSet())

Swift 3:

let urlwithPercentEscapes = myurlstring.addingPercentEncoding( withAllowedCharacters: .urlQueryAllowed)

它对 URL 字符串中问号后的所有内容进行编码。

由于方法 stringByAddingPercentEncodingWithAllowedCharacters 可以 return nil,请按照 Leo Dabus 的回答中的建议使用可选绑定。

在我的最后一个组件是非拉丁字符的情况下,我在 Swift 2.2 中执行了以下操作:

extension String {
 func encodeUTF8() -> String? {
//If I can create an NSURL out of the string nothing is wrong with it
if let _ = NSURL(string: self) {

    return self
}

//Get the last component from the string this will return subSequence
let optionalLastComponent = self.characters.split { [=10=] == "/" }.last


if let lastComponent = optionalLastComponent {

    //Get the string from the sub sequence by mapping the characters to [String] then reduce the array to String
    let lastComponentAsString = lastComponent.map { String([=10=]) }.reduce("", combine: +)


    //Get the range of the last component
    if let rangeOfLastComponent = self.rangeOfString(lastComponentAsString) {
        //Get the string without its last component
        let stringWithoutLastComponent = self.substringToIndex(rangeOfLastComponent.startIndex)


        //Encode the last component
        if let lastComponentEncoded = lastComponentAsString.stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.alphanumericCharacterSet()) {


        //Finally append the original string (without its last component) to the encoded part (encoded last component)
        let encodedString = stringWithoutLastComponent + lastComponentEncoded

            //Return the string (original string/encoded string)
            return encodedString
        }
    }
}

return nil;
}
}

Swift 3.0(来自 grokswift

从字符串创建 URLs 是错误的雷区。只是错过了一个 / 或不小心 URL 编码了 ?在查询中,你的 API 调用将失败,你的应用程序将没有任何数据可显示(如果你没有预料到这种可能性,甚至会崩溃)。 自 iOS 8 以来,有一种使用 NSURLComponentsNSURLQueryItems 构建 URL 的更好方法。

func createURLWithComponents() -> URL? {
        var urlComponents = URLComponents()
        urlComponents.scheme = "http"
        urlComponents.host = "www.mapquestapi.com"
        urlComponents.path = "/geocoding/v1/batch"

        let key = URLQueryItem(name: "key", value: "YOUR_KEY_HERE")
        let callback = URLQueryItem(name: "callback", value: "renderBatch")
        let locationA = URLQueryItem(name: "location", value: "Pottsville,PA")
        let locationB = URLQueryItem(name: "location", value: "Red Lion")
        let locationC = URLQueryItem(name: "location", value: "19036")
        let locationD = URLQueryItem(name: "location", value: "1090 N Charlotte St, Lancaster, PA")

        urlComponents.queryItems = [key, callback, locationA, locationB, locationC, locationD]

        return urlComponents.url
}

下面是使用 guard 语句访问 url 的代码。

guard let url = createURLWithComponents() else {
            print("invalid URL")
            return nil
      }
      print(url)

输出:

http://www.mapquestapi.com/geocoding/v1/batch?key=YOUR_KEY_HERE&callback=renderBatch&location=Pottsville,PA&location=Red%20Lion&location=19036&location=1090%20N%20Charlotte%20St,%20Lancaster,%20PA

在 Swift 3.1 中,我正在使用如下内容:

let query = "param1=value1&param2=" + valueToEncode.addingPercentEncoding(withAllowedCharacters: .alphanumeric)

它比 .urlQueryAllowed 和其他的更安全,因为它会编码除 A-Z、a-z 和 0-9 之外的所有字符。当您编码的值可能使用特殊字符,如 ?、&、=、+ 和空格时,此方法效果更好。

Swift 4.0

let encodedData = myUrlString.addingPercentEncoding(withAllowedCharacters: CharacterSet.urlHostAllowed)