Programing

Swift에서 URL을 인코딩하는 방법

lottogame 2020. 7. 9. 08:24
반응형

Swift에서 URL을 인코딩하는 방법


이것은 나의 것 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)")

스위프트 4.2

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

스위프트 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)")

URL에 추가하는 값에 RFC 3986 의 섹션 2에 정의 된대로 예약 문자 가있을 수 있으면 퍼센트 이스케이프를 세분화해야합니다. 동안 특히, &+URL이 유효 문자는 (때문에, 그들은 URL 쿼리 매개 변수 값 내에서 유효하지 않은 &조기에 당신의 가치를 종료 할 쿼리 매개 변수 사이의 구분 기호로 사용되며, +공백 문자로 변환됩니다). 불행히도, 표준 퍼센트 이스케이프는 이러한 구분 기호를 이스케이프 처리하지 않습니다.

따라서 RFC 3986의 예약되지 않은 문자 목록에없는 모든 문자를 이스케이프 처리하려고 할 수 있습니다.

URI에서 허용되지만 예약 된 용도가없는 문자를 예약되지 않은 전화라고합니다. 여기에는 대문자와 소문자, 십진수, 하이픈, 마침표, 밑줄 및 물결표가 포함됩니다.

     예약되지 않음 = ALPHA / DIGIT / "-"/ "." / "_"/ "~"

나중에 섹션 3.4에서 RFC 는 쿼리 내에서 허용되는 문자 목록을 추가 ?하고 추가 /합니다.

슬래시 ( "/") 및 물음표 ( "?")는 쿼리 구성 요소 내의 데이터를 나타낼 수 있습니다. 상대적으로 오래된 일부 구현에서는 이러한 데이터가 상대 참조 (5.1 절)의 기본 URI로 사용될 때 이러한 데이터를 올바르게 처리하지 못할 수 있습니다. 계층 적 구분 기호를 찾을 때 쿼리 데이터와 경로 데이터를 구분하지 못하기 때문입니다. 그러나 쿼리 구성 요소는 종종 "key = value"쌍의 형태로 식별 정보를 전달하는 데 사용되며 자주 사용되는 하나의 값이 다른 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, 섹션 5.2, URL로 인코딩 된 양식 데이터에서는 고려되지 않았지만 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 :

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

스위프트 2.0

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

유용한 프로그래밍 팁 및 해킹


URLQueryAllowedCharacterSet이 캐릭터가 포함되어 있기 때문에 URL 쿼리 파라미터를 인코딩하는 데 사용되어서는 안된다 &, ?, /등을 예를 들면 URL 쿼리 구분자로서 역할을하는

/?paramname=paramvalue&paramname=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허용 되는지를 고려할 때 URL 인코딩 목적으로 사용하는 것은 단순히 잘못된 것입니다.

용법:

let URLEncodedString = myString.URLEncoded

XCODE 8, SWIFT 3.0

grokswift에서

문자열에서 URL을 작성하는 것은 버그의 지뢰밭입니다. 단일 또는 실수로 URL 인코딩 된 URL을 놓치면됩니다. 쿼리에서 API 호출이 실패하고 앱에 표시 할 데이터가 없습니다 (또는 그 가능성을 예상하지 않으면 충돌이 발생할 수도 있음). iOS 8부터 NSURLComponentsand를 사용하여 URL을 작성하는 더 좋은 방법이 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
}

아래는 guardstatement를 사용하여 URL에 액세스하는 코드 입니다.

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

더 읽기 : NSURLComponents 및 NSURLQueryItems를 사용하여 URL 작성


스위프트 4.1

Create a "Character Set" based on the option you want (urlQueryAllowed). Then remove the additional characters you do not want (+&). Then pass that character set to "addingPercentEncoding".

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

Updated for Swift 3:

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

In Mac OS 10.9 Maverics and iOS 7 NSURLComponents has been introduced which handles the encoding of the different URL parts in a pretty convenient way.

The NSURLComponents class is a class that is designed to parse URLs based on RFC 3986 and to construct URLs from their constituent parts. Its behavior differs subtly from the NSURL class, which conforms to older RFCs. However, you can easily obtain an NSURL object based on the contents of a URL components object or vice versa.

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)

Just completing Desmond Hume's answer to extend the String class for a RFC 3986 unreserved characters valid encoding function (needed if you are encoding query FORM parameters):

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
    }
}

Adding to Bryan Chen's answer above:

Just incase anyone else is getting something similar with Alamofire:

error: Alamofire was compiled with optimization - stepping may behave oddly; variables may not be available.

It's not a very descriptive error. I was getting that error when constructing a URL for google geo services. I was appending a street address to the end of the URL WITHOUT encoding the street address itself first. I was able to fix it using Bryan Chen's solution:

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

That fixed it for me! It didnt like that the address had spaces and commas, etc.

Hope this helps someone else!


I needed to encode my parameters with ISO-8859-1, so the addingPercentEncoding() method doesn't work for me. I made a solution my self in 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
  }

}

Usage:

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

In my case where the last component was non latin characters I did the following in 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;
}
}

참고URL : https://stackoverflow.com/questions/24879659/how-to-encode-a-url-in-swift

반응형