# Swift

URL: https://pieowl.com/docs/sdks/swift





Pieowl doesn't ship a Swift SDK. You send events from Swift with a plain HTTP request to the [Track API](/docs/api/track). The example below uses `URLSession` and `JSONSerialization` from Foundation, so there is no package to add. It works on iOS, macOS, tvOS and watchOS.

<Callout>
  Looking for a step-by-step tutorial? Read the [Swift analytics guide](/guides/swift-analytics).
</Callout>

Before you start [#before-you-start]

You need a client ID and a client secret. Find them in the dashboard under **Settings → Developers → Keys**. Apps can't send the browser headers Pieowl uses to check where a request comes from, so app requests include the secret.

Send an event [#send-an-event]

Every request is a `POST` to `https://api.pieowl.com/track` with a JSON body of `{ "type": ..., "payload": ... }`.

```swift title="Pieowl.swift"
import Foundation

enum Pieowl {
    private static let trackURL = URL(string: "https://api.pieowl.com/track")!
    private static let clientId = "YOUR_CLIENT_ID"
    private static let clientSecret = "YOUR_CLIENT_SECRET"

    @discardableResult
    static func send(_ type: String, _ payload: [String: Any]) async throws -> Int {
        var request = URLRequest(url: trackURL)
        request.httpMethod = "POST"
        request.timeoutInterval = 5
        request.setValue("application/json", forHTTPHeaderField: "Content-Type")
        request.setValue(clientId, forHTTPHeaderField: "pieowl-client-id")
        request.setValue(clientSecret, forHTTPHeaderField: "pieowl-client-secret")
        request.httpBody = try JSONSerialization.data(
            withJSONObject: ["type": type, "payload": payload]
        )

        let (_, response) = try await URLSession.shared.data(for: request)
        return (response as? HTTPURLResponse)?.statusCode ?? 0
    }
}
```

`async` `URLSession` calls need iOS 15, macOS 12, tvOS 15 or watchOS 8.

Usage [#usage]

Call `send` from a `Task`, for example `Task { try? await Pieowl.send(...) }`.

Tracking events [#tracking-events]

```swift
try await Pieowl.send("track", [
    "name": "signup",
    "profileId": "user_123", // optional
    "properties": ["plan": "pro"],
])
```

Tracking screen views [#tracking-screen-views]

To fill the pages report, send a `screen_view` event with the screen name in `__path`:

```swift
try await Pieowl.send("track", [
    "name": "screen_view",
    "properties": ["__path": "/settings"],
])
```

Identifying users [#identifying-users]

```swift
try await Pieowl.send("identify", [
    "profileId": "user_123", // required
    "firstName": "Joe",
    "lastName": "Doe",
    "email": "joe@doe.com",
    "properties": ["tier": "premium"],
])
```

Incrementing and decrementing properties [#incrementing-and-decrementing-properties]

`value` is optional and defaults to 1.

```swift
try await Pieowl.send("increment", ["profileId": "user_123", "property": "visits", "value": 1])
try await Pieowl.send("decrement", ["profileId": "user_123", "property": "credits", "value": 1])
```

Good to know [#good-to-know]

* **Errors:** `send` returns the HTTP status. A `2xx` status means Pieowl accepted the request. Network errors throw, so use `try?` if analytics must never interrupt your app.
* **Offline:** Requests fail while the device is offline. If you need offline support, store events and send them later.
* **More event types:** Revenue, groups and the full request schema are in the [Track API reference](/docs/api/track).
