Getting started

Add Live Hive to your existing iOS app so your app can start a Live Activity and Live Hive will deliver server-controlled updates via APNs. This guide is a quick path to your first visible update — it assumes you already have an iOS app/Xcode project.

1. Prerequisites

  • Existing iOS app and Xcode project (device required for Live Activities)
  • Apple Developer account (App ID with Push Notifications & Live Activities)
  • Xcode compatible with the iOS SDK version below
  • Live Hive account (create a project in the dashboard)

2. Create a Live Hive project

In the Live Hive dashboard create a project and enter your app’s Bundle Identifier (the same bundle ID you use to run the app on device). Upload your APNs .p8 key (Team ID and Key ID) and pick sandboxwhile testing from Xcode, production for TestFlight/App Store.

Copy these keys from the project page:

  • iOS public key (lh_pub_…) — safe to include in the iOS app.
  • Server API key (lh_live_…) — secret: keep on your backend only.

3. Install the SDK (Swift Package Manager)

In Xcode: File → Add Package Dependencies. Paste the package URL and choose the version below. Add LiveHive to the app target.

https://github.com/iangdavis/livehive-ios
.package(url: "https://github.com/iangdavis/livehive-ios.git", from: "0.2.0")

4. Xcode setup

Add a Widget Extension (File → New → Target… → Widget Extension) and check Include Live Activity. On the app target enable Push Notifications and set NSSupportsLiveActivities in your Info.plist:

<key>NSSupportsLiveActivities</key>
<true/>

5. Start a Live Activity (minimal)

The SDK exposes a small API: configure with the public key, then start the activity. The SDK requests the Activity with pushType: .tokenand registers the push token with Live Hive.

Shared attributes (app + widget)

import ActivityKit
import Foundation

struct DeliveryAttributes: ActivityAttributes {
  public struct ContentState: Codable, Hashable {
    var status: String
    var eta: Int
  }
}

Live Activity UI (widget)

Replace the generated Live Activity with this minimal UI.

import ActivityKit
import SwiftUI
import WidgetKit

struct DeliveryLiveActivity: Widget {
  var body: some WidgetConfiguration {
    ActivityConfiguration(for: DeliveryAttributes.self) { context in
      HStack {
        Text(context.state.status)
        Spacer()
        Text("\(context.state.eta) min")
      }
      .padding()
    } dynamicIsland: { context in
      DynamicIsland {
        DynamicIslandExpandedRegion(.bottom) {
          Text(context.state.status)
        }
      } compactLeading: {
        Text("LH")
      } compactTrailing: {
        Text("\(context.state.eta)m")
      } minimal: {
        Text("\(context.state.eta)")
      }
    }
  }
}

App: configure and start

Configure with the public key and start the activity.

import LiveHive

LiveHive.configure(publicKey: "lh_pub_...")

let activity = try LiveHive.start(
  attributes: DeliveryAttributes(),
  contentState: .init(status: "preparing", eta: 12)
)
print(activity.id)

The SDK method LiveHive.start is ActivityKit’sActivity.request(..., pushType: .token) plus token registration so Live Hive can deliver updates.

6. Test the Activity (fast validation)

This is the critical onboarding step: the dashboard Send test updatelets you validate APNs and delivery before writing any backend code.

  1. Run the app on a supported iPhone and trigger the Start action.
  2. Open the Live Hive dashboard → project → Activities. Find the row for your activity.
  3. Click Send test update. The dashboard sends a sample update (the getting-started sample uses status and eta).
  4. Watch the Dynamic Island / Lock Screen on the device for the update.

If the test update succeeds you have validated your APNs configuration and device registration — you can now implement your backend.

7. Backend integration (production flow)

Production flow: your backend → Live Hive API → Apple APNs → iPhone. Authenticate API requests from your server using the server key (lh_live_…).

POST https://www.livehive.dev/v1/activities/{activity_id}/update
Authorization: Bearer lh_live_...
Content-Type: application/json

{ "content_state": { "status": "driver_arriving", "eta": 4 } }
const KEY = process.env.LIVEHIVE_API_KEY // lh_live_...

await fetch("https://www.livehive.dev/v1/activities/abc123/update", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    content_state: { status: "driver_arriving", eta: 4 },
  }),
})

await fetch("https://www.livehive.dev/v1/activities/abc123/end", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    content_state: { status: "delivered", eta: 0 },
  }),
})

The OpenAPI spec is authoritative for the full request schema and other routes: /openapi.json.

8. Security (important)

Key usage

  • lh_pub_… — public: goes in the iOS app (LiveHive.configure).
  • lh_live_… — secret: only on your backend; never embed in an iOS binary.

9. Next steps

This quick-start is focused on time-to-first-success. For full ActivityKit/WidgetKit implementation details and UI patterns, see the iOS SDK docs and the Activity UI guide linked above.