Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 如何在Swift中对URL进行编码_Ios_Swift_Urlencode - Fatal编程技术网

Ios 如何在Swift中对URL进行编码

Ios 如何在Swift中对URL进行编码,ios,swift,urlencode,Ios,Swift,Urlencode,这是我的URL 问题是,地址字段没有附加到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)")

这是我的
URL

问题是,
地址
字段没有附加到
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)")
Swift 4.2 Swift 3.0 使用:


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


如果您要添加到URL的值可能包含保留字符(如的第2节所定义),则可能需要优化转义百分比。值得注意的是,虽然
&
+
是URL中的有效字符,但它们在URL查询参数值中无效(因为
&
用作查询参数之间的分隔符,这将提前终止您的值,
+
转换为空格字符)。不幸的是,标准的百分比转义使这些分隔符无法转义

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

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

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

顺便说一句,虽然上述RFC中没有考虑到这一点,但W3C HTML规范规定,
应用程序/x-www-form-urlencoded
请求还应将空格字符替换为
+
字符(并在不应转义的字符中包含星号)。不幸的是,
URLComponents
无法正确地进行百分比转义,因此苹果建议您在检索
URLComponents
对象的
url
属性之前手动进行百分比转义:

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

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

对于Swift 2格式副本,我自己手动执行所有百分比转义,请参见。

Swift 2.0

let needsLove = "string needin some URL love"
let safeURL = needsLove.stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.URLQueryAllowedCharacterSet())!

URLQueryAllowedCharacterSet
不应用于查询参数的URL编码,因为此字符集包括
&
/
等,它们在URL查询中用作分隔符,例如

/?paramname=paramvalue&paramname=paramvalue
这些字符可以作为一个整体出现在URL查询中,但不能出现在参数值中

具体谈到未保留的字符,这与允许的字符不同:

2.3。无保留字符

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

unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
  unreserved  = ALPHA / DIGIT / "-" / "." / "_" / "~"
因此:

extension String {
    var URLEncoded:String {

        let unreservedChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~"
        let unreservedCharsSet: CharacterSet = CharacterSet(charactersIn: unreservedChars)
        let encodedString = self.addingPercentEncoding(withAllowedCharacters: unreservedCharsSet)!
        return encodedString
    }
}
上面的代码没有调用
alphanumericCharacterSet
,因为它返回的字符集非常大(103806个字符)。考虑到Unicode字符
alphanumericCharacterSet
允许多少个字符,将其用于URL编码是完全错误的

用法:

let URLEncodedString = myString.URLEncoded
"aouäöü!".urlPercentEncoded(withAllowedCharacters: .urlQueryAllowed,
                                         encoding: .isoLatin1) 
// Results in -> "aou%E4%F6%FC!"

Mac OS 10.9中引入了Maverics和iOS 7
NSURLComponents
,它以非常方便的方式处理不同URL部分的编码

NSURLComponents类是一个用于解析URL的类 基于RFC3986并从其组成部分构造URL。 它的行为与NSURL类略有不同,后者符合 旧的RFC。但是,您可以基于以下内容轻松获得NSURL对象: URL组件对象的内容,反之亦然


在最后一个组件是非拉丁字符的情况下,我在
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;
}
}

除了上面Bryan Chen的回答之外:

以防万一,其他人也会从阿拉莫菲尔身上得到类似的东西:

错误:Alamofire是使用优化编译的-单步执行可能会出现问题 奇怪地变量可能不可用

这不是一个非常描述性的错误。我在为谷歌地理服务构建URL时遇到了这个错误。我在URL的末尾附加了一个街道地址,而没有首先对街道地址本身进行编码。 我能够使用Bryan Chen的解决方案修复它:

var streetAdress = "123 fake street, new york, ny"
var escapedStreetAddress = streetAddress.stringByAddingPercentEncodingWithAllowedCharacters(.URLHostAllowedCharacterSet())
let url = "\(self.baseUrl)&address=\(escapedAddress!)"
那帮我修好了!它不喜欢地址有空格和逗号等


