Closed nandofer1 closed 4 years ago
Hey @nandofer1 - are you getting an error from the GitHub API, or is the print
statement just printing nothing? It might be helpful to switch
on the result so you can see what's in the success vs. failure case, and which one is being hit.
@designatednerd - the print statement just printing nothing in the console . I don't receive any warning or error, I don't know if he's doing the fetch, I've tried this way with a switch to handle the different cases :
apollo.fetch(query: SearchUsersQuery(user: "nandofer1")) { result in switch result { case .success(let graphQLResult): if let data = graphQLResult.data { print(data) } else if let errors = graphQLResult.errors { print(errors) } case .failure(let error): // Network or response format errors print(error) } }
but he still doesn't print anything when executing the fetch.
One thing to watch out for: Is there anything holding on to your apollo
client instance, like a singleton or a view controller? If there isn't anything, that completion block won't get called because the client got deallocated.
@designatednerd
the code snippet is called in the viewdidload of my view controller in this way:
import Apollo import Foundation class SearchsUsersViewController: UIViewController{
override func viewDidLoad() {
super.viewDidLoad()
print("get in viewdidload")
let apollo: ApolloClient = {
let configuration = URLSessionConfiguration.default
configuration.httpAdditionalHeaders = [
"Authorization": "Bearer <my token github>"
]
let url = URL(string: "https://api.github.com/graphql")!
return ApolloClient(
networkTransport: HTTPNetworkTransport(
url: url
)
)
}()
/*apollo.fetch(query: SearchUsersQuery(user: "nandofer1")){
result in
guard let data = try? result.get().data else { return }
print(data.search.__typename)
}*/
apollo.fetch(query: SearchUsersQuery(user: "nandofer1")) { result in
switch result {
case .success(let graphQLResult):
if let data = graphQLResult.data {
print(data)
} else if let errors = graphQLResult.errors {
print(errors)
}
case .failure(let error):
// Network or response format errors
print(error)
}
}
}
}
So that let
should be outside the viewDidLoad
, which will make it a property. This is because otherwise as soon as the scope of viewDidLoad
exits, Automatic Reference Counting will go "Oh, nobody's using this anymore, I can kill this off", and deallocate any variable declared within the viewDidLoad()
.
TL;DR:
let apollo: ApolloClient = {
[existing code]
}()
override func viewDidLoad() {
super.viewDidLoad()
print("get in viewdidload")
apollo.fetch(query: SearchUsersQuery(user: "nandofer1")) { result in
...
Is right, You must be out of viewDidLoad, now if you make the request and I am getting an error:
GraphQLHTTPResponseError(body: Optional(131 bytes), response: <NSHTTPURLResponse: 0x600003aaf240> { URL: https://api.github.com/graphql } { Status Code: 401, Headers { "Access-Control-Allow-Origin" = ( "*" ); "Access-Control-Expose-Headers" = ( "ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type" ); "Content-Length" = ( 131 ); "Content-Security-Policy" = ( "default-src 'none'" ); "Content-Type" = ( "application/json; charset=utf-8" ); Date = ( "Mon, 18 Nov 2019 14:52:08 GMT" ); "Referrer-Policy" = ( "origin-when-cross-origin, strict-origin-when-cross-origin" ); Server = ( "GitHub.com" ); Status = ( "401 Unauthorized" ); "Strict-Transport-Security" = ( "max-age=31536000; includeSubdomains; preload" ); "X-Content-Type-Options" = ( nosniff ); "X-Frame-Options" = ( deny ); "X-GitHub-Media-Type" = ( "github.v4; format=json" ); "X-GitHub-Request-Id" = ( "ABAD:3026:60CBDD:CED40D:5DD2B018" ); "X-RateLimit-Limit" = ( 0 ); "X-RateLimit-Remaining" = ( 0 ); "X-RateLimit-Reset" = ( 1574092328 ); "X-XSS-Protection" = ( "1; mode=block" ); } }, kind: Apollo.GraphQLHTTPResponseError.ErrorKind.errorResponse, serializationFormat: Apollo.JSONSerializationFormat)
in the header of apollo I have put the key and the value of the token that I have generated in Github, I have tried it with the same token in the GraphQL console and it works.
Aha, I think I see it: You're setting up the configuration
object but you're never passing it to the HTTPNetworkTransport
object, so the network transport has no idea it exists. I'm surprised you're not getting an unused variable warning there.
You'll need to hand the configuration
object to a URLSession
object, and then hand that to the HTTPNetworkTransport
object. Then the network transport will know to use your configuration and add the proper header.
I've been trying to add the configuration parameter to the HTTPNetworkTransport like this:
let apollo: ApolloClient = {
let configuration = URLSessionConfiguration.default
configuration.httpAdditionalHeaders = [
"Authorization": "Bearer
let url = URL(string: "https://api.github.com/graphql")!
return ApolloClient(
networkTransport: HTTPNetworkTransport(
url: url,
configuration: configuration
)
)
}()
but it shows me an error as well as you tell me that you are surprised that you do not receive a warning that a parameter is needed on the contrary when sending the configuration the parameter received the error extra parameter in call.
I have been seeing other forms and about a year ago if the configuration was sent as a parameter.
This is a (relatively) recent change - to allow for greater flexibility, we updated the initializer to take the URL session rather than just the configuration.
Current documentation for the class is available either inline or on our documentation website.
@designatednerd
It worked with the URL session parameter, thank you very much for everything! (y)
@nandofer1 - mind if we close this out? I can't tell if you reopened accidentally or on purpose 🙃
It was by accident, we can close it. thank you! :D
Am running to this error Cannot find 'HTTPNetworkTransport' in scope
and Cannot find type 'HTTPNetworkTransportDelegate' in scope
when am trying to make calls, ApolloClient Version 0.34.1
Here is my code;
final class Network {
static let shared = Network()
private lazy var networkTransport: NetworkTransport = {
let transport = HTTPNetworkTransport(url: URL(string: "https://exampe.com/grapghql")!)
transport.delegate = self
return transport
}()
private(set) lazy var apollo = ApolloClient(networkTransport: self.networkTransport)
}
extension Network: HTTPNetworkTransportDelegate {
func networkTransport(_ networkTransport: NetworkTransport, shouldSend request: URLRequest) -> Bool {
return true
}
func networkTransport(_ networkTransport: NetworkTransport, willSend request: inout URLRequest) {
let token = ""
var headers = request.allHTTPHeaderFields ?? [String: String]()
headers["Authorization"] = "Bearer \(token)"
request.allHTTPHeaderFields = headers
}
}
I appreciate your feedback.
I am starting to use apollo-ios with the github API, I have followed the steps in this link ( https://www.back4app.com/docs/ios/swift-graphql), I have generated the scheme.json file with my github authorization token and also created my .graphql file with the query that I am sure it works because I tested in the graphQL console application but when implementing the code and doing the fetch does not show me anything, it does not print or error or the parameter I want to print.
Here is my code snippet
and here is what my .graphQL file contains
query searchUsers($user: String!) { search(query: $user, type: USER, first: 100) { nodes { __typename ... on User { name login avatarUrl url bio } } } }
Will I be missing something? please help.