We have a custom scalar type called JSON, which is used when we want to send unstructured data.
When trying to access that field using Apollo (even just trying to print it), we get the following error:
Apollo.JSONDecodingError.couldNotConvert({
amountChanged = "-1467";
}, Swift.String)))
I'm not sure why it would have a problem converting to a String. Also, how can we get the Dictionary value rather than a String?
This may be somewhat similar to #23. I tried the proposed solution there (just aliasing JSON to [String : Any?]) but it gave a bunch of compile errors.
Unfortunately, we don't have real support for custom scalars yet. But I think we should be able to get something working using the --passthrough-custom-scalars workaround.
I haven't tested it, but something like this might be a good starting point:
typealias JSON = [String : Any?]
extension Dictionary: JSONDecodable {
public init(jsonValue value: JSONValue) throws {
guard let dictionary = value as? Dictionary else {
throw JSONDecodingError.couldNotConvert(value: value, to: Dictionary.self)
}
self = dictionary
}
}
I am using the same solution but I am trying to use my custom object class instade of Extenstion
public class Location : JSONDecoder {
var lat : String
var lng : String
public init(jsonValue value: JSONValue) throws {
guard let locationDic = value as? NSDictionary else {
throw JSONDecodingError.couldNotConvert(value: value, to: String.self)
}
guard let lat = locationDic.value(forKey: "lat") else {
throw JSONDecodingError.couldNotConvert(value: value, to: Int64.self)
}
guard let lng = locationDic.value(forKey: "lng") else {
throw JSONDecodingError.couldNotConvert(value: value, to: Int64.self)
}
self.lat = (lat as? String)!
self.lng = (lng as? String)!
}}
but I am getting this error in API.swift file
Cannot convert value of type 'Json.Type' (aka 'Location.Type') to expected argument type 'JSONDecodable.Type'
public struct AllPointOfInterest: GraphQLSelectionSet {
public static let possibleTypes = ["PointOfInterest"]
public static let selections: [GraphQLSelection] = [
GraphQLField("__typename", type: .nonNull(.scalar(String.self))),
GraphQLField("name", type: .nonNull(.scalar(String.self))),
GraphQLField("type", type: .nonNull(.list(.nonNull(.scalar(PointOfInterestType.self))))),
GraphQLField("location", type: .nonNull(.scalar(Json.self))), // error in this line
]
Any thing is missing ?
Any update on this? I have a field which is the type of scalar JSON. Apollo throws the error
Optional(Apollo.GraphQLResultError(path:` ["stage", "0", "parent", "0", "venue"], underlying: Apollo.JSONDecodingError.couldNotConvert(value: {
city = Monza;
coordinates = "45.615899,9.279499";
country = Italia;
"country_code" = ITA;
"curves_left" = 4;
"curves_right" = 7;
debut = 1950;
id = "sr:venue:1024";
laps = 53;
length = 5793;
name = "Autodromo Nazionale Monza";
"url_official" = "http://www.monzanet.it/";
}, to: Swift.String)))
I got same Error. But i know the reason of error. Our Schema.json and mutation or query generate the API.swift. Schema.json have a JSON response. This response is treated as String. So Api.swift create [String] type. Please check your API.swift. your response is [JSON] type. But your API.swift file automatically generate the [String] for your [JSON]. During fetching the data from endpoint response [JSON]. So [JSON] couldNotConvert String error will be Occurred.
Solution is during create a Backend using MUTATION RESPONSE instead of [JSON] type Response.
This is sample response for [JSON].
https://i.stack.imgur.com/zxXiz.png
My sample response is CurrentMissionChallenge is [JSON] type
@VigneshJeyarajG I was able to solve this in a couple steps:
1) Add --passthroughCustomScalars to the build phase like below (see last line):
APOLLO_FRAMEWORK_PATH="$(eval find $FRAMEWORK_SEARCH_PATHS -name "Apollo.framework" -maxdepth 1)"
if [ -z "$APOLLO_FRAMEWORK_PATH" ]; then
echo "error: Couldn't find Apollo.framework in FRAMEWORK_SEARCH_PATHS; make sure to add the framework to your project."
exit 1
fi
cd "${SRCROOT}/${TARGET_NAME}"
$APOLLO_FRAMEWORK_PATH/check-and-run-apollo-cli.sh codegen:generate --queries="$(find . -name '*.graphql')" --passthroughCustomScalars --schema=schema.json API.swift
2) Add the typealias like @martijnwalraven mentioned a while back, like:
public typealias CurrentMissionChallenge = [String : Any?]
extension Dictionary: JSONDecodable {
/// Custom `init` extension so Apollo can decode custom scalar type `CurrentMissionChallenge `
public init(jsonValue value: JSONValue) throws {
guard let dictionary = value as? Dictionary else {
throw JSONDecodingError.couldNotConvert(value: value, to: Dictionary.self)
}
self = dictionary
}
}
Closing this out with @rickycpadilla's solution as the present recommended one.
Hey In Swift 5...there is no JSONDecodable/JSONDecodingError. Is there anything you guys are using for this fix.
@aroraenterprise This is a custom error, not anything thrown by the system. Can you open a new issue with details of the problem you're running into, please?
Most helpful comment
@VigneshJeyarajG I was able to solve this in a couple steps:
1) Add
--passthroughCustomScalarsto the build phase like below (see last line):2) Add the
typealiaslike @martijnwalraven mentioned a while back, like: