> ## Documentation Index
> Fetch the complete documentation index at: https://cometchat-22654f5b-docs-ios-ui-kit-sdk-fixes.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Marking Delivered From Push Notification

> Guide to marking messages as delivered using push notification payload with Notification Service Extension.

<Info>
  **Quick Reference for AI Agents & Developers**

  * **Requires:** UNNotificationServiceExtension target in your app
  * **Purpose:** Mark messages delivered even when app is in background/terminated
  * **Implementation:** Call `CometChat.markAsDelivered()` in notification extension
  * **Parse payload:** Extract message ID, sender ID, receiver type from notification
  * **Related:** [Delivery & Read Receipts](/sdk/ios/delivery-read-receipts) · [Push Notifications](/sdk/ios/push-notification-overview)
</Info>

Implementing the capability to mark a message as "delivered" through a push notification payload can prove to be a pivotal feature. This functionality serves as an accurate representation, confirming to the sender that their message has indeed reached its intended recipient, thereby enhancing the overall user experience.

Setting up Mark as delivered from push notification in iOS requires to have Notification extension to your app project. So let's begin with adding a Notification extension to your app project.

<Note>
  If you already have a Notification extension on your project then you can skip the first part of creating a new extension and use the one you have.
</Note>

### Setting up Notification extension

1. Navigate to your project’s target section and click on the plus iOS

<Frame>
  <img src="https://mintcdn.com/cometchat-22654f5b-docs-ios-ui-kit-sdk-fixes/sXlOkom3A4PRkute/images/bebacc7e-n3luq9beoss2m2rrq441yvklq0qdgdo8l7o5p68hpjd35g14axybs6sqotkj8jba-3987e443fd24ea0c1e32af8f6d7d3699.png?fit=max&auto=format&n=sXlOkom3A4PRkute&q=85&s=cc9d30ebf962a69646054188b7021a25" width="3006" height="1974" data-path="images/bebacc7e-n3luq9beoss2m2rrq441yvklq0qdgdo8l7o5p68hpjd35g14axybs6sqotkj8jba-3987e443fd24ea0c1e32af8f6d7d3699.png" />
</Frame>

2. Then Scroll down, select Notification Service Extension and click on the next.

<Frame>
  <img src="https://mintcdn.com/cometchat-22654f5b-docs-ios-ui-kit-sdk-fixes/vyosMNRRZK5laScN/images/36a79bad-g0r2llvb74jts8wprgrtv7xcc0cp579lj4d8l1jea4iaxomzsadmf4rtilhba2ft-defa21a2b91f8a868993e213cd8689ed.png?fit=max&auto=format&n=vyosMNRRZK5laScN&q=85&s=8ea8c9530acb2b02c2553ebf7262fe61" width="1628" height="1214" data-path="images/36a79bad-g0r2llvb74jts8wprgrtv7xcc0cp579lj4d8l1jea4iaxomzsadmf4rtilhba2ft-defa21a2b91f8a868993e213cd8689ed.png" />
</Frame>

3. Give it a name and click finish

<Frame>
  <img src="https://mintcdn.com/cometchat-22654f5b-docs-ios-ui-kit-sdk-fixes/cikDwPEZyGjQZ4Rn/images/b40d4fe3-hw3bdemnkitlfd9717xrasevp39hwa4og8w8ncyasybi7a0m07dj9xd0c8wletx1-95f99134fe857f52f59bca2194fd3276.png?fit=max&auto=format&n=cikDwPEZyGjQZ4Rn&q=85&s=6934ea35893c1642d9fecece74865757" width="1628" height="1214" data-path="images/b40d4fe3-hw3bdemnkitlfd9717xrasevp39hwa4og8w8ncyasybi7a0m07dj9xd0c8wletx1-95f99134fe857f52f59bca2194fd3276.png" />
</Frame>

* Your notification service extension is ready now, you can see that in the target list. Now we will create app group for the extension. This app group will be needed to share user default between the main application and notification service extension.

