Quick Start
These steps are mandatory for initializing SkyPath correctly.
Before you begin, ensure you have Installed the SkyPath iOS SDK.
Upgrading an existing integration from 3.x? See Migrate from 3.x to 4.0.
1. Import SkyPathSDK
Near the top of any Swift file that uses SkyPathSDK, add the following import statement:
import SkyPathSDK
2. Set Delegate
Set your SkyPathDelegate object. All methods will be called on the main thread.
SkyPath.shared.delegate = delegate
Implement the SkyPathDelegate protocol. All of its methods are required — there are no default implementations, so a missing method is a compile error.
extension Controller: SkyPathDelegate {
func didUpdateRecordingState(to state: RecordingState) {
print("SkyPath recording state: \(state)")
// Turbulence data is not recorded unless the state is `.recording`.
// Show a notice to properly position the device in the cradle
// for `.notInPosition` and `.horizontal`.
}
func didReceiveNewObservationsData(areaType: DataAreaType) {
print("SkyPath did receive new observations data")
// Query observations using `ObservationsQuery` and show them on the map
// See the "Get Observations" step of this guide
}
func didReceiveNewOneLayer(areaType: DataAreaType) {
print("SkyPath did receive new OneLayer data")
// Query OneLayer using `OneLayerQuery` and show it on the map.
// See the OneLayer section of these docs.
}
func didReceiveNotification(_ notification: NotificationResult) {
print("SkyPath did receive a turbulence notification")
// Show the turbulence notification in the app.
// See the Notifications section of these docs.
}
func didFail(with error: SPError, dataType: DataType?) {
print("SkyPath did fail: \(error), dataType: \(String(describing: dataType))")
// `dataType` carries the failing `DataType` for data fetch errors,
// and is `nil` for everything else (authorization, token refresh, location).
}
}
Implementing these methods is enough for a quick start. You can get more details in the corresponding documentation sections.
3. Initialize SDK
Initialize the SDK with an AuthConfig. It will not track and provide data until initialized.
For security purposes, it is recommended to be able to update the API key without having to release a new version.
let config = AuthConfig(
apiKey: "API_KEY",
companyId: "AIRLINE",
userId: "ID",
env: .staging(serverUrl: nil))
SkyPath.shared.initialize(with: config) { error in
if let error {
// handle the error
}
}
API_KEYYour SkyPath API KEY (for production/staging).AIRLINEis a string that identifies the current using airline, i.e.EXAMPLE_AIRLINESorExample AirawaysorEXA. This string value needs to be communicated to SkyPath when onboarding a new airline.IDis the current user's unique identifier..staging(serverUrl: nil)is set to use a default SkyPath staging serverstaging-api.skypath.io.
The completion block will be called asynchronously on the main thread. error will have details in case the SDK can't initialize. Once initialized, SkyPathDelegate.didUpdateRecordingState(to:) reports the current RecordingState. It is not necessarily .recording — the state depends on the device position, so it can also be .notInPosition, .horizontal or .noise.
The SDK cannot be stopped once initialized. To temporarily stop fetching data from the server, use SkyPath.shared.isFetchEnabled — see Data.
4. Setup Aircraft
The turbulence severity level can be different for different aircraft types.
Set the current a/c type by its ICAO code in the fetch config. An unsupported ICAO code throws, so handle the error.
do {
try SkyPath.shared.updateFetchConfig { $0.aircraftICAO = "B737" }
} catch {
print(error)
}
The default is "B737". Read the current value from SkyPath.shared.fetchConfig.aircraftICAO.
5. Set Route Corridor
After the SDK is initialized and the aircraft was set, set a route corridor to get data in.
It should be a valid GeoJSON Polygon RFC 7946. See Data for more details.
Use the following for a quick test.
// KJFK-KIAD as [lng, lat]
let corridor = [(-76.76, 37.43), (-72.55,39.50), (-72.21,40.06), (-72.26,41.33), (-72.64,41.86), (-73.51,42.28), (-74.16,42.26), (-78.15,40.46), (-79.10,39.20), (-78.80,37.96), (-77.72,37.30), (-76.76,37.43)]
.map { CLLocationCoordinate2D(latitude: $0.1, longitude: $0.0) }
do {
try SkyPath.shared.updateFetchConfig { $0.polygon = corridor }
} catch {
print(error)
}
When you set several fields at once — for example the aircraft and the corridor — do it in a single updateFetchConfig closure so validation and the fetch check run once.
6. Get Observations
SDK fetches data from the server and caches it locally automatically.
Use ObservationsQuery to get filtered data as a GeoJSON string or as an array of objects. It will query locally cached data received previously. It blocks the current thread, so using a separate background thread is recommended.
do {
let result = try SkyPath.shared.observations(with: ObservationsQuery()).get()
let geoJSON = result.geoJSON
// Show GeoJSON on the map
} catch {
print(error)
}
7. Set Flight
Setting a flight is optional. When no flight is set, the SDK starts a flight on its own once it detects the aircraft is in the air, and ends it automatically after landing. You do not need to end that one yourself.
Still set a flight whenever your app has the details. It attaches the recorded data to a real flight number and route, which SkyPath needs for reporting and QA. If you set a flight while the SDK is already tracking automatically, the details are merged into the flight in progress, so nothing recorded is lost.
Update flight data at any time and pass nil when a flight is ended or removed.
let flight = Flight(dep: "ICAO", dest: "ICAO", num: "FLIGHT_NUMBER")
SkyPath.shared.setFlight(flight)
ICAOis the airport's ICAO code.FLIGHT_NUMBERis the callsign or flight number of the flight.
Unlike the flight the SDK starts on its own, a flight you set is not ended automatically. So when a flight is removed, deleted or ended in your app, it is essential to end it in the SDK too. This is done by calling:
SkyPath.shared.setFlight(nil)
8. Handle Errors
Process and act on the delegated errors accordingly using the following:
SkyPathDelegate.didFail(with:dataType:)— data fetch, authorization and location errorsSkyPathDelegate.didUpdateRecordingState(to:)— the SDK is not recording
Calls that validate their input throw instead of delegating, so wrap them in do/catch:
SkyPath.updateFetchConfig(_:)/setFetchConfig(_:)throw aQueryError- the query functions such as
observations(with:)return aResulttoget()
9. Whitelist
By default, SDK will access the api.skypath.io domain. This should be whitelisted, so SDK can receive and send data. When a domain is not whitelisted it will work as when offline.
You can use a proxy server to avoid whitelisting a SkyPath domain. It should forward all HTTPS network traffic for api.skypath.io with a wildcard * for a path. docs.skypath.io describes APIs to get data only as it's not possible to send recorded data outside of SDK. SDK will use other non-documented API endpoints, so whitelisting only those or any other fixed endpoint paths list is not sufficient.
10. Test
After completing the above steps run the project and see if the data is provided correctly. You should see some turbulence data. See Test for how to test recording.
11. Set Map Layer
Report whether the SkyPath map layer is enabled or not by calling the following when showing/hiding the SkyPath data layer on the map.
SkyPath.shared.reportAppEvent(.mapLayer(enabled: true))
Thread Safety
SkyPath.initialize(with:completion:) should be called on the main thread. Besides that, SDK is thread-safe in general and will use its own threads when needed.