🌳
Environment
Welcome to Environment – a nicer, type-safe way of working with environment variables in Swift.
Usage
Access Environment Variables
The Environment
struct provides a type-safe API to get and set environment variables.
import Environment
let environment = Environment.environment
// Get "HOST" as String value
let host = environment["HOST"]
// Set "PORT" to String value of "8000"
environment["PORT"] = "8000"
Environment variables are accessed as String
values by default, but can be converted to any type that conforms to EnvironmentStringConvertible
.
// Get "HOST" as URL value
let host: URL? = environment["HOST"]
// Get "PORT" as Int value
let port: Int? = environment["PORT"]
// Set "PORT" to Int value of 8000
environment["PORT"] = 8000
// Get "APP_ID" as UUID value or use a default UUID if "APP_ID" is not set
let appID = environment["APP_ID"] ?? UUID()
Dynamic Member Lookup
The Environment
struct also supports accessing environment variables using @dynamicMemberLookup
.
// Get "HOST" as URL value using dynamic member lookup
let host: URL? = environment.HOST
// Set "PORT" to Int value of 8000 using dynamic member lookup
environment.PORT = 8000
Static Subscripts
The Environment
struct supports static subscript access to environment variables in Swift 5.1.
import Environment
import Foundation
// Get "HOST" as URL value using static subscript
let host: URL? = Environment["HOST"]
// Set "PORT" to Int value of 8000 using static subscript
Environment["PORT"] = 8000
@dynamicMemberLookup
also works with static subscripts.
// Get "HOST" as URL value using static dynamic member lookup
let host: URL? = Environment.HOST
// Set "PORT" to Int value of 8000 using static dynamic member lookup
Environment.PORT = 8000
Property Wrappers
The EnvironmentVariable
property wrapper enables properties to be backed by environment variables in Swift 5.1.
The following example shows how to use the EnvironmentVariable
property wrapper to expose static properties backed by enviornment variables ("HOST"
and "PORT"
).
enum ServerSettings {
@EnvironmentVariable(name: "HOST")
static var host: URL?
@EnvironmentVariable(name: "PORT", defaultValue: 8000)
static var port: Int
}
Type-Safe Variables
Environment variables can be converted from a String
representation to any type that conforms to the EnvironmentStringConvertible
protocol.
Standard Library and Foundation types like Int
, Float
, Double
, Bool
, URL
, UUID
, Data
, and more are already extended to conform to EnvironmentStringConvertible
. Collection types like Array
, Set
, and Dictionary
are also extended with conditional conformance.
You can add conformance to other classes, structures, or enumerations to enable additional types to be used as environment variables.
Custom EnvironmentStringConvertible
Conformance
enum Beverage {
case coffee
case tea
}
extension Beverage: EnvironmentStringConvertible {
init?(environmentString: String) {
switch environmentString {
case "coffee":
self = .coffee
case "tea":
self = .tea
default:
return nil
}
}
var environmentString: String {
switch self {
case .coffee:
return "coffee"
case .tea:
return "tea"
}
}
}
let beverage: Beverage? = environment["DEFAULT_BEVERAGE"]
Default EnvironmentStringConvertible
Conformance
A default implementation of EnvironmentStringConvertible
is provided for types that already conform to LosslessStringConvertible
or RawRepresentable
.
For example, String
-backed enums are RawRepresentable
and may use the default implementation for EnvironmentStringConvertible
conformance.
enum CompassPoint: String {
case north
case south
case east
case west
}
extension CompassPoint: EnvironmentStringConvertible { }
let defaultDirection: CompassPoint? = environment["DEFAULT_DIRECTION"]
API Documentation
Visit the online API reference for full documentation of the public API.
Installation
Environment requires Xcode 10 or a Swift 5 toolchain with the Swift Package Manager.
Swift Package Manager
Add the Environment package as a dependency to your Package.swift
file.
.package(url: "https://github.com/wlisac/environment.git", from: "0.11.1")
Add Environment to your target's dependencies.
.target(name: "Example", dependencies: ["Environment"])