Skip to content

wlisac/environment

Repository files navigation

🌳 Environment

swift platforms version twitter
build jazzy codecov

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"])