Как отправить параметр тела в Alamofire в Swift? - PullRequest
1 голос
/ 18 апреля 2019

У меня есть API, который использует параметр BODY, например,

{"answers":[{"qid":2588,"value":["Free Society"]},{"qid":150,"value":["Closing of fSociety"]}],"uniqid":"t4815694"}

Итак, я сделал, что создал модель данных с именем SubmitAnswerModel, как эта, которая содержит другую модель данных с именем QuestionAnswersToSubmit

import Foundation
import ObjectMapper
import RealmSwift

class SubmitAnswerModel: Object {

    var answers = [QuestionAnswersToSubmit]()
    @objc dynamic var uniqid: String?

    override static func primaryKey() -> String {
        return "uniqid"

    }


}



class QuestionAnswersToSubmit: Object {


    @objc dynamic var qid = 0
    var value = [String]()

    override static func primaryKey() -> String {
        return "qid"

    }

} 

Таким образом, этот объект расширяется RealmObject, и теперь мне нужно установить значения для этого объекта и отправить его как параметр BODY в API.Я делаю это так

func submitAnswerToApi() {

        guard let token = UserDefault().getLoginAccessTokenKey() else {
            print("No login token. Please relogin.")
            return
        }
        let answersToSubmit = SubmitAnswerModel() //main model
        let realm = try! Realm()
        let savedExamResponse = realm.object(ofType: SavedExamResponse.self, forPrimaryKey: id)
        answersToSubmit.uniqid = savedExamResponse?.uniqueId

        var answerListToSubmit =  [QuestionAnswersToSubmit]()

        for item in (savedExamResponse?.questionAnswerList)! {
            let answerToSubmit = QuestionAnswersToSubmit()
            answerToSubmit.qid =  item.questionId
            answerToSubmit.value = [item.selectedOption]            
            answerListToSubmit.append(answerToSubmit)

        }

        answersToSubmit.answers = answerListToSubmit

        let urlString = UrlCollection.submitAnswerUrl + "uniqid=" + answersToSubmit.uniqid! + "&token=" + token

        let param = answersToSubmit
        let uniqidParam = answersToSubmit.uniqid
        dump(param)


        var request = URLRequest(url: URL(string: urlString)!)
        request.httpMethod = "POST"

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

        if (!JSONSerialization.isValidJSONObject(answersToSubmit)) {
            print("is not a valid json object")
            //return
        }

        request.httpBody = try? JSONSerialization.data(withJSONObject: answersToSubmit)

        Alamofire.request(request)
            .responseJSON { response in
                switch response.result {
                case .failure(let error):
                    print(error)

                    if let data = response.data, let responseString = String(data: data, encoding: .utf8) {
                        print(responseString)
                    }
                case .success(let responseObject):
                    print(responseObject)
                }
        }


    }

Итак, проблема в том, что я получаю эту ошибку Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** +[NSJSONSerialization dataWithJSONObject:options:error:]: Invalid top-level type in JSON write'.Как правильно передать параметр BODY в SWIFT.Любая помощь будет оценена.Спасибо!

1 Ответ

0 голосов
/ 18 апреля 2019

Ваш формат Json может быть неправильным, обратитесь к этому вопросу: Недопустимый тип верхнего уровня при записи JSON '

Кстати, предпочтительный способ задать тело с помощью Alamofire - этопередать Dictionary параметрам и затем установить кодировку на URLEncoding.httpbody, например:

let parameters: Parameters = ["foo": "bar"]

Alamofire.request("https://someapi/post", parameters: parameters, encoding: URLEncoding.httpbody)

...