Google Cloud Endpoints生成的iOS客户端无法正常工作

时间:2013-08-09 14:37:10

标签: ios google-app-engine python-2.7 google-cloud-endpoints

我有一个使用GAE Python SDK 1.8.3在本地运行的python webservice。在使用Google Cloud Endpoints Service Generator注释API并生成iOS客户端类之后,我正在尝试使用它来调用远程过程。

如果我使用API​​ Explorer测试我的api,一切正常。

当我使用iOS客户端呼叫时,Web服务会收到呼叫,但请求无法正确解码。这是我第一次使用Endpoints API,所以我不知道出了什么问题。

似乎正在发生的事情是我的请求对象被包装在查询JSON中的“资源”键中。现在,当我的web服务尝试对其进行解码时,它会发出一条警告,说“找不到无法识别的字段:资源的变种”。并且,当我的对象被包含在此键中时,它将被跳过并且永远不会被解码为消息。

当使用API​​ Explorer进行调用时,对象未被包装,因此一切正常。

这就是我在网络服务中所做的事情:

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

这就是我从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;
}

我在这里做了什么令人难以置信的错误?

4 个答案:

答案 0 :(得分:4)

这是一个从iOS到端点进行本地测试的烦人错误。我希望他们尽快解决。 :)

BTW而不是修改QGTQueryMyAPI.m(这是一个生成的文件)。我在创建查询后立即执行Theo的修复。因此,我发送数据的所有查询都是这样的(我设置了一个标志,以便从localhost切换到其他地方部署)。

GTLQueryMyApi *query = [GTLQueryMyApi queryForSearchWithObject:someGtlObject];

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

答案 1 :(得分:1)

这不是一个很好的解决方案,但现在是补丁。在进行iOS端点localhost测试时,我遇到了同样的问题。但是当我使用部署的后端时,我删除了这一行,一切都很好。

    auth.shouldAuthorizeAllRequests = YES;

“资源”密钥包装问题仅在我添加上面的行以使用localhost时发生。所以今天早上我没有使用localhost,只是部署版本。如果您解决了这个问题,请告诉我。 :)显然,指向已部署的版本不适合测试。

答案 2 :(得分:0)

好的! user2697002的回答告诉我,这在部署web服务时有效。

为了使开发工作正常,这就是我所做的解决方法。

生成的API对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;
}

为了在开发服务器上工作,可以替换所有这些行

query.bodyObject = object;

使用

query.JSON = object.JSON;

停止将JSON包装在“资源”字段中。不知何故,我认为不应该在部署发布版本上做到这一点。

答案 3 :(得分:0)

我还在尝试,但相信这是设置在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")