希望这对其他人有帮助

Swift 3:

let escapedString = originalString.addingPercentEncoding(withAllowedCharacters:NSCharacterSet.urlQueryAllowed)
代码8,SWIFT 3.0

来自grokswift

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

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
}
http://maps.googleapis.com/maps/api/geocode/json?address=American%20Tourister,%20Abids%20Road,%20Bogulkunta,%20Hyderabad,%20Andhra%20Pradesh,%20India
下面是使用
guard
语句访问url的代码

输出:

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
}
http://maps.googleapis.com/maps/api/geocode/json?address=American%20Tourister,%20Abids%20Road,%20Bogulkunta,%20Hyderabad,%20Andhra%20Pradesh,%20India

阅读更多信息:

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

斯威夫特3 为Swift 3更新:

var escapedAddress = address.addingPercentEncoding(
    withAllowedCharacters: CharacterSet.urlQueryAllowed)

Swift 4.1

根据所需的选项创建“字符集”(urlQueryAllowed)。然后删除不需要的其他字符(+&)。然后将该字符集传递给“addingPercentEncoding”


我需要用ISO-8859-1对参数进行编码,因此addingPercentEncoding()方法对我不起作用。 我自己在Swift 4中提出了一个解决方案:

extension String {

  // Url percent encoding according to RFC3986 specifications
  // https://tools.ietf.org/html/rfc3986#section-2.1
  func urlPercentEncoded(withAllowedCharacters allowedCharacters: 
    CharacterSet, encoding: String.Encoding) -> String {
    var returnStr = ""

    // Compute each char seperatly
    for char in self {
      let charStr = String(char)
      let charScalar = charStr.unicodeScalars[charStr.unicodeScalars.startIndex]
      if allowedCharacters.contains(charScalar) == false,
        let bytesOfChar = charStr.data(using: encoding) {
        // Get the hexStr of every notAllowed-char-byte and put a % infront of it, append the result to the returnString
        for byte in bytesOfChar {
          returnStr += "%" + String(format: "%02hhX", byte as CVarArg)
        }
      } else {
        returnStr += charStr
      }
    }

    return returnStr
  }

}
用法:

let URLEncodedString = myString.URLEncoded
"aouäöü!".urlPercentEncoded(withAllowedCharacters: .urlQueryAllowed,
                                         encoding: .isoLatin1) 
// Results in -> "aou%E4%F6%FC!"

让urlpath=”http://maps.googleapis.com/maps/api/geocode/json?address=\(地址)“)
就足够了,我想“某个字符串”+“\(aString)”太过分了。。。只需使用“Some string\(aString)”或“Some string”+aString我们可以通过添加PercentEncoding with AllowedCharacters来使用
string方法。您可以在此答案中找到更多详细信息:您可能希望修改该字符集,以便如果
+
&
出现在
地址
值中,它们将得到转义百分比。不幸的是,
URLQueryAllowedCharacterSetvar 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)")
extension String {

  // Url percent encoding according to RFC3986 specifications
  // https://tools.ietf.org/html/rfc3986#section-2.1
  func urlPercentEncoded(withAllowedCharacters allowedCharacters: 
    CharacterSet, encoding: String.Encoding) -> String {
    var returnStr = ""

    // Compute each char seperatly
    for char in self {
      let charStr = String(char)
      let charScalar = charStr.unicodeScalars[charStr.unicodeScalars.startIndex]
      if allowedCharacters.contains(charScalar) == false,
        let bytesOfChar = charStr.data(using: encoding) {
        // Get the hexStr of every notAllowed-char-byte and put a % infront of it, append the result to the returnString
        for byte in bytesOfChar {
          returnStr += "%" + String(format: "%02hhX", byte as CVarArg)
        }
      } else {
        returnStr += charStr
      }
    }

    return returnStr
  }

}
"aouäöü!".urlPercentEncoded(withAllowedCharacters: .urlQueryAllowed,
                                         encoding: .isoLatin1) 
// Results in -> "aou%E4%F6%FC!"