4. Click on the notification service extension name on the target list, then select Signing & Capabilities, then click on “+ Capability” from the top. Make sure All is selected besides it.

<Frame>
  <img src="https://mintcdn.com/cometchat-22654f5b-docs-ios-ui-kit-sdk-fixes/1gjHdq6FrESoHqiS/images/adf243b8-uxobr5po4lg6c9dmfpmxkgwmqrzc3izcr0ebo4o8vbrlizcgp7pivdqzgoxeoq5z-ff82bb13573e5aa62eadb84d4f88641a.png?fit=max&auto=format&n=1gjHdq6FrESoHqiS&q=85&s=a7f88eebd85252941a75fa23c0de086d" width="3006" height="1974" data-path="images/adf243b8-uxobr5po4lg6c9dmfpmxkgwmqrzc3izcr0ebo4o8vbrlizcgp7pivdqzgoxeoq5z-ff82bb13573e5aa62eadb84d4f88641a.png" />
</Frame>

5. Then search for App Group and click on it. You can see a section of the app group section must have been added on the ‘Signing & Capabilities’.

<Frame>
  <img src="https://mintcdn.com/cometchat-22654f5b-docs-ios-ui-kit-sdk-fixes/Vmm9kZCA3UhJtiGD/images/58046089-tj0q9z3hhcyk5oumprf3q9ypu6vyol2nl2bgofw6vs2drdqen2lz3ul7dmr7p0hf-7f701199b876e8a957f12b828c72b844.png?fit=max&auto=format&n=Vmm9kZCA3UhJtiGD&q=85&s=a61491a4d836be0dbd984b5cbcd3a818" width="1586" height="1216" data-path="images/58046089-tj0q9z3hhcyk5oumprf3q9ypu6vyol2nl2bgofw6vs2drdqen2lz3ul7dmr7p0hf-7f701199b876e8a957f12b828c72b844.png" />
</Frame>

6. Select any of the suggested app group ID or you can add your own ID by clicking on the plus icon. Till this step app group is added on the notification extension target and app group is selected.

<Frame>
  <img src="https://mintcdn.com/cometchat-22654f5b-docs-ios-ui-kit-sdk-fixes/Bsq0jnHEltKjyslS/images/bcbd0d7e-63gqeee1j6iwj7ynaebzxtulkzrbekkirzsq4k7egemcu0rxalf9cawqr9rc5v1s-fce3f8e40e188f635733a5455840cf0b.png?fit=max&auto=format&n=Bsq0jnHEltKjyslS&q=85&s=ee49fe40a2d0e51c8379f0c039d0fabf" width="1836" height="398" data-path="images/bcbd0d7e-63gqeee1j6iwj7ynaebzxtulkzrbekkirzsq4k7egemcu0rxalf9cawqr9rc5v1s-fce3f8e40e188f635733a5455840cf0b.png" />
</Frame>

7. Now we will add the Capability of App Group on the main app’s target as well. Just repeat the same steps that you have done on the notification extension(from step 4). You have to select your main app from the target list, then as we did for the notification extension switch to ‘Signing & Capabilities’, then click on “+ Capability” from the top and select App Group.
8. Then select the same group ID that you have selected on the notification extension target’s app group. If it is not there in the suggested IDs, then add it by clicking on the plus icon.

<Note>
  Make sure the app ID is exactly the same on both the notification extension target and the main app target.
</Note>

9. Lastly, add CometChatSDK in your notification extension target in the pod file.

<Tabs>
  <Tab title="Swift">
    ```ruby theme={null}
    # Uncomment the next line to define a global platform for your project
    # platform :ios, '12.0'

    target 'CometChatSwift' do

      pod 'CometChatSDK', '4.1.0'
      pod 'CometChatCallsSDK', '4.2.2'

    end

    # add your notification extension name here
    target 'NotificationExtension' do

      pod 'CometChatSDK', '4.0.67'

    end
    ```
  </Tab>
</Tabs>

All the setup is done, let’s see some code now.

## Code for Mark as read

1. Firstly navigate to the cometchat initialization code on you project and add the group ID that you have selected on app groups on the AppSettingsBuilder.

