在 Swift 中发送简单的 POST,得到 "Empty Post" 响应

Sending simple POST in Swift, getting "Empty Post" response

我的 iOS 应用程序中有注册页面,我正尝试在 Swift 中编写。我要测试的第一件事是发送带有电子邮件地址的 POST,这就是我这样做的方式:

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

但是,我收到一条消息说它是空的 post。这是上面输出的确切响应:responseString = Optional({"complete":"false","message":"Empty Post"}) 我研究了在 Swift 中发送简单 POST 的不同方法,这似乎是正确的。我看不出它有什么问题或者为什么它会输出一条消息说 post 是空的...除了字符串的格式?

数据库需要 "new user" 服务的多项内容,由于它是测试,我只发送了一部分。这可能是问题所在吗?新用户服务期待:

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

(来自文档)。

我没有太多使用 Web 服务。经过更多的头脑风暴后,我认为这些可能是罪魁祸首:我可能会收到回复,因为我没有立即发送所有数据。我也可能发送错误。我可以以文本形式发送还是需要以 JSON 形式发送?

几个问题:

  1. 您有一行内容为:

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

    这不符合您的预期。它正在创建一个包含四个项目的元组,其中包含一个格式字符串和三个值,而不是单个格式化字符串。打印 bodyData 你就会明白我的意思了。

    您要么想使用 String(format: ...),要么更简单,使用字符串插值。 (请参阅下面的代码片段。)

  2. 假设 emailAddresspasswordUITextField 对象,注意 text 属性 是可选的,所以你有在使用它们之前解开这些可选值。查看 bodyData 字符串,您就会明白我的意思。

    我不知道 deviceModel 是否也是可选的,但如果是的话,也打开它。

  3. 您在请求的 userPassword 参数之前有一个 space。这将使它的格式不正确。删除 space。您也可以通过删除一堆 \" 引用来简化该格式字符串。

  4. 您可能应该指定请求的 Content-Type。通常没有必要,但这是一个很好的做法。

  5. 您显然收到了 JSON 响应,因此您可能想要解析它。

因此,您可以这样做:

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

注意,你真的应该对你添加到正文中的值进行百分比转义(值得注意的是,如果这些值可能有 spaces、+& , 或其中的其他保留字符)。参见

如果您不想涉足这类问题,请考虑使用像 Alamofire 这样的框架,它会为您处理这些问题。例如:

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