> ## Documentation Index
> Fetch the complete documentation index at: https://feddy.app/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# iOS SDK reference

> Every public call in the Feddy Swift package, with its signature and what it does.

The Swift package gives you one namespace, `Feddy`, plus three SwiftUI helpers for showing unread counts. Everything else is internal, so this page is the complete list of what you can call.

Requirements: iOS 15 or later, Swift 5.9 or later, no other packages. Package URL `https://github.com/FeddyLab/feddy-ios`, product `Feddy`.

## `Feddy.configure(projectId:apiURL:)`

```swift theme={null}
static func configure(projectId: String, apiURL: URL = URL(string: "https://core.feddy.app")!)
```

Sets Feddy up for this app. Call it once at launch, before anything else can open Feddy; later calls do nothing. It starts loading your project's settings and the unread count, and from then on checks for new replies every 30 seconds while the app is running.

* `projectId`: copied from **Settings → Install** in the dashboard. Public by design; see [Create a project](https://feddy.app/docs/getting-started/create-a-project.md).
* `apiURL`: leave the default in production. Point it at a local server during development.

## `Feddy.present()`

```swift theme={null}
@MainActor static func present()
```

Opens Feddy as a sheet that slides up over whatever's on screen. It opens on the home: a greeting, a button to send a new message, and the user's recent conversations, with a link to all of them. Works from SwiftUI and UIKit alike. Does nothing if the sheet is already open. If called before `configure`, it logs `[Feddy] present() called before configure(projectId:)` and does nothing.

## `Feddy.presentNewConversation()`

```swift theme={null}
@MainActor static func presentNewConversation()
```

Same as `present()`, but opens straight onto the new-message screen.

## `Feddy.identify(userId:email:name:avatarUrl:attributes:)`

```swift theme={null}
static func identify(userId: String, email: String? = nil, name: String? = nil, avatarUrl: String? = nil, attributes: [String: Any] = [:])
```

Tells Feddy which of your users is on this device. Call it after login and whenever the details you send change; it's safe to call as often as you like. Does nothing before `configure`. What happens on the server, including how records from different devices merge, is in [Identify users](https://feddy.app/docs/guides/identify-users.md).

* `userId`: your own stable ID for the user, 1 to 128 characters.
* `email`: optional. Lets replies reach the user by email once your project has a verified email domain.
* `name`: optional. Shown in the inbox.
* `avatarUrl`: optional. An `http(s)` URL of a picture you already have of the user, shown in the inbox. Anything else is ignored.
* `attributes`: optional facts about the user, such as their plan. Values may be `String`, `Bool`, any number, or `Date`; a `Date` is sent as text like `2026-09-22T10:00:00Z`. Other types are dropped on the device. Server-side limits are listed in [Identify users](https://feddy.app/docs/guides/identify-users.md).

## `Feddy.unreadCount(_:)`

```swift theme={null}
static func unreadCount(_ completion: @escaping (Int) -> Void)
```

Fetches the current number of unread replies and hands it to `completion` on the main thread.

## `Feddy.refresh()`

```swift theme={null}
static func refresh()
```

Asks for a fresh unread count right now instead of waiting for the next scheduled check. Call it when your app returns to the foreground so a badge is up to date immediately.

```swift theme={null}
.onChange(of: scenePhase) { phase in
    if phase == .active { Feddy.refresh() }
}
```

## `Feddy.onUnreadCountChanged`

```swift theme={null}
@MainActor static var onUnreadCountChanged: ((Int) -> Void)?
```

A function Feddy calls, on the main thread, whenever the unread count changes. Meant for UIKit badges; SwiftUI apps should use the helpers below instead.

## `Feddy.replyPopupsEnabled`

```swift theme={null}
@MainActor static var replyPopupsEnabled: Bool
```

Whether a card slides in at the top of the screen when the user comes back with a reply they haven't seen. On by default. Set it to `false` before a screen that must not be interrupted, such as a paywall or a game level, and back to `true` afterwards; a waiting reply then shows.

```swift theme={null}
Feddy.replyPopupsEnabled = false
// show the paywall
Feddy.replyPopupsEnabled = true
```

## `View.feddyUnreadBadge()`

```swift theme={null}
func feddyUnreadBadge() -> some View
```

Adds the system row badge with the unread count and keeps it current. Nothing is drawn at zero. Badges only render inside `List`, `Form`, and `TabView`; anywhere else the modifier does nothing.

## `FeddyUnreadDot`

```swift theme={null}
struct FeddyUnreadDot: View {
    init(showsCount: Bool = false)
}
```

A red marker you place yourself, for rows that draw their own chevron or for spots a list badge can't reach. Renders nothing at zero. Pass `showsCount: true` to draw the number inside the marker.

## `FeddyUnread`

```swift theme={null}
@MainActor final class FeddyUnread: ObservableObject {
    static let shared: FeddyUnread
    @Published private(set) var count: Int
}
```

The unread count as an observable object, for custom SwiftUI badges. A view that reads it updates itself whenever the count changes.

```swift theme={null}
@ObservedObject private var unread = FeddyUnread.shared
```

## What happens on its own

* **Identity**: the first time the SDK runs, it creates an anonymous ID and stores it in the Keychain, so a user's history survives reinstalls.
* **Language**: the sheet ships in English, Simplified Chinese, Traditional Chinese, Japanese, Korean, German, French, Spanish, Brazilian Portuguese, and Russian, and follows the device language. Other languages fall back to English. Text you write in the dashboard, such as topics, is translated on the server according to your project settings.
* **Attachments**: up to 5 images per message, resized so the longest edge is 3000 px before upload. The picker needs iOS 16; on iOS 15 the attachment row isn't shown.
* **Reply popups**: when the app becomes active with a reply the user hasn't seen, a card slides in at the top of the screen after about two seconds, saying who replied and showing the first two lines of the latest reply. Tapping it opens that conversation. Swiping up dismisses it, and it goes away on its own after 8 seconds (it stays while VoiceOver is on, with a Close action). If several replies are waiting, only the newest shows. Each reply shows at most once, only replies from the last 14 days, and never while the Feddy sheet is open. The SDK draws it over your screen; it isn't a notification and needs no permission.
* **Branding**: the name, accent color, and logo users see come from the dashboard, not from code.
* **Privacy manifest**: the package ships a `PrivacyInfo.xcprivacy` that declares what the SDK collects, so there's nothing for you to add for App Store review.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.