Swift
enum
raw value
programming
tutorial

How to get enum from raw value in Swift?

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

Introduction

To create a Swift enum case from a raw value, use the failable initializer init?(rawValue:) — for example, MyEnum(rawValue: "some_value"). This returns an optional (MyEnum?) because the raw value may not match any case. Swift automatically synthesizes this initializer for any enum that declares a raw value type (String, Int, Double, etc.). If the value matches a case, you get the enum instance; otherwise you get nil.

Basic Usage

swift
1enum Direction: String {
2    case north = "N"
3    case south = "S"
4    case east = "E"
5    case west = "W"
6}
7
8// Create from raw value — returns Optional
9let dir = Direction(rawValue: "N")  // Optional(Direction.north)
10let invalid = Direction(rawValue: "X")  // nil
11
12// Safely unwrap
13if let direction = Direction(rawValue: "S") {
14    print("Got direction: \(direction)")  // Got direction: south
15} else {
16    print("Invalid direction")
17}
18
19// Access the raw value
20let d = Direction.east
21print(d.rawValue)  // "E"

Integer Raw Values

swift
1enum StatusCode: Int {
2    case ok = 200
3    case notFound = 404
4    case serverError = 500
5}
6
7if let status = StatusCode(rawValue: 404) {
8    print(status)  // notFound
9}
10
11// With implicit integer raw values (auto-incrementing from 0)
12enum Planet: Int {
13    case mercury  // 0
14    case venus    // 1
15    case earth    // 2
16    case mars     // 3
17}
18
19let planet = Planet(rawValue: 2)  // Optional(Planet.earth)

String Enums with Implicit Raw Values

When the raw value type is String and no explicit values are assigned, Swift uses the case name as the raw value:

swift
1enum Color: String {
2    case red      // rawValue = "red"
3    case green    // rawValue = "green"
4    case blue     // rawValue = "blue"
5}
6
7let color = Color(rawValue: "green")  // Optional(Color.green)
8let invalid = Color(rawValue: "Green")  // nil — case sensitive!

Handling the Optional Result

Since init?(rawValue:) is failable, you need to handle the nil case:

swift
1enum Size: String {
2    case small, medium, large
3}
4
5// 1. if-let binding
6if let size = Size(rawValue: "medium") {
7    applySize(size)
8}
9
10// 2. Guard statement
11func processSize(_ raw: String) {
12    guard let size = Size(rawValue: raw) else {
13        print("Invalid size: \(raw)")
14        return
15    }
16    applySize(size)
17}
18
19// 3. Default value with nil-coalescing
20let size = Size(rawValue: userInput) ?? .medium
21
22// 4. Force unwrap (only when guaranteed)
23let knownSize = Size(rawValue: "large")!  // Crashes if nil
24
25// 5. Switch with optional
26switch Size(rawValue: apiResponse) {
27case .small:
28    print("Small")
29case .medium:
30    print("Medium")
31case .large:
32    print("Large")
33case nil:
34    print("Unknown size")
35}

CaseIterable for Validation

Use CaseIterable to list all valid values or build lookup logic:

swift
1enum Fruit: String, CaseIterable {
2    case apple, banana, cherry, date
3}
4
5// List all valid raw values
6let validValues = Fruit.allCases.map { $0.rawValue }
7print(validValues)  // ["apple", "banana", "cherry", "date"]
8
9// Custom lookup with case-insensitive matching
10func fruit(from string: String) -> Fruit? {
11    Fruit.allCases.first { $0.rawValue.lowercased() == string.lowercased() }
12}
13
14fruit(from: "BANANA")  // Optional(Fruit.banana)

Codable Enums with Raw Values

Raw-value enums automatically conform to Codable when their raw type is Codable:

swift
1enum Priority: String, Codable {
2    case low, medium, high, critical
3}
4
5struct Task: Codable {
6    let title: String
7    let priority: Priority
8}
9
10// JSON decoding
11let json = """
12{"title": "Fix bug", "priority": "high"}
13""".data(using: .utf8)!
14
15let task = try JSONDecoder().decode(Task.self, from: json)
16print(task.priority)  // high
17
18// Invalid value causes DecodingError
19let badJson = """
20{"title": "Test", "priority": "urgent"}
21""".data(using: .utf8)!
22
23// Throws: DecodingError.dataCorrupted — "urgent" is not a valid Priority

Custom Raw Value Mapping

When API values do not match your Swift naming conventions:

swift
1enum UserRole: String, Codable {
2    case admin = "ADMIN"
3    case editor = "EDITOR"
4    case viewer = "VIEWER"
5    case superAdmin = "SUPER_ADMIN"
6}
7
8let role = UserRole(rawValue: "SUPER_ADMIN")  // Optional(UserRole.superAdmin)
9print(role?.rawValue)  // "SUPER_ADMIN"

Enums Without Raw Values (Associated Values)

Enums with associated values do not have init?(rawValue:). You need a custom initializer:

swift
1enum NetworkError {
2    case timeout(seconds: Int)
3    case httpError(code: Int, message: String)
4    case unknown
5
6    // Custom initializer from HTTP status code
7    init(statusCode: Int) {
8        switch statusCode {
9        case 408:
10            self = .timeout(seconds: 30)
11        case 400...599:
12            self = .httpError(code: statusCode, message: "HTTP \(statusCode)")
13        default:
14            self = .unknown
15        }
16    }
17}
18
19let error = NetworkError(statusCode: 404)
20// .httpError(code: 404, message: "HTTP 404")

Common Pitfalls

  • Raw value matching is case-sensitive for strings: Color(rawValue: "Red") returns nil if the case is defined as case red. Always normalize input (e.g., .lowercased()) before matching, or use CaseIterable with a custom case-insensitive lookup.
  • Forgetting that init?(rawValue:) returns an optional: Force-unwrapping without checking (MyEnum(rawValue: input)!) crashes at runtime if the value is invalid. Always use if let, guard let, or nil-coalescing (?? .default) to handle the nil case safely.
  • Assuming associated-value enums have raw values: Only enums with a declared raw value type (enum Foo: String) get the synthesized init?(rawValue:). Enums with associated values (case bar(Int)) cannot have raw values — use a custom initializer or static factory method.
  • Not specifying explicit raw values when API format differs: If your API sends "SUPER_ADMIN" but you define case superAdmin without an explicit raw value, Swift assigns "superAdmin" as the raw value. Always assign explicit raw values when the external format differs from Swift naming conventions.
  • Decoding errors crashing the app: When decoding JSON into a raw-value enum, an unrecognized value throws DecodingError. Either handle the error with try?, provide a default case in a custom init(from:), or validate the input before decoding.

Summary

  • Use MyEnum(rawValue: value) to create an enum from a raw value — it returns an optional
  • Swift auto-synthesizes init?(rawValue:) for enums with String, Int, or Double raw types
  • Handle the nil case with if let, guard let, or nil-coalescing (?? .default)
  • Raw-value enums automatically conform to Codable for seamless JSON encoding/decoding
  • For associated-value enums, write a custom initializer since init?(rawValue:) is not available

Related reading
Free course
Beginner
7 lessons
2 hours
Tackling System Design Interview Problems

A short course that equips you with the skills to approach system design interviews methodically.

Start the free course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

All Rights Reserved.