Подтвердить что ты не робот

Как закодировать URL в 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)")
4b9b3361

Ответ 1

Swift 4.2

var urlString = originalString.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)

Swift 3.0

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)")

Используйте stringByAddingPercentEncodingWithAllowedCharacters:

var escapedAddress = address.stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.URLQueryAllowedCharacterSet())

Используйте stringByAddingPercentEscapesUsingEncoding: Устаревший в iOS 9 и OS X v10.11

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)")

Ответ 2

Если возможно, что значение, которое вы добавляете в свой URL, может иметь зарезервированные символы (как определено в разделе 2 RFC 3986), вам, возможно, придется уточнить экранирование percent-. Примечательно, что, хотя & и + являются допустимыми символами в URL, они недопустимы в значении параметра запроса URL (поскольку & используется в качестве разделителя между параметрами запроса, который преждевременно завершит ваше значение, а + преобразуется в пробел), К сожалению, стандартный выход percent- оставляет эти разделители без экранирования.

Таким образом, вы можете захотеть в процентах экранировать все символы, которые не входят в список незарезервированных символов RFC 3986:

Символы, которые разрешены в URI, но не имеют зарезервированной цели, называются незарезервированными. К ним относятся прописные и строчные буквы, десятичные цифры, дефис, точка, подчеркивание и тильда.

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

Позже, в разделе 3.4, RFC дополнительно рассматривает добавление ? и / к списку разрешенных символов в запросе:

Косая черта ("/") и знак вопроса ("?") Могут представлять данные в компоненте запроса. Помните, что некоторые старые, ошибочные реализации могут некорректно обрабатывать такие данные, когда они используются в качестве базового URI для относительных ссылок (раздел 5.1), очевидно, потому что они не могут отличить данные запроса от данных пути при поиске иерархических разделителей. Однако, поскольку компоненты запроса часто используются для передачи идентифицирующей информации в виде пар "ключ = значение", а одно часто используемое значение является ссылкой на другой URI, иногда для удобства использования лучше избегать кодирования этих символов percent-.

В настоящее время вы обычно используете 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!

Кстати, хотя это и не предусмотрено в вышеупомянутом RFC, раздел 5.2, данные формы в кодировке URL, спецификации HTML W3C говорит, что запросы 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, где я вручную выполняю весь этот процент, избегая себя, см. Предыдущую версию этого ответа.

Ответ 3

Swift 3:

let escapedString = originalString.addingPercentEncoding(withAllowedCharacters:NSCharacterSet.urlQueryAllowed)

Ответ 5

URLQueryAllowedCharacterSet не следует использовать для кодирования URL-адресов параметров запроса, поскольку в эту кодировку входят &, ?, / и т.д., которые служат в качестве разделителей в URL-запросе, например

/?paramname=paramvalue&paramname=paramvalue

Эти символы разрешены в URL-запросах в целом, но не в значениях параметров.

RFC 3986 говорит о символах unreserved, которые отличаются от разрешенных:

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 символов). И с учетом того, сколько символов Unicode alphanumericCharacterSet допускает, использование этого с целью кодирования URL будет просто ошибочным.

Использование:

let URLEncodedString = myString.URLEncoded

Ответ 6

XCODE 8, SWIFT 3.0

От grokswift

Создание URL-адресов из строк - это минное поле для ошибок. Просто пропустите одиночный/или случайно URL-код? в запросе и ваш вызов API не удастся, и ваше приложение не будет иметь никаких данных для отображения (или даже сбой, если вы не ожидали такой возможности). Поскольку iOS 8 - лучший способ создания URL-адресов с помощью 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
}

Ниже приведен код доступа к 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

Подробнее: Создание URL-адресов с помощью NSURLComponents и NSURLQueryItems

Ответ 7

Swift 4.1

Создайте "Набор символов" на основе требуемой опции (urlQueryAllowed). Затем удалите дополнительные символы, которые вам не нужны (+ &). Затем передайте этот набор символов в "добавлениеPercentEncoding".

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)")

Ответ 8

Обновлен для Swift 3:

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

Ответ 9

В 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)

Ответ 10

Просто завершите решение Desmond Hume, чтобы расширить класс String для RFC 3986 unreserved characters действительной функции кодирования (необходимо, если вы кодируете параметры запроса FORM):

Swift 3

extension String {

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

Ответ 11

Добавляя к Брайану Чену ответ выше:

Просто подставьте кого-нибудь еще что-то похожее на Alamofire:

Ошибка: Alamofire был скомпилирован с оптимизацией - степпинг может вести себя странно; переменные могут быть недоступны.

Это не очень описательная ошибка. Я получал эту ошибку при создании URL-адреса для гео-сервисов google. Я добавлял адрес улицы до конца URL БЕЗ кодирования самого адреса улицы. Я смог исправить это с помощью решения Bryan Chen:

var streetAdress = "123 fake street, new york, ny"
var escapedStreetAddress = streetAddress.stringByAddingPercentEncodingWithAllowedCharacters(.URLHostAllowedCharacterSet())
let url = "\(self.baseUrl)&address=\(escapedAddress!)"

Это исправило это для меня! Это не понравилось, что адрес имел пробелы и запятые и т.д.

Надеюсь, это поможет кому-то еще!

Ответ 12

Мне нужно было закодировать мои параметры с помощью ISO-8859-1, поэтому метод addPercentEncoding() не работает для меня. Я сделал решение самостоятельно в 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!"

Ответ 13

SWIFT 4.2

Иногда это происходит только потому, что в слаге ИЛИ отсутствует кодировка URL для параметров, проходящих через API URL.

let myString = self.slugValue
                let csCopy = CharacterSet(bitmapRepresentation: CharacterSet.urlPathAllowed.bitmapRepresentation)
                let escapedString = myString!.addingPercentEncoding(withAllowedCharacters: csCopy)!
                //always "info:hello%20world"
                print(escapedString)

ПРИМЕЧАНИЕ: не забудьте изучить bitmapRepresentation.

Ответ 14

В моем случае, когда последний компонент был не латинским символом, я сделал следующее в 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;
}
}