# iOS বার্তা ডেলিভারি ট্র্যাকিং

Pushwoosh-এ একটি [API মেথড](/bn/developer/api-reference/device-api#messagedeliveryevent) আছে যা পুশ নোটিফিকেশনের ডেলিভারি ট্র্যাক করে। iOS অ্যাপগুলি এই মেথডটি সরাসরি সমর্থন করে না, কারণ iOS-এ পুশ নোটিফিকেশনগুলি OS দ্বারা পরিচালিত হয়, Pushwoosh SDK দ্বারা নয়। আপনি আপনার প্রজেক্টে একটি Notification Service Extension যোগ করে ডেলিভারি ট্র্যাকিং যোগ করতে পারেন। এই পৃষ্ঠাটি 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>

## Notification Service Extension যোগ করুন

১. Xcode-এ, **File** > **New** > **Target...** নির্বাচন করুন।

২. **Notification Service Extension** নির্বাচন করুন এবং **Next** চাপুন।

<img src="/ios-push-notifications-ios-message-delivery-tracking-1.webp" alt="Notification Service Extension নির্বাচিত সহ Xcode টার্গেট টেমপ্লেট পিকার"/>

৩. প্রোডাক্টের নাম লিখুন এবং **Finish** চাপুন।

<Aside type="caution">
**Finish** চাপার পরে যে ডায়ালগটি দেখানো হয় তাতে **Activate** নির্বাচন করবেন না।
</Aside>

৪. **Activate scheme** প্রম্পটে **Cancel** চাপুন।

<img
  src="/ios-push-notifications-ios-message-delivery-tracking-2.webp"
  alt="Cancel হাইলাইট করা সহ Activate scheme প্রম্পট"
  style={{ display: "block", margin: "0 auto", maxWidth: "40%", height: "auto" }}
  width="400"
/>

বাতিল করার মাধ্যমে, আপনি Xcode-কে আপনার সদ্য তৈরি করা এক্সটেনশনের পরিবর্তে আপনার অ্যাপ ডিবাগ করতে রাখবেন। যদি আপনি ভুলবশত এটি সক্রিয় করে ফেলেন, আপনি Xcode-এর মধ্যে আপনার অ্যাপ ডিবাগিং-এ ফিরে যেতে পারেন।

## Notification Service Extension-এর জন্য ডিপেন্ডেন্সি (শুধুমাত্র CocoaPods)

আপনি যদি ডিপেন্ডেন্সি পরিচালনা করার জন্য Swift Package Manager ব্যবহার করেন, তবে আপনি এই ধাপটি এড়িয়ে যেতে পারেন, কারণ ডিপেন্ডেন্সিগুলি স্বয়ংক্রিয়ভাবে যোগ হয়ে যায়।

আপনার `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>

### App ID

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>

### App Group (ব্যাজ এবং রিভার্স প্রক্সি)

অ্যাপ এবং এক্সটেনশনের মধ্যে শেয়ার করা একটি App Group ব্যাজ সংখ্যা সিঙ্ক করতে এবং হোস্ট অ্যাপ দ্বারা সংরক্ষিত রিভার্স-প্রক্সি সেটিংস পড়তে প্রয়োজন।

১. এক্সটেনশন টার্গেটে **App Groups** ক্যাপাবিলিটি যোগ করুন এবং সেখানে হোস্ট অ্যাপের মতো একই গ্রুপ সক্রিয় করুন। এটি আবশ্যক — শেয়ার্ড কন্টেইনার ছাড়া ব্যাজ সংখ্যা এবং রিভার্স-প্রক্সি সেটিংস সিঙ্ক করা যাবে না।

২. App Group-এর নাম দিন। `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`) ব্যবহার করে, তাহলে এক্সটেনশনটির এই App Group-টি প্রয়োজন অ্যাপ দ্বারা সংরক্ষিত প্রক্সি URL পড়ার জন্য। এটি ছাড়া, ডেলিভারি ইভেন্টটি সরাসরি পাঠানোর পরিবর্তে আটকে রাখা হয়, প্রক্সি বাইপাস করে।
</Aside>

## নোটিফিকেশন কাস্টমাইজ করুন (ঐচ্ছিক)

বেস ক্লাসটি কয়েকটি ওভাররাইড পয়েন্ট প্রকাশ করে, যা কম থেকে বেশি নিয়ন্ত্রণের সুযোগ দেয়। Pushwoosh প্রতিটি ক্ষেত্রে ডেলিভারি ইভেন্ট, ব্যাজ, অ্যাটাচমেন্ট এবং টাইমআউট ফলব্যাক চালায়।

Info.plist কী ব্যবহার করার পরিবর্তে প্রোগ্রাম্যাটিকভাবে App Group সেট করুন:

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

Pushwoosh পুশ প্রসেস করার আগে অ্যাসিঙ্ক্রোনাস প্রস্তুতি চালান — উদাহরণস্বরূপ, Push Stories মিডিয়া প্রিফেচিং — স্ট্যান্ডার্ড `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) আমাদের সাথে আপনার চিন্তা শেয়ার করতে দ্বিধা করবেন না।