- Published on
Accessing Environment Variables in Swift
- Authors
- Name
- Mick MacCallum
- @0x7fs
Environment variables are dynamic values that exist outside your application's scope, providing a flexible way to configure and influence your app's behavior. In Swift, you can access these variables using the ProcessInfo class, making it easy to manage different configurations for development, testing, and production environments.
Basic Environment Variable Access
To retrieve the value of an environment variable in Swift, use the environment property of ProcessInfo.processInfo:
if let value = ProcessInfo.processInfo.environment["YOUR_VARIABLE_NAME"] {
print("The value is: \(value)")
} else {
print("Environment variable not set.")
}
This simple approach allows you to fetch and utilize environment variable values within your Swift application. The environment property returns a dictionary containing all environment variables available to your process.
Common Use Cases
Configuration Management
Environment variables are perfect for managing different configurations across environments. For example, you might have different server URLs for development and production:
let serverURL = ProcessInfo.processInfo.environment["SERVER_URL"] ?? "https://api.default.com"
let apiVersion = ProcessInfo.processInfo.environment["API_VERSION"] ?? "v1"
API Keys and Secrets
Securing sensitive information like API keys is crucial. Store them as environment variables to keep them separate from your codebase:
let apiKey = ProcessInfo.processInfo.environment["API_KEY"] ?? ""
let secretToken = ProcessInfo.processInfo.environment["SECRET_TOKEN"] ?? ""
Feature Toggles
Use environment variables for feature toggles, enabling controlled feature rollouts and A/B testing:
let isNewFeatureEnabled = ProcessInfo.processInfo.environment["NEW_FEATURE_ENABLED"] == "true"
let debugMode = ProcessInfo.processInfo.environment["DEBUG_MODE"] == "true"
Setting Environment Variables in Xcode
Using Xcode Schemes
The most common way to set environment variables for your app is through Xcode schemes:
- Open your Xcode project
- Go to Product → Scheme → Edit Scheme
- Select Run from the left sidebar
- Click on the Arguments tab
- In the Environment Variables section, click the + button
- Add your variable name and value
This approach is perfect for development and testing, as the variables are only available when running through Xcode.
Using xcodebuild Command Line
For CI/CD pipelines or command-line builds, you can set environment variables using xcodebuild:
Method 1: Set environment variables before running xcodebuild
export API_KEY=your_api_key_here
export SERVER_URL=https://api.example.com
xcodebuild -scheme YourScheme -configuration Debug build
Method 2: Set environment variables inline with xcodebuild
API_KEY=your_api_key_here SERVER_URL=https://api.example.com xcodebuild -scheme YourScheme build
Method 3: Use a custom build configuration
xcodebuild -scheme YourScheme -configuration Debug \
-destination 'platform=iOS Simulator,name=iPhone 15' \
-xcconfig MyConfig.xcconfig
Using .xcconfig Files
Create a .xcconfig
file to manage build settings and preprocessor macros (note: these are primarily for build-time configuration, not runtime environment variables):
// Development.xcconfig
API_KEY = dev_api_key_123
SERVER_URL = https://dev-api.example.com
DEBUG_MODE = true
Then reference this file in your Xcode project settings or use it with xcodebuild:
xcodebuild -xcconfig Development.xcconfig -scheme YourScheme build
Important Note: Variables defined in .xcconfig
files are typically build settings and preprocessor macros, not runtime environment variables. To access them in your Swift code, you'll need to define them as preprocessor macros in your build settings.
Best Practices
Provide Default Values
Always provide default values to prevent crashes if an environment variable is not set:
let timeout = ProcessInfo.processInfo.environment["REQUEST_TIMEOUT"] ?? "30"
let maxRetries = ProcessInfo.processInfo.environment["MAX_RETRIES"] ?? "3"
Type Safety
Convert string values to appropriate types when needed:
let timeoutValue = Double(ProcessInfo.processInfo.environment["TIMEOUT"] ?? "30.0") ?? 30.0
let maxRetriesValue = Int(ProcessInfo.processInfo.environment["MAX_RETRIES"] ?? "3") ?? 3
Security Considerations
- Never commit sensitive environment variables to version control
- Use different values for different environments
- Consider using a secure key management service for production secrets
Example: Complete Configuration Manager
Here's a practical example of a configuration manager that uses environment variables:
struct AppConfig {
static let shared = AppConfig()
let apiKey: String
let serverURL: String
let isDebugMode: Bool
let timeout: TimeInterval
private init() {
self.apiKey = ProcessInfo.processInfo.environment["API_KEY"] ?? ""
self.serverURL = ProcessInfo.processInfo.environment["SERVER_URL"] ?? "https://api.default.com"
self.isDebugMode = ProcessInfo.processInfo.environment["DEBUG_MODE"] == "true"
self.timeout = TimeInterval(ProcessInfo.processInfo.environment["TIMEOUT"] ?? "30.0") ?? 30.0
}
}
// Usage
let config = AppConfig.shared
print("Server URL: \(config.serverURL)")
print("Debug mode: \(config.isDebugMode)")
Environment variables in Swift provide a robust mechanism for configuring and adapting your applications to different scenarios. By incorporating them into your development workflow, you can streamline configuration management, enhance security, and promote a more adaptable and scalable codebase.