【问题标题】:POST request in Swift 3.0Swift 3.0 中的 POST 请求
【发布时间】:2017-09-30 21:10:35
【问题描述】:

我正在尝试使用 Swift 中的发布请求从 Web 服务获取响应。但是我收到“无法读取数据,因为它的格式不正确”错误。以下是代码:

let dict = ["UserName": "2222211111",
                        "Password": "123456",
                        "AppName": "xyz"]
                as [String: Any]

            //create the session object
            let session = URLSession.shared
            let url = "someurl.svc/somefunction"

            //now create the URLRequest object using the url object
            var request = URLRequest(url: url)
            request.httpMethod = "POST" //set http method as POST

            do {
                request.httpBody = try JSONSerialization.data(withJSONObject: dict, options: .prettyPrinted)

            } catch let error {
                print(error.localizedDescription)
            }

            request.addValue("application/json", forHTTPHeaderField: "Content-Type")
            request.addValue("application/json", forHTTPHeaderField: "Accept")

            //create dataTask using the session object to send data to the server
            let task = session.dataTask(with: request as URLRequest, completionHandler: { data, response, error in

                guard error == nil else {
                    return
                }

                guard let data = data else {
                    return
                }

                do {
                    //create json object from data
                    if let json = try JSONSerialization.jsonObject(with: data, options: .mutableContainers) as? [String: Any] {
                        print(json)
                    }

                } catch let error {
                    print(error.localizedDescription)
                }
            })
            task.resume()

我什至使用过 Alamofire、Networking 等第三方库。从这些库中我得到代码 3840,字符 3 周围的响应无效。 但是我使用 Objective-C 代码或使用 Postman Software 得到了正确的响应。 有人可以帮我吗? 谢谢

【问题讨论】:

  • 你试过 alamofire 了吗?
  • 您返回的响应可能不是有效的 JSON 格式。在尝试序列化之前尝试打印响应。这将是一个好的开始。
  • 添加您收到的回复。 Postman 在自己的层面解决了很多问题,所以在 Postman 上工作的 api 不一定在 app 上工作。
  • 除此问题外,请勿将漂亮打印数据发送到服务器。服务器不在乎美观。
  • 我认为你弄错了有效的 Json 格式,所以需要从服务器端改进

标签: ios swift swift3 alamofire nsurlsession


【解决方案1】:
   func postData(_ params : Dictionary<String, String>?,contenturl:String,postCompleted : @escaping (_ jsonDict:NSDictionary, _ msg: NSInteger) -> ()) {
    let url = URL(string: contenturl)
    var request = URLRequest(url: url!)
    let session = URLSession.shared
    request.httpMethod = "POST"
    if(params != nil){
        request.httpBody =  self.getParam(params! as NSDictionary).data(using: String.Encoding.utf8.rawValue)
    }
    request.addValue("application/json", forHTTPHeaderField: "Content-Type")
    request.addValue("application/json", forHTTPHeaderField: "Accept")

    let task = session.dataTask(with: request, completionHandler: {data, response, error -> Void in
        if(data == nil){
           // do something
        }else{
            _ = NSString(data: data!, encoding: String.Encoding.utf8.rawValue)
            do{
                let json = try JSONSerialization.jsonObject(with: data!, options: .mutableLeaves) as? NSDictionary
                if let parseJSON = json {
                    postCompleted(parseJSON, (parseJSON["response_code"] as? NSInteger)!)
                }
            }catch{
                print("Failure")
            }
        }
    })
    task.resume()
}

 func getParam(_ params: NSDictionary) -> NSString{
    var passparam : NSString!
    do {
        let jsonData = try JSONSerialization.data(withJSONObject: params, options: JSONSerialization.WritingOptions.prettyPrinted)
        // here "jsonData" is the dictionary encoded in JSON data
        let theJSONText = NSString(data: jsonData,
                                   encoding: String.Encoding.ascii.rawValue)
        passparam = theJSONText!
    } catch let error as NSError {
        print("getParam() \(error)")
        passparam = ""
    }
    print("getParam() \(passparam!)")
    return passparam
}

【讨论】:

  • 不要在 Swift 中使用 NSStringNSDictionary。根据您的昵称,您应该知道。
  • 加 1 不使用第三方包,特别是。
【解决方案2】:

以下是带有参数的 Alamofire POST api 调用示例;内容类型并接受标题,试试这个。

func performPOSTLogin() -> Void {
        var parameters = [String:String]()
        parameters["email"] = "p@p.com"
        parameters["password"] = "abcd1234"

        let headers: HTTPHeaders = ["Authorization": "sxfsdfsdfsfsfsf", "Accept": "application/json", "Content-Type" :"application/json"]

        Alamofire.request("http://domainname/folder/folder/folder/apiname/", method: .post, parameters: parameters, encoding: JSONEncoding.default, headers: headers).responseJSON { response in

            // original URL request
            print("Request is :",response.request!)

            // HTTP URL response --> header and status code
            print("Response received is :",response.response!)

            // server data : example 267 bytes
            print("Response data is :",response.data!)

            // result of response serialization : SUCCESS / FAILURE
            print("Response result is :",response.result)

            debugPrint("Debug Print :", response)
        }
    }

【讨论】:

  • 使用这个得到响应。这里只是一个更正,我删除了 apiname 之后的 slach(/)。使用斜线导致 api 调用失败。
  • 我能知道为什么“HTTPHeaders”中有“授权”键吗?我没有将它包含在我的代码中。
  • 斜线需求取决于 web api 实现,对于 Authorization 标头来说,它是所有 api 调用中强制发送的关键。基本上是服务器 api 配置。很高兴它对你有用!
  • 知道了。谢谢普里亚尔。 :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-12-06
  • 2014-07-26
  • 1970-01-01
  • 2020-02-10
相关资源
最近更新 更多