JSONSerialization Invalid type in JSON write (_SwiftValue)
AlamofireSwift3Alamofire Problem Overview
Why does the following code give me the error:
> Invalid type in JSON write (_SwiftValue).
The error is thrown on this line:
urlRequest.httpBody = try JSONSerialization.data(withJSONObject: parameters)
Full code:
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
}
Alamofire Solutions
Solution 1 - Alamofire
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.
Solution 2 - Alamofire
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"
Solution 3 - Alamofire
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]
Solution 4 - Alamofire
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)
Solution 5 - Alamofire
In my case I accidentally added an object to the Parameters dictionary instead of a string
Solution 6 - Alamofire
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: [])
Solution 7 - Alamofire
I got this error when used a Set
that is linked with Foundation NSSet
.
let myArray = Array(mySet)
Solution 8 - Alamofire
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...
Solution 9 - Alamofire
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];
Solution 10 - Alamofire
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...