Turbo-iOS base project that's entirely driven from your backend Rails app.

Overview

Turbo-iOS-Base

Turbo-iOS base project that's entirely driven from your backend Rails app.

https://dev.to/dalezak/reusable-turbo-ios-project-configured-entirely-from-your-rails-app-3021

There were five main goals for this project:

  1. reusable base project that can be pointed to any Rails app
  2. app styling, tabs and navbar buttons driven from the server
  3. handle both authenticated and unauthenticated users
  4. all logic and functionality contained in a single Swift file
  5. no need for other developers to write any Swift code

Disclaimer: It's been over six years since I've written anything in Objective-C, and I've never written any Swift prior to this, so the code has lots of room for improvement, refactoring, cleanup, etc.

If you haven't already, I highly recommend you read the following articles about Turbo-iOS.

Clone Repo

Clone this repo locally to get started.

git clone https://github.com/dalezak/turbo-ios-base.git

Update Target Information

  • open App.xcodeproj
  • click on App project
  • select App under Targets
  • change Display Name to the name of your app
  • change Bundle Identifier to your reverse domain name

Update Info.plist URLs

  • open Info.plist file
  • expand TURBO_URL item
  • change development to your local environment
  • change production to your production environment

Replace Asset Images

  • visit https://appicon.co
  • upload 1024 x 1024 image
  • click Generate button
  • replace Assets.xcassets in the project with downloaded file

Add Turbo Gem

Add turbo-rails to your Gemfile.

gem "turbo-rails"

Add Turbo Javascript

If you are using Yarn, then run

yarn add @hotwired/turbo-rails

If you are using NPM, then run

npm add @hotwired/turbo-rails

Import Turbo Javascript

Add the following code to your application.js file.

import { Turbo } from "@hotwired/turbo-rails";
window.Turbo = Turbo;

Add any custom javascript to turbo/bridge.js in your javascript folder.

Hello!" } } ">
export default class Bridge {
  static sayHello() {
    document.body.innerHTML = "

Hello!

"
} }

Then import this in your application.js file.

import Bridge from "../turbo/bridge.js";
window.bridge = Bridge;

Add Rails Helpers

In your Rails app, add the following helpers to your application_helper.rb

def turbo?
  request.user_agent.include?("Turbo-")
end

def turbo_ios?
  request.user_agent.include?("Turbo-iOS")
end

def turbo_android?
  request.user_agent.include?("Turbo-Android")
end

Add Authenticated Header

Add the following metatag to your so the app knows if a user is logged in or not.

">
<meta name="turbo:authenticated" content="<%= user_signed_in? %>">

Hide Page Navigation

Since Turbo-iOS handles the native navbar, you don't need to show your page navigation anymore. Add unless turbo? check around where you usually render your navbar in your Rails app.

<%= render 'partials/navbar' %> <% end %> ">
<% unless turbo? %>
  <nav class="d-block">
    <%= render 'partials/navbar' %>
  nav>
<% end %>

Add Turbo Controller

Add turbo_controller.rb which will return turbo.json used for rules and settings, here's a sample to get you started.

class TurboController < ApplicationController
  def index
    render json: {
      "settings": {
        "navbar": {
          "background": "#888888",
          "foreground": "#ffffff"
        },
        "tabbar": {
          "background": "#888888",
          "selected": "#ffffff",
          "unselected": "#bbbbbb"
        },
        "tabs": [
          {
            "title": "Home",
            "visit": "/",
            "icon_ios": "house",
            "protected": false
          },
          {
            "title": "Profile",
            "visit": "/profile",
            "icon_ios": "person",
            "protected": true
          }
        ],
        "buttons": [
          {
            "path": "/",
            "side": "left",
            "icon_ios": "line.horizontal.3",
            "script": "window.bridge.showMenu();",
            "protected": false
          },
          {
            "path": "/",
            "side": "right",
            "title": "Add",
            "visit": "/posts/new",
            "protected": true
          }
        ]
      },
      "rules": [
        {
          "patterns": [
            "/new$",
            "/edit$"
          ],
          "properties": {
            "presentation": "modal"
          }
        },
        {
          "patterns": [
            "/users/login"
          ],
          "properties": {
            "presentation": "modal"
          }
        },
        {
          "patterns": [
            "/users/logout"
          ],
          "properties": {
            "presentation": "replace"
          }
        }
      ]
    }
    end 
end

To see all the available iOS icons you can use for navbar buttons or tabbar icons, visit https://hotpot.ai/free-icons?s=sfSymbols.

Add Turbo Route

In your routes.rb add route pointing to turbo#index.

get 'turbo', to: "turbo#index", as: :turbo

Write Beautiful Ruby

