6.6 KiB
6.6 KiB
External Integrations
Analysis Date: 2026-01-18
APIs & External Services
Apple CloudKit (Primary Data Source):
- Purpose: Sync game schedules, teams, stadiums, league structure to all users
- Container:
iCloud.com.sportstime.app - Database: Public (read-only for users, admin writes via Python uploader)
- Client:
Core/Services/CloudKitService.swift - Sync:
Core/Services/CanonicalSyncService.swift - Record types:
Game,Team,Stadium,LeagueStructure,TeamAlias,StadiumAlias,Sport - Auth: User iCloud account (automatic), server-to-server JWT (Python uploader)
Apple MapKit:
- Purpose: Geocoding, routing, map snapshots, EV charger search, POI search
- Services used:
MKLocalSearch- Address and POI search (LocationService.swift)MKDirections- Driving routes and ETA (LocationService.swift)MKMapSnapshotter- Static map images for PDF (Export/Services/MapSnapshotService.swift)MKLocalPointsOfInterestRequest- EV chargers (EVChargingService.swift)
- Client:
Core/Services/LocationService.swift,Core/Services/EVChargingService.swift - Auth: Automatic via Apple frameworks
- Rate limits: Apple's standard MapKit limits
Apple StoreKit 2:
- Purpose: In-app subscriptions (Pro tier)
- Products:
com.sportstime.pro.monthly,com.sportstime.pro.annual - Client:
Core/Store/StoreManager.swift - Features gated: Trip limit (1 free, unlimited Pro)
Sports League APIs (Official):
| API | URL | Sport | Reliability | Client |
|---|---|---|---|---|
| MLB Stats API | https://statsapi.mlb.com/api/v1 |
MLB | Official | ScoreAPIProviders/MLBStatsProvider.swift |
| NHL Stats API | https://api-web.nhle.com/v1 |
NHL | Official | ScoreAPIProviders/NHLStatsProvider.swift |
| NBA Stats API | https://stats.nba.com/stats |
NBA | Unofficial | ScoreAPIProviders/NBAStatsProvider.swift |
NBA Stats API Notes:
- Requires specific headers to avoid 403 (User-Agent, Referer, x-nba-stats-origin, x-nba-stats-token)
- May break without notice (unofficial)
Sports Reference Sites (Scraping Fallback):
| Site | URL Pattern | Sport | Client |
|---|---|---|---|
| Baseball-Reference | baseball-reference.com/boxes/?month=M&day=D&year=Y |
MLB | HistoricalGameScraper.swift |
| Basketball-Reference | basketball-reference.com/boxscores/?month=M&day=D&year=Y |
NBA | HistoricalGameScraper.swift |
| Hockey-Reference | hockey-reference.com/boxscores/?month=M&day=D&year=Y |
NHL | HistoricalGameScraper.swift |
| Pro-Football-Reference | pro-football-reference.com/boxscores/... |
NFL | HistoricalGameScraper.swift |
- Uses SwiftSoup for HTML parsing
- On-device scraping (no server costs, unlimited scale)
- Cached per-session to avoid redundant requests
Data Storage
SwiftData (Local):
- Purpose: Offline-first data storage, user trips, preferences
- Location: App sandbox (automatic)
- CloudKit sync: Disabled (
cloudKitDatabase: .none) - Schema: See
SportsTimeApp.swiftModelContainer configuration
CloudKit Public Database (Remote):
- Purpose: Shared schedule data for all users
- Container:
iCloud.com.sportstime.app - Access: Read (all users), Write (admin via Python uploader)
- Sync method: Date-based delta sync (modificationDate filtering)
URLCache (Images):
- Purpose: Cache team logos and stadium photos
- Memory: 50 MB
- Disk: 100 MB
- Path:
ImageCache - Client:
Export/Services/RemoteImageService.swift
File Storage:
- Local filesystem only for PDF export (temporary)
- Photo library access for visit photo imports
Caching:
- In-memory game score cache:
ScoreResolutionCache.swift - In-memory scraper cache:
HistoricalGameScraper.swift - URLSession cache: Team logos, stadium photos
Authentication & Identity
iCloud (Automatic):
- Users authenticate via their iCloud account
- Required for: CloudKit sync, poll voting identity
- Optional: App works offline without iCloud
CloudKit Server-to-Server (Python Uploader):
- JWT authentication with ECDSA P-256 key
- Key ID and team ID from Apple Developer portal
- Used by
Scripts/sportstime_parser/uploaders/cloudkit.py
Monitoring & Observability
Error Tracking:
- None (no Sentry, Crashlytics, etc.)
- Errors logged to console via
os.Logger
Logs:
os.Loggersubsystem:com.sportstime.app- Categories:
BackgroundSyncManager,NetworkMonitor - Rich console output in Python scraper
CI/CD & Deployment
Hosting:
- iOS App Store (planned)
- CloudKit public database (Apple infrastructure)
CI Pipeline:
- None configured (no GitHub Actions, Xcode Cloud, etc.)
Data Pipeline:
- Python CLI (
sportstime-parser) scrapes schedules - Uploads to CloudKit via CloudKit Web Services API
- iOS apps sync from CloudKit automatically
Background Processing
BGTaskScheduler:
- Refresh task:
com.sportstime.app.refresh(periodic CloudKit sync) - Processing task:
com.sportstime.app.db-cleanup(overnight heavy sync) - Manager:
Core/Services/BackgroundSyncManager.swift
Network Monitoring:
NWPathMonitortriggers sync on connectivity restoration- Debounce: 2.5 seconds (handles WiFi/cellular handoffs)
- Manager:
Core/Services/NetworkMonitor.swift
Push Notifications:
- CloudKit subscriptions for data changes
- Silent notifications (
shouldSendContentAvailable) - Subscription IDs:
game-updates,league-structure-updates,team-alias-updates,stadium-alias-updates
Environment Configuration
Required Environment Variables:
iOS App:
- None required (CloudKit container ID hardcoded)
Python Uploader:
- CloudKit key ID (or in config)
- CloudKit team ID (or in config)
- ECDSA private key path
Secrets Location:
- iOS: Entitlements file (
SportsTime.entitlements) - Python: Environment variables or local config file
Webhooks & Callbacks
Incoming:
- CloudKit silent push notifications (background sync trigger)
- Deep links:
sportstime://poll/{shareCode}(poll sharing)
Outgoing:
- None
Rate Limiting
Internal Rate Limiter:
Core/Services/RateLimiter.swift- Per-provider keys:
mlb_stats,nba_stats,nhl_stats - Prevents API abuse when resolving historical game scores
Provider Auto-Disable:
- Official APIs: Never auto-disabled
- Unofficial APIs: Disabled after 3 failures (24h cooldown)
- Scraped sources: Disabled after 2 failures (24h cooldown)
Polls (Group Trip Planning)
CloudKit-Based Polling:
- Record type:
TripPoll,PollVote - Share codes: 6-character uppercase alphanumeric
- Deep link:
sportstime://poll/{shareCode} - Service:
Core/Services/PollService.swift
Integration audit: 2026-01-18