Skip to content

Latest commit

 

History

History
287 lines (184 loc) · 10.1 KB

cordevicljs-howto.textile

File metadata and controls

287 lines (184 loc) · 10.1 KB

Use Enterlab Rente to create a Cordova backed native app for Android and iOS using OnsenUI for user interface, Facebook React wrapped in ClojureScript Reagent using AJAX for logging on to a remote server and websocket via Sente for app/server communication

(Wheew!)

Clone Enterlab Rente

  1. git clone https://github.com/enterlab/rente.git [your-app]
  1. cd [your-app]
  1. rm app.json

Change namespaces and prepare for Cordova

  1. Replace all instances of “rente” in the project with [your-app]; cljs, clj and project.clj
  1. Change project.clj “dev-resources/www/js/out” to “resources/www/js/out”
  1. Change project.clj occurrences of “public” to “www”, including :main, :output-to, :output-dir, :http-server-root, :css-dirs
  1. Rename folder src/rente to src/[your-app]

Build ClojureScript

  1. Build with lein clean && lein figwheel

When no build error, continue:

  1. CTRL+c to stop figwheel

Add Cordova

  1. rm -rf resources
  1. cordova create resources [com.yourcompany.your-app] “Your app description”
  1. cordova platform add browser
  1. cordova platform add ios
    1. add other platforms: android, wp8 etc. if you want
  1. cordova plugin add cordova-plugin-device
  1. cordova plugin add org.apache.cordova.dialogs

Run Cordova sample app

  1. cd .. && lein clean && lein figwheel

In a new terminal tab (or window):

  1. lein run

This starts the server which respond to AJAX/socket connections

In yet another terminal tab/window:

  1. cd resources
  1. cordova prepare && cordova run browser

You should now see an Apache Cordova logo/text and a green box with the text “DEVICE IS READY” in your browser

  1. cordova run ios

You should now see the same, but this time in your iOS Emulator

Convert for “Rente” (CLJS, React, websocket)

  1. edit www/index.html:
    1. change last
    2. Add this just before the tag:

  1. Add ‘unsafe-inline’ in the meta tag containing the Content-Security-Policy. It should be put just after “default-src ‘self’” and just before “data:”
  1. In the end of the value of the tag, just after "media-src ‘*’, add “; connect-src ‘self’ ws://localhost:8080 ws://localhost:3449;”
  1. In index.html add id=“app” to the div element with class=“app”

Test “Rente” features (React and Socket)

  1. In resources folder: cordova run browser

See that the “APACHE CORDOVA” and the “DEVICE READY” has been replaced with content similar to that from Enterlab Rente.

This is rendered using React (via Reagent), which means that Reagent is rendering correctly.

If you open up your browser console, you should see that the app web socket has been connected as well, with a console log line such as:

Channel socket state change: {:type :ws, :open? true, :destroyed? false, :uid :taoensso.sente/nil-uid, :csrf-token nil, :first-open? true}

When you click the two buttons you will get the following console log results respectively:

