ios URL(string: ) 不总是工作
ios URL(string: ) not working always
let testurl = "http://akns-
images.eonline.com/eol_images/Entire_Site/2018029/rs_1024x759-
180129200032-1024.lupita-nyongo-angela-bassett-black-panther-
premiere.ct.012918.jpg?fit=inside|900:auto"
if let url = URL(string: testurl){
print("valid")
}else {
print("invalid")
}
这打印为无效 URL。但在网络浏览器中显示图像。我见过很多方法,但它会抛出 Apple 警告以使用 stringByAddingPercentEncodingWithAllowedCharacters
并且这并不总是有效。
我更喜欢清理 url 而不编码完整 url 字符串的解决方案。在传递给外部库时,在初始步骤对其进行编码可能会产生摩擦,外部库将重新编码 url 并使其无效。
请将您的行替换为:
let finalUrl = testurl.addingPercentEncoding( withAllowedCharacters: .urlUserAllowed)
if let url = URL(string: finalUrl){
print("valid")
} else {
print("invalid")
}
URL 编码对于从字符串构建 URL 是强制性的,以防它包含特殊字符。
为什么我们需要URL编码
来自 this answer:
A URI is represented as a sequence of characters, not as a sequence of octets. That is because URI might be "transported" by means that are not through a computer network, e.g., printed on paper, read over the radio, etc.
和
For original character sequences that contain non-ASCII characters, however, the situation is more difficult. Internet protocols that transmit octet sequences intended to represent character sequences are expected to provide some way of identifying the charset used, if there might be more than one [RFC2277]. However, there is currently no provision within the generic URI syntax to accomplish this identification. An individual URI scheme may require a single charset, define a default charset, or provide a way to indicate the charset used.
在 IOS SDK 中,我们有以下内容:
用户:URLUserAllowedCharacterSet
密码:URLPasswordAllowedCharacterSet
主持人:URLHostAllowedCharacterSet
路径:URLPathAllowedCharacterSet
片段:URLFragmentAllowedCharacterSet
查询:URLQueryAllowedCharacterSet
您可以使用 addingPercentEncoding(withAllowedCharacters:)
对字符串进行正确编码。
根据 the apple docs for that method 的重要说明:
Entire URL strings cannot be percent-encoded, because each URL component specifies a different set of allowed characters. For example, the query component of a URL allows the “@” character, but that character must be percent-encoded in the password component.
UTF-8 encoding is used to determine the correct percent-encoded characters. Any characters in allowedCharacters outside of the 7-bit ASCII range are ignored.
一个例子:
let encodedURL = testurl.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)
if let url = URL(string: finalUrl) {
print("valid url")
} else {
print("invalid url")
}
希望对您有所帮助。
使用URLComponents
,它会自动处理转义字符并正确编码url。无需使用 addingPercentEncoding
func computeURL() {
let testurlStr = "http://akns-images.eonline.com/eol_images/Entire_Site/2018029/rs_1024x759-180129200032-1024.lupita-nyongo-angela-bassett-black-panther-premiere.ct.012918.jpg?fit=inside|900:auto"
let components = transformURLString(testurlStr)
if let url = components?.url {
print("valid")
} else {
print("invalid")
}
}
func transformURLString(_ string: String) -> URLComponents? {
guard let urlPath = string.components(separatedBy: "?").first else {
return nil
}
var components = URLComponents(string: urlPath)
if let queryString = string.components(separatedBy: "?").last {
components?.queryItems = []
let queryItems = queryString.components(separatedBy: "&")
for queryItem in queryItems {
guard let itemName = queryItem.components(separatedBy: "=").first,
let itemValue = queryItem.components(separatedBy: "=").last else {
continue
}
components?.queryItems?.append(URLQueryItem(name: itemName, value: itemValue))
}
}
return components!
}
我想我已经找到答案了。仍然会检查是否有任何副作用,欢迎评论:
let urlst = "http://akns-
images.eonline.com/eol_images/Entire_Site/2018029/rs_1024x759-
180129200032-1024.lupita-nyongo-angela-bassett-black-panther-
premiere.ct.012918.jpg?fit=inside|900:auto"
extension String {
func getCleanedURL() -> URL? {
guard self.isEmpty == false else {
return nil
}
if let url = URL(string: self) {
return url
} else {
if let urlEscapedString = self.addingPercentEncoding(withAllowedCharacters: CharacterSet.urlQueryAllowed) , let escapedURL = URL(string: urlEscapedString){
return escapedURL
}
}
return nil
}
}
这不会对完整的 URL 进行编码,而只会对无效的查询字符进行编码(例如 url 其“|”)。因此它仍然可以作为字符串或有效的 URL 传递。
根据您自己的回答,我什至会进一步简化它,使其成为 URL 的扩展而不是 String,这样我们仍然可以使用类似于 URL(字符串:) 具有相同的输出:
extension URL {
init?(_ string: String) {
guard string.isEmpty == false else {
return nil
}
if let url = URL(string: string) {
self = url
} else if let urlEscapedString = string.addingPercentEncoding(withAllowedCharacters: CharacterSet.urlQueryAllowed),
let escapedURL = URL(string: urlEscapedString) {
self = escapedURL
} else {
return nil
}
}
}
let testurl = "http://akns-
images.eonline.com/eol_images/Entire_Site/2018029/rs_1024x759-
180129200032-1024.lupita-nyongo-angela-bassett-black-panther-
premiere.ct.012918.jpg?fit=inside|900:auto"
if let url = URL(string: testurl){
print("valid")
}else {
print("invalid")
}
这打印为无效 URL。但在网络浏览器中显示图像。我见过很多方法,但它会抛出 Apple 警告以使用 stringByAddingPercentEncodingWithAllowedCharacters
并且这并不总是有效。
我更喜欢清理 url 而不编码完整 url 字符串的解决方案。在传递给外部库时,在初始步骤对其进行编码可能会产生摩擦,外部库将重新编码 url 并使其无效。
请将您的行替换为:
let finalUrl = testurl.addingPercentEncoding( withAllowedCharacters: .urlUserAllowed)
if let url = URL(string: finalUrl){
print("valid")
} else {
print("invalid")
}
URL 编码对于从字符串构建 URL 是强制性的,以防它包含特殊字符。
为什么我们需要URL编码
来自 this answer:
A URI is represented as a sequence of characters, not as a sequence of octets. That is because URI might be "transported" by means that are not through a computer network, e.g., printed on paper, read over the radio, etc.
和
For original character sequences that contain non-ASCII characters, however, the situation is more difficult. Internet protocols that transmit octet sequences intended to represent character sequences are expected to provide some way of identifying the charset used, if there might be more than one [RFC2277]. However, there is currently no provision within the generic URI syntax to accomplish this identification. An individual URI scheme may require a single charset, define a default charset, or provide a way to indicate the charset used.
在 IOS SDK 中,我们有以下内容:
用户:URLUserAllowedCharacterSet
密码:URLPasswordAllowedCharacterSet
主持人:URLHostAllowedCharacterSet
路径:URLPathAllowedCharacterSet
片段:URLFragmentAllowedCharacterSet
查询:URLQueryAllowedCharacterSet
您可以使用 addingPercentEncoding(withAllowedCharacters:)
对字符串进行正确编码。
根据 the apple docs for that method 的重要说明:
Entire URL strings cannot be percent-encoded, because each URL component specifies a different set of allowed characters. For example, the query component of a URL allows the “@” character, but that character must be percent-encoded in the password component.
UTF-8 encoding is used to determine the correct percent-encoded characters. Any characters in allowedCharacters outside of the 7-bit ASCII range are ignored.
一个例子:
let encodedURL = testurl.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)
if let url = URL(string: finalUrl) {
print("valid url")
} else {
print("invalid url")
}
希望对您有所帮助。
使用URLComponents
,它会自动处理转义字符并正确编码url。无需使用 addingPercentEncoding
func computeURL() {
let testurlStr = "http://akns-images.eonline.com/eol_images/Entire_Site/2018029/rs_1024x759-180129200032-1024.lupita-nyongo-angela-bassett-black-panther-premiere.ct.012918.jpg?fit=inside|900:auto"
let components = transformURLString(testurlStr)
if let url = components?.url {
print("valid")
} else {
print("invalid")
}
}
func transformURLString(_ string: String) -> URLComponents? {
guard let urlPath = string.components(separatedBy: "?").first else {
return nil
}
var components = URLComponents(string: urlPath)
if let queryString = string.components(separatedBy: "?").last {
components?.queryItems = []
let queryItems = queryString.components(separatedBy: "&")
for queryItem in queryItems {
guard let itemName = queryItem.components(separatedBy: "=").first,
let itemValue = queryItem.components(separatedBy: "=").last else {
continue
}
components?.queryItems?.append(URLQueryItem(name: itemName, value: itemValue))
}
}
return components!
}
我想我已经找到答案了。仍然会检查是否有任何副作用,欢迎评论:
let urlst = "http://akns-
images.eonline.com/eol_images/Entire_Site/2018029/rs_1024x759-
180129200032-1024.lupita-nyongo-angela-bassett-black-panther-
premiere.ct.012918.jpg?fit=inside|900:auto"
extension String {
func getCleanedURL() -> URL? {
guard self.isEmpty == false else {
return nil
}
if let url = URL(string: self) {
return url
} else {
if let urlEscapedString = self.addingPercentEncoding(withAllowedCharacters: CharacterSet.urlQueryAllowed) , let escapedURL = URL(string: urlEscapedString){
return escapedURL
}
}
return nil
}
}
这不会对完整的 URL 进行编码,而只会对无效的查询字符进行编码(例如 url 其“|”)。因此它仍然可以作为字符串或有效的 URL 传递。
根据您自己的回答,我什至会进一步简化它,使其成为 URL 的扩展而不是 String,这样我们仍然可以使用类似于 URL(字符串:) 具有相同的输出:
extension URL {
init?(_ string: String) {
guard string.isEmpty == false else {
return nil
}
if let url = URL(string: string) {
self = url
} else if let urlEscapedString = string.addingPercentEncoding(withAllowedCharacters: CharacterSet.urlQueryAllowed),
let escapedURL = URL(string: urlEscapedString) {
self = escapedURL
} else {
return nil
}
}
}