68

我在 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 字符集似乎包含修剪我的 URL 的集。IE,

URL 的路径组件是紧跟在主机组件(如果存在)之后的组件。它在查询或片段组件开始的地方结束。例如,在 URL http://www.example.com/index.php?key1=value1中,路径组件是 /index.php。

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

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

let urlwithPercentEscapes = myurlstring.stringByAddingPercentEscapesUsingEncoding(NSUTF8StringEncoding)

作为它

使用给定的编码返回字符串的表示,以确定将字符串转换为合法 URL 字符串所需的百分比转义

谢谢

4

6 回答 6

160

对于给定的 URL 字符串,等效于

let urlwithPercentEscapes = myurlstring.stringByAddingPercentEscapesUsingEncoding(NSUTF8StringEncoding)

是字符集URLQueryAllowedCharacterSet

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

斯威夫特 3:

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

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

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

于 2015-08-18T07:17:43.920 回答
20

这将取决于您的网址。如果您的 url 是路径,您可以使用字符集 urlPathAllowed

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

为 URL 编码创建字符集

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

另一种选择是使用 URLComponents 正确创建您的 url

于 2015-08-18T06:21:31.737 回答
7

Swift 3.0(来自grokswift

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

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
于 2016-11-17T19:20:23.693 回答
3

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

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

它比 .urlQueryAllowed 和其他更安全,因为它会编码除 AZ、az 和 0-9 之外的所有字符。当您正在编码的值可能使用特殊字符(如 ?、&、=、+ 和空格)时,这会更好。

于 2017-06-08T22:58:44.860 回答
2

在我的最后一个组件是非拉丁字符的情况下,我在 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 { $0 == "/" }.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($0) }.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;
}
}
于 2016-03-21T19:40:18.497 回答
0

斯威夫特 4.0

let encodedData = myUrlString.addingPercentEncoding(withAllowedCharacters: CharacterSet.urlHostAllowed)
于 2018-04-02T09:46:56.437 回答