Skip to content

Commit 51f4f6d

Browse files
committed
Create example Weather app
1 parent 1a39114 commit 51f4f6d

43 files changed

Lines changed: 6249 additions & 0 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
schemaVersion: 1
2+
enabledWorkflows:
3+
- simulator
4+
- ui-automation
5+
debug: false
6+
sentryDisabled: false
7+
sessionDefaults:
8+
projectPath: Weather.xcodeproj
9+
scheme: Weather
10+
simulatorName: iPhone 17 Pro
11+
simulatorId: A2C64636-37E9-4B68-B872-E7F0A82A5670
12+
setupPreferences:
13+
platforms:
14+
- iOS

example_projects/Weather/AGENTS.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# AGENTS.md
2+
3+
- If using XcodeBuildMCP, use the installed XcodeBuildMCP skill before calling XcodeBuildMCP tools.

example_projects/Weather/README.md

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
# Atmos Weather
2+
3+
Atmos Weather is a native SwiftUI weather app prototype for iOS.
4+
5+
## Launch with mock weather data
6+
7+
Build and run the app with XcodeBuildMCP first:
8+
9+
```bash
10+
../../build/cli.js simulator build-and-run
11+
```
12+
13+
Then relaunch the installed app with the mock API argument:
14+
15+
```bash
16+
../../build/cli.js simulator launch-app \
17+
--bundle-id com.sentry.weather.Weather \
18+
--args=--mock-weather-api
19+
```
20+
21+
## JSON fixtures
22+
23+
Fixture JSON files live in:
24+
25+
```text
26+
WeatherTests/Fixtures/
27+
```
28+
29+
Current fixtures:
30+
31+
- `WeatherTests/Fixtures/default-locations.json`
32+
- `WeatherTests/Fixtures/search-locations.json`
33+
- `WeatherTests/Fixtures/weather-report-loc-current-san-francisco.json`
34+
35+
## API schemas
36+
37+
OpenAI-compatible API schema files live in:
38+
39+
```text
40+
Schemas/
41+
```
42+
43+
Current schemas:
44+
45+
- `Schemas/default-locations.schema.json`
46+
- `Schemas/search-locations.schema.json`
47+
- `Schemas/weather-report.schema.json`
48+
49+
These schemas describe the JSON response shape expected by the DTO layer.
50+
51+
## Expected API endpoints
52+
53+
The production client is `URLSessionWeatherAPIClient`. It currently expects a JSON API rooted at:
54+
55+
```text
56+
https://api.atmosweather.example/v1
57+
```
58+
59+
All endpoints are `GET` requests.
60+
61+
| Purpose | Method | Path | Request shape | Schema |
62+
| --- | --- | --- | --- | --- |
63+
| Default saved locations | `GET` | `/locations/default` | No path params, query params, or body. | `Schemas/default-locations.schema.json` |
64+
| Search locations | `GET` | `/locations/search` | Query string: `query=<string>` | `Schemas/search-locations.schema.json` |
65+
| Weather report for a location | `GET` | `/weather/{locationID}` | Path param: `locationID=<WeatherLocationDTO.id>` | `Schemas/weather-report.schema.json` |
66+
67+
### Request examples
68+
69+
Default locations:
70+
71+
```http
72+
GET /v1/locations/default
73+
```
74+
75+
Search locations:
76+
77+
```http
78+
GET /v1/locations/search?query=San%20Francisco
79+
```
80+
81+
Weather report:
82+
83+
```http
84+
GET /v1/weather/loc-current-san-francisco
85+
```
86+
87+
### Response expectations
88+
89+
- Responses must be JSON.
90+
- Successful responses should use a `2xx` HTTP status code.
91+
- Non-`2xx` responses are treated as API failures.
92+
93+
## Tests
94+
95+
Run the app test suite through XcodeBuildMCP:
96+
97+
```bash
98+
../../build/cli.js simulator test
99+
```
100+
101+
UI tests inject `--mock-weather-api` themselves so they do not depend on the production API endpoint.
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
{
2+
"type": "json_schema",
3+
"json_schema": {
4+
"name": "default_locations_response",
5+
"strict": true,
6+
"schema": {
7+
"type": "object",
8+
"additionalProperties": false,
9+
"properties": {
10+
"locations": {
11+
"type": "array",
12+
"items": {
13+
"type": "object",
14+
"additionalProperties": false,
15+
"properties": {
16+
"id": {
17+
"type": "string"
18+
},
19+
"name": {
20+
"type": "string"
21+
},
22+
"subtitle": {
23+
"type": "string"
24+
},
25+
"country": {
26+
"type": [
27+
"string",
28+
"null"
29+
]
30+
},
31+
"temperatureC": {
32+
"type": "integer"
33+
},
34+
"highC": {
35+
"type": "integer"
36+
},
37+
"lowC": {
38+
"type": "integer"
39+
},
40+
"condition": {
41+
"type": "string",
42+
"enum": [
43+
"sunny",
44+
"mostly_sunny",
45+
"partly_cloudy",
46+
"cloudy",
47+
"clear_day",
48+
"clear_night",
49+
"light_rain",
50+
"heavy_rain",
51+
"light_snow",
52+
"snow_showers",
53+
"thunderstorms",
54+
"hazy"
55+
]
56+
},
57+
"localTime": {
58+
"type": "object",
59+
"additionalProperties": false,
60+
"properties": {
61+
"hour": {
62+
"type": "integer"
63+
},
64+
"minute": {
65+
"type": "integer"
66+
}
67+
},
68+
"required": [
69+
"hour",
70+
"minute"
71+
]
72+
}
73+
},
74+
"required": [
75+
"id",
76+
"name",
77+
"subtitle",
78+
"country",
79+
"temperatureC",
80+
"highC",
81+
"lowC",
82+
"condition",
83+
"localTime"
84+
]
85+
}
86+
}
87+
},
88+
"required": [
89+
"locations"
90+
]
91+
}
92+
}
93+
}
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
{
2+
"type": "json_schema",
3+
"json_schema": {
4+
"name": "search_locations_response",
5+
"strict": true,
6+
"schema": {
7+
"type": "object",
8+
"additionalProperties": false,
9+
"properties": {
10+
"locations": {
11+
"type": "array",
12+
"items": {
13+
"type": "object",
14+
"additionalProperties": false,
15+
"properties": {
16+
"id": {
17+
"type": "string"
18+
},
19+
"name": {
20+
"type": "string"
21+
},
22+
"subtitle": {
23+
"type": "string"
24+
},
25+
"country": {
26+
"type": [
27+
"string",
28+
"null"
29+
]
30+
},
31+
"temperatureC": {
32+
"type": "integer"
33+
},
34+
"highC": {
35+
"type": "integer"
36+
},
37+
"lowC": {
38+
"type": "integer"
39+
},
40+
"condition": {
41+
"type": "string",
42+
"enum": [
43+
"sunny",
44+
"mostly_sunny",
45+
"partly_cloudy",
46+
"cloudy",
47+
"clear_day",
48+
"clear_night",
49+
"light_rain",
50+
"heavy_rain",
51+
"light_snow",
52+
"snow_showers",
53+
"thunderstorms",
54+
"hazy"
55+
]
56+
},
57+
"localTime": {
58+
"type": "object",
59+
"additionalProperties": false,
60+
"properties": {
61+
"hour": {
62+
"type": "integer"
63+
},
64+
"minute": {
65+
"type": "integer"
66+
}
67+
},
68+
"required": [
69+
"hour",
70+
"minute"
71+
]
72+
}
73+
},
74+
"required": [
75+
"id",
76+
"name",
77+
"subtitle",
78+
"country",
79+
"temperatureC",
80+
"highC",
81+
"lowC",
82+
"condition",
83+
"localTime"
84+
]
85+
}
86+
}
87+
},
88+
"required": [
89+
"locations"
90+
]
91+
}
92+
}
93+
}

0 commit comments

Comments
 (0)