Ошибка JSON: NSInvalidArgumentException причина Недопустимый тип верхнего уровня в записи JSON в Swift3 iOS - PullRequest
0 голосов
/ 18 мая 2018

Я получаю это исключение при попытке отправить свои данные на сервер:

Завершение приложения из-за необработанного исключения 'NSInvalidArgumentException', причина: '*** + [NSJSONSerialization dataWithJSONObject: options: error:]: Недопустимый тип верхнего уровня в JSON write '

Вот мой класс Entity:

class RequestModel {

    var CompanyId: Int? = 0
    var RollupYear: Int? = 0
    var UserId: Int? = 0

    var dataRollupArr:[DataRollupModel]?
    var seasonalityArr:[SeasonalityModel]?
}

class DataRollupModel {

    var Name: String? = ""
    var CurrentValue: Float? = 0.0
    var RollupYear: Int? = 0
    var DataRollupColumnID: Int? = 0
}

class SeasonalityModel {

    var CompanyPeriodId: Int? = 0
    var UserId: Int? = 0
    var Seasonality: String? = ""
}

Здесь устанавливаются значения и метод сервера:

func createJSONFromMadal(){

        let resqM = RequestModel()
        resqM.dataRollupArr = [DataRollupModel]()
        resqM.seasonalityArr = [SeasonalityModel]()

        let rollupYear = Int(self.lblYear.text!)
        let userId = UserDefaults.standard.value(forKey: "userid") ?? 0
        let companyId = UserDefaults.standard.value(forKey: "companyid") ?? 0

        resqM.CompanyId = companyId as? Int
        resqM.RollupYear = rollupYear
        resqM.UserId = userId as? Int

        //For DataRollupModel
        for i in 0..<self.responseModel.dataRollupValuesArray.count {

        let dataRollup = responseModel.dataRollupValuesArray[i] as! DataRollupValuesModel

        let r1 = DataRollupModel()

        r1.Name = dataRollup.name
        r1.CurrentValue = dataRollup.currentValue
        r1.RollupYear = rollupYear

        resqM.dataRollupArr?.append(r1)
        }


        //For SeasonalityModel
        for i in 0..<self.responseModel.seasonalityDataResponseArray.count {

            let seasonalityData = responseModel.seasonalityDataResponseArray[i] as! SeasonalityDataResponseModel

            let s1 = SeasonalityModel()
            s1.CompanyPeriodId = seasonalityData.id
            s1.UserId = userId as? Int
            s1.Seasonality = seasonalityData.seasonality

            resqM.seasonalityArr?.append(s1)
        }

        //server code
        do {

            HUDIndicatorView.shared.showHUD(view: self.view,
                                            title: "Loading ..")

            DispatchQueue.global(qos: .userInitiated).async {

                let servicemodel = ServiceModel()

                servicemodel.saveGoal(requestModel: resqM) { returnstring in
                    print(returnstring)

                    DispatchQueue.main.async {

                        HUDIndicatorView.shared.dismissHUD()


                    }
                }
            }

        } catch {

            handleError(error: error)
        }

    }

И мой вызов API:

func saveGoal(requestModel:RequestModel,  completion:@escaping (NSDictionary) -> ()) {

        if let url = NSURL(string: baseurl+"Save") {
            let request = NSMutableURLRequest( url: url as URL)

            request.httpMethod = "POST"

            let myDict = requestModel

            let jsonData = try! JSONSerialization.data(withJSONObject: myDict, options: [])//CRASHING HERE

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

            request.httpBody = jsonData
            let task = URLSession.shared.dataTask(with: request as URLRequest) {
                data, response, error in
                do{
                    if let data = data,
                        let jsonString =  try JSONSerialization.jsonObject(with: data, options: JSONSerialization.ReadingOptions.mutableContainers) as? NSDictionary
                        , error == nil {
                        completion(jsonString)
                        print(jsonString)
                    } else {
                        print("error=\(error!.localizedDescription)")
                        let errorDict = ["error_status":true,"message":error!.localizedDescription] as [String : Any]
                        completion(errorDict as NSDictionary)

                    }
                }
                catch{
                    print("error=\(error.localizedDescription)")
                    let errorDict = ["error_status":true,"message":error.localizedDescription] as [String : Any]
                    completion(errorDict as NSDictionary)

                }

            }
            task.resume()
        }
    }

