Amazon web services 以编程方式而不是硬编码方式引用AWS S3存储桶名称

Amazon web services 以编程方式而不是硬编码方式引用AWS S3存储桶名称,amazon-web-services,amazon-s3,aws-amplify,aws-sdk-ios,Amazon Web Services,Amazon S3,Aws Amplify,Aws Sdk Ios,我正在与AWS Amplify合作开发一个iOS应用程序。我已经通过S3添加了存储来承载一些资产,并且正在尝试配置应用程序来下载它们。唯一的问题是,我看到的每个示例都硬编码了bucket名称和路径,但因为我有多个环境,有时会创建新环境,并且每个bucket都附加了环境名称,所以我不想每次都重写bucket名称 例如,如果我在我的测试环境中,bucket名称可能是assetsxxxxxx test,但是如果我切换到一个新环境,我可能会引用assetsyyy dev 问题是在aswconfigura

我正在与AWS Amplify合作开发一个iOS应用程序。我已经通过S3添加了存储来承载一些资产,并且正在尝试配置应用程序来下载它们。唯一的问题是,我看到的每个示例都硬编码了bucket名称和路径,但因为我有多个环境,有时会创建新环境,并且每个bucket都附加了环境名称,所以我不想每次都重写bucket名称

例如,如果我在我的测试环境中,bucket名称可能是assetsxxxxxx test,但是如果我切换到一个新环境,我可能会引用assetsyyy dev

问题是在aswconfiguration.json文件中引用了bucket名称:

"S3TransferUtility": {
    "Default": {
        "Bucket": "assetsxxxxx-test",
        "Region": "us-east-2"
    }
}
所以我的问题是如何以编程方式引用该bucket名称,以便在切换环境时重写该字段时,不必更改代码


谢谢

我不清楚您使用什么来构建Amplify资源(cloudformation、terrraform、console?等),进而创建“aswconfiguration.json文件”。但听起来你需要传递一个动态变量,这是很容易实现的

如果您使用codepipeline、codebuild安排来部署资源和配置文件,那么您可以在codebuild阶段使用bash命令(sed或perl)来更改变量。或者使用自定义lambda更新文件内容并复制到S3,然后将动态变量传递到环境变量参数中

通常,如果这是一个cloudformation模板,您可以使用一个伪参数引用,然后该参数将在早期声明并引用任何环境,例如

“Bucket”:“asssetxxxxxx-${Environment}”


我不清楚您使用什么来构建Amplify资源(cloudformation、terrraform、console?等),进而创建“aswconfiguration.json文件”。但听起来你需要传递一个动态变量,这是很容易实现的

如果您使用codepipeline、codebuild安排来部署资源和配置文件,那么您可以在codebuild阶段使用bash命令(sed或perl)来更改变量。或者使用自定义lambda更新文件内容并复制到S3,然后将动态变量传递到环境变量参数中

通常,如果这是一个cloudformation模板,您可以使用一个伪参数引用,然后该参数将在早期声明并引用任何环境,例如

“Bucket”:“asssetxxxxxx-${Environment}”


我解决了。对于任何想知道的人,我仍然不确定AWS SDK中是否内置了字段,但我决定直接在自定义结构中解析awsconfiguration.json文件:

struct AWSConfigurationJSON: Codable{
    let S3TransferUtility: S3TransferUtility
}

struct S3TransferUtility: Codable{
    let Default: S3TransferUtilityDefault
}

struct S3TransferUtilityDefault: Codable{
    let Bucket: String
    let Region: String
}
然后我读取文件并解析JSON

if let path = Bundle.main.path(forResource: "awsconfiguration", ofType: "json") {
            do{
                let data = try Data(contentsOf: URL(fileURLWithPath: path), options: .mappedIfSafe)
                let jsonResult = try JSONDecoder().decode(AWSConfigurationJSON.self, from: data)
                print(jsonResult.S3TransferUtility.Default.Bucket)
                bucketPath = jsonResult.S3TransferUtility.Default.Bucket
            }catch let e{
                print("error \(e)")
                bucketPath = ""

            }
        }else{
            bucketPath = ""

        }

我解决了。对于任何想知道的人,我仍然不确定AWS SDK中是否内置了字段,但我决定直接在自定义结构中解析awsconfiguration.json文件:

struct AWSConfigurationJSON: Codable{
    let S3TransferUtility: S3TransferUtility
}

