{"id":"0240db32-fc06-4e66-b94d-46104bd845ab","shortId":"4mhSzp","kind":"skill","title":"Weatherkit","tagline":"Swift Ios Skills skill by Dpearson2699","description":"# WeatherKit\n\nFetch current conditions, hourly and daily forecasts, weather alerts, and\nhistorical statistics using `WeatherService`. Display required Apple Weather\nattribution. Targets Swift 6.3 / iOS 26+.\n\n## Contents\n\n- [Setup](#setup)\n- [Fetching Current Weather](#fetching-current-weather)\n- [Forecasts](#forecasts)\n- [Weather Alerts](#weather-alerts)\n- [Selective Queries](#selective-queries)\n- [Attribution](#attribution)\n- [Availability](#availability)\n- [Common Mistakes](#common-mistakes)\n- [Review Checklist](#review-checklist)\n- [References](#references)\n\n## Setup\n\n### Project Configuration\n\n1. Enable the **WeatherKit** capability in Xcode (adds the entitlement)\n2. Enable WeatherKit for your App ID in the Apple Developer portal\n3. Add `NSLocationWhenInUseUsageDescription` to Info.plist if using device location\n4. WeatherKit requires an active Apple Developer Program membership\n\n### Import\n\n```swift\nimport WeatherKit\nimport CoreLocation\n```\n\n### Creating the Service\n\nUse the shared singleton or create an instance. The service is `Sendable` and\nthread-safe.\n\n```swift\nlet weatherService = WeatherService.shared\n// or\nlet weatherService = WeatherService()\n```\n\n## Fetching Current Weather\n\nFetch current conditions for a location. Returns a `Weather` object with all\navailable datasets.\n\n```swift\nfunc fetchCurrentWeather(for location: CLLocation) async throws -> CurrentWeather {\n    let weather = try await weatherService.weather(for: location)\n    return weather.currentWeather\n}\n\n// Using the result\nfunc displayCurrent(_ current: CurrentWeather) {\n    let temp = current.temperature  // Measurement<UnitTemperature>\n    let condition = current.condition  // WeatherCondition enum\n    let symbol = current.symbolName  // SF Symbol name\n    let humidity = current.humidity  // Double (0-1)\n    let wind = current.wind  // Wind (speed, direction, gust)\n    let uvIndex = current.uvIndex  // UVIndex\n\n    print(\"\\(condition): \\(temp.formatted())\")\n}\n```\n\n## Forecasts\n\n### Hourly Forecast\n\nReturns 25 contiguous hours starting from the current hour by default.\n\n```swift\nfunc fetchHourlyForecast(for location: CLLocation) async throws -> Forecast<HourWeather> {\n    let weather = try await weatherService.weather(for: location)\n    return weather.hourlyForecast\n}\n\n// Iterate hours\nfor hour in hourlyForecast {\n    print(\"\\(hour.date): \\(hour.temperature.formatted()), \\(hour.condition)\")\n}\n```\n\n### Daily Forecast\n\nReturns 10 contiguous days starting from the current day by default.\n\n```swift\nfunc fetchDailyForecast(for location: CLLocation) async throws -> Forecast<DayWeather> {\n    let weather = try await weatherService.weather(for: location)\n    return weather.dailyForecast\n}\n\n// Iterate days\nfor day in dailyForecast {\n    print(\"\\(day.date): \\(day.lowTemperature.formatted()) - \\(day.highTemperature.formatted())\")\n    print(\"  Condition: \\(day.condition), Precipitation: \\(day.precipitationChance)\")\n}\n```\n\n### Custom Date Range\n\nRequest forecasts for specific date ranges using `WeatherQuery`.\n\n```swift\nfunc fetchExtendedForecast(for location: CLLocation) async throws -> Forecast<DayWeather> {\n    let startDate = Date.now\n    let endDate = Calendar.current.date(byAdding: .day, value: 10, to: startDate)!\n\n    let forecast = try await weatherService.weather(\n        for: location,\n        including: .daily(startDate: startDate, endDate: endDate)\n    )\n    return forecast\n}\n```\n\n## Weather Alerts\n\nFetch active weather alerts for a location. Alerts include severity, summary,\nand affected regions.\n\n```swift\nfunc fetchAlerts(for location: CLLocation) async throws -> [WeatherAlert]? {\n    let weather = try await weatherService.weather(for: location)\n    return weather.weatherAlerts\n}\n\n// Process alerts\nif let alerts = weatherAlerts {\n    for alert in alerts {\n        print(\"Alert: \\(alert.summary)\")\n        print(\"Severity: \\(alert.severity)\")\n        print(\"Region: \\(alert.region)\")\n        if let detailsURL = alert.detailsURL {\n            // Link to full alert details\n        }\n    }\n}\n```\n\n## Selective Queries\n\nFetch only the datasets you need to minimize API usage and response size. Each\n`WeatherQuery` type maps to one dataset.\n\n### Single Dataset\n\n```swift\nlet current = try await weatherService.weather(\n    for: location,\n    including: .current\n)\n// current is CurrentWeather\n```\n\n### Multiple Datasets\n\n```swift\nlet (current, hourly, daily) = try await weatherService.weather(\n    for: location,\n    including: .current, .hourly, .daily\n)\n// current: CurrentWeather, hourly: Forecast<HourWeather>, daily: Forecast<DayWeather>\n```\n\n### Minute Forecast\n\nAvailable in limited regions. Returns precipitation forecasts at minute\ngranularity for the next hour.\n\n```swift\nlet minuteForecast = try await weatherService.weather(\n    for: location,\n    including: .minute\n)\n// minuteForecast: Forecast<MinuteWeather>?  (nil if unavailable)\n```\n\n### Available Query Types\n\n| Query | Return Type | Description |\n|---|---|---|\n| `.current` | `CurrentWeather` | Current observed conditions |\n| `.hourly` | `Forecast<HourWeather>` | 25 hours from current hour |\n| `.daily` | `Forecast<DayWeather>` | 10 days from today |\n| `.minute` | `Forecast<MinuteWeather>?` | Next-hour precipitation (limited regions) |\n| `.alerts` | `[WeatherAlert]?` | Active weather alerts |\n| `.availability` | `WeatherAvailability` | Dataset availability for location |\n\n## Attribution\n\nApple requires apps using WeatherKit to display attribution. This is a\nlegal requirement.\n\n### Fetching Attribution\n\n```swift\nfunc fetchAttribution() async throws -> WeatherAttribution {\n    return try await weatherService.attribution\n}\n```\n\n### Displaying Attribution in SwiftUI\n\n```swift\nimport SwiftUI\nimport WeatherKit\n\nstruct WeatherAttributionView: View {\n    let attribution: WeatherAttribution\n    @Environment(\\.colorScheme) private var colorScheme\n\n    var body: some View {\n        VStack(spacing: 8) {\n            // Display the Apple Weather mark\n            AsyncImage(url: markURL) { image in\n                image\n                    .resizable()\n                    .scaledToFit()\n                    .frame(height: 20)\n            } placeholder: {\n                EmptyView()\n            }\n\n            // Link to the legal attribution page\n            Link(\"Weather data sources\", destination: attribution.legalPageURL)\n                .font(.caption2)\n                .foregroundStyle(.secondary)\n        }\n    }\n\n    private var markURL: URL {\n        colorScheme == .dark\n            ? attribution.combinedMarkDarkURL\n            : attribution.combinedMarkLightURL\n    }\n}\n```\n\n### Attribution Properties\n\n| Property | Use |\n|---|---|\n| `combinedMarkLightURL` | Apple Weather mark for light backgrounds |\n| `combinedMarkDarkURL` | Apple Weather mark for dark backgrounds |\n| `squareMarkURL` | Square Apple Weather logo |\n| `legalPageURL` | URL to the legal attribution web page |\n| `legalAttributionText` | Text alternative when a web view is not feasible |\n| `serviceName` | Weather data provider name |\n\n## Availability\n\nCheck which weather datasets are available for a given location. Not all datasets\nare available in all countries.\n\n```swift\nfunc checkAvailability(for location: CLLocation) async throws {\n    let availability = try await weatherService.weather(\n        for: location,\n        including: .availability\n    )\n\n    // Check specific dataset availability\n    if availability.alertAvailability == .available {\n        // Safe to fetch alerts\n    }\n\n    if availability.minuteAvailability == .available {\n        // Minute forecast available for this region\n    }\n}\n```\n\n## Common Mistakes\n\n### DON'T: Ship without Apple Weather attribution\n\nOmitting attribution violates the WeatherKit terms of service and risks App Review\nrejection.\n\n```swift\n// WRONG: Show weather data without attribution\nVStack {\n    Text(\"72F, Sunny\")\n}\n\n// CORRECT: Always include attribution\nVStack {\n    Text(\"72F, Sunny\")\n    WeatherAttributionView(attribution: attribution)\n}\n```\n\n### DON'T: Fetch all datasets when you only need current conditions\n\nEach dataset query counts against your API quota. Fetch only what you display.\n\n```swift\n// WRONG: Fetches everything\nlet weather = try await weatherService.weather(for: location)\nlet temp = weather.currentWeather.temperature\n\n// CORRECT: Fetch only current conditions\nlet current = try await weatherService.weather(\n    for: location,\n    including: .current\n)\nlet temp = current.temperature\n```\n\n### DON'T: Ignore minute forecast unavailability\n\nMinute forecasts return `nil` in unsupported regions. Force-unwrapping crashes.\n\n```swift\n// WRONG: Force-unwrap minute forecast\nlet minutes = try await weatherService.weather(for: location, including: .minute)\nfor m in minutes! { ... } // Crash in unsupported regions\n\n// CORRECT: Handle nil\nif let minutes = try await weatherService.weather(for: location, including: .minute) {\n    for m in minutes { ... }\n} else {\n    // Minute forecast not available for this region\n}\n```\n\n### DON'T: Forget the WeatherKit entitlement\n\nWithout the capability enabled, `WeatherService` calls throw at runtime.\n\n```swift\n// WRONG: No WeatherKit capability configured\nlet weather = try await weatherService.weather(for: location) // Throws\n\n// CORRECT: Enable WeatherKit in Xcode Signing & Capabilities\n// and in the Apple Developer portal for your App ID\n```\n\n### DON'T: Make repeated requests without caching\n\nWeather data updates every few minutes, not every second. Cache responses\nto stay within API quotas and improve performance.\n\n```swift\n// WRONG: Fetch on every view appearance\n.task {\n    let weather = try? await fetchWeather()\n}\n\n// CORRECT: Cache with a staleness interval\nactor WeatherCache {\n    private var cached: CurrentWeather?\n    private var lastFetch: Date?\n\n    func current(for location: CLLocation) async throws -> CurrentWeather {\n        if let cached, let lastFetch,\n           Date.now.timeIntervalSince(lastFetch) < 600 {\n            return cached\n        }\n        let fresh = try await WeatherService.shared.weather(\n            for: location, including: .current\n        )\n        cached = fresh\n        lastFetch = .now\n        return fresh\n    }\n}\n```\n\n## Review Checklist\n\n- [ ] WeatherKit capability enabled in Xcode and Apple Developer portal\n- [ ] Active Apple Developer Program membership (required for WeatherKit)\n- [ ] Apple Weather attribution displayed wherever weather data appears\n- [ ] Attribution mark uses correct color scheme variant (light/dark)\n- [ ] Legal attribution page linked or `legalAttributionText` displayed\n- [ ] Only needed `WeatherQuery` datasets fetched (not full `weather(for:)` when unnecessary)\n- [ ] Minute forecast handled as optional (nil in unsupported regions)\n- [ ] Weather alerts checked for nil before iteration\n- [ ] Responses cached with a reasonable staleness interval (5-15 minutes)\n- [ ] `WeatherAvailability` checked before fetching region-limited datasets\n- [ ] Location permission requested before passing `CLLocation` to service\n- [ ] Temperature and measurements formatted with `Measurement.formatted()` for locale\n\n## References\n\n- Extended patterns (SwiftUI dashboard, charts integration, historical statistics): [references/weatherkit-patterns.md](references/weatherkit-patterns.md)\n- [WeatherKit framework](https://sosumi.ai/documentation/weatherkit)\n- [WeatherService](https://sosumi.ai/documentation/weatherkit/weatherservice)\n- [WeatherAttribution](https://sosumi.ai/documentation/weatherkit/weatherattribution)\n- [WeatherQuery](https://sosumi.ai/documentation/weatherkit/weatherquery)\n- [CurrentWeather](https://sosumi.ai/documentation/weatherkit/currentweather)\n- [Forecast](https://sosumi.ai/documentation/weatherkit/forecast)\n- [HourWeather](https://sosumi.ai/documentation/weatherkit/hourweather)\n- [DayWeather](https://sosumi.ai/documentation/weatherkit/dayweather)\n- [WeatherAlert](https://sosumi.ai/documentation/weatherkit/weatheralert)\n- [WeatherAvailability](https://sosumi.ai/documentation/weatherkit/weatheravailability)\n- [Fetching weather forecasts with WeatherKit](https://sosumi.ai/documentation/weatherkit/fetching_weather_forecasts_with_weatherkit)","tags":["weatherkit","swift","ios","skills","dpearson2699"],"capabilities":["skill","source-dpearson2699","category-swift-ios-skills"],"categories":["swift-ios-skills"],"synonyms":[],"warnings":[],"endpointUrl":"https://skills.sh/dpearson2699/swift-ios-skills/weatherkit","protocol":"skill","transport":"skills-sh","auth":{"type":"none","details":{"install_from":"skills.sh"}},"qualityScore":"0.300","qualityRationale":"deterministic score 0.30 from registry signals: · indexed on skills.sh · published under dpearson2699/swift-ios-skills","verified":false,"liveness":"unknown","lastLivenessCheck":null,"agentReviews":{"count":0,"score_avg":null,"cost_usd_avg":null,"success_rate":null,"latency_p50_ms":null,"narrative_summary":null,"summary_updated_at":null},"enrichmentModel":"deterministic:skill:v1","enrichmentVersion":1,"enrichedAt":"2026-04-22T03:40:33.669Z","embedding":null,"createdAt":"2026-04-18T20:34:34.584Z","updatedAt":"2026-04-22T03:40:33.669Z","lastSeenAt":"2026-04-22T03:40:33.669Z","tsv":"'-1':209 '-15':1128 '/documentation/weatherkit)':1169 '/documentation/weatherkit/currentweather)':1185 '/documentation/weatherkit/dayweather)':1197 '/documentation/weatherkit/fetching_weather_forecasts_with_weatherkit)':1213 '/documentation/weatherkit/forecast)':1189 '/documentation/weatherkit/hourweather)':1193 '/documentation/weatherkit/weatheralert)':1201 '/documentation/weatherkit/weatherattribution)':1177 '/documentation/weatherkit/weatheravailability)':1205 '/documentation/weatherkit/weatherquery)':1181 '/documentation/weatherkit/weatherservice)':1173 '0':208 '1':74 '10':269,341,532 '2':84 '20':623 '25':228,525 '26':32 '3':96 '4':105 '5':1127 '6.3':30 '600':1033 '72f':783,791 '8':607 'activ':109,362,546,1062 'actor':1008 'add':81,97 'affect':373 'alert':17,46,49,360,364,368,394,397,400,402,404,419,544,548,742,1114 'alert.detailsurl':415 'alert.region':411 'alert.severity':408 'alert.summary':405 'altern':683 'alway':786 'api':431,813,984 'app':89,558,771,961 'appear':995,1077 'appl':25,93,110,556,610,655,662,670,758,956,1059,1063,1070 'async':170,244,285,329,381,574,721,1023 'asyncimag':613 'attribut':27,55,56,555,563,570,582,594,630,650,678,760,762,780,788,794,795,1072,1078,1087 'attribution.combinedmarkdarkurl':648 'attribution.combinedmarklighturl':649 'attribution.legalpageurl':637 'avail':57,58,162,482,511,549,552,696,702,711,724,731,735,738,745,748,913 'availability.alertavailability':737 'availability.minuteavailability':744 'await':176,250,291,347,387,449,466,500,579,726,827,842,878,899,941,1000,1039 'background':660,667 'bodi':602 'byad':338 'cach':969,979,1003,1012,1028,1035,1045,1121 'calendar.current.date':337 'call':928 'capabl':78,925,936,952,1054 'caption2':639 'category-swift-ios-skills' 'chart':1159 'check':697,732,1115,1131 'checkavail':717 'checklist':65,68,1052 'cllocat':169,243,284,328,380,720,1022,1143 'color':1082 'colorschem':597,600,646 'combinedmarkdarkurl':661 'combinedmarklighturl':654 'common':59,62,752 'common-mistak':61 'condit':11,152,194,222,308,522,806,838 'configur':73,937 'content':33 'contigu':229,270 'coreloc':119 'correct':785,834,892,946,1002,1081 'count':810 'countri':714 'crash':867,888 'creat':120,128 'current':10,37,41,148,151,187,234,275,447,454,455,462,471,474,518,520,528,805,837,840,847,1019,1044 'current.condition':195 'current.humidity':206 'current.symbolname':200 'current.temperature':191,850 'current.uvindex':219 'current.wind':212 'currentweath':172,188,457,475,519,1013,1025,1182 'custom':312 'daili':14,266,352,464,473,478,530 'dailyforecast':302 'dark':647,666 'dashboard':1158 'data':634,693,778,971,1076 'dataset':163,426,442,444,459,551,700,709,734,800,808,1096,1137 'date':313,319,1017 'date.now':334 'date.now.timeintervalsince':1031 'day':271,276,298,300,339,533 'day.condition':309 'day.date':304 'day.hightemperature.formatted':306 'day.lowtemperature.formatted':305 'day.precipitationchance':311 'dayweath':1194 'default':237,278 'descript':517 'destin':636 'detail':420 'detailsurl':414 'develop':94,111,957,1060,1064 'devic':103 'direct':215 'display':23,562,581,608,819,1073,1092 'displaycurr':186 'doubl':207 'dpearson2699':7 'els':909 'emptyview':625 'enabl':75,85,926,947,1055 'enddat':336,355,356 'entitl':83,922 'enum':197 'environ':596 'everi':973,977,993 'everyth':823 'extend':1155 'feasibl':690 'fetch':9,36,40,147,150,361,423,569,741,798,815,822,835,991,1097,1133,1206 'fetchalert':377 'fetchattribut':573 'fetchcurrentweath':166 'fetchdailyforecast':281 'fetchextendedforecast':325 'fetchhourlyforecast':240 'fetching-current-weath':39 'fetchweath':1001 'font':638 'forc':865,871 'force-unwrap':864,870 'forecast':15,43,44,224,226,246,267,287,316,331,345,358,477,479,481,488,507,524,531,537,747,855,858,874,911,1105,1186,1208 'foregroundstyl':640 'forget':919 'format':1149 'frame':621 'framework':1166 'fresh':1037,1046,1050 'full':418,1099 'func':165,185,239,280,324,376,572,716,1018 'given':705 'granular':491 'gust':216 'handl':893,1106 'height':622 'histor':19,1161 'hour':12,225,230,235,257,259,463,472,476,495,523,526,529,540 'hour.condition':265 'hour.date':263 'hour.temperature.formatted':264 'hourlyforecast':261 'hourweath':1190 'humid':205 'id':90,962 'ignor':853 'imag':616,618 'import':114,116,118,586,588 'improv':987 'includ':351,369,453,470,504,730,787,846,882,903,1043 'info.plist':100 'instanc':130 'integr':1160 'interv':1007,1126 'io':3,31 'iter':256,297,1119 'lastfetch':1016,1030,1032,1047 'legal':567,629,677,1086 'legalattributiontext':681,1091 'legalpageurl':673 'let':140,144,173,189,193,198,204,210,217,247,288,332,335,344,384,396,413,446,461,497,593,723,824,831,839,848,875,896,938,997,1027,1029,1036 'light':659 'light/dark':1085 'limit':484,542,1136 'link':416,626,632,1089 'local':1153 'locat':104,155,168,179,242,253,283,294,327,350,367,379,390,452,469,503,554,706,719,729,830,845,881,902,944,1021,1042,1138 'logo':672 'm':885,906 'make':965 'map':439 'mark':612,657,664,1079 'markurl':615,644 'measur':192,1148 'measurement.formatted':1151 'membership':113,1066 'minim':430 'minut':480,490,505,536,746,854,857,873,876,883,887,897,904,908,910,975,1104,1129 'minuteforecast':498,506 'mistak':60,63,753 'multipl':458 'name':203,695 'need':428,804,1094 'next':494,539 'next-hour':538 'nil':508,860,894,1109,1117 'nslocationwheninuseusagedescript':98 'object':159 'observ':521 'omit':761 'one':441 'option':1108 'page':631,680,1088 'pass':1142 'pattern':1156 'perform':988 'permiss':1139 'placehold':624 'portal':95,958,1061 'precipit':310,487,541 'print':221,262,303,307,403,406,409 'privat':598,642,1010,1014 'process':393 'program':112,1065 'project':72 'properti':651,652 'provid':694 'queri':51,54,422,512,514,809 'quota':814,985 'rang':314,320 'reason':1124 'refer':69,70,1154 'references/weatherkit-patterns.md':1163,1164 'region':374,410,485,543,751,863,891,916,1112,1135 'region-limit':1134 'reject':773 'repeat':966 'request':315,967,1140 'requir':24,107,557,568,1067 'resiz':619 'respons':434,980,1120 'result':184 'return':156,180,227,254,268,295,357,391,486,515,577,859,1034,1049 'review':64,67,772,1051 'review-checklist':66 'risk':770 'runtim':931 'safe':138,739 'scaledtofit':620 'scheme':1083 'second':978 'secondari':641 'select':50,53,421 'selective-queri':52 'sendabl':134 'servic':122,132,768,1145 'servicenam':691 'setup':34,35,71 'sever':370,407 'sf':201 'share':125 'ship':756 'show':776 'sign':951 'singl':443 'singleton':126 'size':435 'skill':4,5 'sosumi.ai':1168,1172,1176,1180,1184,1188,1192,1196,1200,1204,1212 'sosumi.ai/documentation/weatherkit)':1167 'sosumi.ai/documentation/weatherkit/currentweather)':1183 'sosumi.ai/documentation/weatherkit/dayweather)':1195 'sosumi.ai/documentation/weatherkit/fetching_weather_forecasts_with_weatherkit)':1211 'sosumi.ai/documentation/weatherkit/forecast)':1187 'sosumi.ai/documentation/weatherkit/hourweather)':1191 'sosumi.ai/documentation/weatherkit/weatheralert)':1199 'sosumi.ai/documentation/weatherkit/weatherattribution)':1175 'sosumi.ai/documentation/weatherkit/weatheravailability)':1203 'sosumi.ai/documentation/weatherkit/weatherquery)':1179 'sosumi.ai/documentation/weatherkit/weatherservice)':1171 'sourc':635 'source-dpearson2699' 'space':606 'specif':318,733 'speed':214 'squar':669 'squaremarkurl':668 'stale':1006,1125 'start':231,272 'startdat':333,343,353,354 'statist':20,1162 'stay':982 'struct':590 'summari':371 'sunni':784,792 'swift':2,29,115,139,164,238,279,323,375,445,460,496,571,585,715,774,820,868,932,989 'swiftui':584,587,1157 'symbol':199,202 'target':28 'task':996 'temp':190,832,849 'temp.formatted':223 'temperatur':1146 'term':766 'text':682,782,790 'thread':137 'thread-saf':136 'throw':171,245,286,330,382,575,722,929,945,1024 'today':535 'tri':175,249,290,346,386,448,465,499,578,725,826,841,877,898,940,999,1038 'type':438,513,516 'unavail':510,856 'unnecessari':1103 'unsupport':862,890,1111 'unwrap':866,872 'updat':972 'url':614,645,674 'usag':432 'use':21,102,123,182,321,559,653,1080 'uvindex':218,220 'valu':340 'var':599,601,643,1011,1015 'variant':1084 'view':592,604,687,994 'violat':763 'vstack':605,781,789 'weather':16,26,38,42,45,48,149,158,174,248,289,359,363,385,547,611,633,656,663,671,692,699,759,777,825,939,970,998,1071,1075,1100,1113,1207 'weather-alert':47 'weather.currentweather':181 'weather.currentweather.temperature':833 'weather.dailyforecast':296 'weather.hourlyforecast':255 'weather.weatheralerts':392 'weatheralert':383,398,545,1198 'weatherattribut':576,595,1174 'weatherattributionview':591,793 'weatheravail':550,1130,1202 'weathercach':1009 'weathercondit':196 'weatherkit':1,8,77,86,106,117,560,589,765,921,935,948,1053,1069,1165,1210 'weatherqueri':322,437,1095,1178 'weatherservic':22,141,145,146,927,1170 'weatherservice.attribution':580 'weatherservice.shared':142 'weatherservice.shared.weather':1040 'weatherservice.weather':177,251,292,348,388,450,467,501,727,828,843,879,900,942 'web':679,686 'wherev':1074 'wind':211,213 'within':983 'without':757,779,923,968 'wrong':775,821,869,933,990 'xcode':80,950,1057","prices":[{"id":"baf5cc03-180c-4c4e-8d86-7ca50b7bb493","listingId":"0240db32-fc06-4e66-b94d-46104bd845ab","amountUsd":"0","unit":"free","nativeCurrency":null,"nativeAmount":null,"chain":null,"payTo":null,"paymentMethod":"skill-free","isPrimary":true,"details":{"org":"dpearson2699","category":"swift-ios-skills","install_from":"skills.sh"},"createdAt":"2026-04-18T20:34:34.584Z"}],"sources":[{"listingId":"0240db32-fc06-4e66-b94d-46104bd845ab","source":"github","sourceId":"dpearson2699/swift-ios-skills/weatherkit","sourceUrl":"https://github.com/dpearson2699/swift-ios-skills/tree/main/skills/weatherkit","isPrimary":false,"firstSeenAt":"2026-04-18T22:01:31.666Z","lastSeenAt":"2026-04-22T00:53:46.022Z"},{"listingId":"0240db32-fc06-4e66-b94d-46104bd845ab","source":"skills_sh","sourceId":"dpearson2699/swift-ios-skills/weatherkit","sourceUrl":"https://skills.sh/dpearson2699/swift-ios-skills/weatherkit","isPrimary":true,"firstSeenAt":"2026-04-18T20:34:34.584Z","lastSeenAt":"2026-04-22T03:40:33.669Z"}],"details":{"listingId":"0240db32-fc06-4e66-b94d-46104bd845ab","quickStartSnippet":null,"exampleRequest":null,"exampleResponse":null,"schema":null,"openapiUrl":null,"agentsTxtUrl":null,"citations":[],"useCases":[],"bestFor":[],"notFor":[],"kindDetails":{"org":"dpearson2699","slug":"weatherkit","source":"skills_sh","category":"swift-ios-skills","skills_sh_url":"https://skills.sh/dpearson2699/swift-ios-skills/weatherkit"},"updatedAt":"2026-04-22T03:40:33.669Z"}}