### Install SwiftMETAR using Swift Package Manager Source: https://github.com/riscfuture/swiftmetar/blob/main/README.md This snippet shows how to add the SwiftMETAR library as a dependency in your Swift Package Manager project. It ensures you can utilize the library's parsing capabilities in your Swift applications. ```swift dependencies: [ .package(url: "https://github.com/RISCfuture/SwiftMETAR/", .branch("main")), ] ``` -------------------------------- ### Parse METAR Remarks in Swift Source: https://context7.com/riscfuture/swiftmetar/llms.txt Provides examples of parsing detailed supplementary information from the remarks section of a METAR report using SwiftMETAR. This includes accessing sea-level pressure, exact temperature/dewpoint, weather events, lightning, wind shifts, and more. ```swift import SwiftMETAR let metar = try await METAR.from(string: "METAR KORD 011955Z 27015KT 10SM SCT025 24/18 A2998 RMK AO2 SLP132 T02440183 TSNO") for entry in metar.remarks { let urgency = entry.urgency // .routine, .caution, .urgent, or .unknown switch entry.remark { case .observationType(let type, let augmented): print("Station type: \(type)") // AO1 or AO2 if augmented { print("Human augmented") } case .seaLevelPressure(let pressure): if let p = pressure { print("Sea level pressure: \(p) hPa") // 1013.2 } case .temperatureDewpoint(let temp, let dewpoint): print("Exact temp: \(temp)°C") // 24.4 if let dp = dewpoint { print("Exact dewpoint: \(dp)°C") // 18.3 } case .hourlyPrecipitationAmount(let amount): print("Hourly precip: \(amount) inches") case .lightning(let frequency, let types, let proximity, let directions): print("Lightning detected!") if let freq = frequency { print(" Frequency: \(freq)") // .occasional, .frequent, .constant } case .peakWinds(let wind, let time): print("Peak winds: \(wind) at \(time)") case .windShift(let time, let frontalPassage): print("Wind shift at \(time)") if frontalPassage { print(" Due to frontal passage") } case .tornadicActivity(let type, let begin, let end, let location, let moving): print("TORNADO WARNING: \(type) at \(location)") case .pressureTendency(let character, let change): print("Pressure \(character): \(change) hPa") case .unknown(let text): print("Unparsed remark: \(text)") default: break } } ``` -------------------------------- ### Format METAR Winds using String Interpolation (Swift) Source: https://github.com/riscfuture/swiftmetar/blob/main/Sources/METARFormatting/Documentation.docc/Usage.md Demonstrates how to format wind data from a METAR object using String(localized:) with the .wind() formatter. This method allows for locale-aware formatting directly within string interpolations. It shows basic usage and an example with custom speed formatting. ```swift func printWinds(metar: METAR) -> String { return String(localized: "Winds are \(metar.wind, format: .wind())") } ``` ```swift func printWinds(metar: METAR) -> String { return String(localized: "Winds are \(metar.wind, format: .wind(speedFormat: .measurement(width: .narrow)))") } ``` -------------------------------- ### Parse TAF Forecasts from String Source: https://context7.com/riscfuture/swiftmetar/llms.txt Demonstrates how to initialize a TAF object from a raw string and iterate through its forecast groups to access period types, wind, visibility, and sky conditions. ```swift import SwiftMETAR let tafString = """ TAF KPIR 111140Z 1112/1212 13012KT P6SM BKN100 WS020/35035KT TEMPO 1112/1114 5SM BR FM111500 16015G25KT P6SM SCT040 BKN250 FM120000 14012KT P6SM BKN080 OVC150 PROB30 1200/1204 3SM TSRA BKN030CB FM120400 14008KT P6SM SCT040 OVC080 TEMPO 1204/1208 3SM TSRA OVC030CB """ let taf = try await TAF.from(string: tafString) for group in taf.groups { switch group.period { case .range(let period): print("Valid: \(period.start) to \(period.end)") case .from(let date): print("From: \(date)") case .temporary(let period): print("TEMPO: \(period.start) to \(period.end)") case .becoming(let period): print("BECMG: \(period.start) to \(period.end)") case .probability(let prob, let period): print("PROB\(prob): \(period.start) to \(period.end)") } } ``` -------------------------------- ### Generate METARFormatting Documentation Source: https://github.com/riscfuture/swiftmetar/blob/main/README.md Generates DocC documentation specifically for the METARFormatting module within the SwiftMETAR project. This allows for detailed API exploration of formatting capabilities. ```sh swift package generate-documentation --target METARFormatting ``` -------------------------------- ### Remark Module Overview Source: https://github.com/riscfuture/swiftmetar/blob/main/Sources/SwiftMETAR/Documentation.docc/Remark.md Overview of the associated types and data structures available in the SwiftMETAR Remark module. ```APIDOC ## Remark Module Overview ### Description The Remark module provides the necessary data structures to parse and represent meteorological remarks found in METAR reports. ### Associated Types - **RemarkEntry** (Struct) - Represents a single parsed remark entry. - **Location** (Enum/Struct) - Defines the geographic context or station location associated with the remark. - **PrecipitationEvent** (Struct) - Details regarding specific precipitation occurrences. - **ThunderstormEvent** (Struct) - Details regarding thunderstorm activity and intensity. ### Usage These types are utilized by the SwiftMETAR parser to convert raw string data into structured Swift objects for further analysis. ``` -------------------------------- ### Parse and Query Winds Aloft Data in Swift Source: https://github.com/riscfuture/swiftmetar/blob/main/Sources/SwiftMETAR/Documentation.docc/WindsAloft.md Demonstrates how to initialize a WindsAloft object from a raw string and iterate through station data to extract wind and temperature information for a specific altitude. The code handles both light-and-variable wind conditions and standard wind/temperature entries. ```swift let product = try await WindsAloft.from(string: rawText) for station in product.stations { if let entry = station[12000] { switch entry { case .lightAndVariable: print("\(station.id): light and variable at 12,000 ft") case let .wind(direction, speed, temperature): print("\(station.id): \(direction)° at \(speed) kt") } } } ``` -------------------------------- ### Format METAR Winds Directly or Fluently (Swift) Source: https://github.com/riscfuture/swiftmetar/blob/main/Sources/METARFormatting/Documentation.docc/Usage.md Illustrates alternative ways to format METAR wind data in Swift. It shows using a formatter instance directly and a fluent-style interface for more concise formatting. These methods are useful when String(localized:) interpolation is not needed or preferred. ```swift let formatter = Wind.FormatStyle() formatter.format(metar.wind) ``` ```swift func printWinds(metar: METAR) -> String { return String(localized: "Winds are \(metar.wind, format: .wind.speedFormat(.measurement(width: .narrow)))") } ``` -------------------------------- ### Decode Winds Aloft using Command-Line Tool Source: https://github.com/riscfuture/swiftmetar/blob/main/README.md Leverages the DecodeWindsAloft command-line tool to decode winds aloft data into a human-readable format. This tool is part of the SwiftMETAR project for analyzing upper-air wind information. ```sh swift run DecodeWindsAloft ``` -------------------------------- ### Generate SwiftMETAR Documentation Source: https://github.com/riscfuture/swiftmetar/blob/main/README.md Generates DocC documentation for the SwiftMETAR library. This can be opened in Xcode for browseable API documentation and tutorials. ```sh swift package generate-documentation --target SwiftMETAR ``` -------------------------------- ### Parse Altimeter Settings in Swift Source: https://context7.com/riscfuture/swiftmetar/llms.txt Demonstrates how to parse altimeter pressure settings from METAR reports in both inches of mercury (inHg) and hectopascals (hPa/QNH) using SwiftMETAR. It shows how to access the raw values and convert them using the `measurement` property. ```swift import SwiftMETAR // US METAR with inHg altimeter let usMetar = try await METAR.from(string: "METAR KLAX 011955Z 25010KT 10SM CLR 22/12 A2992") if let altimeter = usMetar.altimeter { switch altimeter { case .inHg(let value): let pressure = Float(value) / 100.0 print("Altimeter: \(pressure) inHg") // 29.92 inHg case .hPa(let value): print("QNH: \(value) hPa") } // Use measurement for conversion print("Pressure: \(altimeter.measurement.converted(to: .millibars))") } // International METAR with QNH let intlMetar = try await METAR.from(string: "METAR EGLL 011955Z 27015KT 9999 FEW040 18/10 Q1013") if let altimeter = intlMetar.altimeter { print("QNH: \(altimeter.measurement)") // 1013 hPa } ``` -------------------------------- ### Parse Weather Phenomena with SwiftMETAR Source: https://context7.com/riscfuture/swiftmetar/llms.txt Explains how to extract weather phenomena, intensity, and descriptors from a METAR report. This includes detecting precipitation, obscurations, and critical events like tornadoes. ```swift import SwiftMETAR let metar = try await METAR.from(string: "METAR KMIA 011955Z 09012KT 2SM +TSRA BR FEW015CB SCT025 BKN040 27/25 A2985") if let weather = metar.weather { for wx in weather { switch wx.intensity { case .light: print("Light ", terminator: "") case .moderate: print("Moderate ", terminator: "") case .heavy: print("Heavy ", terminator: "") case .vicinity, .vicinityLight, .vicinityHeavy: print("In vicinity: ", terminator: "") } if let descriptor = wx.descriptor { switch descriptor { case .thunderstorms: print("thunderstorm ", terminator: "") case .freezing: print("freezing ", terminator: "") case .showering: print("showering ", terminator: "") case .blowing: print("blowing ", terminator: "") case .lowDrifting: print("low drifting ", terminator: "") case .shallow: print("shallow ", terminator: "") case .partial: print("partial ", terminator: "") case .patchy: print("patchy ", terminator: "") } } for phenomenon in wx.phenomena { switch phenomenon { case .rain: print("rain") case .snow: print("snow") case .drizzle: print("drizzle") case .fog: print("fog") case .mist: print("mist") case .haze: print("haze") case .hail: print("hail") case .thunderstorm: print("thunderstorm") case .funnelCloud: print("funnel cloud") default: print("\(phenomenon)") } } if wx.isTornado { print("WARNING: Tornado reported!") } } } ``` -------------------------------- ### Add SwiftMETAR dependency to Package.swift Source: https://github.com/riscfuture/swiftmetar/blob/main/Sources/SwiftMETAR/Documentation.docc/Documentation.md This snippet demonstrates how to include the SwiftMETAR library as a dependency in a Swift Package Manager project configuration file. ```swift dependencies: [ .package(url: "https://github.com/RISCfuture/SwiftMETAR/", .branch("main")), ] ``` -------------------------------- ### Parse Visibility Values with SwiftMETAR Source: https://context7.com/riscfuture/swiftmetar/llms.txt Demonstrates how to parse visibility from a METAR string and handle different units like statute miles, meters, and feet. It includes logic for variable visibility conditions and unit conversion. ```swift import SwiftMETAR let metar = try await METAR.from(string: "METAR KJFK 011955Z 18010KT 3/4SM +TSRA OVC010 22/21 A2980") if let visibility = metar.visibility { switch visibility { case .equal(let value): switch value { case .statuteMiles(let ratio): print("Visibility: \(ratio) SM") case .statuteMilesDecimal(let miles): print("Visibility: \(miles) SM") case .meters(let m): print("Visibility: \(m) meters") case .feet(let ft): print("Visibility: \(ft) feet") } print("Visibility: \(value.measurement.converted(to: .kilometers))") case .lessThan(let value): print("Visibility less than \(value.measurement)") case .greaterThan(let value): print("Visibility greater than \(value.measurement)") case .variable(let low, let high): print("Visibility variable between \(low) and \(high)") case .notRecorded: print("Visibility not recorded") } } ``` -------------------------------- ### Parsing Sky Conditions Source: https://context7.com/riscfuture/swiftmetar/llms.txt Explains how to parse cloud layers, coverage amounts, and ceiling types from METAR reports. ```APIDOC ## Parsing Sky Conditions ### Description Iterates through sky conditions to identify cloud coverage (Few, Scattered, Broken, Overcast) and specific cloud types like Cumulonimbus. ### Method METAR.from(string: String) ### Response - **conditions** (array) - A collection of cloud layer objects. ### Response Example { "conditions": [ { "coverage": "broken", "height": 4000, "unit": "ft" } ] } ``` -------------------------------- ### POST /winds-aloft/parse Source: https://github.com/riscfuture/swiftmetar/blob/main/Sources/SwiftMETAR/Documentation.docc/WindsAloft.md Parses a raw NWS Winds and Temperatures Aloft string into a structured WindsAloft object. ```APIDOC ## POST /winds-aloft/parse ### Description Parses a raw fixed-width string containing NWS Winds and Temperatures Aloft data into a structured format. ### Method POST ### Endpoint /winds-aloft/parse ### Parameters #### Request Body - **rawText** (string) - Required - The raw fixed-width text product from the NWS. ### Request Example { "rawText": "KORD 12000 3209+02..." } ### Response #### Success Response (200) - **stations** (array) - List of parsed station data. - **header** (object) - Metadata regarding the product issuance. #### Response Example { "stations": [ { "id": "KORD", "entries": { "12000": { "direction": 320, "speed": 9, "temperature": 2 } } } ] } ``` -------------------------------- ### Parse Sky Conditions with SwiftMETAR Source: https://context7.com/riscfuture/swiftmetar/llms.txt Shows how to iterate through cloud layers and ceiling information. It handles various coverage types (few, scattered, broken, overcast) and identifies specific cloud types like cumulonimbus. ```swift import SwiftMETAR let metar = try await METAR.from(string: "METAR KORD 011955Z 27015KT 10SM SCT025 BKN040 OVC100CB 24/18 A2998") for condition in metar.conditions { switch condition { case .clear: print("Sky clear (automated)") case .skyClear: print("Sky clear (human observed)") case .noSignificantClouds: print("No significant clouds") case .cavok: print("CAVOK - Ceiling and visibility OK") case .few(let height, let type): print("Few clouds at \(height) ft AGL") if type == .cumulonimbus { print(" - Cumulonimbus") } if type == .toweringCumulus { print(" - Towering cumulus") } case .scattered(let height, let type): print("Scattered clouds at \(height) ft AGL") case .broken(let height, let type): print("Broken ceiling at \(height) ft AGL") case .overcast(let height, let type): print("Overcast at \(height) ft AGL") if let cloudType = type { print(" - Type: \(cloudType)") } case .indefinite(let ceiling): print("Vertical visibility \(ceiling) ft (obscured)") } if let measurement = condition.heightMeasurement { print("Height: \(measurement.converted(to: .meters))") } } ``` -------------------------------- ### Parsing Weather Phenomena Source: https://context7.com/riscfuture/swiftmetar/llms.txt Explains how to parse precipitation, obscurations, and weather descriptors with intensity levels. ```APIDOC ## Parsing Weather Phenomena ### Description Extracts weather phenomena including intensity, descriptors (e.g., thunderstorms, freezing), and specific precipitation types. ### Method METAR.from(string: String) ### Response - **weather** (array) - List of weather phenomena objects. ### Response Example { "weather": [ { "intensity": "heavy", "descriptor": "thunderstorms", "phenomena": ["rain"] } ] } ``` -------------------------------- ### Format METAR Data for Localized Output in Swift Source: https://context7.com/riscfuture/swiftmetar/llms.txt Utilizes the METARFormatting library for locale-aware formatting of weather data, including wind and remarks. It demonstrates how to use String interpolation with custom formatters and fluent-style interfaces for localized output, enhancing user experience. ```swift import SwiftMETAR import METARFormatting let metar = try await METAR.from(string: "METAR KSFO 011955Z 27015G25KT 10SM FEW020 22/14 A2998") // Format wind using String interpolation let windDescription = String(localized: "Winds are \(metar.wind, format: .wind())") // Customize speed format let customWind = String(localized: "Winds: \(metar.wind, format: .wind(speedFormat: .measurement(width: .narrow)))") // Use formatter directly let formatter = Wind.FormatStyle() let formattedWind = formatter.format(metar.wind) // Fluent-style interface let fluentWind = String(localized: "Winds: \(metar.wind, format: .wind.speedFormat(.measurement(width: .narrow)))") // Format remarks in plain English for remark in metar.remarks { let description = String(localized: "\(remark, format: .remark)") print(description) } ``` -------------------------------- ### Query Weather at Specific Time from TAF Source: https://context7.com/riscfuture/swiftmetar/llms.txt Shows how to use the during() method to retrieve an aggregate forecast for a specific timestamp, ensuring the time falls within the TAF's validity period. ```swift import SwiftMETAR let taf = try await TAF.from(string: "TAF KSFO\n 111200Z 1112/1212 27010KT P6SM FEW020 SCT200\n FM111800 29015G25KT P6SM SCT030 BKN100\n TEMPO 1120/1124 3SM -RA BKN020\n FM120600 VRB05KT P6SM SCT015 BKN040") let targetDate = Calendar.current.date(byAdding: .hour, value: 8, to: Date())! if taf.covers(targetDate) { if let conditions = taf.during(targetDate) { print("Forecast for \(targetDate): \(conditions)") } } ``` -------------------------------- ### Parsing Visibility Source: https://context7.com/riscfuture/swiftmetar/llms.txt Explains how to parse and interpret visibility values, including statute miles, meters, and variable conditions. ```APIDOC ## Parsing Visibility ### Description Extracts visibility data from a METAR string and handles various units (SM, meters, feet) and conditions (equal, less than, greater than, variable). ### Method METAR.from(string: String) ### Response - **visibility** (enum) - The visibility object containing the value or condition type. ### Response Example { "visibility": { "type": "equal", "value": { "unit": "statuteMiles", "ratio": "3/4" } } } ``` -------------------------------- ### Parse METAR String into Structured Data Source: https://context7.com/riscfuture/swiftmetar/llms.txt Demonstrates how to parse a raw METAR string into a METAR object and access properties like station ID, temperature, and dewpoint using Swift's Measurement API. ```swift import SwiftMETAR let metarString = "METAR KOKC 011955Z AUTO 22015G25KT 180V250 3/4SM R17L/2600FT +TSRA BR OVC010CB 18/16 A2992 RMK AO2 TSB25 TS OHD MOV E SLP132" do { let metar = try await METAR.from(string: metarString) print("Station: \(metar.stationID)") print("Issuance: \(metar.issuance)") print("Observer: \(metar.observer)") print("Date: \(metar.date)") if let temp = metar.temperature { print("Temperature: \(temp)°C") } if let dewpoint = metar.dewpoint { print("Dewpoint: \(dewpoint)°C") } if let tempMeasurement = metar.temperatureMeasurement { let fahrenheit = tempMeasurement.converted(to: .fahrenheit) print("Temperature: \(fahrenheit)") } } catch { print("Parse error: \(error)") } ``` -------------------------------- ### METAR Parsing API Source: https://github.com/riscfuture/swiftmetar/blob/main/Sources/SwiftMETAR/Documentation.docc/METAR.md Methods for initializing a METAR object from raw data strings or XML formats. ```APIDOC ## POST /METAR/from ### Description Parses a raw METAR string or XML data into a structured METAR object. ### Method POST ### Endpoint /METAR/from ### Parameters #### Request Body - **string** (String) - Optional - The raw METAR string to parse. - **xml** (Data) - Optional - The XML representation of the METAR report. - **lenientRemarks** (Bool) - Optional - Flag to enable lenient parsing of remarks. ### Request Example { "string": "KJFK 121251Z 18010KT 10SM FEW030 25/20 A3000", "lenientRemarks": true } ### Response #### Success Response (200) - **text** (String) - The original METAR text. - **stationID** (String) - The ICAO station identifier. - **wind** (Object) - Parsed wind conditions. - **temperature** (Double) - Temperature in Celsius. #### Response Example { "stationID": "KJFK", "temperature": 25.0, "wind": { "direction": 180, "speed": 10 } } ``` -------------------------------- ### Decode Winds Aloft using SwiftMETAR CLI Source: https://context7.com/riscfuture/swiftmetar/llms.txt Decodes winds aloft data from a text file using the SwiftMETAR command-line tool. This is useful for processing bulk winds aloft information. Dependencies include the Swift toolchain and a text file containing the data. ```bash # Decode winds aloft swift run decode-winds-aloft < winds_aloft.txt ``` -------------------------------- ### Parsing METAR Data Source: https://github.com/riscfuture/swiftmetar/blob/main/Sources/SwiftMETAR/Documentation.docc/Documentation.md This section describes how to parse raw METAR strings into a structured METAR object using the SwiftMETAR library. ```APIDOC ## SwiftMETAR Parsing: METAR ### Description Parses a raw METAR string into a structured `METAR` object. The library expects the input to follow standard aviation weather report formats. ### Method Library Function Call ### Parameters #### Request Body - **rawString** (String) - Required - The raw METAR text string to be parsed. ### Request Example let rawMETAR = "KJFK 121851Z 27012G20KT 10SM FEW040 BKN060 22/16 A2992" ### Response #### Success Response (Object) - **station** (String) - The ICAO station identifier. - **time** (Date) - The observation time. - **wind** (Wind) - Structured wind speed and direction data. - **visibility** (Measurement) - Visibility distance. - **clouds** ([Cloud]) - Array of cloud layers. - **temperature** (Measurement) - Ambient temperature. - **dewPoint** (Measurement) - Dew point temperature. - **altimeter** (Measurement) - Altimeter setting. ``` -------------------------------- ### Decode METARs using Command-Line Tool Source: https://github.com/riscfuture/swiftmetar/blob/main/README.md Utilizes the DecodeMETAR command-line tool to convert METAR weather reports into a human-readable text format. This tool is part of the SwiftMETAR project for easy data interpretation. ```sh swift run DecodeMETAR ``` -------------------------------- ### Extract and Handle Wind Data Source: https://context7.com/riscfuture/swiftmetar/llms.txt Shows how to process wind information from a parsed METAR object, including handling calm conditions, variable winds, and specific wind speeds with gust data. ```swift import SwiftMETAR let metar = try await METAR.from(string: "METAR KSFO 011955Z 22015G25KT 180V250 10SM FEW020 18/12 A3001") if let wind = metar.wind { switch wind { case .calm: print("Winds are calm") case .variable(let speed, let headingRange): print("Variable winds at \(speed)") if let range = headingRange { print("Varying between \(range.0)° and \(range.1)°") } case .direction(let heading, let speed, let gust): switch speed { case .knots(let value): print("Winds \(heading)° at \(value) knots") case .kph(let value): print("Winds \(heading)° at \(value) km/h") case .mps(let value): print("Winds \(heading)° at \(value) m/s") } if let gust = gust { print("Gusting to \(gust.measurement)") } case .directionRange(let heading, let range, let speed, let gust): print("Winds \(heading)° (varying \(range.0)°-\(range.1)°) at \(speed.measurement)") } } ``` -------------------------------- ### POST /weather/parse-string Source: https://context7.com/riscfuture/swiftmetar/llms.txt Parses individual METAR or TAF strings with support for reference dates and lenient remarks. ```APIDOC ## POST /weather/parse-string ### Description Parses individual weather reports. Supports providing a reference date for month/year context and enabling lenient parsing for international remarks. ### Method POST ### Endpoint /weather/parse-string ### Request Body - **string** (string) - Required - The raw METAR or TAF string. - **referenceDate** (date) - Optional - Date object to provide context for day-hour-minute timestamps. - **lenientRemarks** (boolean) - Optional - If true, parses remarks without the standard 'RMK' prefix. ### Request Example { "string": "METAR KSFO 151955Z...", "referenceDate": "2024-06-01T00:00:00Z", "lenientRemarks": true } ### Response #### Success Response (200) - **data** (object) - The parsed METAR or TAF object. ``` -------------------------------- ### Decode TAFs using Command-Line Tool Source: https://github.com/riscfuture/swiftmetar/blob/main/README.md Employs the DecodeTAF command-line tool to parse TAF (Terminal Aerodrome Forecast) weather data and present it in an easily understandable text format. This is a utility provided by the SwiftMETAR project. ```sh swift run DecodeTAF ``` -------------------------------- ### POST /weather/parse-xml Source: https://context7.com/riscfuture/swiftmetar/llms.txt Parses bulk aviation weather XML files for batch processing of METAR or TAF data. ```APIDOC ## POST /weather/parse-xml ### Description Parses aviationweather.gov bulk cache XML files for efficient batch processing of METARs or TAFs. ### Method POST ### Endpoint /weather/parse-xml ### Request Body - **xmlData** (binary) - Required - The XML content from aviationweather.gov. - **type** (string) - Required - The type of data to parse ('METAR' or 'TAF'). ### Request Example { "type": "METAR", "xmlData": "..." } ### Response #### Success Response (200) - **results** (array) - An asynchronous stream of parsed weather objects or error results. ``` -------------------------------- ### Use Reference Dates for Parsing in Swift Source: https://context7.com/riscfuture/swiftmetar/llms.txt Provides a reference date when parsing aviation weather products where the month and year context is crucial, such as for METARs and TAFs which typically only include day and time. This ensures accurate date interpretation for reports. ```swift import SwiftMETAR // METARs only include day-hour-minute, not month/year // Use a reference date to provide context let referenceDate = Calendar.current.date(from: DateComponents(year: 2024, month: 6))! let metar = try await METAR.from( string: "METAR KSFO 151955Z 27015KT 10SM FEW020 22/14 A2998", on: referenceDate ) // Now metar.date will be in June 2024 print("Date: \(metar.date)") // June 15, 2024 19:55Z // Same for TAFs let taf = try await TAF.from( string: "TAF KSFO 151200Z 1512/1612 27010KT P6SM SCT020", on: referenceDate ) print("Origin: \(taf.originDate ?? Date())") // June 15, 2024 12:00Z ``` -------------------------------- ### Parse METAR from String in Swift Source: https://github.com/riscfuture/swiftmetar/blob/main/README.md Demonstrates how to parse a METAR report provided as a raw string into a Swift METAR object. This method allows programmatic access to weather details like wind speed and direction. Error handling is included via Swift's `try await`. ```swift let observation = try await METAR.from(string: myString) if let winds = observation.winds { switch winds { case let .direction(heading, speed, gust): switch speed { case let .knots(value): print("Winds are \(heading) at \(speed) knots") } } } ``` -------------------------------- ### Format METAR Remarks (Swift) Source: https://github.com/riscfuture/swiftmetar/blob/main/Sources/METARFormatting/Documentation.docc/Usage.md Shows how to format remarks from a METAR object in Swift using the .remark formatter. This is typically used within SwiftUI views to display remarks in plain English, often within a ForEach loop. ```swift ForEach(metar.remarks) { remark in Text(remark, format: .remark) } ``` -------------------------------- ### Parse METAR from XML Data in Swift Source: https://github.com/riscfuture/swiftmetar/blob/main/README.md Illustrates parsing METAR data from XML format, typically obtained from sources like aviationweather.gov. This approach is suitable for bulk loading weather data and iterates through observations. Note that XML parsing may not include remarks or RVR data. ```swift let data = // XML data from aviationweather.gov for await observation in METAR.from(xml: data) { print("\(observation.stationID): \(observation.wind)") } ``` -------------------------------- ### Parsing TAF Data Source: https://github.com/riscfuture/swiftmetar/blob/main/Sources/SwiftMETAR/Documentation.docc/Documentation.md This section describes how to parse Terminal Aerodrome Forecasts (TAF) into structured objects. ```APIDOC ## SwiftMETAR Parsing: TAF ### Description Parses a raw TAF string into a `TAF` object, providing point forecasts for expected weather conditions at an airport. ### Method Library Function Call ### Parameters #### Request Body - **rawString** (String) - Required - The raw TAF text string to be parsed. ### Request Example let rawTAF = "TAF KJFK 121720Z 1218/1324 28015KT P6SM FEW050 FM122200 26012KT P6SM SCT050" ### Response #### Success Response (Object) - **station** (String) - The ICAO station identifier. - **forecasts** ([Forecast]) - A collection of forecast periods and associated weather conditions. ``` -------------------------------- ### Decode METAR using SwiftMETAR CLI Source: https://context7.com/riscfuture/swiftmetar/llms.txt Decodes a METAR (Meteorological Aerodrome Report) string using the SwiftMETAR command-line tool. It can optionally include remarks or raw text in the output. Dependencies include the Swift toolchain. ```bash # Decode a METAR swift run decode-metar "METAR KSFO 011955Z 27015KT 10SM FEW020 22/14 A2998" # Include remarks in output swift run decode-metar --remarks "METAR KSFO 011955Z 27015KT 10SM FEW020 22/14 A2998 RMK AO2 SLP132" # Include raw text in output swift run decode-metar --raw "METAR KSFO 011955Z 27015KT 10SM FEW020 22/14 A2998" ``` -------------------------------- ### Parse AviationWeather.gov XML Bulk Data in Swift Source: https://context7.com/riscfuture/swiftmetar/llms.txt Parses aviationweather.gov bulk cache XML files for efficient batch processing of METAR and TAF data. It uses an AsyncStream to handle results, allowing for asynchronous iteration over parsed weather reports. This method is suitable for bulk data ingestion and processing. ```swift import SwiftMETAR // Load XML data from aviationweather.gov cache file let xmlData = try Data(contentsOf: URL(fileURLWithPath: "metars.cache.xml")) // Parse returns an AsyncStream of Results for await result in METAR.from(xml: xmlData) { switch result { case .success(let metar): print("\(metar.stationID): \(metar.wind ?? .calm)") print(" Temp: \(metar.temperature ?? 0)°C") print(" Visibility: \(metar.visibility ?? .notRecorded)") case .failure(let error): print("Parse error: \(error)") } } // Same pattern works for TAFs let tafXmlData = try Data(contentsOf: URL(fileURLWithPath: "tafs.cache.xml")) for await result in TAF.from(xml: tafXmlData) { switch result { case .success(let taf): print("\(taf.airportID): \(taf.groups.count) groups") case .failure(let error): print("Parse error: \(error)") } } ``` -------------------------------- ### Parse METAR XML Data with SwiftMETAR Source: https://github.com/riscfuture/swiftmetar/blob/main/Sources/SwiftMETAR/Documentation.docc/GettingStarted.md Parses METAR data directly from XML content, typically from bulk cache files. It returns an AsyncStream of Results, allowing for individual error handling during parsing. This method is efficient for bulk data but does not populate remarks or runway visual range. ```swift let data = try Data(contentsOf: metarsCacheURL) for await result in METAR.from(xml: data) { switch result { case .success(let observation): print("\(observation.stationID): \(observation.wind)") case .failure(let error): print("Parse error: \(error)") } } ``` -------------------------------- ### Lenient Remarks Parsing for International METARs in Swift Source: https://context7.com/riscfuture/swiftmetar/llms.txt Enables lenient parsing mode for METARs, particularly useful for non-US reports that may omit the standard 'RMK' prefix for remarks. This allows the library to correctly parse remarks even without the expected prefix, improving compatibility with international data. ```swift import SwiftMETAR // Some international METARs don't use the standard RMK prefix let internationalMetar = "METAR EGLL 011955Z 27015KT 9999 FEW040 18/10 Q1013 NOSIG" // Enable lenient remarks parsing let metar = try await METAR.from( string: internationalMetar, lenientRemarks: true ) // Check for NOSIG remark for entry in metar.remarks { if case .nosig = entry.remark { print("No significant weather changes expected") } } ``` -------------------------------- ### METAR Properties Access Source: https://github.com/riscfuture/swiftmetar/blob/main/Sources/SwiftMETAR/Documentation.docc/METAR.md Accessors for meteorological conditions and station metadata. ```APIDOC ## GET /METAR/properties ### Description Retrieves specific meteorological properties from a parsed METAR object. ### Method GET ### Endpoint /METAR/properties ### Parameters #### Query Parameters - **property** (String) - Required - The specific property to retrieve (e.g., 'wind', 'visibility', 'altimeter'). ### Response #### Success Response (200) - **value** (Any) - The value associated with the requested property. #### Response Example { "property": "altimeter", "value": 30.00 } ``` -------------------------------- ### Parse Runway Visual Range in Swift Source: https://context7.com/riscfuture/swiftmetar/llms.txt Shows how to parse runway-specific visibility reports (RVR) from METAR data using SwiftMETAR. It iterates through reported RVR values, handling cases for equal, variable, less than, and greater than visibility. ```swift import SwiftMETAR let metar = try await METAR.from(string: "METAR KJFK 011955Z 04008KT 1/4SM R04R/2000V3000FT FG VV002 12/12 A3010") for rvr in metar.runwayVisibility { print("Runway \(rvr.runwayID):") // "04R" switch rvr.visibility { case .equal(let value): print(" RVR: \(value.measurement)") case .variable(let low, let high): print(" RVR variable: \(low) to \(high)") case .lessThan(let value): print(" RVR less than \(value.measurement)") case .greaterThan(let value): print(" RVR greater than \(value.measurement)") default: break } } ``` -------------------------------- ### Decode TAF using SwiftMETAR CLI Source: https://context7.com/riscfuture/swiftmetar/llms.txt Decodes a TAF (Terminal Aerodrome Forecast) string using the SwiftMETAR command-line tool. This tool is useful for interpreting aviation forecast data. Dependencies include the Swift toolchain. ```bash # Decode a TAF swift run decode-taf "TAF KSFO 011200Z 0112/0212 27010KT P6SM SCT020" ``` -------------------------------- ### Parse METAR String with SwiftMETAR Source: https://github.com/riscfuture/swiftmetar/blob/main/Sources/SwiftMETAR/Documentation.docc/GettingStarted.md Parses a METAR observation from a string format. It returns a struct containing weather information that can be queried. This method is comprehensive, including remarks and runway visual range. ```swift let observation = try await METAR.from(string: myString) if let winds = observation.winds { switch winds { case let .direction(heading, speed, gust): switch speed { case let .knots(value): print("Winds are \(heading) at \(speed) knots") // [...] } // [...] } } ``` -------------------------------- ### Parse TAF String with SwiftMETAR Source: https://github.com/riscfuture/swiftmetar/blob/main/Sources/SwiftMETAR/Documentation.docc/GettingStarted.md Parses a TAF (Terminal Aerodrome Forecast) from a string format. It returns a forecast struct that can be iterated to access periods and altimeter information. This method provides structured access to forecast data. ```swift let forecast = try await TAF.from(string: myString) for group in forecast.groups { switch group.period { case let .from(from): let date = Calendar.current.date(from: from) print("From \(date): ", terminator: "") // [...] } switch group.altimeter { case let .inHg(value): print("\(Float(value)/100) inHg") // [...] } } ``` -------------------------------- ### Parse NWS Winds Aloft Forecasts in Swift Source: https://context7.com/riscfuture/swiftmetar/llms.txt Parses National Weather Service (NWS) winds and temperatures aloft forecasts from a given text string. It extracts header information, altitudes, and detailed wind data for multiple stations and altitudes. This functionality is useful for applications needing to display or process upper-air wind data. ```swift import SwiftMETAR let windsAloftText = """FBUS31 KWNO 121200 FD1US1 BASED ON 121200Z DATA VALID 121800Z FOR USE 1400-2100Z TEMPS NEG ABV 24000 FT 3000 6000 9000 12000 18000 24000 30000 34000 39000 ABI 2714 2725+10 2625+05 2531-08 2542-19 265931 256442 256652 """ let windsAloft = try await WindsAloft.from(string: windsAloftText) // Access header information print("Product: \(windsAloft.header.productID)") // FBUS31 print("Office: \(windsAloft.header.issuingOffice)") // KWNO print("Level: \(windsAloft.level)") // .low or .high print("Valid at: \(windsAloft.validAt)") print("Altitudes: \(windsAloft.altitudes)") // [3000, 6000, 9000, ...] // Iterate through stations for station in windsAloft.stations { print("Station: \(station.id)") // "ABI" for entry in station.entries { print(" \(entry.altitude) ft:") switch entry.data { case .lightAndVariable: print(" Light and variable") case .wind(let direction, let speed, let temperature): print(" Direction: \(direction)°") print(" Speed: \(speed.measurement)") if let temp = temperature { print(" Temperature: \(temp)°C") } } } // Quick lookup by altitude if let data = station[12000] { print("At 12000 ft: \(data)") } } ``` -------------------------------- ### Parse Military TAF Icing and Turbulence Source: https://context7.com/riscfuture/swiftmetar/llms.txt Extracts specialized icing and turbulence data from military TAF reports, including intensity, base/top altitudes, and specific weather phenomena types. ```swift import SwiftMETAR let taf = try await TAF.from(string: "TAF KNID\n 2523/2623 VRB05KT 9999 SCT270 QNH2975INS\n BECMG 2617/2619 19012G24KT 9999 SCT250 510009 510909 QNH2983INS\n BECMG 2620/2622 21020G32KT 9999 BKN250 520009 520909 QNH2977INS") for group in taf.groups { for icing in group.icing { print("Icing Type: \(icing.type)") } for turbulence in group.turbulence { print("Turbulence Intensity: \(turbulence.intensity)") } } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.