0

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

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

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

似乎正在发生的事情是我的请求对象被包装在查询 JSON 中的“资源”键中。现在,当我的网络服务尝试对其进行解码时,它会产生一条警告,提示“未找到无法识别的字段的变体:资源”。而且,由于我的对象被包裹在这个键中,它被跳过并且永远不会解码为消息。

当使用 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

4 回答 4

4

这是从 iOS 到 Endpoints 进行本地测试的一个恼人的错误。我希望他们尽快修复它。:)

顺便说一句,而不是修改 QGTQueryMyAPI.m (这是一个生成的文件)。我只是在创建查询之后才进行 Theo 的修复。所以我所有发送数据的查询都是这样的(我设置了一个标志来从本地主机切换到部署在其他地方)。

GTLQueryMyApi *query = [GTLQueryMyApi queryForSearchWithObject:someGtlObject];

if (LOCAL_HOST_TESTING) {
    [query setJSON:someGtlObject.JSON];        
}
于 2013-08-27T17:40:05.030 回答
1

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

    auth.shouldAuthorizeAllRequests = YES;

“资源”密钥包装问题仅在我添加上面的行以使用 localhost 时发生。所以今天早上我没有使用本地主机,只是部署的版本。让我知道你是否解决了这个问题。:) 显然指向已部署的版本不是测试的首选。

于 2013-08-19T15:47:57.333 回答
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 包装在“资源”字段中。不知何故,我认为这不应该在部署版本上完成。

于 2013-08-20T14:05:40.043 回答
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")
于 2016-03-28T20:10:22.073 回答