Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible in Swift to execute code at runtime from a string?

I have a list of items that have conditions associated with them. I want to store this list of items and their conditions in a plist rather than hardcode them into a .swift file.

The only problem with that is that there needs to a function associated with each item to check a condition. Here is what it might look like hardcoded:

let myJobStep1 = JobStep(heading: "My Heading", description: "This is the description", warningText: "", condition_check: { () -> Bool in
    return (self.trayColor == .Blue) || (self.trayColor == .Red)
})

let myJobStep2 = JobStep(heading: "My Heading", description: "Another description", warningText: "", condition_check: { () -> Bool in
    return (self.trayColor == .Green)
})

The question is how to encapsulate the function that is checking conditions in a string that can be in a plist file.

Thanks!

like image 722
chaimp Avatar asked Feb 03 '26 16:02

chaimp


1 Answers

The closest you're going to come is NSPredicate and/or NSExpression which give you a limited ability to dynamically evaluate expressions given as strings.

enum Colors : Int {
    case Red = 1
    case Green = 2
    case Blue = 3
}

class Line : NSObject {
    var lineColor : Int

    init(lineColor:Colors) {
        self.lineColor = lineColor.rawValue
    }
}

let red = Line(lineColor: .Red)
let green = Line(lineColor: .Green)

let basic = NSPredicate(format: "self.lineColor == $Red")
let test = basic.predicateWithSubstitutionVariables(["Red":Colors.Red.rawValue])

test.evaluateWithObject(red)       // true
test.evaluateWithObject(green)     // false

Since NSExpression is based on Objective-C and Key Values, there are some restrictions:

  1. The object being evaluated must be derived from NSObject.
  2. Properties must be automatically translatable to AnyObject, hence we store the int and not the Color. Note that you could probably handle this a little differently by using a derived property.
  3. The substitution dictionary must be [String:AnyObject] so you'll have to use the enum raw value instead of the enum value itself.
like image 114
David Berry Avatar answered Feb 05 '26 06:02

David Berry



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!