Last active
May 12, 2020 21:26
-
-
Save foxicode/a02e479b131e3210ff7519d2fc494a42 to your computer and use it in GitHub Desktop.
ViewController using JavaScript
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
| import UIKit | |
| import JavaScriptCore | |
| class JSViewController: UIViewController { | |
| @IBOutlet weak var vPluginContainer: UIView! | |
| let jsContext = JSContext()! | |
| var timer: Timer? = nil | |
| let updateProperty: @convention(block) (Int, String, Any) -> Void = { tag, property, value in | |
| NotificationCenter.default.post(name: NSNotification.Name("updateWidgetProperty"), object: (tag, property, value)) | |
| } | |
| let addWidget: @convention(block) (String, [String: Any]) -> Void = { widgetName, widgetProperties in | |
| print("Creating \(widgetName) with properties \(widgetProperties)") | |
| switch widgetName { | |
| case "Circle": | |
| guard let x = widgetProperties["x"] as? Double, | |
| let y = widgetProperties["y"] as? Double, | |
| let r = widgetProperties["radius"] as? Double else { | |
| break | |
| } | |
| let color = widgetProperties["color"] as? String ?? "#ffffff" | |
| let tag = widgetProperties["tag"] as? Int ?? 0 | |
| let v = UIView(frame: CGRect(x: x - r, y: y - r, width: r * 2, height: r * 2)) | |
| v.layer.cornerRadius = CGFloat(r) | |
| v.tag = tag | |
| let uiColor = UIColor(hex: color) ?? .black | |
| v.backgroundColor = uiColor | |
| NotificationCenter.default.post(name: NSNotification.Name("addWidget"), object: v) | |
| break | |
| default: | |
| print("Unknown widget - \(widgetName)") | |
| } | |
| } | |
| @objc func addWidget(notification: NSNotification) { | |
| guard let w = notification.object as? UIView else { return } | |
| self.vPluginContainer.addSubview(w) | |
| } | |
| @objc func updateWidgetProperty(notification: NSNotification) { | |
| guard let attr = notification.object as? (tag: Int, property: String, value: Any) else { return } | |
| guard let w = vPluginContainer.viewWithTag(attr.tag) else { return } | |
| switch attr.property { | |
| case "color": | |
| if let strValue = attr.value as? String, | |
| let color = UIColor(hex: strValue) { | |
| w.backgroundColor = color | |
| } | |
| default: | |
| break | |
| } | |
| } | |
| private func loadJavaScript() { | |
| NotificationCenter.default.addObserver(self, selector: #selector(addWidget(notification:)), name: NSNotification.Name("addWidget"), object: nil) | |
| NotificationCenter.default.addObserver(self, selector: #selector(updateWidgetProperty(notification:)), name: NSNotification.Name("updateWidgetProperty"), object: nil) | |
| // Add an exception handler. | |
| jsContext.exceptionHandler = { _, exception in | |
| print("JS Exception: ", exception?.toString() ?? "Unknown") | |
| } | |
| guard let jsSourcePath = Bundle.main.path(forResource: "jsPluginCode", ofType: "js") else { | |
| print("JS file not found") | |
| return | |
| } | |
| do { | |
| let jsCode = try String(contentsOfFile: jsSourcePath) | |
| jsContext.evaluateScript(jsCode) | |
| let addWidgetObject = unsafeBitCast(self.addWidget, to: ViewController.self) | |
| jsContext.setObject(addWidgetObject, forKeyedSubscript: "addWidget" as NSString) | |
| let updatePropertyObject = unsafeBitCast(self.updateProperty, to: ViewController.self) | |
| jsContext.setObject(updatePropertyObject, forKeyedSubscript: "updateProperty" as NSString) | |
| } | |
| catch { | |
| print(error.localizedDescription) | |
| } | |
| } | |
| @IBAction func runPlugin() { | |
| loadJavaScript() | |
| let startFunction = jsContext.objectForKeyedSubscript("start") | |
| startFunction?.call(withArguments: [vPluginContainer.bounds.width, vPluginContainer.bounds.height]) | |
| timer = Timer.scheduledTimer(timeInterval: 0.01, target: self, selector: #selector(tick), userInfo: nil, repeats: true) | |
| } | |
| @objc func tick() { | |
| let tickFunction = jsContext.objectForKeyedSubscript("tick") | |
| tickFunction?.call(withArguments: [10.0]) | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment