JSON 写入(_ SwiftValue)中的 JSONSerialization 无效类型

为什么下面的代码会给我错误:

JSON 写入中的类型无效(_ SwiftValue)。

该错误在以下行中引发:

urlRequest.httpBody = try JSONSerialization.data(withJSONObject: parameters)

完整代码:

let parameters:Parameters = ["resource":[
[
"appUserCode":uuidString,
"productNFCode": self.nfCode!,
"status":code,
"applicationKey":appDelegate.api_key
]
]
]
do {


urlRequest.httpBody = try JSONSerialization.data(withJSONObject: parameters)
} catch {
// No-op
}
66879 次浏览

I had this problem and it was because one of my strings was Optional. It was trying to serialize a value like: "Optional(\"string value\")"

Instead of "string value"

If your problem is still not resolved by the answer given here. I believe one of your objects inside the parameters might not be an instance of NSString, NSNumber, NSArray, NSDictionary, or NSNull. As given in the documentation for JSONSerialization class:

An object that may be converted to JSON must have the following properties:

  1. The top level object is an NSArray or NSDictionary. All objects are instances of NSString, NSNumber, NSArray, NSDictionary, or NSNull.

  2. All dictionary keys are instances of NSString. Numbers are not NaN or infinity.

  3. Other rules may apply. Calling isValidJSONObject(_:) or attempting a conversion are the definitive ways to tell if a given object can be converted to JSON data.

So, please check if any of the objects in your parameters object doesn't satisfy the above constraints.

Just in case anyone is still having problems and is using Enums, another cause may be if you are passing an Enum value and not it's rawValue.

Example:

enum Status: String {
case open
case closed
}

instead of passing the enum:

params = ["status": Status.open]

pass

params = ["status": Status.open.rawValue]

If you're using SwiftyJSON to access a JSON object, it's important to use the dictionaryObject property of the JSON (instead of using dictionaryValue, dictionary or nothing at all), because you will get this error (or a variation of it) otherwise. For example:

guard let jsonDict = json.dictionaryObject else {
return
}


let jsonData = try JSONSerialization.data(withJSONObject: jsonDict, options: [])

You should convert NSObject to NSDictionary at first

Try this to convert to NSDictionary.

#import <objc/runtime.h>


//Add this utility method in your class.
+ (NSDictionary *)dictionaryWithPropertiesOfObject:(id)obj {
NSMutableDictionary *dict = [NSMutableDictionary dictionary];


unsigned count;
objc_property_t *properties = class_copyPropertyList([obj class], &count);


for (int i = 0; i < count; i++) {
NSString *key = [NSString stringWithUTF8String:property_getName(properties[i])];
[dict setObject:[obj valueForKey:key] ? [obj valueForKey:key] : @"" forKey:key];
}


free(properties);


return [NSDictionary dictionaryWithDictionary:dict];
}

Then call this:

NSData *jsonData = [NSJSONSerialization dataWithJSONObject:dic options:0 error:&err];
NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];

I got this error when used a Set that is linked with Foundation NSSet.

let myArray = Array(mySet)

You can call this method too and see if your parameter can be converted to a JSON object, this will return a Bool.

let checker = JSONSerialization.isValidJSONObject(parameters)

In my case I accidentally added an object to the Parameters dictionary instead of a string

I was getting this runtime error because my dictionary was like this:

var dictionary: [AnyHashable: Any] = [:]
let elapsedTime = Date.timeIntervalSince(oldDate)
dictionary["elapsedTime"] = elapsedTime

Can you tell me what the problem is? hover your mouse on the box below to see answer!

elapsedTime's type is Function it's not TimeInterval. I needed to change Date. to Date(). ie use the instance method rather than the static method. When you're dictionary values are Any then this sort of issue doesn't get found until a runtime error where it can't serialize the dictionary to a JSON string...

Had the same problem and error as you! FINALLY found the issue...

My code:

params = [
"gender": request.gender.first ?? "",
"age": 15
]

Problem: Even though request.gender.first ?? "" returns a string, its a type of String.Element, which ANY JSONEncoder or JSONSerialization cannot encode (and is not in the list of types it can handle, according to documentation).

Solution:

params = [
"gender": request.gender.first?.description ?? "",
"age": 15
]

Typically, just make sure its a string or an appropriate number the Encoders can handle...