ios Swift - 编码 URL

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/24551816/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-31 01:12:53  来源:igfitidea点击:

Swift - encode URL

iosswifturlencode

提问by MegaCookie

If I encode a string like this:

如果我对这样的字符串进行编码:

var escapedString = originalString.stringByAddingPercentEscapesUsingEncoding(NSUTF8StringEncoding)

it doesn't escape the slashes /.

它没有逃脱斜线/

I've searched and found this Objective C code:

我搜索并找到了这个 Objective C 代码:

NSString *encodedString = (NSString *)CFURLCreateStringByAddingPercentEscapes(
                        NULL,
                        (CFStringRef)unencodedString,
                        NULL,
                        (CFStringRef)@"!*'();:@&=+$,/?%#[]",
                        kCFStringEncodingUTF8 );

Is there an easier way to encode an URL and if not, how do I write this in Swift?

有没有更简单的方法来编码 URL,如果没有,我该如何在 Swift 中编写它?

回答by zaph

Swift 3

斯威夫特 3

In Swift 3 there is addingPercentEncoding

在 Swift 3 中有 addingPercentEncoding

let originalString = "test/test"
let escapedString = originalString.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed)
print(escapedString!)

Output:

输出:

test%2Ftest

测试%2Ftest

Swift 1

斯威夫特 1

In iOS 7 and above there is stringByAddingPercentEncodingWithAllowedCharacters

在 iOS 7 及以上有 stringByAddingPercentEncodingWithAllowedCharacters

var originalString = "test/test"
var escapedString = originalString.stringByAddingPercentEncodingWithAllowedCharacters(.URLHostAllowedCharacterSet())
println("escapedString: \(escapedString)")

Output:

输出:

test%2Ftest

测试%2Ftest

The following are useful (inverted) character sets:

以下是有用的(倒置的)字符集:

URLFragmentAllowedCharacterSet  "#%<>[\]^`{|}
URLHostAllowedCharacterSet      "#%/<>?@\^`{|}
URLPasswordAllowedCharacterSet  "#%/:<>?@[\]^`{|}
URLPathAllowedCharacterSet      "#%;<>?[\]^`{|}
URLQueryAllowedCharacterSet     "#%<>[\]^`{|}
URLUserAllowedCharacterSet      "#%/:<>?@[\]^`

If you want a different set of characters to be escaped create a set:
Example with added "=" character:

如果要转义一组不同的字符,请创建一组:
添加“=”字符的示例:

var originalString = "test/test=42"
var customAllowedSet =  NSCharacterSet(charactersInString:"=\"#%/<>?@\^`{|}").invertedSet
var escapedString = originalString.stringByAddingPercentEncodingWithAllowedCharacters(customAllowedSet)
println("escapedString: \(escapedString)")

Output:

输出:

test%2Ftest%3D42

测试%2Ftest%3D42

Example to verify ascii characters not in the set:

验证不在集合中的 ascii 字符的示例:

func printCharactersInSet(set: NSCharacterSet) {
    var characters = ""
    let iSet = set.invertedSet
    for i: UInt32 in 32..<127 {
        let c = Character(UnicodeScalar(i))
        if iSet.longCharacterIsMember(i) {
            characters = characters + String(c)
        }
    }
    print("characters not in set: \'\(characters)\'")
}

回答by Leo Dabus

You can use URLComponents to avoid having to manually percent encode your query string:

您可以使用 URLComponents 来避免手动对查询字符串进行百分比编码:

let scheme = "https"
let host = "www.google.com"
let path = "/search"
let queryItem = URLQueryItem(name: "q", value: "Formula One")


var urlComponents = URLComponents()
urlComponents.scheme = scheme
urlComponents.host = host
urlComponents.path = path
urlComponents.queryItems = [queryItem]

if let url = urlComponents.url {
    print(url)   // "https://www.google.com/search?q=Formula%20One"
}


extension URLComponents {
    init(scheme: String = "https",
         host: String = "www.google.com",
         path: String = "/search",
         queryItems: [URLQueryItem]) {
        self.init()
        self.scheme = scheme
        self.host = host
        self.path = path
        self.queryItems = queryItems
    }
}


let query = "Formula One"
if let url = URLComponents(queryItems: [URLQueryItem(name: "q", value: query)]).url {
    print(url)  // https://www.google.com/search?q=Formula%20One
}

回答by iHTCboy

Swift 3:

斯威夫特 3:

let originalString = "http://www.ihtc.cc?name=htc&title=iOS开发工程师"