And that's it! Everything should now be configured including the app colors, tabs, navbar buttons, etc which are all driven from the turbo.json returned from turbo_controller.rb.

Now the app tabs and navbar buttons should appear according to the protected property if the user is authenticated or not. Your navbar buttons can either visit a page or trigger javascript on your server.

The best part is you shouldn't need to write any Swift code, so you can focus on your backend Rails application. This is something I've dreamt about ever since I first started using Rails, and it's now possible thanks to Turbo-iOS!

If you find this project useful or have suggestions on improvements, please let me know!

Comments
  • Settings not loading from turbo.json

    Settings not loading from turbo.json

    Hey thanks for the awesome starting point for us who know nothing about Swift!

    I'm not sure if this issue is related to my rails setup. I created a new project and followed the instructions from the readme.

    CleanShot 2021-06-25 at 18 10 01

    CleanShot 2021-06-25 at 18 13 26

    opened by aviderambo 6
  • Fatal error: Unexpectedly found nil while unwrapping an Optional value

    Fatal error: Unexpectedly found nil while unwrapping an Optional value

    Hi, I'm trying to integrate your TurboController into my turbo ios app and I'm getting the error: Thread 1: Fatal error: Unexpectedly found nil while unwrapping an Optional value on line 224:

    let environment = ProcessInfo.processInfo.environment["ENVIRONMENT"]! as String

    When I ran your demo on my local machine no problems, so is this a configuration issue on my end or code compatibility with newer version of iOS? I noticed under Deployment target your demo is set to 14.5, while mine is 15.2, but even if I change mine to 14.5 I keep getting the error. Any help would be greatly appreciated!

    Thanks!

    opened by estebanutz 3
  • App Crashes with Error on fetching env variable on TestFlight

    App Crashes with Error on fetching env variable on TestFlight

    So I was able to deploy my app to testflight, but when I tried testing the app it started crashing and the report points me to this code. Any easy fix, anything I'm missing here?

    image
    opened by jensnowww 2
  • Fix isReplace method

    Fix isReplace method

    Hi, thank you so much for releasing this. It's a great starting point for me! I noticed that "replace" wasn't working even though it was configured.

    Please let me know if this PR fixes it correctly.

    opened by yanshiyason 0
  • turbo-android-base equivalent ?

    turbo-android-base equivalent ?

    @dalezak First of all many many thanks for creating this wonderful repository.

    Second of all would you know of an equivalent repository to get started with the android counterpart e.g. turbo-android-base?

    opened by iamonkara 0
  • Incompatibility from turbo-ios 7.0.0-rc.6

    Incompatibility from turbo-ios 7.0.0-rc.6

    Thanks for putting this together! I was trying this out with a web app I've been experimenting with turbo on, and I noticed the turbo-ios version referenced is an older beta release. I tried switching to the main branch, but the build fails with 'TurboController' does not conform to protocol 'SessionDelegate'. It appears to stem from a change in release 7.0.0-rc.6 if you have a chance to look at it. I have next to zero experience with Swift, so not sure I can be of much help. =/

    Screen Shot 2022-08-21 at 11 05 26 PM
    opened by unRARed 0
  • leftBarButtonItem not showing on modal

    leftBarButtonItem not showing on modal

    In the turbo-ios demo when you open a link on modal you can see there is a "Cancel" button on the top left corner. How would you implement that into your TurboController main file? Any pointers will be greatly appreciated!

    opened by estebanutz 0
  • Local rails app won't load

    Local rails app won't load

    I've been able to get this working with the app at https://turbo-native-demo.glitch.me, but when I try to connect to a local development rails app at http://localhost:3000 things go wrong.

    I've set TURBO_URL->development to http://localhost:3000 and App Transport Security Settings->Allows Local Networking is YES. When building and launching the app, I get the following output in the Xcode console:

    2022-02-08 11:38:09.881444-0500 App[87765:101296449] [Storyboard] Unknown class _TtC3App14ViewController in Interface Builder file.
    2022-02-08 16:38:09 +0000 - [ColdBootVisit] startVisit()
    2022-02-08 16:38:10 +0000 - [Bridge] โ† pageLoadFailed
    2022-02-08 11:38:10.138793-0500 App[87765:101296449] [Loading] 0x157030818 - [pageProxyID=5, webPageID=6, PID=87769] WebPageProxy::didFailLoadForFrame: frameID=3, domain=NSURLErrorDomain, code=-999
    2022-02-08 16:38:10 +0000 - [Bridge] โ† pageLoaded
    

    This looks to me like there's something in iOS preventing the webview from loading from localhost. Note this is using http, not https. I tried enabling NSAllowsArbitraryLoads but that didn't help either.

    Am I missing something really simple here?

    opened by johndbritton 1
