Code Structure: In the Files
As described on the Code Structure page,
InvisibleMapCreator2 is a restructuring and redesign of the original
InvisibleMapCreator app. Marion and Avery describe the code structure in
their write-up of their work and also
link to more detailed resources to understand the architecture. In summary, the app utilizes a
composable finite state machine, which tracks the different UIs (views) of the app as states.
The state machine responds to events which are usually triggered by some user input or action,
and can transition between states or emit a command in response to an events. The commands
are used to communicate with the main functional components of the app (such as gathering data points).
The map creator uploads the map's raw data to Firebase to be processed by the backend.
The AppDelegate is the root object of the app. It calls on the files in the Authentication directory
to handle Apple ID sign in and anonymous authentication if the user declines Apple ID sign in. Currently,
the Invisible Map relies on the user signing in to Map Creator with Apple ID in order for it to be able
to find the maps the user has created (anonymous authenticaiton creates a different ID for different
apps).
State Machine
The state machine consists of StateType, AppState, AppController, and MapRecorder. StateType is the protocal
that provides the basic structure for the AppState class. AppState stores the different states (UI views)
that the app can be in (Ex: main screen, recording a map, viewing locations, etc.), the events that can
happen (Ex: a new recording is requested, a new AR frame is available to be processed, adding a new
location is reqeusted, etc.), and what commands can be fired as a result of events (Ex: record data,
detect tags, pin location, etc.). The handleEvent() function translates the current app state and one or
more events into one or more commands to be fired. The response to events can also be transitioning
between app states in addition to or instead of commands.
AppController is the main class that processes the commands emmitted when events occur and calls functions
in the app. The AppController.swift file also contains protocals for other controllers that dictate
what functions they need. The processCommands() function translates commands emmitted by AppState into
functions in various other files, including MapRecorder and some of the views. The proccessing functions
in the extension to AppController are called when things happen while the app is used, such as when
certain buttons are pressed, and send events to AppState's handleEvent() to get commands to then send
to processCommands(). AppController contains an object named shared, which is a shared instance of
the AppController that is referenced throughout all the app files. AppController has an instance of
MapRecorder, ARViewController, and RecordViewController.
MapRecorder contains the bulk of the backend processing for Invisible Map Creator, which is mainly
taking image frames from the phone and detecting tags in them, finding their position, saving the position
along with the phone odometry data, and uploading the raw data at the end of making a map.
Views
ContentView dictates the main screen when the app is first opened and loads in maps from Firebase. Currently,
the maps that are loaded are the ones that you created while signed in to your Apple ID. In the future,
you will be able to edit your created maps (change location names, map name, map picture).
EditMapView is currently empty, and is the view that will be transitioned to when editing map details
as mentioned in the previous paragraph.
RecordMapView is the view that displays while recording a map and contains all the buttons and options
available while recording. It includes instruction text that transitions based on user actions.
ARView handles everything to do with ARKit. Its role is described in more detail below in the
How it Works section of this page. It handles any AR visualizations and
also any data collection that involves the AR scene (mainly raycasting, described below).
The Record Map Subviews directory contains a collection of subviews for the different components that
appear in the RecordMapView (e.g. add location button).