如何在Swift中编码URL

use*_*467 125 urlencode ios swift

这是我的URL.

问题是,该address字段未被追加urlpath.

有谁知道那是为什么?

var address:string
address = "American Tourister, Abids Road, Bogulkunta, Hyderabad, Andhra Pradesh, India"
let urlpath = NSString(format: "http://maps.googleapis.com/maps/api/geocode/json?address="+"\(address)")
Run Code Online (Sandbox Code Playgroud)

Bry*_*hen 197

用途stringByAddingPercentEncodingWithAllowedCharacters:

var urlString = originalString.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)
Run Code Online (Sandbox Code Playgroud)

使用 stringByAddingPercentEscapesUsingEncoding: 在iOS 9和OS X v10.11中不推荐使用

var address = "American Tourister, Abids Road, Bogulkunta, Hyderabad, Andhra Pradesh, India"
let escapedAddress = address.addingPercentEncoding(withAllowedCharacters: CharacterSet.urlQueryAllowed)
let urlpath = String(format: "http://maps.googleapis.com/maps/api/geocode/json?address=\(escapedAddress)")
Run Code Online (Sandbox Code Playgroud)

SWIFT 3

var escapedAddress = address.stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.URLQueryAllowedCharacterSet())
Run Code Online (Sandbox Code Playgroud)

  • 您可能希望修改该字符集,以便在`address`值中出现`+`或`&`时,它们会被转义百分比.不幸的是,`URLQueryAllowedCharacterSet`将让那些传递未转义,这将改变服务器解析的值. (12认同)
  • Rob是对的,`var escapedAddress = address.stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.URLQueryAllowedCharacterSet())`仍然对**&**和**+**字符视而不见 (7认同)
  • stringByAddingPercentEscapesUsingEncoding:在iOS 9上不推​​荐使用,最好使用stringByAddingPercentEncodingWithAllowedCharacters (4认同)
  • `let s = NSCharacterSet.URLQueryAllowedCharacterSet().mutableCopy()s.addCharactersInString("+&")` (3认同)
  • urlString = urlString.addingPercentEncoding(withAllowedCharacters:NSCharacterSet.urlQueryAllowed)! (2认同)

Rob*_*Rob 66

如果您添加到URL的值可能具有保留字符(由RFC 3986的第2部分定义),则可能必须优化百分比转义.值得注意的是,虽然&+在一个URL的有效字符,他们是不是有效的URL查询参数值内(因为&被用作查询参数之间的分隔符这将提前终止你的价值,并+转换为一个空格字符).不幸的是,标准的百分比逃逸使得那些分隔符没有转义.

因此,您可能希望百分比转义不在RFC 3986的无保留字符列表中的所有字符:

URI中允许但没有保留目的的字符称为unreserved.这些包括大写和小写字母,十进制数字,连字符,句点,下划线和波浪号.

     unreserved  = ALPHA / DIGIT / "-" / "." / "_" / "~"

后来,在3.4节的RFC还考虑增加?/在查询中允许的字符列表:

字符斜杠("/")和问号("?")可以表示查询组件中的数据.请注意,当某些较旧的错误实现用作相对引用的基本URI时(第5.1节),可能无法正确处理此类数据,这显然是因为它们在查找分层分隔符时无法区分查询数据和路径数据.但是,由于查询组件通常用于携带"key = value"对形式的标识信息,而一个常用值是对另一个URI的引用,因此有时可以更好地避免对这些字符进行百分比编码.

如今,您通常使用URLComponents百分比来转义查询值:

var address = "American Tourister, Abids Road, Bogulkunta, Hyderabad, Andhra Pradesh, India"
var components = URLComponents(string: "http://maps.googleapis.com/maps/api/geocode/json")!
components.queryItems = [URLQueryItem(name: "address", value: address)]
let url = components.url!
Run Code Online (Sandbox Code Playgroud)

顺便说一下,虽然在上述RFC中没有考虑到,W3C HTML规范的URL编码表单数据4.10.22.6部分application/x-www-form-urlencoded请求也应该用+字符替换空格字符(并且在不应该的字符中包含星号)逃脱).并且,遗憾的是,它URLComponents不能正确地逃避这一点,因此Apple建议您在检索对象的url属性之前手动百分之以逃避它URLComponents:

// configure `components` as shown above, and then:

components.percentEncodedQuery = components.percentEncodedQuery?.replacingOccurrences(of: "+", with: "%2B")
let url = components.url!
Run Code Online (Sandbox Code Playgroud)

对于Swift 2再现,我手动完成所有这些百分比逃避自己,请参阅此答案上一版本.

  • 这是更高级和防弹响应. (5认同)
  • x-www-form-urlencoded部分的+1.我在那里看到的每一个其他答案都无法解决这种情况. (3认同)

