# Set up InboxKit with CocoaPods

*Available since iOS SDK [7.0.40](https://github.com/Pushwoosh/pushwoosh-ios-sdk/releases/tag/7.0.40).*

InboxKit ships as an optional subspec of the umbrella `PushwooshXCFramework` pod. You need the main SDK to be already integrated; if you are starting from scratch, follow the [Basic integration guide](/developer/pushwoosh-sdk/ios-sdk/setting-up-pushwoosh-ios-sdk-7-0/basic-integration-guide/) first.

## Add the InboxKit pod

1\. Open your `Podfile` and add the InboxKit subspec to your app target:

```ruby
target 'MyApp' do
  use_frameworks!

  pod 'PushwooshXCFramework'
  pod 'PushwooshXCFramework/PushwooshInboxKit'
end
```

2\. Run `pod install` from your project directory:

```bash
pod install
```

3\. Open the generated `.xcworkspace` file. InboxKit is now linked alongside the main SDK.

## Show the inbox

Add the inbox controller to any navigation flow. The default configuration is enough to get a working inbox with the three standard cell types:

<Tabs syncKey="code-example">
<TabItem label="Swift">
```swift
import PushwooshInboxKit

let inboxVC = PushwooshInboxKitViewController()
navigationController?.pushViewController(inboxVC, animated: true)
```
</TabItem>

<TabItem label="Objective-C">
```objective-c
@import PushwooshInboxKit;

PushwooshInboxKitViewController *inboxVC = [PushwooshInboxKitViewController new];
[self.navigationController pushViewController:inboxVC animated:YES];
```
</TabItem>
</Tabs>

## Customize the inbox

In Swift, configure the controller through the `PushwooshInboxKitAttributes` value type. In Objective-C, use the `@objc`-friendly setters on the controller — `PushwooshInboxKitAttributes` is a Swift struct and is not bridged.

<Tabs syncKey="code-example">
<TabItem label="Swift">
```swift
var attributes = PushwooshInboxKitAttributes()
attributes.pullToRefreshEnabled = true
attributes.swipeToDeleteEnabled = true
attributes.pinningEnabled = true
attributes.style.unreadBadgeColor = .systemBlue
attributes.style.titleFont = .systemFont(ofSize: 17, weight: .semibold)

let inboxVC = PushwooshInboxKitViewController(attributes: attributes)
```
</TabItem>

<TabItem label="Objective-C">
```objective-c
PushwooshInboxKitViewController *inboxVC = [PushwooshInboxKitViewController new];
[inboxVC setBackgroundColor:[UIColor systemBackgroundColor]];
[inboxVC setEmptyMessage:@"You have no messages yet"];
```
</TabItem>
</Tabs>

The `Style` struct exposes all colors, fonts, corner radii and the date formatter used by the default cells. Every value is an Apple semantic color by default, so the inbox reacts to system dark mode automatically.

<img src="/setting-up-pushwoosh-inboxkit-ios-custom.webp" alt="Custom-styled InboxKit feed with brand colors applied to title and unread indicator" width="280" style="display: block; margin: 0 auto;"/>

<p style="text-align: center; opacity: 0.7; font-size: 0.875rem; margin-top: 0.5rem;">Captioned cell with a custom theme applied through <code>PushwooshInboxKitAttributes.Style</code>.</p>

## Handle taps and refreshes

Conform to `PushwooshInboxKitDelegate` to react to user actions and refresh events. Every method has a default implementation, so you only override what you need:

<Tabs syncKey="code-example">
<TabItem label="Swift">
```swift
final class InboxCoordinator: NSObject, PushwooshInboxKitDelegate {
    func inboxKit(_ vc: PushwooshInboxKitViewController,
                  didSelect message: PWInboxMessageProtocol) -> Bool {
        // Return true to let the SDK open the message URL or richmedia.
        // Return false if you handled the tap entirely (e.g. routed to a custom screen).
        return true
    }

    func inboxKit(_ vc: PushwooshInboxKitViewController,
                  didRefreshWith messages: [PWInboxMessageProtocol],
                  error: Error?) {
        // Show your own empty / error state here if needed.
    }
}

inboxVC.delegate = inboxCoordinator
```
</TabItem>
</Tabs>

The SDK ships bulk operations as `@objc` methods on the controller, so you can wire them straight to a `UIBarButtonItem`:

<Tabs syncKey="code-example">
<TabItem label="Swift">
```swift
let markAll = UIBarButtonItem(
    image: UIImage(systemName: "checkmark.circle"),
    style: .plain,
    target: inboxVC,
    action: #selector(PushwooshInboxKitViewController.markAllAsRead)
)
let clearRead = UIBarButtonItem(
    image: UIImage(systemName: "trash"),
    style: .plain,
    target: inboxVC,
    action: #selector(PushwooshInboxKitViewController.clearReadMessages)
)
inboxVC.navigationItem.rightBarButtonItems = [clearRead, markAll]
```
</TabItem>
</Tabs>

<Aside type="note" title="Persistence">
Mark-as-read, mark-all-as-read, delete, and clear-read all persist to the local Pushwoosh inbox storage before the network request is sent. State survives a process restart even when the backend has not yet acknowledged the change.
</Aside>

## Next steps

<LinkCard
  title="PushwooshInboxKit API reference"
  description="Generated DocC documentation for every public type."
  href="https://pushwoosh.github.io/pushwoosh-ios-sdk/PushwooshInboxKit/documentation/pushwooshinboxkit/"
/>