Skip to main content

Build script

The app is built using scripts/build-ios.sh, which handles configuration, SDK selection, and API URL injection.
# Usage
./scripts/build-ios.sh [Configuration] [SDK]
The script injects the correct API URL at build time based on the configuration and environment.

API sources

EnvironmentURLPurpose
Productionapi.sightscreen.appLive production API
Fakefake-api.sightscreen.appFake API for development and testing

URL resolution order

The API base URL is resolved in this priority order:
1

Build-time override

If an explicit API URL is passed to the build script, it takes priority.
2

SANDBOX_API_URL environment variable

If set, this env var overrides the default. Useful for pointing at local or staging servers.
3

Default

Falls back to the production URL (api.sightscreen.app).
To test against the fake API locally, set SANDBOX_API_URL=https://fake-api.sightscreen.app before building.

Info.plist configuration

Key entries in the app’s Info.plist:
KeyValuePurpose
NSSupportsLiveActivitiesYESEnables Live Activity support
UIBackgroundModesfetch, remote-notificationEnables background fetch and push processing
Both background modes are required. fetch enables periodic stale-detection checks. remote-notification enables silent push processing for Live Activity token management.

Bundle identifiers

TargetBundle ID
Main appcom.sightscreen.ios
Widgetcom.sightscreen.ios.SightscreenWidget
The main app bundle ID is registered with APNs for push notifications and Live Activity updates.

Widget target

The widget target SightscreenWidget is a separate build target that shares models with the main app.
Shared resourceHow
Generated modelsLiveActivityModels.generated.swift included in both targets
Cached imagesApp group shared container (ImageCacheService writes, widget reads)
ConstantsShared constants file for match IDs, URLs, etc.

Fonts

The app uses two custom font families:
FontUsage
Clash DisplayHeadings, scores, large display text
SatoshiBody text, labels, secondary information
Both are bundled in the app and registered in Info.plist.

Theme system

Visual theming is managed through three files:
FilePurpose
Colors.swiftApp-wide color definitions (background, text, accent, etc.)
Typography.swiftFont size and weight presets mapped to Clash Display and Satoshi
TeamBranding.swiftIPL team-specific colors (primary, secondary, gradient) for match cards and Live Activities
struct TeamBranding {
    let primary: Color
    let secondary: Color
    let gradient: [Color]

    static func branding(for teamAbbr: String) -> TeamBranding {
        switch teamAbbr {
        case "MI": return TeamBranding(
            primary: .blue,
            secondary: .gold,
            gradient: [.blue, .darkBlue]
        )
        case "CSK": return TeamBranding(
            primary: .yellow,
            secondary: .blue,
            gradient: [.yellow, .darkYellow]
        )
        // ... other IPL teams
        default: return defaultBranding
        }
    }
}
Team branding colors are one of the few things defined on the client side, since they are purely visual and do not depend on match state or backend logic.