If you're not using Jumpstart Pro Rails, here are the steps needed to update your web application to work with Jumpstart Pro iOS & Android.
Your Rails API will be used for authentication and other features.
The host and URL base path are configurable in the iOS / Android app Endpoint configuration. By default, the host is http://localhost:3000
and base API uri is /api/v1
. You can change this configuration to match your application's API.
When making requests to the API, you'll want to follow these rules:
Android (Turbo Native)
or iOS (Turbo Native)
in the User Agent for all API requests. This tells the API the request came from Turbo Native and should be handled accordingly.Authorization
header to authenticate user with an API tokenSome views will need a custom version for Turbo Native. You can use Request Variants to accomplish this.
Hotwire includes a turbo_native_app?
helper that checks the User-Agent
header for Turbo Native. You can set the request variant for Turbo Native requests using that.
before_action do
request.variant = :phone if turbo_native_app?
end
The iOS / Android app uses a native header so it feels native. We add a hamburger button to this which triggers a Javascript event using the Turbo Bridge.
In Rails, you'll want to hide your navbar on Turbo Native requests. Use a request variant template for this so you can minimize the HTML used for mobile.
The menu should be hidden, but toggles when the toggle-nav-bar
event fires. You can create a simple Stimulus Controller to listen to that event and toggle the navbar visibility.
The Turbo Bridge is how your iOS / Android app and Javascript talk to each other. Add this to your Javascript. We're using Webpacker, but you can probably use this in the asset pipeline as well, it just might take a few small tweaks.
class Bridge {
// Toggles navbar visibility in browser from Turbo Native
static toggleNavBar() {
const event = new CustomEvent("toggle-nav-bar")
window.dispatchEvent(event)
}
// Sends a message to the native app, if active.
static postMessage(name, data = {}) {
// iOS
window.webkit?.messageHandlers?.nativeApp?.postMessage({name, ...data})
// Android
window.nativeApp?.postMessage(JSON.stringify({name, ...data}))
}
}
// Expose this on the window object so TurboNative can interact with it
window.TurboNativeBridge = Bridge
export default Bridge
Authentication requires an API endpoint that accepts email
and password
params.
It should:
POST /api/v1/auth
token
- the API token for the iOS / Android device to make API requestsSuccessful authentication will refresh the currently visible page.
Sign out must happen on the iOS / Android app side. That way we can delete the API token, make an API request to remove the NotificationToken, and clear cookies in the WebView.
To intercept the Sign out link in the HTML, use the following Javascript:
import { Controller } from "stimulus"
export default class extends Controller {
signOut(event) {
if (this._isTurboNativeApp) {
event.preventDefault()
event.stopImmediatePropagation()
window.TurboNativeBridge.postMessage("signOut")
}
}
get _isTurboNativeApp() {
return navigator.userAgent.indexOf("Turbo Native") !== -1
}
}
The API endpoint for Sign out needs to do two things:
DELETE /api/v1/auth
Changing your password is a simple API request
PATCH /api/v1/password
Headers:
Authorization
- The user's API tokenParams:
user[current_password]
- The user's current passworduser[password]
- The new passworduser[password_confirmation]
- The new passwordReturns:
Success - 200 OK
{ success: true }
Failure - 422 Unprocessable Entity
{ error: "Password confirmation did not match" }
Registering for Push Notifications happens when the user is signed in.
The Backend needs NotificationToken model to store the token and platform for push notifications.
rails g model NotificationToken user:belongs_to platform token
An API endpoint for notification tokens should:
POST /api/v1/notification_tokens
Authorization
header to authenticate user with API tokentoken
- device notification tokenplatform
- platform of device (iOS, fcm). "fcm" is Firebase Cloud Messaging which is used for Android.