这是我的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)")
答案 0 :(得分:185)
使用stringByAddingPercentEncodingWithAllowedCharacters
:
var escapedAddress = address.stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.URLQueryAllowedCharacterSet())
使用 在iOS 9和OS X v10.11中弃用 stringByAddingPercentEscapesUsingEncoding:
var address = "American Tourister, Abids Road, Bogulkunta, Hyderabad, Andhra Pradesh, India"
var escapedAddress = address.stringByAddingPercentEscapesUsingEncoding(NSUTF8StringEncoding)
let urlpath = NSString(format: "http://maps.googleapis.com/maps/api/geocode/json?address=\(escapedAddress)")
SWIFT 3
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)")
答案 1 :(得分:64)
如果您添加到网址中的值可能包含保留字符(由RFC 3986的第2部分定义),则可能需要优化百分比转义。值得注意的是,虽然&
和+
是网址中的有效字符,但它们在网址查询参数值中无效(因为&
用作查询参数之间的分隔符提前终止您的值,+
被转换为空格字符。不幸的是,标准的百分比逃逸使得这些分隔符没有转义。
因此,您可能希望百分比转义不在RFC 3986的非保留字符列表中的所有字符:
URI中允许但没有保留的字符 目的被称为无保留。这些包括大写和小写 字母,十进制数字,连字符,句号,下划线和波浪号。
unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
稍后,在第3.4节中,RFC进一步考虑将?
和/
添加到查询中允许的字符列表中:
字符斜线(" /")和问号("?")可能代表数据 在查询组件中。要小心一些年纪大了,错了 当实现它时,实现可能无法正确处理这些数据 显然,相对引用的基URI(第5.1节) 因为他们无法区分查询数据和路径数据 寻找分层分隔符。但是,作为查询组件 通常用于携带形式的识别信息 "键=值"对和一个经常使用的值是对的引用 另一个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!
顺便说一下,虽然W3C HTML规范中上述RFC section 5.2, URL-encoded form data中没有考虑到这一点,但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!
对于Swift 2演绎,我手动完成所有这些百分比逃脱,请参阅previous revision of this answer。
答案 2 :(得分:62)
斯威夫特3:
let escapedString = originalString.addingPercentEncoding(withAllowedCharacters:NSCharacterSet.urlQueryAllowed)
答案 3 :(得分:33)
Swift 2.0
let needsLove = "string needin some URL love"
let safeURL = needsLove.stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.URLQueryAllowedCharacterSet())!
答案 4 :(得分:11)
URLQueryAllowedCharacterSet
不应用于查询参数的网址编码,因为此字符集包含&
,?
,/
等,用作网址查询中的分隔符,例如
/?paramname=paramvalue¶mname=paramvalue
这些字符在URL查询中是允许的,但不在参数值中。
RFC 3986专门讨论无保留字符,这些字符与允许字符不同:
2.3。未保留的字符
URI中允许但没有保留的字符 目的被称为无保留。这些包括大写和小写 字母,十进制数字,连字符,句号,下划线和波浪号。
unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
因此:
extension String {
var URLEncoded:String {
let unreservedChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~"
let unreservedCharset = NSCharacterSet(charactersInString: unreservedChars)
let encodedString = self.stringByAddingPercentEncodingWithAllowedCharacters(unreservedCharset)
return encodedString ?? self
}
}
上面的代码没有调用alphanumericCharacterSet
,因为它返回的字符集非常庞大(103806个字符)。鉴于alphanumericCharacterSet
允许使用多少个Unicode字符,将其用于URL编码只会是错误的。
用法:
let URLEncodedString = myString.URLEncoded
答案 5 :(得分:6)
XCODE 8,SWIFT 3.0
来自grokswift
从字符串创建URL是bug的一个雷区。只是错过一个/或不小心的URL编码?在查询中,您的API调用将失败,您的应用程序将不会显示任何数据(如果您没有预料到这种可能性,甚至会崩溃)。 从iOS 8开始,使用NSURLComponents
和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
}
以下是使用guard
语句访问网址的代码。
guard let url = createURLWithComponents() else {
print("invalid URL")
return nil
}
print(url)
输出:
http://maps.googleapis.com/maps/api/geocode/json?address=American%20Tourister,%20Abids%20Road,%20Bogulkunta,%20Hyderabad,%20Andhra%20Pradesh,%20India
答案 6 :(得分:6)
Swift 4.1
创建一个"字符集"基于您想要的选项(urlQueryAllowed)。然后删除您不想要的其他字符(+&)。然后将该字符集传递给" addsPercentEncoding"。
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)")
答案 7 :(得分:4)
针对Swift 3进行了更新:
var escapedAddress = address.addingPercentEncoding(
withAllowedCharacters: CharacterSet.urlQueryAllowed)
答案 8 :(得分:3)
在Mac OS 10.9 Maverics和iOS 7中引入了NSURLComponents
,它以非常方便的方式处理不同URL部分的编码。
NSURLComponents类是一个用于解析URL的类 基于RFC 3986并从其组成部分构造URL。 它的行为与NSURL类略有不同,后者符合 较旧的RFC。但是,您可以轻松获取基于NSURL的对象 URL组件对象的内容,反之亦然。
let address = "American Tourister, Abids Road, Bogulkunta, Hyderabad, Andhra Pradesh, India"
let components = NSURLComponents(string: "http://maps.googleapis.com/maps/api/geocode/json")!
// create a query item key=value
let queryItem = NSURLQueryItem(name: "address", value: address)
// add the query item to the URL, NSURLComponents takes care of adding the question mark.
components.queryItems = [queryItem]
// get the properly percent encoded string
let urlpath = components.string!
print(urlpath)
答案 9 :(得分:2)
完成Desmond Hume的答案,为 RFC 3986无保留字符有效编码功能扩展String类(如果您正在编码查询FORM参数,则需要):
colNamesOutputFile=["PROGRAM_NAME", "TEST_GROUP", "NAME", "OFFER"]
inputDF=pd.read_csv(InputFile
, skiprows=1
, names=colNamesOutputFile
, converters={'PROGRAM_NAME': convert_to_string, 'TEST_GROUP': convert_to_string, 'NAME': convert_to_string, 'OFFER': convert_to_string}
, index_col=False)
inputDF1SUM = pd.DataFrame({'Count' : inputDF.groupby(['PROGRAM_NAME','TEST_GROUP']).size()}).reset_index()
inputDF2SUM = pd.DataFrame(inputDF.groupby('NAME')).reset_index()
inputDF3SUM = pd.DataFrame(inputDF.groupby('OFFER')).reset_index()
print(inputDF1SUM)
print(inputDF2SUM)
print(inputDF3SUM)
答案 10 :(得分:0)
在上面回答Bryan Chen的回答:
只是让其他人得到与Alamofire相似的东西:
错误:Alamofire是通过优化编译的 - 步进可能会表现出来 奇怪;变量可能无法使用。
这不是一个非常具有描述性的错误。在为Google地理服务构建网址时,我遇到了这个错误。我在URL的末尾附加了一个街道地址,没有首先编码街道地址本身。 我能够使用Bryan Chen的解决方案解决它:
var streetAdress = "123 fake street, new york, ny"
var escapedStreetAddress = streetAddress.stringByAddingPercentEncodingWithAllowedCharacters(.URLHostAllowedCharacterSet())
let url = "\(self.baseUrl)&address=\(escapedAddress!)"
为我修好了!它不喜欢地址有空格和逗号等。
希望这有助于其他人!
答案 11 :(得分:0)
我需要使用ISO-8859-1对参数进行编码,因此addsPercentEncoding()方法对我不起作用。 我在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
}
}
用法:
"aouäöü!".urlPercentEncoded(withAllowedCharacters: .urlQueryAllowed,
encoding: .isoLatin1)
// Results in -> "aou%E4%F6%FC!"
答案 12 :(得分:-1)
在我的情况下,最后一个组件是非拉丁字符,我在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;
}
}