Comments (27)
@NiltiakSivad I dug a little deeper, and I found that Apollo CLI now expects the parameter this way: --passthroughCustomScalars
.
You can check out Apollo CLI's other parameters here:
https://github.com/apollographql/apollo-cli#apollo-codegengenerate-output
Hope this helps you :)
from apollo-ios.
thanks @martijnwalraven! judging by the nature of
centAmount
field, I think the value can be pretty high in some cases
the current workaround could be manually altering the local schema file; is there anything better you’d suggest?
I hope to add better support for custom scalars soon, but in the meantime there is a temporary apollo-codegen
option --passthrough-custom-scalars
that doesn't attempt to map custom scalars to string but keeps them as is. That means you're responsible for defining the type and making sure it is JSONDecodable
and JSONEncodable
.
I haven't tested it, but something like this should work:
typealias Long = Int64
extension Int64: JSONDecodable, JSONEncodable {
public init(jsonValue value: JSONValue) throws {
guard let string = value as? String else {
throw JSONDecodingError.couldNotConvert(value: value, to: String.self)
}
guard let number = Int64(string) else {
throw JSONDecodingError.couldNotConvert(value: value, to: Int64.self)
}
self = number
}
public var jsonValue: JSONValue {
return String(self)
}
}
from apollo-ios.
According to the GraphQL spec, Long
is not a built-in scalar, so it is treated as a custom scalar. Right now in Apollo iOS, all custom scalars are mapped to string (which is also how they are encoded in JSON).
I would definitely like to add better support for custom scalars, which should give you the opportunity to define your own mapping.
But in this case, do you really need Long
here, or would Int
suffice?
from apollo-ios.
Hi @martijnwalraven
I am getting an error on iOS client
Error
"Error at path "history.itemid": couldNotConvert(value: 1100025, to: Swift.String)"
System Info
-
apollo-codegen version : 0.16.5
-
Apollo Client SDK version : (0.6.2)
-
schema.json type
{ "defaultValue": null, "name": "itemId", "description": null, "type": { "kind": "NON_NULL", "name": null, "ofType": { "kind": "SCALAR", "name": "Long", "ofType": null } } }
What I tried
Tried extension you have mentioned and updated the build generation script in Xcode -> Build Phases -> Ran Script
$APOLLO_FRAMEWORK_PATH/check-and-run-apollo-codegen.sh generate $(find . -name '*.graphql') --schema schema.json --output API.swift --passthrough-custom-scalars
Please let me know if I am going wrong somewhere
from apollo-ios.
@AnandWalvekar: Does the generated API code reference Long
? Where are you including typealias Long = Int64
and the extension?
from apollo-ios.
@martijnwalraven
Yes it is having Long
public var itemId: Long
I have included both typealias & extension in a new file in my project as
import Apollo
public typealias Long = Int64
But still getting the same error
from apollo-ios.
@AnandWalvekar: That is surprising. Can you check if the generated API code includes a typealias Long = String
by any chance? (It shouldn't, because you specify --passthrough-custom-scalars
. But then even if it doesn't pick up your typealias Long
, it should fail with a compiler error.)
from apollo-ios.
@martijnwalraven
It works if I write like below
guard let long = value as? Long else { throw JSONDecodingError.couldNotConvert(value: value, to: String.self) } self = long
Is this the solution?
from apollo-ios.
@AnandWalvekar: Ah, so you're encoding Long
as a JSON number instead of a string! If that's the case, something like your code would work (although you may want to change the error message as well).
Note that numbers in JavaScript can't represent 64-bit integers however, so unless you're sure the value will never exceed Number.MAX_SAFE_INTEGER
(2^53 - 1), that might lead to unexpected problems.
from apollo-ios.
@martijnwalraven
Understood. Thank you very much for your quick support.
from apollo-ios.
@martijnwalraven suggestion worked fine for me originally, but the latest Apollo code generation script installation changes does not accept the --passthrough-custom-scalars
option. Worked with check-and-run-apollo-codegen.sh
(Apollo 0.8) but does not work with the new check-and-run-apollo-cli.sh
(Apollo 0.9.2).
from apollo-ios.
@NiltiakSivad same problem here.. :(
from apollo-ios.
@szantogab I re-read martijnwalraven's post and he does mention it's a "temporary" flag. I'm not sure if anything is mentioned about its removal and future plans in another issue/merge request, I need to investigate more, if I find anything I'll post here.
from apollo-ios.
Hi @martijnwalraven
It seems like the typealias was a viable solution for many people. I tried the typealias Long = Int64
and the extension that you have posted above.
When generating the API.swift file I am using the ----passthroughCustomScalars
flag, when building the project Xcode/Swift complains about Property cannot be declared public because its type uses an internal type
.
I am using Apollo through Cocoapods and the Apollo cli (not apollo-codegen) as well as the script provided in the installation process of the apollo ios website.
I tried both Swift 4 and Swift 4.2 in the build settings. but the error persists.
This error is in the API.swift file. No typealias is declared in the generated file.
Since API.swift should not be modified, any idea on how this can be resolved.
EDIT: Solved :)
from apollo-ios.
Since API.swift should not be modified, any idea on how this can be resolved.
EDIT: Solved :)
I copy the code into Long.swift and then changed the line to read public typealias Long = Int64
.
from apollo-ios.
Is there a workaround to use "Any" as custom type?
One of the API i am consuming returns "Object" type which can contain Int Decimal or a string value.
I tried the following but it will not work.
public typealias Object = Any
extension Object : JSONDecodable, JSONEncodable { }
Any help is appreciated
Thanks!
from apollo-ios.
Remember to import Apollo and conform "JSONDecodable", not inherit "JSONDecoder"...
(I'm stuck for this for an hour... such a fool)
from apollo-ios.
I am getting an error on iOS client. Incorrect code generation: String instead of Array.
The resulting API.swift that was generated using apollo-ios
GraphQLField("reactiondata", type: .scalar(String.self)),
public var reactiondata: String? {
get {
return resultMap["reactiondata"] as? String
}
set {
resultMap.updateValue(newValue, forKey: "reactiondata")
}
}
The actual type from the schema file:
{ "name": "reactiondata", "description": null, "args": [], "type": { "kind": "SCALAR", "name": "Array", "ofType": null }, "isDeprecated": false, "deprecationReason": null },
If I am try with --passthroughCustomScalars Also I am geting error.
The resulting API.swift that was generated with --passthroughCustomScalars
public typealias Array = [AnyObject]
GraphQLField("reactiondata", type: .scalar(Array.self)),
public var reactiondata: Array? { get { return resultMap["reactiondata"] as? Array } set { resultMap.updateValue(newValue, forKey: "reactiondata") } }
`# Type a script or drag a script file from your workspace to insert its path.
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
Please let me know if I am going wrong somewhere
from apollo-ios.
@niraj1991 The type in the schema you posted seems to be a custom scalar called Array
, not an actual GraphQL list type. If reactiondata
is meant to be represented as an array, you should change the type in the schema.
from apollo-ios.
@martijnwalraven Thanks for writing to me.
I am updating my above post. can you please check again?
from apollo-ios.
@niraj1991 You'll have to change reactiondata
to be an actual list in your schema, not a scalar. You can't generate a scalar with the name Array
and expect it to map to a Swift Array
.
from apollo-ios.
@martijnwalraven I changed the schema file like below.
{ "name": "details", "description": null, "args": [], "type": { "kind": "SCALAR", "name": "Json", "ofType": null }, "isDeprecated": false, "deprecationReason": null }
But I am Getting below error.
`Error at path "posts.0.reactiondata": couldNotConvert(value: <__NSArray0 0x600002408050>(
)
, to: Swift.Dictionary<Swift.String, Swift.Optional<Any>>)`
The resulting API.swift that was generated like below.
public static let selections: [GraphQLSelection] = [
GraphQLField("reactiondata", type: .scalar(Json.self)),
]
public var reactiondata: Json? {
get {
return resultMap["reactiondata"] as? Json
}
set {
resultMap.updateValue(newValue, forKey: "reactiondata")
}
}
Also I am creating typealias like below.
public typealias Json = [String : Any?]
Let me know if you need any other details, I would be happy to share you.
Please let me know if I am going wrong somewhere.
Thanks in advance.
from apollo-ios.
@niraj1991 It seems you're returning an array from the server and trying to map this to a SwiftDictionary
([String : Any?]
). If you need to use a JSON type (as opposed to changing the schema to something more specific), you'll have to use public typealias JSON = Any
.
from apollo-ios.
@martijnwalraven if I am writing public typealias Json = Any Then I get the below error.
public typealias Json = Any
Here is schema file.
{
"name": "reactiondata",
"description": null,
"args": [],
"type": {
"kind": "SCALAR",
"name": "Json",
"ofType": null
},
"isDeprecated": false,
"deprecationReason": null
},
Please let me know if I need to change anything.
from apollo-ios.
@niraj1991 Ah, my mistake, I don't think Any
is supported as a custom scalar type. Honestly, this doesn't seem like a great use case for custom scalars, you should really give reactiondata
a proper type.
from apollo-ios.
Sript phase: SCRIPT_PATH="${PODS_ROOT}/Apollo/scripts"
cd "${SRCROOT}/${TARGET_NAME}"
"${SCRIPT_PATH}"/check-and-run-apollo-cli.sh codegen:generate --target=swift --includes=./**/*.graphql --passthroughCustomScalars --localSchemaFile="schema.json" API.swift
I do it in: JSONStandardTypeConversions
typealias Long = Int64
extension Long: JSONDecodable, JSONEncodable {
public init(jsonValue value: JSONValue) throws {
guard let number = value as? NSNumber else {
throw JSONDecodingError.couldNotConvert(value: value, to: Int64.self)
}
self = number.int64Value
}
public var jsonValue: JSONValue {
return self
}
}
but run API.Swift get an error: Use of unresolved identifier 'Long'
who can tell me what wrong with that?
from apollo-ios.
Int
support for custom scalars has (finally) shipped in 0.14.0
.
@JakeTorres Can you please take your question to our Spectrum chat? it's not quite related to this issue. Thank you!
from apollo-ios.
Related Issues (20)
- Parity with Apollo Kotlin: Ability to Observe ApolloStore Changes? HOT 3
- Narrowly Scoped equality on SelectionSet models HOT 1
- SQLite dependency needs to be bumped to 0.15.0 HOT 3
- Generated mocks in test target missing @testable annotation against main target HOT 8
- codegen: Append type to generated filenames HOT 6
- Add support for SPM `Package.resolved` version `3`
- Support multiple schemas / endpoint in one project HOT 7
- Parity with Kotlin SDK for cache chaining and optimistic cache updates HOT 2
- PrivacyInfo.xcprivacy file is invalid for Apollo and ApolloApi. HOT 7
- SchemaConfiguration should be scoped within the namespace enum for `embeddedInTarget` module type
- Investigation: Allow codegen projects to modify generated filenames HOT 2
- Add support for incremental cache writes
- Add support for incremental cache reads
- Avoid File Overwriting for Unchanged Files HOT 1
- `InMemoryNormalizedCache` is a memory bomb HOT 5
- iOS 13.0 or newer error - compile fails HOT 3
- Custom Scalar | ApolloAPI.JSONDecodingError.couldNotConvert(value: AnyHashable to: Swift.String HOT 5
- How should I continue after handleErrorAsync inside a custom ApolloErrorInterceptor? HOT 5
- Defining a CustomScalarType which is [String:Any] HOT 12
- Deprecate `legacyResponse` and prepare for partial/incremental caching HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from apollo-ios.