- Three-scenario planning engine (A: date range, B: selected games, C: directional routes) - GeographicRouteExplorer with anchor game support for route exploration - Shared ItineraryBuilder for travel segment calculation - TravelEstimator for driving time/distance estimation - SwiftUI views for trip creation and detail display - CloudKit integration for schedule data - Python scraping scripts for sports schedules 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
4.3 KiB
4.3 KiB
CloudKit Setup Guide for SportsTime
1. Configure Container in Apple Developer Portal
- Go to Apple Developer Portal
- Navigate to Certificates, Identifiers & Profiles > Identifiers
- Select your App ID or create one for
com.sportstime.app - Enable iCloud capability
- Click Configure and create container:
iCloud.com.sportstime.app
2. Configure in Xcode
- Open
SportsTime.xcodeprojin Xcode - Select the SportsTime target
- Go to Signing & Capabilities
- Ensure iCloud is added (should already be there)
- Check CloudKit is selected
- Select container
iCloud.com.sportstime.app
3. Create Record Types in CloudKit Dashboard
Go to CloudKit Dashboard
Record Type: Stadium
| Field | Type | Notes |
|---|---|---|
stadiumId |
String | Unique identifier |
name |
String | Stadium name |
city |
String | City |
state |
String | State/Province |
location |
Location | CLLocation (lat/lng) |
capacity |
Int(64) | Seating capacity |
sport |
String | NBA, MLB, NHL |
teamAbbrevs |
String (List) | Team abbreviations |
source |
String | Data source |
yearOpened |
Int(64) | Optional |
Indexes:
sport(Queryable, Sortable)location(Queryable) - for radius searchesteamAbbrevs(Queryable)
Record Type: Team
| Field | Type | Notes |
|---|---|---|
teamId |
String | Unique identifier |
name |
String | Full team name |
abbreviation |
String | 3-letter code |
sport |
String | NBA, MLB, NHL |
city |
String | City |
Indexes:
sport(Queryable, Sortable)abbreviation(Queryable)
Record Type: Game
| Field | Type | Notes |
|---|---|---|
gameId |
String | Unique identifier |
sport |
String | NBA, MLB, NHL |
season |
String | e.g., "2024-25" |
dateTime |
Date/Time | Game date and time |
homeTeamRef |
Reference | Reference to Team |
awayTeamRef |
Reference | Reference to Team |
venueRef |
Reference | Reference to Stadium |
isPlayoff |
Int(64) | 0 or 1 |
broadcastInfo |
String | TV channel |
source |
String | Data source |
Indexes:
sport(Queryable, Sortable)dateTime(Queryable, Sortable)homeTeamRef(Queryable)awayTeamRef(Queryable)season(Queryable)
4. Import Data
After creating record types:
# 1. First scrape the data
cd Scripts
python3 scrape_schedules.py --sport all --season 2025 --output ./data
# 2. Run the import script (requires running from Xcode or with proper entitlements)
# The Swift script cannot run standalone - use the app or create a macOS command-line tool
Alternative: Import via App
Add this to your app for first-run data import:
// In AppDelegate or App init
Task {
let importer = CloudKitImporter()
// Load JSON from bundle or downloaded file
if let stadiumsURL = Bundle.main.url(forResource: "stadiums", withExtension: "json"),
let gamesURL = Bundle.main.url(forResource: "games", withExtension: "json") {
// Import stadiums first
let stadiumsData = try Data(contentsOf: stadiumsURL)
let stadiums = try JSONDecoder().decode([ScrapedStadium].self, from: stadiumsData)
let count = try await importer.importStadiums(from: stadiums)
print("Imported \(count) stadiums")
}
}
5. Security Roles (CloudKit Dashboard)
For the Public Database:
| Role | Stadium | Team | Game |
|---|---|---|---|
| World | Read | Read | Read |
| Authenticated | Read | Read | Read |
| Creator | Read/Write | Read/Write | Read/Write |
Users should only read from public database. Write access is for your admin imports.
6. Testing
- Build and run the app on simulator or device
- Check CloudKit Dashboard > Data to see imported records
- Use Logs tab to debug any issues
Troubleshooting
"Container not found"
- Ensure container is created in Developer Portal
- Check entitlements file has correct container ID
- Clean build and re-run
"Permission denied"
- Check Security Roles in CloudKit Dashboard
- Ensure app is signed with correct provisioning profile
"Record type not found"
- Create record types in Development environment first
- Deploy schema to Production when ready