Feature Flag in iOS (Swift)

Feature Flag in iOS

Installation

Add the package using Swift Package Manager
Package link: AWS SDK for Swift
Select App Config

Fetch temporary access key, secret key, and session token from Cognito

private static func getTemporaryAWSCredentials(region: String, idToken: String) async throws -> CognitoIdentityClientTypes.Credentials {
    let identityConfig = try await CognitoIdentityClient.CognitoIdentityClientConfiguration(
        region: region
    )
    let identityClient = CognitoIdentityClient(config: identityConfig)
    let identityIdInput = GetIdInput(
        identityPoolId: Secrets.cognitoIdentityPoolId,
        logins: ["cognito-idp.\(region).amazonaws.com/\(Secrets.cognitoUserPoolId)": idToken]
    )
    let identityIdResponse = try await identityClient.getId(input: identityIdInput)
    guard let identityId = identityIdResponse.identityId else {
        throw NSError(
            domain: "FeatureFlagManager",
            code: 3,
            userInfo: [NSLocalizedDescriptionKey: "Failed to retrieve identity ID."]
        )
    }
    let credentialsInput = GetCredentialsForIdentityInput(
        identityId: identityId,
        logins: identityIdInput.logins
    )
    let credentialsResponse = try await identityClient.getCredentialsForIdentity(input: credentialsInput)
    guard let credentials = credentialsResponse.credentials else {
        throw NSError(
            domain: "FeatureFlagManager",
            code: 2,
            userInfo: [NSLocalizedDescriptionKey: "Failed to retrieve temporary AWS credentials."]
        )
    }
    return credentials
}

Configure AppConfig

 let credentials = try await FeatureFlagManager.getTemporaryAWSCredentials(region: region, idToken: idToken)
        // Create static credentials provider
        let credentialsProvider = AWSCredentialIdentity(
            accessKey: credentials.accessKeyId ?? "",
            secret: credentials.secretKey ?? "",
            sessionToken: credentials.sessionToken
        )
        debugLog(credentials)
        // Configure the AWS
        let identity = try StaticAWSCredentialIdentityResolver(credentialsProvider)
        let config = try await AppConfigDataClient.AppConfigDataClientConfiguration(awsCredentialIdentityResolver: identity, region: region)
        self.client = try await AppConfigDataClient(config: config)
        self.appConfigId = appConfigId
        self.environment = environment

Start a configuration session and fetch latest configuration

 func getConfiguration() async throws -> String {
        let sessionInput = StartConfigurationSessionInput(
            applicationIdentifier: appConfigId,
            configurationProfileIdentifier: Secrets.configurationID,
            environmentIdentifier: environment
        )
        let sessionResponse = try await client.startConfigurationSession(input: sessionInput)
        token = sessionResponse.initialConfigurationToken ?? ""
        // Fetch latest configuration
        let getConfigInput = GetLatestConfigurationInput(configurationToken: token)
        let configResponse = try await client.getLatestConfiguration(input: getConfigInput)
        // Extract configuration data
        guard let content = configResponse.configuration,
              let jsonString = String(data: content, encoding: .utf8) else {
            throw NSError(
                domain: "FeatureFlagManager",
                code: 1,
                userInfo: [NSLocalizedDescriptionKey: "Failed to decode configuration content."]
            )
        }
        return jsonString
    }

Example response

{"release-1":{"enabled":true},"release-2":{"enabled":false}}
5 Likes

Very well articulated Amisha. Good work

1 Like

@amishashetty How can we access these flags without logging In with Cognito
Or how can we access feature flags without cognito?