# iOS संदेश डिलीवरी ट्रैकिंग

Pushwoosh में एक [API मेथड](/hi/developer/api-reference/device-api#messagedeliveryevent) है जो पुश नोटिफिकेशन की डिलीवरी को ट्रैक करता है। iOS ऐप्स इस मेथड को आउट ऑफ द बॉक्स सपोर्ट नहीं करते हैं, क्योंकि iOS पर पुश नोटिफिकेशन OS द्वारा हैंडल किए जाते हैं, Pushwoosh SDK द्वारा नहीं। आप अपने प्रोजेक्ट में एक नोटिफिकेशन सर्विस एक्सटेंशन जोड़कर डिलीवरी ट्रैकिंग जोड़ सकते हैं। यह पेज दिखाता है कि iOS ऐप्स के लिए संदेश डिलीवरी ट्रैकिंग कैसे लागू करें।

<Aside>
इसके लिए Pushwoosh iOS SDK 7.x की आवश्यकता है, जो iOS 13.0 और बाद के संस्करणों का समर्थन करता है।
</Aside>

<Aside type="note">
Pushwoosh iOS SDK 7.1.0 से, अनुशंसित इंटीग्रेशन नीचे दिखाया गया ड्रॉप-इन `PushwooshNotificationServiceExtension` बेस क्लास है। यह संदेश डिलीवरी इवेंट भेजता है, बैज सेट करता है, मीडिया अटैचमेंट डाउनलोड करता है, और आपके लिए अनिवार्य `serviceExtensionTimeWillExpire` फॉलबैक को हैंडल करता है। पुराना `PWNotificationExtensionManager` API अभी भी काम करता है लेकिन इसे पदावनत कर दिया गया है — [लिगेसी इंटीग्रेशन](#legacy-integration) देखें।
</Aside>

## नोटिफिकेशन सर्विस एक्सटेंशन जोड़ें

1. Xcode में, **File** > **New** > **Target...** चुनें।

2. **Notification Service Extension** चुनें और **Next** दबाएँ।

<img src="/ios-push-notifications-ios-message-delivery-tracking-1.webp" alt="Xcode टारगेट टेम्प्लेट पिकर जिसमें नोटिफिकेशन सर्विस एक्सटेंशन चुना गया है"/>

3. उत्पाद का नाम दर्ज करें और **Finish** दबाएँ।

<Aside type="caution">
**Finish** दबाने के बाद दिखाए जाने वाले डायलॉग पर **Activate** न चुनें।
</Aside>

4. **Activate scheme** प्रॉम्प्ट पर **Cancel** दबाएँ।

<img
  src="/ios-push-notifications-ios-message-delivery-tracking-2.webp"
  alt="एक्टिवेट स्कीम प्रॉम्प्ट जिसमें कैंसिल हाइलाइट किया गया है"
  style={{ display: "block", margin: "0 auto", maxWidth: "40%", height: "auto" }}
  width="400"
/>

कैंसिल करके, आप Xcode को आपके द्वारा बनाए गए एक्सटेंशन के बजाय आपके ऐप को डीबग करने देते हैं। यदि आपने गलती से इसे सक्रिय कर दिया है, तो आप Xcode के भीतर अपने ऐप को डीबग करने के लिए वापस स्विच कर सकते हैं।

## नोटिफिकेशन सर्विस एक्सटेंशन के लिए निर्भरताएँ (केवल CocoaPods)

यदि आप निर्भरताओं को प्रबंधित करने के लिए स्विफ्ट पैकेज मैनेजर का उपयोग करते हैं, तो आप इस चरण को छोड़ सकते हैं, क्योंकि निर्भरताएँ स्वचालित रूप से जुड़ जाती हैं।

अपनी `Podfile` खोलें और टारगेट के लिए निर्भरता जोड़ें:

```ruby title="Podfile"
target 'NotificationServiceExtension' do
  use_frameworks!
  pod 'PushwooshXCFramework'
end
```

निर्भरताओं को स्थापित करने के लिए टर्मिनल में निम्नलिखित कमांड चलाएँ:

```shell
rm -rf Podfile.lock
pod deintegrate
pod setup
pod repo update
pod install
```

## संदेश डिलीवरी इवेंट्स को ट्रैक करने के लिए कोड जोड़ें

अपने एक्सटेंशन को `PushwooshNotificationServiceExtension` का एक सबक्लास बनाएँ। एक खाली सबक्लास पर्याप्त है: Pushwoosh संदेश डिलीवरी इवेंट भेजता है, बैज सेट करता है, मीडिया अटैचमेंट डाउनलोड करता है, और टाइमआउट फॉलबैक को स्वचालित रूप से हैंडल करता है।

अपनी **NotificationService** फ़ाइल की उत्पन्न सामग्री को बदलें:

<Tabs>
<TabItem label="Swift">

```swift
import UserNotifications
import PushwooshFramework

class NotificationService: PushwooshNotificationServiceExtension {}
```

</TabItem>

<TabItem label="Objective-C">

```objective-c
#import <PushwooshFramework/PushwooshNotificationServiceExtension.h>

@interface NotificationService : PushwooshNotificationServiceExtension

@end

@implementation NotificationService

@end
```

</TabItem>
</Tabs>

<Aside type="tip">
यदि आपको किसी कस्टम कोड की आवश्यकता नहीं है, तो आप स्रोत फ़ाइल को पूरी तरह से छोड़ सकते हैं और एक्सटेंशन की Info.plist `NSExtensionPrincipalClass` को सीधे `PushwooshNotificationServiceExtension` पर इंगित कर सकते हैं।
</Aside>

### ऐप आईडी

7.1.0 से एक्सटेंशन होस्ट ऐप की Info.plist से `Pushwoosh_APPID` (और अन्य `Pushwoosh_*` कुंजियाँ) विरासत में लेता है, इसलिए आपको इसे एक्सटेंशन में डुप्लिकेट करने की आवश्यकता नहीं है। एक्सटेंशन Info.plist में `Pushwoosh_APPID` केवल तभी जोड़ें जब आप होस्ट मान को ओवरराइड करना चाहते हैं:

```xml title="NotificationService/Info.plist"
<key>Pushwoosh_APPID</key>
<string>XXXXX-XXXXX</string>
```

<Aside type="note">
Pushwoosh iOS SDK के 7.1.0 से पहले के संस्करणों पर एक्सटेंशन होस्ट ऐप से कॉन्फ़िगरेशन विरासत में नहीं लेता है। उन संस्करणों पर आपको एक्सटेंशन Info.plist में `Pushwoosh_APPID` जोड़ना होगा।
</Aside>

### ऐप ग्रुप (बैज और रिवर्स प्रॉक्सी)

ऐप और एक्सटेंशन के बीच साझा किया गया एक ऐप ग्रुप बैज काउंट को सिंक करने और होस्ट ऐप द्वारा संग्रहीत रिवर्स-प्रॉक्सी सेटिंग्स को पढ़ने के लिए आवश्यक है।

1. एक्सटेंशन टारगेट में **App Groups** क्षमता जोड़ें और वहां उसी ग्रुप को सक्षम करें जैसा कि होस्ट ऐप में है। यह आवश्यक है — साझा कंटेनर के बिना बैज काउंट और रिवर्स-प्रॉक्सी सेटिंग्स सिंक नहीं की जा सकती हैं।

2. ऐप ग्रुप का नाम प्रदान करें। `Pushwoosh_APPID` की तरह, एक्सटेंशन 7.1.0 से होस्ट ऐप की Info.plist से `PW_APP_GROUPS_NAME` विरासत में लेता है, इसलिए यदि आपने इसे पहले से ही बैज के लिए सेट किया है तो आपको इसे एक्सटेंशन में जोड़ने की आवश्यकता नहीं है। इसे एक्सटेंशन Info.plist में केवल होस्ट मान को ओवरराइड करने के लिए सेट करें, या इसे `pushwooshAppGroupsName` को ओवरराइड करके प्रोग्रामेटिक रूप से प्रदान करें।

```xml title="App Info.plist"
<key>PW_APP_GROUPS_NAME</key>
<string>group.com.example.app</string>
```

<Aside type="caution">
यदि होस्ट ऐप एक रिवर्स प्रॉक्सी (`Pushwoosh_ALLOW_REVERSE_PROXY`) का उपयोग करता है, तो एक्सटेंशन को ऐप द्वारा वहां संग्रहीत प्रॉक्सी URL को पढ़ने के लिए इस ऐप ग्रुप की आवश्यकता होती है। इसके बिना, डिलीवरी इवेंट को सीधे भेजने के बजाय रोक दिया जाता है, प्रॉक्सी को बायपास करते हुए।
</Aside>

## नोटिफिकेशन को कस्टमाइज़ करें (वैकल्पिक)

बेस क्लास कुछ ओवरराइड पॉइंट उजागर करता है, कम से कम से लेकर सबसे अधिक नियंत्रण तक। Pushwoosh अभी भी हर मामले में डिलीवरी इवेंट, बैज, अटैचमेंट और टाइमआउट फॉलबैक चलाता है।

Info.plist कुंजी का उपयोग करने के बजाय ऐप ग्रुप को प्रोग्रामेटिक रूप से सेट करें:

```swift
override func pushwooshAppGroupsName() -> String? {
    "group.com.example.app"
}
```

Pushwoosh द्वारा पुश को प्रोसेस करने से पहले एसिंक्रोनस तैयारी चलाएँ — उदाहरण के लिए, पुश स्टोरीज़ मीडिया को प्रीफ़ेच करना — मानक `didReceive` को ओवरराइड किए बिना। `completion` को मुख्य थ्रेड पर ठीक एक बार कॉल करें:

```swift
override func pushwooshPrepare(for request: UNNotificationRequest,
                              completion: @escaping () -> Void) {
    // async work here
    completion()
}
```

`didReceive` को ओवरराइड करके सामग्री को दिखाए जाने से पहले संशोधित करें। अपने स्वयं के सामग्री हैंडलर के साथ `super` को कॉल करें, इसके अंदर सामग्री को म्यूटेट करें, फिर इसे मूल हैंडलर को फॉरवर्ड करें:

```swift
override func didReceive(_ request: UNNotificationRequest,
                         withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) {
    super.didReceive(request) { content in
        let mutable = (content.mutableCopy() as? UNMutableNotificationContent) ?? content
        // customize `mutable` here
        contentHandler(mutable)
    }
}
```

## लिगेसी इंटीग्रेशन

<Aside type="caution">
`PWNotificationExtensionManager` 7.1.0 से पदावनत है। इसका उपयोग केवल तभी करें जब आप `PushwooshNotificationServiceExtension` को सबक्लास नहीं कर सकते — उदाहरण के लिए, एक एक्सटेंशन जो पहले से ही किसी अन्य SDK के बेस क्लास का विस्तार करता है, या एक क्रॉस-प्लेटफ़ॉर्म रैपर (React Native, Flutter, Unity)। नए इंटीग्रेशन को ऊपर दिए गए बेस क्लास का उपयोग करना चाहिए।
</Aside>

यह निम्न-स्तरीय API एक सादे `UNNotificationServiceExtension` से समान प्रसंस्करण (डिलीवरी इवेंट, बैज, अटैचमेंट) को संचालित करता है:

<Tabs>
<TabItem label="Swift">

```swift
import UserNotifications
import PushwooshFramework

class NotificationService: UNNotificationServiceExtension {

    override func didReceive(_ request: UNNotificationRequest,
                             withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) {
        PWNotificationExtensionManager.sharedManager()
            .handleNotificationRequest(request, contentHandler: contentHandler)
    }
}
```

</TabItem>

<TabItem label="Objective-C">

```objective-c
#import "PWNotificationExtensionManager.h"

@interface NotificationService : UNNotificationServiceExtension

@end

@implementation NotificationService

- (void)didReceiveNotificationRequest:(UNNotificationRequest *)request
                   withContentHandler:(void (^)(UNNotificationContent *))contentHandler {
    [[PWNotificationExtensionManager sharedManager] handleNotificationRequest:request
                                                              contentHandler:contentHandler];
}

@end
```

</TabItem>
</Tabs>

## हमारे साथ अपनी प्रतिक्रिया साझा करें

आपकी प्रतिक्रिया हमें एक बेहतर अनुभव बनाने में मदद करती है, इसलिए यदि आपको SDK इंटीग्रेशन प्रक्रिया के दौरान कोई समस्या आती है तो हम आपसे सुनना पसंद करेंगे। यदि आपको कोई कठिनाई आती है, तो कृपया [इस फ़ॉर्म के माध्यम से](https://docs.google.com/forms/d/e/1FAIpQLSd_0b8jwn-V_JmoPLIxIFYbHACCQhrzidOZV3ELywoQPXRSxw/viewform) हमारे साथ अपने विचार साझा करने में संकोच न करें।