Execute Swift scripts dynamically in iOS

I have a transformation function that takes in data, executes some instructions, and returns an output. This function is dynamic and not shipped with the binary. Currently, I’m executing it using JavaScriptCore.JSContext, which works well, but the function itself is written in JavaScript.

Is there a way to achieve something similar using Swift – such as executing a dynamic Swift script, either directly or through other means? I know this is possible on macOS, but I’m not sure about iOS. I’ve also heard that extensions might open up some possibilities here. Any insights or alternative approaches would be appreciated.

Answered by DTS Engineer in 846700022

It’s certainly possible, but probably more hassle than it’s worth.

Specifically, Swift supports compiling to WebAssembly (Wasm) [1] and you could then run the Wasm instructions yourself. However, this is much more difficult than the equivalent path with JavaScriptCore because:

  • JavaScriptCore can interpret JavaScript directly. In Swift you’d have to include a copy of the Swift compiler within your app.

  • Additionally, there’s no built-in Wasm runtime, so you’d have to write or acquire one of those.

Of these, the second point is less of an issue. Wasm runtimes are relatively small and easy to maintain. Indeed, there’s a default one featured on the Swift website [2].

The first point, however, is much more complex. The Swift compiler is big and complicated, and successfully embedding it in an iOS app would not be trivial.

Finally, there’s the App Review side of this. I don’t work for App Review, and thus can’t make definitive statements on their behalf. However, the App Review Guidelines do place restrictions on downloadable code, so I encourage you to read those.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

[1] See Swift.org > Getting Started with Swift SDKs for WebAssembly.

[2] WasmKit

Accepted Answer

It’s certainly possible, but probably more hassle than it’s worth.

Specifically, Swift supports compiling to WebAssembly (Wasm) [1] and you could then run the Wasm instructions yourself. However, this is much more difficult than the equivalent path with JavaScriptCore because:

  • JavaScriptCore can interpret JavaScript directly. In Swift you’d have to include a copy of the Swift compiler within your app.

  • Additionally, there’s no built-in Wasm runtime, so you’d have to write or acquire one of those.

Of these, the second point is less of an issue. Wasm runtimes are relatively small and easy to maintain. Indeed, there’s a default one featured on the Swift website [2].

The first point, however, is much more complex. The Swift compiler is big and complicated, and successfully embedding it in an iOS app would not be trivial.

Finally, there’s the App Review side of this. I don’t work for App Review, and thus can’t make definitive statements on their behalf. However, the App Review Guidelines do place restrictions on downloadable code, so I encourage you to read those.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

[1] See Swift.org > Getting Started with Swift SDKs for WebAssembly.

[2] WasmKit

Thanks, Quinn. I've explored wasm and (like you already said) find it quite an overkill specifically for this scenario.

Just a quick follow-up. There was a similar thread about this over on Swift Forums — see Using Swift as a embedded scripting language for a macOS App? — and I loved this comment on it:

Also keep in mind that a stripped swift-frontend binary is 125Mb or so, which is probably quite a bit larger than some of the other scripting engines out there.

O-:

But it also captures another key point:

If in your case it's acceptable for script authors to compile Swift code to Wasm before executing their scripts

That is, there’s a difference between:

  • Supporting plug-ins that are made by developers and then deployed to your app.
  • Supporting users entering code directly into your app.

I believe that your goal is more like the second, and that’s where things get challenging for Swift. But for any other folks reading this thread, if your goal is more like the first then Wasm is something I recommend you explore.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Yes, my use case matches closely with the second - update the script as a result of user interaction. Swift (via wasm) isn't yet as convenient as java script using JavaScriptCore.

Execute Swift scripts dynamically in iOS
 
 
Q