Home > Software design >  Is it possible to instantiate a SwiftUI view from a string?
Is it possible to instantiate a SwiftUI view from a string?

Time:12-12

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)

CodePudding user response:

  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?

CodePudding user response:

!!! 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

  • Related