Я должен передать запрос JSON, как показано ниже:

{
    "CompanyId": 162,
    "RollupYear": 2018,
    "UserId": 1609,
    "datarollup": [{
            "Name": "My Cards",
            "RollupYear": 2018,
            "DataRollupColumnID": 210,
            "CurrentValue": 520
        },
        {
            "Name": "Pros calls",
            "RollupYear": 2018,
            "DataRollupColumnID": 212,
            "CurrentValue": 1300
        }
    ],
    "Seasonalitylist": [{
            "CompanyPeriodId": 386,
            "UserId": 1609,
            "Seasonality": 25
        },
        {
            "CompanyPeriodId": 387,
            "UserId": 1609,
            "Seasonality": 25
        }
    ]
}

Пожалуйста, помогите мне, как добавить заголовок заголовка массива "datarollup" и"Seasonalitylist" в моем коде?Может кто-нибудь предложить мне, как я могу решить эту ошибку?

Спасибо!

1 Ответ

0 голосов
/ 18 мая 2018

Создать Encodable класс, как показано ниже,

class RequestModel : Encodable {
    var CompanyId: Int? = 0
    var RollupYear: Int? = 0
    var UserId: Int? = 0
}

Теперь вы можете создать тот же JSON String, выполнив следующие действия,

let myStruct = RequestModel()
myStruct.CompanyId = 5
myStruct.RollupYear = 2018
myStruct.UserId = 108

let encoder = JSONEncoder()
encoder.outputFormatting = .prettyPrinted
let data = try! encoder.encode(myStruct)
print(String(data: data, encoding: .utf8)!)

Вывод будет ниже,

{
  "UserId" : 108,
  "CompanyId" : 5,
  "RollupYear" : 2018
}

Надеюсь, это поможет вам.

К вашему сведению .это просто ссылка для вас.Пожалуйста, обновите полную структуру класса в соответствии с вашими требованиями.

ОБНОВЛЕНИЕ

Используйте JsonSerializerSwift подобную библиотеку,

class RequestModel {
    var CompanyId: Int? = 0
    var RollupYear: Int? = 0
    var UserId: Int? = 0
    var dataRollupArr = [DataRollupModel]()
}

class DataRollupModel {
    var Name: String? = ""
    var CurrentValue: Float? = 0.0
    var RollupYear: Int? = 0
    var DataRollupColumnID: Int? = 0
}

Я реализовал ниже,

let myStruct = RequestModel()
myStruct.CompanyId = 5
myStruct.RollupYear = 2018
myStruct.UserId = 108

for i in 0...2 {
    let rollUpModel = DataRollupModel()
    rollUpModel.Name = "Test \(i)"
    rollUpModel.CurrentValue = 25.5
    rollUpModel.DataRollupColumnID = 5
    rollUpModel.RollupYear = 2015
    myStruct.dataRollupArr.append(rollUpModel)
}

let json = JSONSerializer.toJson(myStruct)
print(json)

Вывод будет таким,

{"CompanyId": 5, "RollupYear": 2018, "UserId": 108, "dataRollupArr": [{"Name": "Test 0", "CurrentValue": 25.5, "RollupYear": 2015, "DataRollupColumnID": 5}, {"Name": "Test 1", "CurrentValue": 25.5, "RollupYear": 2015, "DataRollupColumnID": 5}, {"Name": "Test 2", "CurrentValue": 25.5, "RollupYear": 2015, "DataRollupColumnID": 5}]}

http://json.parser.online.fr/ Вывод будет выглядеть так,

enter image description here

...