amplify-swift
amplify-swift copied to clipboard
[iOS] Config Amplify for Multi Environments
Describe the bug
Currently we are using amplify iOS SDK(1.26.1) working fine with staging environment. But we have requirement to setup preprod and prod environment.
So I am trying fetch the json amplifyconfiguration.json
file based on the environment and passing amplify configuration and no error throwing during the first-time initialization.
similarly we have awsconfiguration.json
file based on environment I am trying to pass JSONValue and no error throwing during the first-time initialization.
After renamed amplify and aws configuration file names then only the issue is happening , but without renaming the file how to handle for multiple environment's like stage, preprod and prod
PROBLEM But when I am trying to login facebook, google, apple sigin , email and phone number app is crashing.
Here is code:
private func initAmplify() {
do {
#if DEBUG
Amplify.Logging.logLevel = .verbose
#endif
let awsCognitoAuthPlugin = AWSCognitoAuthPlugin()
let awsConfiguration: JSONValue = getAwsJsonConfiguration(fileName: "awsconfiguration.preprod")
try awsCognitoAuthPlugin.configure(using: awsConfiguration)
try Amplify.add(plugin: awsCognitoAuthPlugin)
let amplifyJsonPath = getAmplifyJsonFilePath()
try Amplify.add(plugin: AWSCognitoAuthPlugin())
if amplifyJsonPath != nil {
let amplifyConfig = try AmplifyConfiguration(configurationFile: URL(fileURLWithPath: amplifyJsonPath!))
try Amplify.configure(amplifyConfig)
}
} catch {
helpers.logger?.error("Failed initializing Amplify", error: error, attributes: nil)
}
}
func getAwsJsonConfiguration(fileName: String) -> JSONValue {
if let path: String = Bundle.main.path(forResource: fileName, ofType: "json") {
if let data = NSData(contentsOfFile: path) {
if let rawString = JSON(data).rawString() {
do {
let jsonValue = try JSONDecoder().decode(JSONValue.self, from: rawString.data(using: .utf8)!)
return jsonValue
} catch {
return [:]
}
}
}
}
return [:]
}
func getAmplifyJsonFilePath() -> URL? {
guard let file = Bundle.main.url(forResource: "amplifyconfiguration.preprod", withExtension: ".json") else {
return nil
}
return file
}

