GitHub - hbmartin/justaline-ios-resurrected: The first cross-platform collaborative AR app (for doodling)

2 min read Original article ↗

SwiftFormat SwiftLint SwiftAsk DeepWiki

Just a Line - iOS

Overview

Just a Line is an AR Experiment that lets you draw simple white lines in 3D space, on your own or together with a friend, and share your creation with a video. Draw by pressing your finger on the screen and moving the phone around the space.

This app was written in Swift using ARKit and ARCore. ARCore Cloud Anchors to enable Just a Line to pair two phones, allowing users to draw simultaneously in a shared space. Pairing works across Android and iOS devices, and drawings are synchronized live on Firebase Realtime Database.

This is not an official Google product, but an AR Experiment that was developed at the Google Creative Lab in collaboration with Uncorked Studios.

Just a Line is also developed for Android. The open source code for Android can be found here.

Get started

To build the project, first install all dependencies using CocoaPods by running

Then the project can be built using Xcode 16.

Firebase Setup

You will need to set up a cloud project with Firebase, ARCore, and with nearby messages enabled before running the app. Follow the setup steps in the ARCore Cloud Anchors Quickstart guide.

Important Firebase Configuration Requirements:

  • Anonymous Authentication must be enabled in Firebase Authentication
  • Realtime Database must be enabled and configured
  • Ensure your GoogleService-Info.plist file is properly added to the project

The app uses Firebase Anonymous Authentication for user identification and Firebase Realtime Database for storing and synchronizing drawing data between devices.

Architecture

Manager Pattern

The application extensively uses the Manager pattern to separate concerns and coordinate complex operations. Each manager has a specific responsibility:

  • PairingManager: Orchestrates multi-device collaboration (PairingManager.swift36)
  • RoomManager: Handles Firebase operations and room lifecycle (RoomManager.swift41)
  • StateManager: Coordinates UI state transitions (referenced throughout)
  • StrokeUploadManager: Manages batched stroke uploads (RoomManager.swift58)

Delegate Pattern

Communication between managers uses the delegate pattern to maintain loose coupling while enabling coordinated behavior:

  • PairingManagerDelegate: Notifies AR controller of collaboration events (PairingManager.swift22-33)
  • RoomManagerDelegate: Handles Firebase room events (RoomManager.swift22-36)
  • InterfaceViewControllerDelegate: Forwards UI interactions to main controller

Observer Pattern

Firebase integration uses the observer pattern for real-time synchronization:

State Machine Pattern

The UI state management implements a state machine that coordinates complex pairing flows with appropriate user feedback and error handling across network operations and AR anchor resolution.

Sources: PairingManager.swift1-804 RoomManager.swift1-881 ViewControllers/ViewController.swift1-397