4

Is it possible to convert a string to a SwiftUI view? Something like JavaScript's eval(). In the code below I'm looking for an XXX function.

let uiString: String = “VStack { Text(\“hi there\”) }”
let view: some View = XXX(uiString)
2
  • 1
    No, it's not. Rather than JavaScript's JIT there is a real compilation phase in SwiftUI. Commented Dec 11, 2021 at 20:26
  • 1
    Yes, it is possible, but you need a custom decoder from String to some View! there is no ready API for it, but if you want, you can do it. That means you are building Xcode/SwiftUI again! because you are acutely compiling String to View code for SwiftUI. Commented Dec 11, 2021 at 21:49

2 Answers 2

3
  1. No, because Swift is compiled to machine code. There isn't an interpreter to evaluate arbitrary expressions on the go.
  2. That sounds a lot like a security vulnerability. Why would you want to do that?
Sign up to request clarification or add additional context in comments.

Comments

3

!!! Not recommended !!! Do not try This at home!

Here is an example, but you need to consider any possible view, or may you just limit your work for just some special input, like I did.

PS: You can do some big optimization in codes to make it better and faster with using some more for loop, switch or enums, but at the end of the day, the things that I showed here is work of SwiftUI not us! And not recommended. It was just a show case that how code be done.

struct ContentView: View {
    var body: some View {
        StringDecoderView(string: "Circle().fill(Color.red); Rectangle()")
    }
}

struct StringDecoderView: View {
    
    let string: String
    
    var body: some View {
        
        let arrayOfComponents: [String] = string.components(separatedBy: ";")
        
        var anyView: [CustomViewType] = [CustomViewType]()
        
        for item in arrayOfComponents {
            
            if item.contains("Circle()") {

                if item.contains(".fill") && item.contains("Color.red") {
                    anyView.append(CustomViewType(anyView: AnyView(Circle().fill(Color.red))))
                }
                else {
                    anyView.append(CustomViewType(anyView: AnyView(Circle())))
                }
            }
            else if item.contains("Rectangle()") {
                anyView.append(CustomViewType(anyView: AnyView(Rectangle())))
            }
            
        }
        
        return ForEach(anyView) { item in
            
            item.anyView
            
        }
        .padding()
        
    }
}

struct CustomViewType: Identifiable {
    let id: UUID = UUID()
    var anyView: AnyView
}

enter image description here

2 Comments

Thank you this is a clever approach I hadn't considered!
You are welcome, as I said it is not recommended, I just answered your question.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.