Swift-4: Как получить данные, используя запрос POST с параметрами в URLSession с «Content-Type»: «application / x-www-form-urlencoded» - PullRequest
0 голосов
/ 20 ноября 2018

Друзья, я просмотрел множество примеров, которые доступны на SO. Хотя я не получил правильного ответа, и все же я сталкиваюсь с проблемой получения данных через API-запрос с использованием URLSession с Post-запросом и передачи параметров сЭто.

Во-первых, я хотел бы показать вам, что у меня есть.пытался до сих пор ...

func requestApiCall(){

    let renewal_id = ""
    let policy_no = ""
    let client_name = ""
    let client_id = ""
    let product_name = ""
    let created_date_from = ""
    let created_date_to = ""
    let policy_expiry_from = ""
    let policy_expiry_to = ""

    self.parameters = ["renewal_id":renewal_id,"policy_no":policy_no,"client_name":client_name,"client_id":client_id,"product_name":product_name,"created_date_from":created_date_from,"created_date_to":created_date_to,"policy_expiry_from":policy_expiry_from,"policy_expiry_to":policy_expiry_to]

    let config = URLSessionConfiguration.default
    config.httpAdditionalHeaders = [
        "Accept" : "application/json",
        "Content-Type" : "application/x-www-form-urlencoded"
    ]
    let session = URLSession(configuration: config)
    let Url = String(format: "http://myapi-url");
    let serviceUrl = URL(string: Url)
    var request = URLRequest(url: serviceUrl!)
    print(request.url!)
    request.httpMethod = "POST"
    request.timeoutInterval = 60

    request.httpBody  = try! JSONSerialization.data(withJSONObject: parameters!, options: [])

    let task = session.dataTask(with: request as URLRequest, completionHandler: {data, response, error -> Void in

        if error == nil{
            print(response!)
        }
        else {
            print(error?.localizedDescription as Any)
        }

        print(response!)
        guard let httpResponse = response as? HTTPURLResponse, let receivedData = data
            else {
                print("error: not a valid http response")
                return
        }

        switch (httpResponse.statusCode)
        {
        case 200: //The request was fulfilled
            let response = NSString (data: receivedData, encoding: String.Encoding.utf8.rawValue)

            if response == "SUCCESS"
            {
                print("Network - HandShaking Successfull...!!!")
            }
            else{
                print("Network - HandShaking is not successfull...!!!")
            }

        case 400:
            print("response-status - 400 : The request had bad syntax or was inherently impossible to be satisfied.")
        case 500:
            print("\nresponse-status - 500 : Internal Server Error...!!!")
        default:
            print("response-status - Unknown : Received Response =>  \(httpResponse.statusCode)")
        }
    })
    task.resume()
}

После запуска вышеуказанной функции, я получаю httpResponse.statusCode = 500

Но когда я запускаю это в почтальоне, я получаю ответ должным образом, как и было.

Api-запрос почтальона

Также я пытался генерировать фрагменты кода с помощью почтальона ..., которые следующие ...

func postmanSnippetApiCall(){
    let headers = [
        "Content-Type": "application/x-www-form-urlencoded",
        "cache-control": "no-cache",
        "Postman-Token": "5d571157-86c5-4eac-ba6d-b00779ae5dbd"
    ]

    let postData = NSMutableData(data: "renewal_id=".data(using: String.Encoding.utf8)!)
    postData.append("&policy_no=".data(using: String.Encoding.utf8)!)
    postData.append("&client_name=".data(using: String.Encoding.utf8)!)
    postData.append("&client_id=".data(using: String.Encoding.utf8)!)
    postData.append("&product_name=".data(using: String.Encoding.utf8)!)
    postData.append("&created_date_from=".data(using: String.Encoding.utf8)!)
    postData.append("&created_date_to=".data(using: String.Encoding.utf8)!)
    postData.append("&policy_expiry_from=".data(using: String.Encoding.utf8)!)
    postData.append("&policy_expiry_to=".data(using: String.Encoding.utf8)!)
    postData.append("&undefined=undefined".data(using: String.Encoding.utf8)!)

    let request = NSMutableURLRequest(url: NSURL(string: "http://myapiurl")! as URL,
                                      cachePolicy: .useProtocolCachePolicy,
                                      timeoutInterval: 10.0)
    request.httpMethod = "POST"
    request.allHTTPHeaderFields = headers
    request.httpBody = postData as Data

    let session = URLSession.shared
    let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
        if (error != nil) {
            print(error)
        } else {
            let httpResponse = response as? HTTPURLResponse
            print(httpResponse)
        }
    })

    dataTask.resume()
}

