M2 app icon M2 Engineering Docs

Architecture

System Overview

M2 is an offline music player focused on local-file playback with a single-process runtime. Most implementation lives in Objective-C, with app services in M2Services.*, view composition in M2MusicModule.*, and app shell in ViewController.*.

Targets

Target Role Languages
M2 Main app: playback, library, playlists, favorites, desktop shell. Objective-C + Swift bridge
M2LiveActivityExtension Sleep timer Live Activity UI. Swift

Startup Sequence

AppDelegate
  -> configure AVAudioSession
  -> initialize Core Data container

SceneDelegate
  -> create UIWindow
  -> preload library/playlists/favorites/analytics/cache
  -> initialize playback manager singleton
  -> show root shell (ViewController)

ViewController
  -> build tabs (Music / Playlists / Favorites)
  -> build desktop sidebar + mini-player for Catalyst
  -> sync shell with playback notifications

Module Boundaries

File Responsibility
M2Services.* Library scanning, metadata caches, playlist/favorites stores, playback core, analytics, sleep timer.
M2MusicModule.* Feature view controllers, list/grid presentation, desktop-specific feature pages.
ViewController.* Application shell, desktop sidebar, mini-player, keyboard shortcuts, tab coordination.
M2Cells.* Reusable track/playlist cells for table and collection contexts.
M2Models.* Runtime domain models (M2Track, M2Playlist).

Notification Contracts

  • M2PlaybackStateDidChangeNotification: transport state changed.
  • M2PlaybackProgressDidChangeNotification: current playback time update.
  • M2PlaylistsDidChangeNotification: playlist storage mutation.
  • M2FavoritesDidChangeNotification: favorites mutation.
  • M2SleepTimerDidChangeNotification: sleep timer state update.

Desktop Shell Behavior

  • Catalyst shell enforces dark visual style and a fixed left sidebar.
  • Mini-player is always present in desktop layout.
  • Tab transitions and navigation pushes are configured without animation on desktop feature flows.
  • Pinned playlists are managed in sidebar and open directly into playlist details.

Runtime Sequence: Track Tap

User tap on track
  -> controller resolves queue + index
  -> opens player screen (if needed)
  -> playback manager receives playTracks:startIndex:
  -> AVAudioPlayer starts
  -> playback state notification sent
  -> mini-player and active lists refresh