Theo
Theo

Reputation: 465

Google Cloud Endpoints generated iOS Client not working

I have a python webservice running locally using GAE Python SDK 1.8.3. After annotating the API and generating iOS client classes using Google Cloud Endpoints Service Generator I'm trying to call a remote procedure using it.

If I test my api using API Explorer, everything works just fine.

When I call using the iOS client, the call is received by the webservice, however the request cannot be decoded correctly. This is my first time using the Endpoints API so I don't know what is wrong.

What seems to be happening is that my request object is being wrapped in a "resource" key in the query JSON. Now, when my webservice tries to decode it, it yields a warning saying "No variant found for unrecognized field: resource". And, as my object is wrapped inside this key, it is skipped and never decoded to a message.

When the call is made using the API Explorer the object is not wrapped, so everything works.

This is what I'm doing in my webservice:

@endpoints.method(SearchRequest, 
                  ContactListResponse,
                  path='search', http_method='post',
                  name='api.search')
def search(self, request):
    user = request.user
    number = request.number

This is how I call it from iOS:

GTLMyAPIMessagesSearchRequest * request = [[GTLMyAPIMessagesSearchRequest alloc] init];
request.user = @"+552199881234";
request.number = @"+5521717171";


GTLQueryMyAPI *query = [GTLQueryMyAPI queryForApiSearchWithObject:request];
[service executeQuery:query completionHandler:^(GTLServiceTicket *ticket,
                                                GTLMyAPIMessagesContactListResponse* object,
                                                NSError *error)
{
    NSArray* contacts = object.contacts;
}

Am I doing anything incredibly wrong here?

Upvotes: 0

Views: 1005

Answers (4)

Dewey
Dewey

Reputation: 776

I'm still experimenting but believe this is the proper way (swift) to set up for testing on localhost....

let _service = GTLServiceBackendAPI();
_service.allowInsecureQueries = true;
_service.isRESTDataWrapperRequired = false;
_service.retryEnabled = true;
_service.fetcherService.allowLocalhostRequest = true;
_service.rpcURL = NSURL(string: "http://localhost:8080/_ah/api/rpc?prettyPrint=true")

Upvotes: 0

Dave Fisher
Dave Fisher

Reputation: 1223

This is an annoying bug from iOS to Endpoints for local testing. I hope they fix it soon. :)

BTW instead of modifying QGTQueryMyAPI.m (which is a generated file). I do Theo's fix just after I create the query instead. So all of my queries that send data look like this (and I set that one flag to switch from localhost to deployed in other places too).

GTLQueryMyApi *query = [GTLQueryMyApi queryForSearchWithObject:someGtlObject];

if (LOCAL_HOST_TESTING) {
    [query setJSON:someGtlObject.JSON];        
}

Upvotes: 4

Theo
Theo

Reputation: 465

Alright! user2697002's answer showed me that this works when the webservice is deployed.

For development to work correctly this is the workaround I did.

The generated API uses a template like this for all queries in GTLQueryMyAPI.m

+ (id)queryForSearchWithObject:(GTLMyAPIMessagesSearchRequest *)object {
  if (object == nil) {
    GTL_DEBUG_ASSERT(object != nil, @"%@ got a nil object", NSStringFromSelector(_cmd));
    return nil;
  }
  NSString *methodName = @"myapi.search";
  GTLQueryMyAPI *query = [self queryWithMethodName:methodName];
  query.bodyObject = object;
  query.expectedObjectClass = [GTLMyAPIMessagesContactListResponse class];
  return query;
}

For this to work on development server one could substitute all these lines

query.bodyObject = object;

With

query.JSON = object.JSON;

This stops from wrapping the JSON in a "resource" field. Somehow I believe this shouldn't be done on deployment release version.

Upvotes: 0

user2697002
user2697002

Reputation: 26

This is not a great solution but a patch for now. I have the same problem when doing iOS endpoints localhost testing. However when I use the deployed backend I remove this line and everything is fine.

    auth.shouldAuthorizeAllRequests = YES;

The "resource" key wrapping issue only happens when I add the line above to use localhost. So this morning I'm not using localhost, just the deployed version. Let me know if you fix the issue. :) Obviously pointing to the deployed version is not preferred for testing.

Upvotes: 1

Related Questions