Last active
May 17, 2023 05:14
-
-
Save akingdom/4609b07d75b4d4c44c7a36ce0444952f to your computer and use it in GitHub Desktop.
Use a string key to reference a property in a class or struct; Get the name of a property as a string
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Demonstrates Swift-based reflection concept like Key-Value coding in Objective-C (but slower) | |
// and use of @dynamicMemberLookup. | |
// | |
// Uses Mirror to reference a property in a class or struct by string key name; | |
// Uses @dynamicMemberLookup to get the name of a property as a string, to reverse the reflection. | |
// | |
// DynamicMemberLookupExample.swift | |
// | |
// Copyright Andrew Kingdom 2023-05-17. | |
// MIT License | |
// | |
import SwiftUI | |
@main | |
struct DynamicMemberLookupExample: App { | |
@State var result = MemberLookup().b // .a or .b work but .c does not | |
var body: some Scene { | |
WindowGroup() { // normally references ContentView definition | |
Text("\(result)") | |
.padding() | |
} | |
} | |
} | |
@dynamicMemberLookup | |
public struct MemberLookup { | |
fileprivate var a = "Hi" | |
fileprivate var b = "There" | |
public subscript(dynamicMember member: String) -> Any? { | |
let value = Mirror.lookup(key: member, in: self) | |
print(".lookup(\"\(member)\" -> \(value ?? "??")") | |
return value | |
} | |
} | |
public extension Mirror { | |
static func lookup(key:String, `in`:Any) -> Any? { | |
let mirror = Mirror(reflecting:`in`) | |
let children = mirror.children | |
if let firstIndex = children.firstIndex(where: {$0.label == key}) { | |
let value = children[firstIndex].value | |
return value | |
} | |
return nil // default value is nil | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment