web-dev-qa-db-ja.com

Swift 2.0のURLにstringByAddingPercentEncodingWithAllowedCharacters()を使用する方法

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です。

しかし、私はその側面を整えたくありません。たとえば、myurlstringなどの文字列を使用すると、失敗します。

しかし、以下を使用した場合、問題はありませんでした。文字列を魔法でエンコードし、URLデータを取得できました。

let urlwithPercentEscapes = myurlstring.stringByAddingPercentEscapesUsingEncoding(NSUTF8StringEncoding)

そのまま

指定されたエンコーディングを使用して文字列の表現を返し、文字列を有効なURL文字列に変換するために必要なパーセントエスケープを決定します

ありがとう

63
DogCoffee

指定されたURL文字列に対して

let urlwithPercentEscapes = myurlstring.stringByAddingPercentEscapesUsingEncoding(NSUTF8StringEncoding)

文字セットURLQueryAllowedCharacterSetです

let urlwithPercentEscapes = myurlstring.stringByAddingPercentEncodingWithAllowedCharacters( NSCharacterSet.URLQueryAllowedCharacterSet())

スウィフト3:

let urlwithPercentEscapes = myurlstring.addingPercentEncoding( withAllowedCharacters: .urlQueryAllowed)

URL文字列の疑問符の後のすべてをエンコードします。

メソッドstringByAddingPercentEncodingWithAllowedCharactersはnilを返すことができるため、Leo Dabusの回答で提案されているオプションのバインディングを使用します。

150
vadian

URLに依存します。 URLがパスの場合、文字セット rlPathAllowed を使用できます

let myFileString = "My File.txt"
if let urlwithPercentEscapes = myFileString.addingPercentEncoding(withAllowedCharacters: .urlPathAllowed) {
    print(urlwithPercentEscapes)  // "My%20File.txt"
}

RLエンコード用の文字セットの作成

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

別のオプションは RLComponentsを使用してURLを適切に作成する です

17
Leo Dabus

Swift 3.0(From grokswift

文字列からURLを作成することは、バグの地雷原です。単一の/または誤ってURLエンコードを逃すだけですか?クエリでAPI呼び出しが失敗し、アプリに表示するデータがなくなります(または、その可能性を予期していなかった場合はクラッシュします)。 iOS 8以降、NSURLComponentsおよびNSURLQueryItemsを使用してURLを構築するより良い方法があります。

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
}

以下は、guardステートメントを使用してurlにアクセスするためのコードです。

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
6
Ashok R

Swift 3.1では、次のようなものを使用しています。

let query = "param1=value1&param2=" + valueToEncode.addingPercentEncoding(withAllowedCharacters: .alphanumeric)

これは、.urlQueryAllowedやその他のものより安全です。A-Z、a-z、0-9以外のすべての文字をエンコードするためです。これは、エンコードする値に?、&、=、+、スペースなどの特殊文字を使用できる場合に効果的です。

3

最後のコンポーネントが非ラテン文字である私の場合、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;
}
}
2
Bobj-C

Swift 4.

let encodedData = myUrlString.addingPercentEncoding(withAllowedCharacters: CharacterSet.urlHostAllowed)
1
Supertecnoboff