struct S3TransferUtility: Codable{
    let Default: S3TransferUtilityDefault
}

struct S3TransferUtilityDefault: Codable{
    let Bucket: String
    let Region: String
}
然后我读取文件并解析JSON

if let path = Bundle.main.path(forResource: "awsconfiguration", ofType: "json") {
            do{
                let data = try Data(contentsOf: URL(fileURLWithPath: path), options: .mappedIfSafe)
                let jsonResult = try JSONDecoder().decode(AWSConfigurationJSON.self, from: data)
                print(jsonResult.S3TransferUtility.Default.Bucket)
                bucketPath = jsonResult.S3TransferUtility.Default.Bucket
            }catch let e{
                print("error \(e)")
                bucketPath = ""

            }
        }else{
            bucketPath = ""

        }

我也有同样的问题。我的解决方案类似,但不完全相同。 首先,我创建了如下的可编码结构

import Foundation

struct AwsConfiguration: Codable {
    struct S3TransferUtility : Codable {
        private enum CodingKeys: String, CodingKey {
            case defaultConfig = "Default"
        }

        struct DefaultConfig : Codable {
            private enum CodingKeys: String, CodingKey {
                case bucket = "Bucket"
                case region = "Region"
            }
            var bucket: String
            var region: String
        }

        var defaultConfig: DefaultConfig
    }

    private enum CodingKeys: String, CodingKey {
        case s3TransferUtility = "S3TransferUtility"
    }

    var s3TransferUtility: S3TransferUtility
}
然后我定义了一个DataHelper类

final class DataHelper {
    static func load<T: Decodable>(_ filename: String, as type: T.Type = T.self) -> T {
        let data: Data

        guard let file = Bundle.main.url(forResource: filename, withExtension: nil)
            else {
                fatalError("Couldn't find \(filename) in main bundle.")
        }

        do {
            data = try Data(contentsOf: file)
        } catch {
            fatalError("Couldn't load \(filename) from main bundle:\n\(error)")
        }

        do {
            let decoder = JSONDecoder()
            return try decoder.decode(T.self, from: data)
        } catch {
            fatalError("Couldn't parse \(filename) as \(T.self):\n\(error)")
        }
    }
}

我也有同样的问题。我的解决方案类似,但不完全相同。 首先,我创建了如下的可编码结构

import Foundation

struct AwsConfiguration: Codable {
    struct S3TransferUtility : Codable {
        private enum CodingKeys: String, CodingKey {
            case defaultConfig = "Default"
        }

        struct DefaultConfig : Codable {
            private enum CodingKeys: String, CodingKey {
                case bucket = "Bucket"
                case region = "Region"
            }
            var bucket: String
            var region: String
        }

        var defaultConfig: DefaultConfig
    }

    private enum CodingKeys: String, CodingKey {
        case s3TransferUtility = "S3TransferUtility"
    }

    var s3TransferUtility: S3TransferUtility
}
然后我定义了一个DataHelper类

final class DataHelper {
    static func load<T: Decodable>(_ filename: String, as type: T.Type = T.self) -> T {
        let data: Data

        guard let file = Bundle.main.url(forResource: filename, withExtension: nil)
            else {
                fatalError("Couldn't find \(filename) in main bundle.")
        }

        do {
            data = try Data(contentsOf: file)
        } catch {
            fatalError("Couldn't load \(filename) from main bundle:\n\(error)")
        }

        do {
            let decoder = JSONDecoder()
            return try decoder.decode(T.self, from: data)
        } catch {
            fatalError("Couldn't parse \(filename) as \(T.self):\n\(error)")
        }
    }
}

谢谢amplify资源使用amplify CLI进行配置,该CLI为每个资源生成自己的cloudformation模板。我对实际切换环境没有问题,因为amplify使其简单到调用“amplify env checkout{env name}”,然后“amplify pull”,AWSCOConfiguration.json bucket名称将自动更改为正确的bucket。我的问题是,当传输实用程序请求bucket name时,如何在swift代码中引用该bucket name,而不是硬编码字符串?谢谢!amplify资源使用amplify CLI进行配置,该CLI为每个资源生成自己的cloudformation模板。我对实际切换环境没有问题,因为amplify使其简单到调用“amplify env checkout{env name}”,然后“amplify pull”,AWSCOConfiguration.json bucket名称将自动更改为正确的bucket。我的问题是,当传输实用程序请求bucket name时,如何在swift代码中引用该bucket name,而不是硬编码字符串?