【问题标题】:Google Cloud Endpoints generated iOS Client not workingGoogle Cloud Endpoints 生成的 iOS 客户端无法正常工作
【发布时间】:2013-08-11 12:56:01
【问题描述】:

我有一个使用 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;
}

我在这里做错了什么吗?

【问题讨论】:

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


【解决方案1】:

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

【讨论】:

    【解决方案2】:

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

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

    GTLQueryMyApi *query = [GTLQueryMyApi queryForSearchWithObject:someGtlObject];
    
    if (LOCAL_HOST_TESTING) {
        [query setJSON:someGtlObject.JSON];        
    }
    

    【讨论】:

    • 很好的接触,戴夫。这确实更容易实现,因此您不必一直更改生成的代码。从来没想过!!! =)
    • 截至 2014 年 10 月,这仍然是一个问题,此修复仍然有效!
    【解决方案3】:

    好的! 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 包装在“资源”字段中。不知何故,我认为这不应该在部署发布版本上完成。

    【讨论】:

    • Theo,你能发布一下你如何配置iOS客户端api连接到本地服务器而不是在线服务器吗?
    • @Teg,很抱歉我之前没有看到你的评论。你还需要这个还是已经解决了?
    【解决方案4】:

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

        auth.shouldAuthorizeAllRequests = YES;
    

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

    【讨论】:

    • user2697002,我还没有尝试部署版本。也许这应该可以解决问题,我会尽快尝试您的解决方案,如果可行,我会将其标记为已接受的答案。谢谢!
    • 是的!它确实在部署中起作用!我将其标记为已接受,因为它使我知道这适用于 apppot。我正在发布解决此问题的解决方法,以作为另一个答案,因为它可能对其他人有所帮助。
    猜你喜欢
    • 2013-06-03
    • 2014-05-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-19
    • 1970-01-01
    • 2014-05-03
    • 2014-06-11
    相关资源
    最近更新 更多