<Tabs>
  <Tab title="Swift">
    ```swift theme={null}
    let appSettings = AppSettings.AppSettingsBuilder()
                    .subscribePresenceForAllUsers()
                    .setRegion(region: Constants.region)
                    .setExtensionGroupID(id: "group.com.comechatcalls.appgroup") //add you app group ID here
                    .build()
    ```
  </Tab>
</Tabs>

<Accordion title="Sample Payload - AppSettings with Extension Group ID">
  **Configuration Parameters:**

  | Parameter                      | Type   | Description                                                                                 |
  | ------------------------------ | ------ | ------------------------------------------------------------------------------------------- |
  | subscribePresenceForAllUsers() | Method | Subscribe to presence updates for all users                                                 |
  | setRegion(region:)             | String | CometChat region. Example: `"us"`                                                           |
  | setExtensionGroupID(id:)       | String | App Group ID shared between main app and extension. Example: `"group.com.yourapp.appgroup"` |

  **Important Notes:**

  | Note         | Description                                                    |
  | ------------ | -------------------------------------------------------------- |
  | App Group ID | Must match exactly in both main app and notification extension |
  | Capability   | App Groups capability must be enabled in both targets          |
  | Shared data  | Allows SDK to share user session between app and extension     |
</Accordion>

2. Now navigate to your notification extension named group that is been created And open its swift file.
3. Then import CometChatSDK on that file and call these 2 functions on the didReceive(\_ request: , withContentHandler: ) function.

<Tabs>
  <Tab title="Swift">
    ```swift theme={null}
    override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) {
            self.contentHandler = contentHandler
            bestAttemptContent = (request.content.mutableCopy() as? UNMutableNotificationContent)        

            CometChat.setExtensionGroupID(id: "group.com.comechatcalls.appgroup") //add you group id
        
            if let bestAttemptContent = bestAttemptContent {
                
                CometChat.markAsDelivered(withNotificationPayload: bestAttemptContent.userInfo) //send the payload here
                
                contentHandler(bestAttemptContent)
            }
        }
    ```
  </Tab>
</Tabs>

<Accordion title="Sample Payload - markAsDelivered from Push Notification">
  **Method Signature:**

  | Method                                    | Parameter           | Description                                       |
  | ----------------------------------------- | ------------------- | ------------------------------------------------- |
  | setExtensionGroupID(id:)                  | String              | Set the App Group ID before marking delivered     |
  | markAsDelivered(withNotificationPayload:) | \[AnyHashable: Any] | Push notification payload containing message data |

  **Sample Push Notification Payload (userInfo):**

  | Parameter            | Type       | Description                                          |
  | -------------------- | ---------- | ---------------------------------------------------- |
  | aps                  | Dictionary | Apple Push Notification Service data                 |
  | aps.alert.title      | String     | Notification title. Example: `"John Doe"`            |
  | aps.alert.body       | String     | Notification body. Example: `"Hello, how are you?"`  |
  | aps.mutable-content  | Int        | Must be `1` for notification extension. Example: `1` |
  | message              | Dictionary | CometChat message data                               |
  | message.id           | Int        | Unique message identifier. Example: `1772174760`     |
  | message.sender       | String     | Sender UID. Example: `"cometchat-uid-2"`             |
  | message.receiver     | String     | Receiver UID or GUID. Example: `"cometchat-uid-1"`   |
  | message.receiverType | String     | Type of receiver. Example: `"user"` or `"group"`     |

  **Effect After Marking Delivered:**

  | Effect             | Description                                     |
  | ------------------ | ----------------------------------------------- |
  | Server update      | Message marked as delivered on CometChat server |
  | Delivery receipt   | Sender receives delivery receipt (if listening) |
  | Timestamp          | Message `deliveredAt` timestamp updated         |
  | Background support | Works even when app is in background/terminated |
</Accordion>

