Question

I've used lein-fruit to generate a basic Clojure project that targets iOS through RoboVM. I've introduced core.async to pass button taps along a channel, but mutating the button in the go block doesn't seem to have an effect.

Is there reason to believe the Java implementation of core.async doesn't work under RoboVM?

Here's my code, slightly modified from the basic lein-fruit template.

(ns core-async-demo.core
  (:require [core-async-demo.core-utils :as u]
            [clojure.core.async :refer [go chan put! <!]]))

(def window (atom nil))

(def taps (chan))

(defn init
  []
  (let [main-screen (u/static-method :uikit.UIScreen :getMainScreen)
        button-type (u/static-field :uikit.UIButtonType :RoundedRect)
        button (u/static-method :uikit.UIButton :fromType button-type)
        normal-state (u/static-field :uikit.UIControlState :Normal)
        click-count (atom 0)]
    (doto button
      (.setFrame (u/init-class :coregraphics.CGRect 115 121 91 37))
      (.setTitle "Click me!" normal-state)
      (.addOnTouchUpInsideListener
        (proxy [org.robovm.cocoatouch.uikit.UIControl$OnTouchUpInsideListener] []
          (onTouchUpInside [control event]
            (put! taps true)))))
    (reset! window (u/init-class :uikit.UIWindow (.getBounds main-screen)))
    (go
      (loop [_ (<! taps)]
        (.setTitle button (str "Click #" (swap! click-count inc)) normal-state)
        (recur (<! taps))))
    (doto @window
      (.setBackgroundColor (u/static-method :uikit.UIColor :lightGrayColor))
      (.addSubview button)
      .makeKeyAndVisible)))
Was it helpful?

Solution

I don't know about core.async on RoboVM specifically, but background threads in general are not supposed to interact with UIKit. It's a documented limitation of the framework. I would try something simpler to test out core.async on RoboVM and, if it works, you should be able to use Grand Central Dispatch to run your code on the main queue.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top