Steps To Reproduce
- Lunch iOS app
- Call
initAmplify()
didFinishLaunchingWithOptions from Appdelegate. - Dynamically configure AWSCognitoAuthPlugin with JSONValue
- Get the Json file path from bundle and pass to Amplify configuration.
Expected behavior
It should work with all accounts(socials, email & iPhone number) when do to configure dynamically.
Amplify Framework Version
1.26.2
Amplify Categories
Auth
Dependency manager
Cocoapods
Swift version
5.0
CLI version
9.1.0
Xcode version
13.4
Relevant log output
No response
Is this a regression?
No
Regression additional context
No response
Device
Iphone 13
iOS Version
15.5
Specific to simulators
Iphone 13 Pro
Additional context
Below attached error screenshots for reference:
Hi @AdiPomelo, thanks for opening this issue. Dynamic configuration like you're doing here is supported and should work. Let's try to figure out what's going on here. Can you please post the contents of the four configuration files you're using? Please make sure to strip out any confidential information. Once we know what those look like, we can try to reproduce what you're experiencing. Thanks!
@atierian Thank you for quick reply.
Here is amplify json file looks like.
amplifyconfiguration.json
{
"UserAgent": "aws-amplify-cli/2.0",
"Version": "1.0",
"auth": {
"plugins": {
"awsCognitoAuthPlugin": {
"UserAgent": "aws-amplify/cli",
"Version": "0.1.0",
"IdentityManager": {
"Default": {}
},
"CredentialsProvider": {
"CognitoIdentity": {
"Default": {
"PoolId": "XXXXXXX",
"Region": "ap-southeast-1"
}
}
},
"CognitoUserPool": {
"Default": {
"PoolId": "XXXXXXXX",
"AppClientId": "XXXXXXXX",
"Region": "ap-southeast-1"
}
},
"Auth": {
"Default": {
"OAuth": {
"WebDomain": "XXXXXXXXX",
"AppClientId": "XXXXXXXXXX",
"SignInRedirectURI": "XXXX://auth/login",
"SignOutRedirectURI": "XXXXX://auth/logout",
"Scopes": [
"phone",
"email",
"openid",
"profile",
"aws.cognito.signin.user.admin"
]
},
"authenticationFlowType": "CUSTOM_AUTH"
}
}
}
}
}
}
awsconfiguration.json
{
"UserAgent": "aws-amplify/cli",
"Version": "0.1.0",
"IdentityManager": {
"Default": {}
},
"CredentialsProvider": {
"CognitoIdentity": {
"Default": {
"PoolId": "XXXXXXX",
"Region": "ap-southeast-1"
}
}
},
"CognitoUserPool": {
"Default": {
"PoolId": "XXXXXX",
"AppClientId": "XXXXXXXXX",
"Region": "ap-southeast-1"
}
},
"Auth": {
"Default": {
"OAuth": {
"WebDomain": "auth.pre-production.XXX.co",
"AppClientId": "XXXXXXXXXX",
"SignInRedirectURI": "XXXX://auth/login",
"SignOutRedirectURI": "XXXXX://auth/logout",
"Scopes": [
"phone",
"email",
"openid",
"profile",
"aws.cognito.signin.user.admin"
]
},
"authenticationFlowType": "CUSTOM_AUTH"
}
}
}
Below mentioned key values will be changed based on environment.
CredentialsProvider -> CognitoIdentity -> Default -> PoolId
Auth -> Default -> OAuth -> WebDomain
Auth -> Default -> OAuth -> AppClientId
CognitoUserPool -> PoolId
CognitoUserPool -> AppClientId
Thanks for the info. We'll work on reproducing your issue and follow up here with any updates.
@AdiPomelo I created an example of how to support multiple build variants previously which I have now shared here on GitHub.
Normally Amplify and the AWS SDK just have a single .json file for each one. You also would not want to include the staging and preprod configuration files in the prod build. It would reveal those endpoints in your app bundle. The sample project shows how you can use Build Schemes and Xcode configuration files to support build variants. Individual developers could even create their own named environments.
See the section on Cloud Configuration. You can create a folder for each build variant you want to support and place the .json files in those folders with the default names. Once you have this set up you can just change the selected Build Scheme in Xcode to build and run the app for the environment you want. Since you can set a unique App ID for each build you can have each app installed on a device or simulator concurrently with a different cloud configuration. And the tool linked in that repo will give you way to easily create app icons for the staging and prepared environments.
You could also set up an environment for integration testing which you run with CI/CD. Having isolated resources for this purpose would make your build automation more reliable and prevent interference with staging and preprod.
Let us know if this helps simplify your setup.
@brennanMKE Thank you for quick replay with sample project. I will try the solution suggested by you and let you know. I am assuming it will work 100%.
Once again thank you 🙏
@atierian Any update ?
Your initAmplify
function is making some unnecessary, and incorrect, actions that are most likely the cause behind this.
If you change the function to this, does it resolve your issue?
private func initAmplify() {
do {
#if DEBUG
Amplify.Logging.logLevel = .verbose
#endif
let awsCognitoAuthPlugin = AWSCognitoAuthPlugin()
try Amplify.add(plugin: awsCognitoAuthPlugin)
let amplifyJsonPath = getAmplifyJsonFilePath()
if let configFilePath = amplifyJsonPath {
let amplifyConfig = try AmplifyConfiguration(configurationFile: URL(fileURLWithPath: configFilePath))
try Amplify.configure(amplifyConfig)
} else {
assertionFailure("amplifyconfiguration file couldn't be found")
}
} catch {
helpers.logger?.error("Failed initializing Amplify", error: error, attributes: nil)
}
}
@atierian Thank you for reply. I don't think so it will work with the code provided by you.
The code will work for amplifyconfiguration.json
file and what about configuring the awsconfiguration.json
using json object?
You don't need to use awsconfiguration.json
when configuring Amplify.
Hey @AdiPomelo, just checking in. Did the snippet above resolve your issue?
@atierian No.
Sorry to hear that. Is the error you're experiencing the same that you outlined in the original issue?
@atierian Yes
Based on the information you provided and using the altered code snippet for configuring Amplify that I posted above, I am not able to reproduce the issue you're experiencing here. If you're still experiencing this issue, I suggest isolating it down to a small reproducible example that you can share so we can test it.
Closing due to inactivity.