Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/jagreenwood/open-weather-kit
An open implementation of Apple's WeatherKit for Swift.
https://github.com/jagreenwood/open-weather-kit
async-await swift swift-package-manager weather
Last synced: 3 months ago
JSON representation
An open implementation of Apple's WeatherKit for Swift.
- Host: GitHub
- URL: https://github.com/jagreenwood/open-weather-kit
- Owner: jagreenwood
- License: mit
- Created: 2022-09-06T13:06:02.000Z (about 2 years ago)
- Default Branch: main
- Last Pushed: 2024-01-26T14:28:47.000Z (10 months ago)
- Last Synced: 2024-07-05T02:09:04.068Z (4 months ago)
- Topics: async-await, swift, swift-package-manager, weather
- Language: Swift
- Homepage:
- Size: 136 KB
- Stars: 21
- Watchers: 3
- Forks: 5
- Open Issues: 2
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# OpenWeatherKit
[![Linux](https://github.com/jagreenwood/OpenWeatherKit/actions/workflows/swift-ubuntu.yml/badge.svg)](https://github.com/jagreenwood/OpenWeatherKit/actions?query=workflow%3Aswift-linux)
[![macOS](https://github.com/jagreenwood/OpenWeatherKit/actions/workflows/swift-macos.yml/badge.svg)](https://github.com/jagreenwood/OpenWeatherKit/actions?query=workflow%3Aswift-macos)
[![](https://img.shields.io/endpoint?url=https%3A%2F%2Fswiftpackageindex.com%2Fapi%2Fpackages%2Fjagreenwood%2Fopen-weather-kit%2Fbadge%3Ftype%3Dswift-versions)](https://swiftpackageindex.com/jagreenwood/open-weather-kit)
[![](https://img.shields.io/endpoint?url=https%3A%2F%2Fswiftpackageindex.com%2Fapi%2Fpackages%2Fjagreenwood%2Fopen-weather-kit%2Fbadge%3Ftype%3Dplatforms)](https://swiftpackageindex.com/jagreenwood/open-weather-kit)This package is Swift wrapper around the [WeatherKit REST API](https://developer.apple.com/documentation/weatherkitrestapi).
Its intention is to bring a native Swift WeatherKit alternative to platforms Apple does not currently support. The API of this package
is nearly identical to Apple's [WeatherKit](https://developer.apple.com/documentation/weatherkit).## 💻 Supported Platforms
- iOS 13+
- watchOS 6+
- tvOS 13+
- macOS 11+
- Ubuntu 18.04+## ⚙️ Setup
The REST API requires a signed JWT to be sent with each request. To set this up you need:
- A paid developer account
- A Service Identifier
- A key### Apple Developer Portal Setup
#### App Identifier
1. Go to [Identifiers](https://developer.apple.com/account/resources/identifiers/list)
2. On the top left, click the add button (+), select Services IDs, then click Continue.
3. Register a Service ID.
4. Make note of the Identifier (you'll need it later)
5. Click Continue, review the registration information, and click Register.#### Key
1. Go to [Keys](https://developer.apple.com/account/resources/authkeys/list)
2. On the top left, click the add button (+)
3. Give your key a name, tick the "WeatherKit" box
4. Click Continue, review the registration information, and click Register.
5. Make note of the Key ID (you'll need it later)
6. Download the private key### JWT
The WeatherKit REST API requires a JSON Web Token (JWT) to be sent with every request. Implementing the
logic necessary to generate a JWT is beyond the scope of the OpenWeatherKit project at this time.
For general information on JWT please visit https://jwt.ioThat being said, the recommended package to handle this task is Vapor's [jwt-kit](https://github.com/vapor/jwt-kit). Here is how to set that up:
Implement model conforming to `JWTPayload`
```swift
import JWTKitstruct Payload: JWTPayload, Equatable {
enum CodingKeys: String, CodingKey {
case expiration = "exp"
case issued = "iat"
case issuer = "iss"
case subject = "sub"
}let expiration: ExpirationClaim
let issued: IssuedAtClaim
let issuer: IssuerClaim
let subject: SubjectClaimfunc verify(using signer: JWTKit.JWTSigner) throws {}
}
```Generate the JWT
```swift
struct JWTProvider {
static func generate() -> String {
let signers = JWTSigners()
try signers.use(.es256(key: ECDSAKey.private(pem: PRIVATE_KEY_FROM_DEV_PORTAL))let payload = Payload(
expiration: .init(value: .distantFuture),
issued: .init(value: .now),
issuer: TEAM_ID,
subject: SERVICE_IDENTIFIER
)return try! signers.sign(payload, kid: KEY_ID)
}
}
```Note the variables:
`PRIVATE_KEY_FROM_DEV_PORTAL`: The contents of the private key file including `-----BEGIN PRIVATE KEY-----` and `-----END PRIVATE KEY-----`
`TEAM_ID`: Found in Membership Details on the developer portal
`SERVICE_IDENTIFIER`: The reverse-domain name noted earlier
`KEY_ID`: The ID of the service key
## 🌤️ Usage
### Configure Service
The service must be configured with a JWT generating closure and optionally a language.
If you choose to use the `WeatherService.shared` instance, call the following before referencing `shared`:
```swift
WeatherService.configure {
$0.jwt = JWTProvider.generate
}
```### Get a Full Weather Forecast
```swift
let weather = try await WeatherService.shared
.weather(
for: Location(
latitude: 37.541290,
longitude: -77.511429),
countryCode: "US"
)
```### Get a Partial Weather Forecast
```swift
let (dailyForecast, hourlyForecast, alerts) = try await WeatherService.shared
.weather(
for: Location(
latitude: 37.541290,
longitude: -77.511429),
including: .daily, .hourly, .alerts(countryCode: "US")
)
```### Get Availability
Note that minute forecasts and alerts are not always available in all regions. Use the `.availability` query
check their availability.```swift
let availabilty = try await WeatherService.shared
.weather(
for: Location(
latitude: 37.541290,
longitude: -77.511429),
including: .availability
)
```### Geocoding for Country Code (Apple platforms only)
When the library is used on an Apple platform, the `countryCode` parameter is not required. Internally the libary will use `CoreLocation` to reverse geocode the location to determine the country code. If the country cannot be determined, an error will be thrown.
## 📝 Attribution
Please be advised of [Apple's attribution guidelines](https://developer.apple.com/weatherkit/get-started/#attribution-requirements) when using this package.
Attribution information can be accessed with:
```swift
let attribution = WeatherService.shared.attribution
```Note that this property returns a static `WeatherAttribution` instance using information from `WeatherKit` and is not guaranteed to be accurate or complete.