Owner
Dale Zak
Veteran mobile developer that was building and designing mobile apps, before mobile apps were cool ;)
Dale Zak
Owl is a portable Wayland compositor written in Objective-C, using Cocoa as its backend.

Owl is a portable Wayland compositor written in Objective-C, using Cocoa as its backend. Owl primarily targets Mac OS X, but also supports a varie

Owl compositor 62 Dec 31, 2022
NetFun-Backend - BFF layer (written in Swift)

NetFun-Backend BFF layer (written in Swift). One can setup BFF using Core Classess (which is already added as a dependency of this package. See Packag

Minhaz Panara 0 Jan 3, 2022
Docker images for Swift on Raspberry Pi and other ARM devices from balena's base images.

Swift on Balena Welcome to Swift on Balena โ€“ a set of Docker images for Swift on Raspberry Pi and other ARM devices. These images are based on balena'

Will Lisac 173 Dec 5, 2022
A Kotlin multiplatform library for building dynamic server-driven UI

Component Box ยท A Kotlin multiplatform library for building dynamic server-driven UI. Material Component-Based Interoperable Dynamic What You See Is W

Dropbox 216 Dec 31, 2022
The most powerful Event-Driven Observer Pattern solution the Swift language has ever seen!

Event-Driven Swift Decoupling of discrete units of code contributes massively to the long-term maintainability of your project(s). While Observer Patt

Flowduino 4 Nov 14, 2022
A starter project for Sample Project in Objective C.

A starter project for Sample Project in Objective C.

Zeeshan Haider 31 Jul 31, 2021
A Swift command line tool for generating your Xcode project

XcodeGen XcodeGen is a command line tool written in Swift that generates your Xcode project using your folder structure and a project spec. The projec

Yonas Kolb 5.9k Jan 9, 2023
Codepath-intro-prework - Hello World iOS App | Prework Project for CodePath Intro to Mobile App Development

Hello World iOS App App Description Prework Project for CodePath Intro to Mobile

null 0 Jan 25, 2022
The Art World in Your Pocket or Your Trendy Tech Company's Tote, Artsy's mobile app.

Meta State: production Point People: Brian Beckerle, Mounir Dhahri, Pavlos Vinieratos CI : This is an Artsy OSS project. Other mobile projects are Ene

Artsy 3.2k Jan 4, 2023
Project 03 I created for "iOS & Swift - The Complete iOS App Development Bootcamp"

Dicee This is the third project I created for "iOS & Swift - The Complete iOS App Development Bootcamp" Our Goal The objective of this tutorial is to

Lukas Goodfellow 0 Dec 23, 2021
CodePath-iOS-Prework - Prework project for Intro to Mobile App Development course on CodePath

CodePath iOS Prework App Description This app has an input field, text, and seve

Russell Elliott 0 Feb 2, 2022
Displays your HomeKit temperature sensors in your menu bar

Temperature Glance Displays your HomeKit temperature sensors in your menu bar Screenshot Note This is a very simple app that I made for myself but dec

Fernando Bunn 15 Nov 14, 2022
Save development time! Respresso automatically transforms and delivers your digital assets into your projects

Introduction Respresso is a centralized resource manager for shared Android, iOS and Web frontend projects. It allows you to simply import the latest

Respresso 10 Nov 8, 2022
Save development time! Respresso automatically transforms and delivers your digital assets into your projects

Respresso Android client Respresso is a centralized resource manager for shared Android, iOS and Web frontend projects. It allows you to simply import

Respresso 11 May 27, 2021
Save development time! Respresso automatically transforms and delivers your digital assets into your projects

Respresso iOS client Respresso is a centralized resource manager for shared Android, iOS and Web frontend projects. It allows you to simply import the

Respresso 50 May 1, 2021
You can monitor your APIs and websites on your menubar. Gives you status code ๐ŸŽ‰ Cool & good

Hope not. Monitor your APIs and websites on your menubar. For macOS. Right now! YyeeeHav!

Steven J. Selcuk 10 Nov 29, 2022
RegistrationScreen - Original App Design Project

Original App Design Project Spots Table of Contents Overview Product Spec Wireframes Schema Overview Description Have you ever went to a different cit

null 0 Nov 23, 2021
UIKit-based app project template for Swift Playgrounds 4

playgrounds-uikit-app This is a simplistic sample template for Swift Playgrounds 4 to begin with a UIKit-based app delegate & window scene instead of

Steven Troughton-Smith 39 Sep 19, 2022
Codepath prework project (Hello World app)

Hello World App Description TODO:// A Hello World App App Walk-though TODO:// Add the URL to your animated app walk-though gif in the image tag below.

null 0 Jan 17, 2022