Yus*_*f X 62

斯威夫特3:

let escapedString = originalString.addingPercentEncoding(withAllowedCharacters:NSCharacterSet.urlQueryAllowed)
Run Code Online (Sandbox Code Playgroud)

  • 谢啦!我找不到如何用Swift 3做到这一点! (3认同)
  • 非常棒的回答,谢谢.为了帮助谷歌,这取代旧的风格......**withAllowedCharacters:.urlQueryAllowed()** (3认同)

que*_*ful 33

Swift 2.0

let needsLove = "string needin some URL love"
let safeURL = needsLove.stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.URLQueryAllowedCharacterSet())!
Run Code Online (Sandbox Code Playgroud)

有用的编程技巧和黑客


Des*_*ume 11

URLQueryAllowedCharacterSet不应该被用于查询参数的URL编码,因为此charset包括&,?,/等,其作为在一个URL查询定界符,例如

/?paramname=paramvalue&paramname=paramvalue
Run Code Online (Sandbox Code Playgroud)

这些字符在URL查询中是允许的,但不在参数值中.

RFC 3986专门讨论了与保留字符不同的非保留字符:

2.3.未保留的角色

URI中允许但没有保留
目的的字符称为unreserved.这些包括大写和小写字母,十进制数字,连字符,句点,下划线和波浪号.

  unreserved  = ALPHA / DIGIT / "-" / "." / "_" / "~"
Run Code Online (Sandbox Code Playgroud)

因此:

extension String {
    var URLEncoded:String {
        let unreservedChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~"
        let unreservedCharset = NSCharacterSet(charactersInString: unreservedChars)
        let encodedString = self.stringByAddingPercentEncodingWithAllowedCharacters(unreservedCharset)
        return encodedString ?? self
    }
}
Run Code Online (Sandbox Code Playgroud)

上面的代码没有调用,alphanumericCharacterSet因为它返回的字符集的大小(103806个字符).并且鉴于有多少Unicode字符alphanumericCharacterSet允许,将其用于URL编码的目的将是错误的.

用法:

let URLEncodedString = myString.URLEncoded
Run Code Online (Sandbox Code Playgroud)


Ash*_*k R 6

XCODE 8,SWIFT 3.0

来自grokswift

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

func createURLWithComponents() -> URL? {
    var urlComponents = URLComponents()
    urlComponents.scheme = "http"
    urlComponents.host = "maps.googleapis.com"
    urlComponents.path = "/maps/api/geocode/json"

    let addressQuery = URLQueryItem(name: "address", value: "American Tourister, Abids Road, Bogulkunta, Hyderabad, Andhra Pradesh, India")
    urlComponents.queryItems = [addressQuery]

    return urlComponents.url
}
Run Code Online (Sandbox Code Playgroud)

下面是使用guardstatement 访问url的代码.

guard let url = createURLWithComponents() else {
            print("invalid URL")
            return nil
      }
      print(url)
Run Code Online (Sandbox Code Playgroud)

输出:

http://maps.googleapis.com/maps/api/geocode/json?address=American%20Tourister,%20Abids%20Road,%20Bogulkunta,%20Hyderabad,%20Andhra%20Pradesh,%20India
Run Code Online (Sandbox Code Playgroud)

阅读更多:使用NSURLComponents和NSURLQueryItems构建URL

  • Swift 3.0 urlAsString = urlAsString.addingPercentEncoding(withAllowedCharacters: NSCharacterSet.urlQueryAllowed)! (2认同)

Dar*_*ryl 6

Swift 4.1

根据您想要的选项(urlQueryAllowed)创建"字符集".然后删除您不想要的其他字符(+&).然后将该字符集传递给"addingPercentEncoding".

var address = "American Tourister, Abids Road, Bogulkunta, Hyderabad, Andhra Pradesh, India"
var queryCharSet = NSCharacterSet.urlQueryAllowed
queryCharSet.remove(charactersIn: "+&")
let escapedAddress = address.addingPercentEncoding(withAllowedCharacters: queryCharSet)!
let urlpath = String(format: "http://maps.googleapis.com/maps/api/geocode/json?address=\(escapedAddress)")
Run Code Online (Sandbox Code Playgroud)


Jor*_*rez 5

刚刚完成 Desmond Hume 的回答以扩展RFC 3986 非保留字符有效编码函数的 String 类(如果您对查询 FORM 参数进行编码,则需要):

斯威夫特 3

extension String {

    var RFC3986UnreservedEncoded:String {
        let unreservedChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~"
        let unreservedCharsSet: CharacterSet = CharacterSet(charactersIn: unreservedChars)
        let encodedString: String = self.addingPercentEncoding(withAllowedCharacters: unreservedCharsSet)!
        return encodedString
    }
}
Run Code Online (Sandbox Code Playgroud)