1. encodingQuery:

1.编码查询:

let escapedString = originalString.addingPercentEncoding(withAllowedCharacters:NSCharacterSet.urlQueryAllowed)

result:

结果:

"http://www.ihtc.cc?name=htc&title=iOS%E5%BC%80%E5%8F%91%E5%B7%A5%E7%A8%8B%E5%B8%88" 


2. encodingURL:

2.编码网址:

let escapedString = originalString.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed)

result:

结果:

"http:%2F%2Fwww.ihtc.cc%3Fname=htc&title=iOS%E5%BC%80%E5%8F%91%E5%B7%A5%E7%A8%8B%E5%B8%88"

回答by Hong Wei

Swift 3:

斯威夫特 3:

let allowedCharacterSet = (CharacterSet(charactersIn: "!*'();:@&=+$,/?%#[] ").inverted)

if let escapedString = originalString.addingPercentEncoding(withAllowedCharacters: allowedCharacterSet) {
//do something with escaped string
}

回答by Marián ?erny

Swift 4

斯威夫特 4

To encode a parameter in URL I find using .alphanumericscharacter set the easiest option:

要在 URL 中编码参数,我发现使用.alphanumerics字符集是最简单的选项:

let encoded = parameter.addingPercentEncoding(withAllowedCharacters: .alphanumerics)
let url = "http://www.example.com/?name=\(encoded!)"

Using any of the standard Character Sets for URL Encoding (like URLQueryAllowedCharacterSetor URLHostAllowedCharacterSet) won't work, because they do not exclude =or &characters.

使用任何标准字符集进行 URL 编码(如URLQueryAllowedCharacterSetURLHostAllowedCharacterSet)都不起作用,因为它们不排除=&字符。

Notethat by using .alphanumericsit will encode some characters that do not need to be encoded (like -, ., _or ~-– see 2.3. Unreserved charactersin RFC 3986). I find using .alphanumericssimpler than constructing a custom character set and do not mind some additional characters to be encoded. If that bothers you, construct a custom character set as is described in How to percent encode a URL String, like for example:

注意,通过使用.alphanumerics它编码无需编码的某些字符(如-._~-见2.3未保留的字符。在RFC 3986)。我发现使用.alphanumerics比构建自定义字符集更简单,并且不介意对一些额外的字符进行编码。如果这让您感到困扰,请按照如何对 URL String 进行百分比编码中所述构建自定义字符集,例如:

var allowed = CharacterSet.alphanumerics
allowed.insert(charactersIn: "-._~") // as per RFC 3986
let encoded = parameter.addingPercentEncoding(withAllowedCharacters: allowed)
let url = "http://www.example.com/?name=\(encoded!)"

Warning:The encodedparameter is force unwrapped. For invalid unicode string it might crash. See Why is the return value of String.addingPercentEncoding() optional?. Instead of force unwrapping encoded!you can use encoded ?? ""or use if let encoded = ....

警告:encoded参数是力展开。对于无效的 unicode 字符串,它可能会崩溃。请参阅为什么 String.addingPercentEncoding() 的返回值是可选的?. 相反的力展开encoded!,您可以使用encoded ?? ""或使用if let encoded = ...

回答by Bryan Chen

Everything is same

一切都一样

var str = CFURLCreateStringByAddingPercentEscapes(
    nil,
    "test/test",
    nil,
    "!*'();:@&=+$,/?%#[]",
    CFStringBuiltInEncodings.UTF8.rawValue
)

// test%2Ftest

回答by Alessandro Ornano

Swift 4:

斯威夫特 4:

It depends by the encoding rules followed by your server.

这取决于您的服务器遵循的编码规则。

Apple offer this class method, but it don't report wich kind of RCF protocol it follows.

Apple 提供了此类方法,但它没有报告它遵循哪种 RCF 协议。

var escapedString = originalString.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed)!

Following this useful toolyou should guarantee the encoding of these chars for your parameters:

遵循这个有用的工具,您应该保证为您的参数编码这些字符:

  • $ (Dollar Sign) becomes %24
  • & (Ampersand) becomes %26
  • + (Plus) becomes %2B
  • , (Comma) becomes %2C
  • : (Colon) becomes %3A
  • ; (Semi-Colon) becomes %3B
  • = (Equals) becomes %3D
  • ? (Question Mark) becomes %3F
  • @ (Commercial A / At) becomes %40
  • $(美元符号)变成 %24
  • &(与号)变成 %26
  • + (Plus) 变成 %2B
  • , (逗号) 变成 %2C
  • : (冒号) 变成 %3A
  • ; (分号)变成 %3B
  • = (等于) 变成 %3D
  • ? (问号) 变成 %3F
  • @(商业A / At)变成%40

