Different Requests

Start here

Add the package, build one object, and show a board your users can post to.

What you need

  • iOS 26 or newer, or macOS 26 or newer.
  • Xcode 26, Swift 6.2.
  • An app key, which names your app to us.

Add the package

In Xcode: File โ†’ Add Package Dependencies, and paste this address.

https://github.com/Different-Productions/DifferentRequestsSDK

Or in Package.swift:

dependencies: [
  .package(url: "https://github.com/Different-Productions/DifferentRequestsSDK", from: "0.8.0"),
],

Get your app key

Your key is shown once, when you make it.Open an account

Your app key is not a secret. It ships inside your App Store binary, and anyone who installs your app can read it off their own device. It names your app; it does not protect it.

Show the board

Build one hub where your app builds everything else it keeps, and hand it to a screen. A SwiftUI view is thrown away and rebuilt on every redraw above it, so a hub built inside one would take the board's pages and a half-written request with it every time.

import DifferentRequests
import SwiftUI

@main
struct MyApp: App {
  private let requests = DifferentRequestsHub(client: .make(appKey: "your-app-key"))

  var body: some Scene {
    WindowGroup {
      NavigationStack {
        DifferentRequestsView(hub: requests)
      }
    }
  }
}

Sign your person in

Reading the board needs only your app key. Voting, asking, following and commenting act for somebody, so they need a session. Your app already knows who its users are โ€” hand over your own identifier rather than making them sign up again.

NavigationStack {
  DifferentRequestsView(hub: requests)
}
.task {
  do {
    let signedIn = try await requests.client.createSession(
      externalID: currentUser.id,
      email: currentUser.email,
      displayName: currentUser.name,
      traits: ["plan": currentUser.plan]
    )
    logger.info("DifferentRequests: signed in as \(signedIn.user.id)")
  } catch {
    logger.error("DifferentRequests: \(error.localizedDescription)")
  }
}
Leave that out and the board still draws, but Submit answers "That didn't send. Try again in a moment." every time, because there is nobody to file the request as.

Use an identifier nobody can guess โ€” a UUID you keep for each person, not their email address and not a number in order. The same identifier is the same person forever, which is what carries their votes across a reinstall.

Open it without the wait

The board's first page is a round trip. If you know it is about to be opened, read it while the reader is still looking at something else, and it draws rows on the first frame.

Button("Feature requests") {
  showingRequests = true
}
.task {
  await requests.readTheBoardBeforeItIsShown()
}