<Accordion title="Sample Payload - Push Notification for User Message">
  **Complete userInfo Dictionary:**

  | Parameter              | Type   | Description                                            |
  | ---------------------- | ------ | ------------------------------------------------------ |
  | aps.alert.title        | String | Sender name. Example: `"John Doe"`                     |
  | aps.alert.body         | String | Message text. Example: `"Hello, how are you?"`         |
  | aps.mutable-content    | Int    | Enables modification. Example: `1`                     |
  | aps.sound              | String | Notification sound. Example: `"default"`               |
  | message.id             | Int    | Message ID. Example: `12345`                           |
  | message.muid           | String | Message unique ID. Example: `"msg_abc123"`             |
  | message.sender         | String | Sender UID. Example: `"john_doe"`                      |
  | message.receiver       | String | Receiver UID. Example: `"jane_smith"`                  |
  | message.receiverType   | String | Receiver type. Example: `"user"`                       |
  | message.type           | String | Message type. Example: `"text"`                        |
  | message.text           | String | Message content. Example: `"Hello, how are you?"`      |
  | message.sentAt         | Int    | Unix timestamp. Example: `1699800000`                  |
  | message.conversationId | String | Conversation ID. Example: `"john_doe_user_jane_smith"` |
</Accordion>

<Accordion title="Sample Payload - Push Notification for Group Message">
  **Complete userInfo Dictionary:**

  | Parameter            | Type   | Description                                            |
  | -------------------- | ------ | ------------------------------------------------------ |
  | aps.alert.title      | String | Group name. Example: `"Team Chat"`                     |
  | aps.alert.body       | String | Message with sender. Example: `"John: Meeting at 3pm"` |
  | aps.mutable-content  | Int    | Enables modification. Example: `1`                     |
  | message.id           | Int    | Message ID. Example: `12346`                           |
  | message.sender       | String | Sender UID. Example: `"john_doe"`                      |
  | message.receiver     | String | Group GUID. Example: `"team_chat_guid"`                |
  | message.receiverType | String | Receiver type. Example: `"group"`                      |
  | message.type         | String | Message type. Example: `"text"`                        |
  | message.text         | String | Message content. Example: `"Meeting at 3pm"`           |
  | message.sentAt       | Int    | Unix timestamp. Example: `1699800100`                  |
</Accordion>

<Accordion title="Sample Payload - When to Use markAsDelivered">
  **Usage Scenarios:**

  | Scenario          | Use markAsDelivered? | Reason                                  |
  | ----------------- | -------------------- | --------------------------------------- |
  | App in foreground | No                   | SDK handles automatically via WebSocket |
  | App in background | Yes                  | Via Notification Service Extension      |
  | App terminated    | Yes                  | Via Notification Service Extension      |

  **Prerequisites:**

  | Requirement            | Description                                            |
  | ---------------------- | ------------------------------------------------------ |
  | Notification Extension | UNNotificationServiceExtension target added to project |
  | App Groups             | Capability enabled in both main app and extension      |
  | Same Group ID          | Identical App Group ID in both targets                 |
  | CometChatSDK           | Added to extension target in Podfile                   |
</Accordion>

And we are finally done, run your notification extension by selecting the notification extension target from the run target on the top.

<Frame>
  <img src="https://mintcdn.com/cometchat-22654f5b-docs-ios-ui-kit-sdk-fixes/Ur5VUmw7QzwdTuYq/images/0e77a2b1-nqjmfzzns44ay0dttcwyldax2ty22al3madpljdu57yhdolln45cfx7pa89vnn6k-e1fc7f626a5adf1f5838c528d49f79be.png?fit=max&auto=format&n=Ur5VUmw7QzwdTuYq&q=85&s=0f69ce4bc4ca545953621822f8f28150" width="1620" height="592" data-path="images/0e77a2b1-nqjmfzzns44ay0dttcwyldax2ty22al3madpljdu57yhdolln45cfx7pa89vnn6k-e1fc7f626a5adf1f5838c528d49f79be.png" />
</Frame>

<Note>
  Run the main app target first and make sure you are receiving notifications there. And then run the notification extension target.
</Note>