In other words, speaking about URL encoding, you should following the RFC 1738 protocol.

换句话说,说到 URL 编码,您应该遵循RFC 1738 协议

And Swift don't cover the encoding of the + char for example, but it works well with these three @ : ?chars.

例如,Swift 没有涵盖 + char 的编码,但它与这三个@ :一起工作得很好字符。

So, to correctly encoding each your parameter , the .urlHostAllowedoption is not enough, you should add also the special chars as for example:

因此,要正确编码每个参数,该.urlHostAllowed选项还不够,您还应该添加特殊字符,例如:

encodedParameter = parameter.replacingOccurrences(of: "+", with: "%2B")

Hope this helps someone who become crazy to search these informations.

希望这可以帮助那些变得疯狂搜索这些信息的人。

回答by AJP

Swift 4 (not tested - please comment if it works or not. Thanks @sumizome for suggestion)

Swift 4(未测试 - 请评论它是否有效。感谢@sumizome 的建议)

var allowedQueryParamAndKey = NSCharacterSet.urlQueryAllowed
allowedQueryParamAndKey.remove(charactersIn: ";/?:@&=+$, ")
paramOrKey.addingPercentEncoding(withAllowedCharacters: allowedQueryParamAndKey)

Swift 3

斯威夫特 3

let allowedQueryParamAndKey =  NSCharacterSet.urlQueryAllowed.remove(charactersIn: ";/?:@&=+$, ")
paramOrKey.addingPercentEncoding(withAllowedCharacters: allowedQueryParamAndKey)

Swift 2.2(Borrowing from Zaph's and correcting for url query key and parameter values)

Swift 2.2(从 Zaph's 借用并更正 url 查询键和参数值)

var allowedQueryParamAndKey =  NSCharacterSet(charactersInString: ";/?:@&=+$, ").invertedSet
paramOrKey.stringByAddingPercentEncodingWithAllowedCharacters(allowedQueryParamAndKey)

Example:

例子:

let paramOrKey = "https://some.website.com/path/to/page.srf?a=1&b=2#top"
paramOrKey.addingPercentEncoding(withAllowedCharacters: allowedQueryParamAndKey)
// produces:
"https%3A%2F%2Fsome.website.com%2Fpath%2Fto%2Fpage.srf%3Fa%3D1%26b%3D2%23top"

This is a shorter version of Bryan Chen's answer. I'd guess that urlQueryAllowedis allowing the control characters through which is fine unless they form part of the key or value in your query string at which point they need to be escaped.

这是 Bryan Chen 答案的简短版本。我猜这urlQueryAllowed允许控制字符通过它很好,除非它们构成查询字符串中的键或值的一部分,此时它们需要被转义。

回答by ajzbc

Swift 4.2

斯威夫特 4.2

A quick one line solution. Replace originalStringwith the String you want to encode.

一种快速的单线解决方案。替换originalString为您要编码的字符串。

var encodedString = originalString.addingPercentEncoding(withAllowedCharacters: CharacterSet(charactersIn: "!*'();:@&=+$,/?%#[]{} ").inverted)

Online Playground Demo

在线游乐场演示

回答by BadPirate

Had need of this myself, so I wrote a String extension that both allows for URLEncoding strings, as well as the more common end goal, converting a parameter dictionary into "GET" style URL Parameters:

我自己需要这个,所以我写了一个字符串扩展,它既允许 URLEncoding 字符串,也允许更常见的最终目标,将参数字典转换为“GET”样式的 URL 参数:

extension String {
    func URLEncodedString() -> String? {
        var escapedString = self.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed)
        return escapedString
    }
    static func queryStringFromParameters(parameters: Dictionary<String,String>) -> String? {
        if (parameters.count == 0)
        {
            return nil
        }
        var queryString : String? = nil
        for (key, value) in parameters {
            if let encodedKey = key.URLEncodedString() {
                if let encodedValue = value.URLEncodedString() {
                    if queryString == nil
                    {
                        queryString = "?"
                    }
                    else
                    {
                        queryString! += "&"
                    }
                    queryString! += encodedKey + "=" + encodedValue
                }
            }
        }
        return queryString
    }
}

Enjoy!

享受!