CALLBACK from server: [:cordevicljs/testevent {:message “Hello socket from server Callback, received: {:message \”Hello socket Callback!\"}"}]

and:
PUSHed :cordevicljs/testevent from server: {:message “Hello socket from server Event (no callback), received: {:message \”Hello socket Event!\"}"}

Add Device Native Interop

  1. Add the following two functions in app.cljs, just above the main function:

(defn ^:export onDeviceReady []
(→ (js* “navigator”)
(.-notification)
(.alert “Device Native Bridge works!”
(fn [] nil)
""
"")))

(defn ^:export prepare-device []
(.addEventListener js/document “deviceready” onDeviceReady true))

  1. Then add a call to (prepare-device) as the first line in the main function

Test Device Native Interop

  1. One more: cordova run browser

You should now see a standard javascript alert showing that “Device Native Bridge works!”

Let’s test it on the device as well:

  1. cordova run ios

If you get an alert in the native app that looks like a native alert showing the exact same text, “Device Native Bridge works!”, then you’re good to go – you’ve got the native device bridge working, so you can communicate with most native device features via Cordova! w00t!

Now is a good time for a walk in the park with a great cup of coffee and perhaps a good friend/colleage etc.

Add Angular.js

Checkout tag: cljs-react-socket-device

  1. Add language=“en” ng-app=“app” attributes to index.html’s element
  1. Add to bottom of index.html element
  1. In top of app.cljs main function (before call to prepare-device), add this angular initialization:
    (.module (.-angular js/window) “app” #js [])
  1. test in browser with cordova run browser

If you get the alert as usual, and reagent renders the Rente like content, it works.

  1. test in device like cordova run ios

If you get the alert there as well, you’re good to go on! :)

Add OnsenUI

Checkout tag: cljs-react-socket-device-angular

To add support for OnsenUI (http://onsen.io) in CorDeviCLJS, perform the following steps:

  1. Above the newly inserted Angular.js reference (index.html), insert this:


  1. Below the link to angular.js, insert this:
  1. In app.cljs add “onsen” to the empty vector in the function call we added earlier. It should end up looking like this:
    (.module (.-angular js/window) “app” #js [“onsen”])

Again: test both browser and ios emulator.

If both work, you have all the basics working, and can now develop your app as you wish! :)

If you continue we’ll add some native-ish look-and-feel to the app.

Native-ish look-and-feel

Checkout tag: cljs-react-socket-device-angular-onsen

Here we will add a native-like look and feel, resembling some sort of a flat UI usable for all mobile platforms.

  1. Delete the
    element in index.html, and replace it with this:

Register Bookmark
Enterlab CorDeviCLJS


  1. Put these 2 functions in top of app.cljs (below the namespace declaration, duh..):
    ;; OnsenUI Interop
    (defn ons-component [component dom-id & [callback]]
    (with-meta component
    {:component-did-mount
    (fn [this]
    (.compile js/ons (.getElementById js/document dom-id))
    (when callback (callback)))}))

(defn ons-render [component dom-id state-wrapper & [callback]]
(reagent/render-component
[(ons-component component dom-id callback) state-wrapper]
(.getElementById js/document dom-id)))

  1. In view.cljs replace the main function with these two functions:
    (defn footer []
    [:ons-row {:style {:margin-top “10px” :text-align "center"}}
    [:ons-col
    [:p {:style {:color “#999” :font-size "13px"}}
    “Click top left icon to close/open menu”
    [:br]
    “You can also swipe the page left/right.”]]])

(defn main [data]
[:div
[:span “Hello Clojure World!”]
[:br][:br]
[:ons-button {:modifier “large” :on-click socket/test-socket-callback} “Send Callback”]
[:br][:br]
[:ons-button {:modifier “large” :on-click socket/test-socket-event} “Send Event”]
[footer]])

As you can see, because of the small trick in ons-component and ons-render, we can easily use OnsenUI elements in our hiccup-ish Reagent/React components! :)

  1. In the main function, delete the the call to (prepare-device) and the when-let form, and replace both with this:
    (.ready js/ons
    (fn []
    (ons-render app “app” state)
    (prepare-device)))
  1. Test in browser with cordova run browser, and on device with cordova run ios.

If both looks like a native-ish flat UI app, you can open the menu and the alert shows, then everything works perfectly. That’s it!

If you want to make sure that you get the exact same code as desribed above, checkout from github via the tag cljs-react-socket-device-angular-onsen-lookandfeel

You’ve now successfully built your own mobile app with native-like performance and native-ish flat look-and-feel via OnsenUI, web socket communication to your server via Sente, React as client side framework via Reagent and Cordova for built tool and access to native device features such as location, camera, Bluetooth etc.

w00t, what a day! :)

You can now add more views etc. to your app using OnsenUI components:
http://onsen.io/guide/overview.html

You can add Cordova plugins for access to native device features:
http://plugins.cordova.io

We use this template ourselves when building hybrid/native mobile apps for iOS and Android. So don’t hesitate to contact us if you have any questions/suggestions.

Happy-happy-happy, joy-joy-joy! :)

Best,
@luposlip
@enterlab

http://enterlab.com