Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
388 views
in Technique[技术] by (71.8m points)

ios - How to escape the HTTP params in Swift

I'm trying to make a post to an HTTP server

By the way this is my code:

  func sendPostToUrl(url:String, withParams params: [String: String?] ) {
    var request = NSMutableURLRequest(URL: NSURL(string: url)!)
    var session = NSURLSession.sharedSession()
    request.HTTPMethod = "POST"

    var err: NSError?
    var bodyData = ""
    for (key,value) in params{
        if (value==nil){ continue }
        let scapedKey = key.stringByAddingPercentEncodingWithAllowedCharacters(
                 .URLHostAllowedCharacterSet())!
        let scapedValue = value!.stringByAddingPercentEncodingWithAllowedCharacters(
                .URLHostAllowedCharacterSet())!
        bodyData += "(scapedKey)=(scapedValue)&"
    }
    request.HTTPBody = bodyData.dataUsingEncoding
               (NSUTF8StringEncoding, allowLossyConversion: true)

    var task = session.dataTaskWithRequest(request, 
    completionHandler: {data, response, error -> Void in
        println("Response: (response)")
        let dataString = NSString(data: data, encoding: NSUTF8StringEncoding)
        println("Data: (dataString)")

    })
    task.resume()
}

It works but is not perfect. If I call the function this way:

    client.sendPostToUrl("http://novagecko.com/tests/test.php", 
        withParams: ["hello":"world","inject":"param1=value1&param2=value2"]);

The server detects 3 post fields (with keys hello,inject and param2) instead of 2.

How can I escape the key and values?

Is there something more I could do for improving the method?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

If you can target iOS 8 (thanks @Rob), use NSURLComponents to escape your parameters instead:

import Foundation

func encodeParameters(#params: [String: String]) -> String {
    var queryItems = map(params) { NSURLQueryItem(name:$0, value:$1)}
    var components = NSURLComponents()
    components.queryItems = queryItems
    return components.percentEncodedQuery ?? ""
}

Now encodeParameters(params:["hello":"world","inject":"param1=value1&param2=value2"]) returns hello=world&inject=param1%3Dvalue1%26param2%3Dvalue2 as you would expect.

Otherwise, the best way to create the character set that will let you escape your values properly is this:

var safeCharacterSet = NSCharacterSet.URLQueryAllowedCharacterSet().mutableCopy()
safeCharacterSet.removeCharactersInString("&=")

and see @rintaro's answer to use filter/map properly to perform the encoding in a nice way.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...