如何在iOS/Swift项目中调用我的AWS API网关REST API

如何在iOS/Swift项目中调用我的AWS API网关REST API,ios,swift,amazon-web-services,aws-api-gateway,aws-amplify,Ios,Swift,Amazon Web Services,Aws Api Gateway,Aws Amplify,我创建了一个单视图应用程序,然后按照AWS Amplify iOS SDK指南使用现有的Cognito用户池插入身份验证。工作得很好 然后,使用AWS Amplify,我允许我的iOS应用程序通过Amplify生成的API网关和Lambda函数访问预先存在的DynamoDB表。然而,我不得不重新连接所有东西,以使用我预先存在的Cognito用户池,因为Amplify CLI意外地创建了一个链接到它创建的REST API的新用户池 我在尝试调用API时遇到以下错误,无论我做什么,都无法使其消失:

我创建了一个单视图应用程序,然后按照AWS Amplify iOS SDK指南使用现有的Cognito用户池插入身份验证。工作得很好

然后,使用AWS Amplify,我允许我的iOS应用程序通过Amplify生成的API网关和Lambda函数访问预先存在的DynamoDB表。然而,我不得不重新连接所有东西,以使用我预先存在的Cognito用户池,因为Amplify CLI意外地创建了一个链接到它创建的REST API的新用户池

我在尝试调用API时遇到以下错误,无论我做什么,都无法使其消失:

Optional("{\"message\":\"Authorization header requires \'Credential\' parameter. 
Authorization header requires \'Signature\' parameter. Authorization header requires 
\'SignedHeaders\' parameter. 
Authorization=abJarWQiOiJyR0NiTHFsbVwvbWdGeXgzcVA1YmNRaV...
403
更新5 有关更多血淋淋的详细信息,请参阅我的。:)

更新4 此更新优先于我以前的更新,因为现在看起来很清楚,因为上面的错误表明我没有通过iOS应用程序的经过身份验证的Cognito用户正确调用REST API。我注意到Amplify创建了一个用户池,其中有两个应用程序客户端,一个用于Web访问,另一个用于移动访问。我先前存在的用户池只有一个为Web访问定制的应用程序客户端。因此,我创建了一个新的移动接入应用程序客户端,带有一个应用程序客户端密码

不幸的是,我得到了同样的错误。所以我想知道是否还有其他东西需要重新连接;或者我有个象征性的问题。正如我在下面的评论中提到的,也许我不应该使用RESTAPI指南中指定的OIDC令牌?也许我应该用结束更新4

我的API有一个资源
/items
,我有一个
ANY
和一个
OPTIONS
方法。
ANY
方法没有为方法请求指定任何URL查询字符串参数。但是它确实为请求主体指定了类型为
application/json
RequestSchema

我的API调用函数正是这样(我按照他们的说明使用Cognito User Pools authorizer调用我的API网关端点),除了我将
httpMethodName
POST
更改为
GET
,因为POST导致了崩溃。下面是它的样子:

func doInvokeAPI(token:String) {
        // change the method name, or path or the query string parameters here as desired
        let httpMethodName = "GET"
        // the guid is the partition key for the DynamoDB table
        let URLString = "/items/178dc797-4e3d-5bc4-815f-a280536fcd3a"
        //let queryStringParameters = ["key1":"{value1}"]
        let headerParameters = [
            "Content-Type": "application/json",
            "Accept": "application/json",
            "Authorization": token
        ]

        //let httpBody = "{ \n  " +
        //    "\"key1\":\"value1\", \n  " +
        //    "\"key2\":\"value2\", \n  " +
        //    "\"key3\":\"value3\"\n}"


        // Construct the request object
        let apiRequest = AWSAPIGatewayRequest(httpMethod: httpMethodName,
                                              urlString: URLString,
                                              queryParameters: nil,
                                              headerParameters: headerParameters,
                                              httpBody: nil)

...
...
        invocationClient.invoke(apiRequest).continueWith { (task: AWSTask) -> Any? in
            if let error = task.error {
                print("Error occurred: \(error)")
                // Handle error here
                return nil
            }

            // Handle successful result here
            let result = task.result!
            let responseString = String(data: result.responseData!, encoding: .utf8)

            print(responseString as Any)
            print(result.statusCode)

            return nil
        }
    }
上面给出的错误由
print(responseString)
打印

我的DynamoDB表需要一个
userId
的分区键。Guid字符串

我非常确定我想要传递的API只是一个
userId
,这样API就可以检索与之相关的所有项目。不需要我的分拣钥匙

我如何通过API网关REST API发出此GET请求是否存在问题

更新1 有两个JavaScript文件与我的Lambda函数关联:
index.js
app.js
,由Amplify创建

index.js
非常短:

const awsServerlessExpress = require('aws-serverless-express');
const app = require('./app');

const server = awsServerlessExpress.createServer(app);

exports.handler = (event, context) => {
  console.log(`EVENT: ${JSON.stringify(event)}`);
  awsServerlessExpress.proxy(server, event, context);
};
app.js
包含一些设置(第一个屏幕截图),然后是一系列方法,用于
get
put
post
删除
。我只是包括两个
get
方法的屏幕截图——这个问题的主题)

更新2 下面是我在单击API的
ANY
方法的集成请求时看到的内容。请注意,我没有映射模板的下拉列表

更新3 但我确实有一个
Prod
舞台,放大了我的创作。但我仍然看不到任何映射模板

“/items/{userId}”
只是一个字符串。请尝试
“/items/\(userId)”

抱歉,我没有足够的分数发表评论。

“/items/{userId}”
只是一个字符串。请尝试
“/items/\(userId)”


很抱歉,我没有足够的要点发表评论。

API网关映射模板,这里是关于如何查看它们的第一步:第二步:发布您看到的内容我很感激。你帮了我很大的忙。。。带我去一个我应该找的地方。我不知道为什么AWS Amplify没有为这个RESTAPI生成映射模板。我将对API网关做更多的研究,并将记住您的报价。谢谢映射模板向lambda函数发送查询参数。如果没有此选项,则不会传递任何参数,因此它会失败您在headerParameters中缺少AWS调用请求所需的一些参数。我过去常常手动签署请求@motivus可以使用Charles调试器调试请求。我认为你可以看到实际的请求并找到解决方案。为你的API网关映射模板,这里是关于如何查看它们的第一步:第二步:发布你看到的我很感激。你帮了我很大的忙。。。带我去一个我应该找的地方。我不知道为什么AWS Amplify没有为这个RESTAPI生成映射模板。我将对API网关做更多的研究,并将记住您的报价。谢谢映射模板向lambda函数发送查询参数。如果没有此选项,则不会传递任何参数,因此它会失败您在headerParameters中缺少AWS调用请求所需的一些参数。我过去常常手动签署请求@motivus可以使用Charles调试器调试请求。我认为您可以在那里看到实际请求并找到解决方案。
userId
在我的例子中是一个Guid,它是一个字符串。因此,上面将
userId
视为整数文本。尽管如此,我还是感谢你的帮助!在Swift中,
{userId}
将不会替换为
userId
变量。您的URL字符串字面上是
/items/{userId}
。我很确定那不是你想做的。要使用字符串插值,您需要使用
\(userId)
。然后您的URL字符串将是
/items/whateverisintheserivariable
。我明白您的意思了。那不是我的密码。。。我只是代表