Sending simple POST in Swift, getting “Empty Post” response

我的梦境 提交于 2019-12-23 01:24:31

问题


I have registration page in my iOS app that I'm trying to write in Swift. The first thing I'm testing out is sending a POST with the email address, this is the way I'm doing so:

var bodyData = ("userEmail=%@\" \" &userPassword=%@\" \"&userDevice=%@\" \"", emailAddress.text, password.text, deviceModel)

    let dataToSend = (bodyData as NSString).dataUsingEncoding(NSUTF8StringEncoding)

            request.HTTPMethod = "POST"
            request.HTTPBody = dataToSend
            let task = NSURLSession.sharedSession().dataTaskWithRequest(request) {
                data, response, error in

                if error != nil {
                    print("error=\(error)")
                    return
                }
                // print("response = \(response)")

                let responseString = NSString(data: data!, encoding: NSUTF8StringEncoding)
                print("responseString = \(responseString)")
            }
            task.resume()

However, I'm getting a message back stating that it was an empty post. This is the exact response from the output above: responseString = Optional({"complete":"false","message":"Empty Post"}) I've researched different ways to send a simple POST in Swift, and this appears to be correct. I can't see anything wrong with it or why it would output a message saying that the post was empty... Except for maybe the format of the string?

The database is expecting multiple things for the "new user" service, and I'm only sending one part due to it being a test. Could this be the issue? The new-user service is expecting:

Service URL : https://test.com/services/new-user/
Required Post Fields:
For New User:
'userEmail'
'userPassword'
'userDevice'

(From the documentation).

I haven't worked with web services much. After brainstorming more I think these may be the culprits: I may be getting the response back because I'm not sending all the data at once. I also may be sending it incorrectly. Can I send it as text or do I need to send it as JSON?


回答1:


A couple of issues:

  1. You have a line that says:

    var bodyData = ("userEmail=%@\" \" &userPassword=%@\" \"&userDevice=%@\" \"", emailAddress.text, password.text, deviceModel)
    

    That does not do what you intended. It's creating a tuple with four items that consists of a format string and three values, not a single formatted string. Print the bodyData and you'll see what I mean.

    You either want to use String(format: ...), or even easier, use string interpolation. (See code snippet below.)

  2. Assuming that emailAddress and password are UITextField objects, note that the text property is optional, so you have to unwrap those optionals before you use them. Look at the bodyData string and you'll see what I mean.

    I don't know if deviceModel was optional as well, but if so, unwrap that, too.

  3. You have a space right before the userPassword parameter of the request. That will make it not well formed. Remove that space. You can probably simplify that format string by getting rid of a bunch of those \" references, too.

  4. You probably should be specifying the Content-Type of the request. It's often not necessary, but it's good practice.

  5. You're clearly getting a JSON response, so you might want to parse it.

Thus, you might do something like:

guard emailAddress.text != nil && password.text != nil else {
    print("please fill in both email address and password")
    return
}

// use 
//
// let bodyString = String(format: "userEmail=%@&userPassword=%@&userDevice=%@", emailAddress.text!, password.text!, deviceModel)
//
// or use string interpolation, like below:

let bodyString = "userEmail=\(emailAddress.text!)&userPassword=\(password.text!)&userDevice=\(deviceModel)"

let bodyData = bodyString.dataUsingEncoding(NSUTF8StringEncoding)

request.HTTPMethod = "POST"
request.HTTPBody = bodyData
request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")

let task = NSURLSession.sharedSession().dataTaskWithRequest(request) { data, response, error in
    guard error == nil && data != nil else {
        print("error=\(error)")
        return
    }

    do {
        let responseObject = try NSJSONSerialization.JSONObjectWithData(data!, options: [])

        print(responseObject)
    } catch let parseError as NSError {
        print(parseError)
    }
}
task.resume()

Note, you really should be percent-escaping the values you are adding to the body, too (notably, if the values might have spaces, +, &, or other reserved characters in them). See https://stackoverflow.com/a/28027627/1271826.

If you don't want to get into the weeds of this sort of stuff, consider using a framework like Alamofire, which takes care of this stuff for you. For example:

guard emailAddress.text != nil && password.text != nil else {
    print("please fill in both email address and password")
    return
}

let parameters = [
    "userEmail" : emailAddress.text!,
    "userPassword" : password.text!,
    "userDevice" : deviceModel
]

Alamofire.request(.POST, urlString, parameters: parameters)
    .responseJSON { response in
        switch response.result {
        case .Failure(let error):
            print(error)
        case .Success(let value):
            print(value)
        }
}


来源:https://stackoverflow.com/questions/33508406/sending-simple-post-in-swift-getting-empty-post-response

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!