Как использовать stringByAddingPercentEncodingWithAllowedCharacters() для URL-адреса в Swift 2.0
Я использовал это в Swift 1.2
let urlwithPercentEscapes = myurlstring.stringByAddingPercentEscapesUsingEncoding(NSUTF8StringEncoding)
Теперь это дает мне предупреждение с просьбой использовать
stringByAddingPercentEncodingWithAllowedCharacters
Мне нужно использовать NSCharacterSet как аргумент, но их так много, и я не могу определить, какой из них даст мне тот же результат, что и использованный ранее метод.
Пример URL, который я хочу использовать, будет выглядеть следующим образом
http://www.mapquestapi.com/geocoding/v1/batch?key=YOUR_KEY_HERE&callback=renderBatch&location=Pottsville,PA&location=Red Lion&location=19036&location=1090 N Charlotte St, Lancaster, PA
Набор символов URL для кодировки, по-видимому, содержит настройки:
URL. т.е.
Компонент пути URL-адреса - это компонент, следующий за хост-компонент (если имеется). Он заканчивается там, где запрос или фрагмент компонент начинается. Например, в URL-адресе http://www.example.com/index.php?key1=value1, компонент пути /index.php.
Однако я не хочу обрезать любой аспект этого.
Когда я использовал свою String, например myurlstring
, она потерпит неудачу.
Но когда используется следующее, тогда проблем не было. Он закодировал строку с некоторой магией, и я мог получить данные URL.
let urlwithPercentEscapes = myurlstring.stringByAddingPercentEscapesUsingEncoding(NSUTF8StringEncoding)
Как он
Возвращает представление строки, используя заданную кодировку, для определить процентные escape-последовательности, необходимые для преобразования String в юридическая строка URL
Спасибо
Ответы
Ответ 1
Для данной строки URL эквивалент
let urlwithPercentEscapes = myurlstring.stringByAddingPercentEscapesUsingEncoding(NSUTF8StringEncoding)
- набор символов URLQueryAllowedCharacterSet
let urlwithPercentEscapes = myurlstring.stringByAddingPercentEncodingWithAllowedCharacters( NSCharacterSet.URLQueryAllowedCharacterSet())
Swift 3:
let urlwithPercentEscapes = myurlstring.addingPercentEncoding( withAllowedCharacters: .urlQueryAllowed)
Он кодирует все после знака вопроса в строке URL.
Так как метод stringByAddingPercentEncodingWithAllowedCharacters
может возвращать нуль, используйте необязательные привязки, как предложено в ответе Льва Дабуса.
Ответ 2
Это будет зависеть от вашего URL. Если ваш URL-адрес - это путь, вы можете использовать набор символов urlPathAllowed
let myFileString = "My File.txt"
if let urlwithPercentEscapes = myFileString.addingPercentEncoding(withAllowedCharacters: .urlPathAllowed) {
print(urlwithPercentEscapes) // "My%20File.txt"
}
Создание набора символов для кодировки URL
urlFragmentAllowed
urlHostAllowed
urlPasswordAllowed
urlQueryAllowed
urlUserAllowed
Вы также можете создать собственный набор символов URL:
let myUrlString = "http://www.mapquestapi.com/geocoding/v1/batch?key=YOUR_KEY_HERE&callback=renderBatch&location=Pottsville,PA&location=Red Lion&location=19036&location=1090 N Charlotte St, Lancaster, PA"
let urlSet = CharacterSet.urlFragmentAllowed
.union(.urlHostAllowed)
.union(.urlPasswordAllowed)
.union(.urlQueryAllowed)
.union(.urlUserAllowed)
extension CharacterSet {
static let urlAllowed = CharacterSet.urlFragmentAllowed
.union(.urlHostAllowed)
.union(.urlPasswordAllowed)
.union(.urlQueryAllowed)
.union(.urlUserAllowed)
}
if let urlwithPercentEscapes = myUrlString.addingPercentEncoding(withAllowedCharacters: .urlAllowed) {
print(urlwithPercentEscapes) // "http://www.mapquestapi.com/geocoding/v1/batch?key=YOUR_KEY_HERE&callback=renderBatch&location=Pottsville,PA&location=Red%20Lion&location=19036&location=1090%20N%20Charlotte%20St,%20Lancaster,%20PA"
}
Другой вариант - использовать URLComponents для правильного создания URL-адреса
Ответ 3
SWIFT 3.0
От grokswift
Создание URL-адресов из строк - это минное поле для ошибок. Просто пропустите одиночный/или случайно URL-код? в запросе и ваш вызов API не удастся, и ваше приложение не будет иметь никаких данных для отображения (или даже сбой, если вы не ожидали такой возможности). Поскольку iOS 8 - лучший способ создания URL-адресов с помощью NSURLComponents
и NSURLQueryItems
.
func createURLWithComponents() -> URL? {
var urlComponents = URLComponents()
urlComponents.scheme = "http"
urlComponents.host = "www.mapquestapi.com"
urlComponents.path = "/geocoding/v1/batch"
let key = URLQueryItem(name: "key", value: "YOUR_KEY_HERE")
let callback = URLQueryItem(name: "callback", value: "renderBatch")
let locationA = URLQueryItem(name: "location", value: "Pottsville,PA")
let locationB = URLQueryItem(name: "location", value: "Red Lion")
let locationC = URLQueryItem(name: "location", value: "19036")
let locationD = URLQueryItem(name: "location", value: "1090 N Charlotte St, Lancaster, PA")
urlComponents.queryItems = [key, callback, locationA, locationB, locationC, locationD]
return urlComponents.url
}
Ниже приведен код доступа к URL-адресу с помощью инструкции guard
.
guard let url = createURLWithComponents() else {
print("invalid URL")
return nil
}
print(url)
Выход:
http://www.mapquestapi.com/geocoding/v1/batch?key=YOUR_KEY_HERE&callback=renderBatch&location=Pottsville,PA&location=Red%20Lion&location=19036&location=1090%20N%20Charlotte%20St,%20Lancaster,%20PA
Ответ 4
В моем случае, когда последний компонент был не латинским символом, я сделал следующее в 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;
}
}
Ответ 5
В Swift 3.1 я использую что-то вроде следующего:
let query = "param1=value1¶m2=" + valueToEncode.addingPercentEncoding(withAllowedCharacters: .alphanumeric)
Это безопаснее, чем .urlQueryAllowed и другие, потому что это будет кодировать все символы, отличные от A-Z, a-z и 0-9. Это лучше работает, когда значение, которое вы кодируете, может использовать специальные символы, такие как?, &, =, + и пробелы.