Но в фрагменте кода, сгенерированного почтальоном , я получаю сообщение об ошибке в этой строке, т.е. request.httpBody = postData as Data и error это: Cannot convert value of type 'NSMutableData' to type 'Data' in coercion

ЕслиЯ использую ThirdParty Library, т.е. Alamofire , тогда я могу получить данные очень легко.

Фрагмент кода Alamofire ... работает отлично .. и дает правильный ответ.

func apiRequestByAlamofire(){
        let urlString = "http://myapiurl"

        let params: [String: Any]? = ["renewal_id":"","policy_no":"","client_name":"","client_id":"","product_name":"","created_date_from":"","created_date_to":"","policy_expiry_from":"","policy_expiry_to":""]

        Alamofire.request(urlString, method: .post, parameters: params).responseJSON { response in
            print(response) //Here getting perfect response successfully...!!!
        }

    }

Но все же я борюсь с этим через URLSession ... !!!

И все же я сомневаюсь, что поэтому я получаю слишком много проблем при работе с URLSession.

Друзья за мои сомнения, пожалуйста, я открыт для ваших предложений, а также, пожалуйста, помогите мне понять это.

Не знаю, куда я иду не так.пожалуйста, помогите мне здесь.

Ответы [ 2 ]

0 голосов
/ 20 ноября 2018

Я даю вам простую функцию, вы можете редактировать эту функцию согласно вашему требованию.Вы также можете изменить свой URL и параметры.И в ответе я написал две строки, если вы берете массив JSON с сервера, затем используете первую, если вы берете объект, затем вторую удалите обе строки.

func abc()  {
    let request = NSMutableURLRequest(url: URL(string: "Your URL")!)
    request.httpMethod = "POST"
    let postString = "param_name_one=\( value_1 )&param_name_two=\(value_2)&........."
    request.httpBody = postString.data(using: String.Encoding.utf8)
    let task = URLSession.shared.dataTask(with: request as URLRequest) {
        data, response, error in
        if(error != nil){
            // Show Error Message
        } else{
            do {
                //For JSON ARRAY
                let jsonItem  = try JSONSerialization.jsonObject(with: data!, options: .allowFragments) as! NSArray
                let json = jsonItem[0] as AnyObject
               //For JSON object 
                let json_object  = try JSONSerialization.jsonObject(with: data!, options: .allowFragments) as AnyObject
                print(json_object)

            } catch {

            }
        }
    }
    task.resume();
}

Надеюсь, эта функция поможет вам!

0 голосов
/ 20 ноября 2018

Попробуйте добавить заголовки в URLRequest вместо URLSession напрямую, а также попробуйте другие Content-Type s и Accept s, например application/json, application/x-www-form-urlencoded и т. Д.

let config = URLSessionConfiguration.default
config.timeoutIntervalForRequest = TimeInterval(30)
config.timeoutIntervalForResource = TimeInterval(30)

let session = URLSession(configuration: config)
let Url = String(format: "http://myapi-url")
let serviceUrl = URL(string: Url)

var request = URLRequest(url: serviceUrl!)
print(request.url!)

request.httpMethod = "POST"

let parameters: [String: Any]? = //Request parameters in Dictionary format like ["user_id": 2, "name": "TestUser"]

//Set body to url request
if parameters != nil {

    do {
        let bodyData = try JSONSerialization.data(withJSONObject: parameters!,
                                                  options: JSONSerialization.WritingOptions.prettyPrinted)
        request.httpBody = bodyData
    } catch let error {
        print(error.localizedDescription)
    }
}

request.addValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type") //Try different types of Content-Types here like "application/json", etc.
request.addValue("application/json", forHTTPHeaderField: "Accept") //Try different types of Content-Types here like "application/json", etc.

let task = session.dataTask(with: request) { (data, response, error) in

    // Your code here
    guard data != nil && error == nil else {
        return
    }

    let apiResponse = String.init(data: data!, encoding: String.Encoding.utf8)!
    print(apiResponse)
}

task.resume()
session.finishTasksAndInvalidate()

Пожалуйста, перейдите по ссылке ниже, чтобы узнать, как кодировать URLSession.

https://github.com/sateeshyegireddi/MovieFlix/blob/master/MovieFlix/MovieFlix/API/APIHandler.swift

...