JSON error: NSInvalidArgumentException reason Invalid top-level type in JSON write in Swift3 iOS
JSON error: NSInvalidArgumentException reason Invalid top-level type in JSON write in Swift3 iOS
我在尝试 POST 我的数据到服务器时遇到此异常:
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** +[NSJSONSerialization
dataWithJSONObject:options:error:]: Invalid top-level type in JSON
write'
这是我的实体 class:
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
}
]
}
请帮助我如何在我的代码中添加数组 header 标题 "datarollup"
和 "Seasonalitylist"
?
谁能建议我如何解决这个错误?
谢谢!
创建 Encodable
class 如下所示,
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
}
希望对您有所帮助。
仅供参考。这只是给你参考。请根据您的要求更新完整的 class 结构。
更新
像这样使用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/ 输出将如下所示,
我在尝试 POST 我的数据到服务器时遇到此异常:
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** +[NSJSONSerialization dataWithJSONObject:options:error:]: Invalid top-level type in JSON write'
这是我的实体 class:
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
}
]
}
请帮助我如何在我的代码中添加数组 header 标题 "datarollup"
和 "Seasonalitylist"
?
谁能建议我如何解决这个错误?
谢谢!
创建 Encodable
class 如下所示,
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
}
希望对您有所帮助。
仅供参考。这只是给你参考。请根据您的要求更新完整的 class 结构。
更新
像这样使用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/ 输出将如下所示,