# iOS পুশ প্রাইমার

পুশ প্রাইমার হলো একটি সফট অপ্ট-ইন ডায়ালগ যা আপনি iOS সিস্টেম পুশ পারমিশন প্রম্পটের **আগে** দেখান। iOS প্রতি ইনস্টলে মাত্র একবার সিস্টেম প্রম্পট দেখায় — যদি ব্যবহারকারী **Don't Allow** ট্যাপ করে, তাহলে পুশ নোটিফিকেশন বন্ধ হয়ে যায় যতক্ষণ না তারা Settings থেকে এটি আবার চালু করে। প্রাইমার আপনাকে প্রথমে এর সুবিধা ব্যাখ্যা করতে এবং সঠিক মুহূর্তে জিজ্ঞাসা করার সুযোগ দেয়, যাতে আপনি সেইসব ব্যবহারকারীদের জন্য ওয়ান-শট সিস্টেম প্রম্পটটি ব্যবহার করতে পারেন যারা ইতিমধ্যেই হ্যাঁ বলেছে।

সংস্করণ 7.1.1 থেকে উপলব্ধ। প্রাইমারটি `PushwooshFramework`-এর একটি অংশ; কোনো অতিরিক্ত মডিউলের প্রয়োজন নেই।

<figure style={{ textAlign: "center" }}>
  <img
    src="/ios-push-primer-1.webp"
    alt="সিস্টেম পারমিশন প্রম্পটের আগে দেখানো পুশ প্রাইমার ডায়ালগ"
    style={{ display: "block", margin: "0 auto", maxWidth: "300px", height: "auto" }}
    width="300"
  />
  <figcaption>iOS সিস্টেম পারমিশন প্রম্পটের আগে দেখানো পুশ প্রাইমার</figcaption>
</figure>

## এটি কিভাবে কাজ করে

প্রাইমারটি সম্পূর্ণভাবে স্টেট-অ্যাওয়ার। এটি বর্তমান নোটিফিকেশন অথরাইজেশন স্ট্যাটাস পড়ে এবং কী করতে হবে তা নির্ধারণ করে, তাই প্রতিটি লঞ্চে এটি কল করা নিরাপদ:

- **Not determined** — প্রাইমার দেখায়; গ্রহণ করলে এটি সিস্টেম পারমিশন প্রম্পট ট্রিগার করে।
- **Authorized or provisional** — প্রাইমারটি নিঃশব্দে দমন করে (কিছুই দেখানো হয় না)।
- **Denied** — প্রাইমার দেখায়; গ্রহণ করলে এটি ব্যবহারকারীকে অ্যাপের নোটিফিকেশন সেটিংসে নিয়ে যায় (যখন `fallbackToSettings` সক্রিয় থাকে)।

আপনি সিদ্ধান্ত নেন **কখন** প্রাইমার কল করবেন (উদাহরণস্বরূপ অনবোর্ডিংয়ের পরে বা কোনো মূল অ্যাকশনের পরে)। SDK নিজে থেকে কোনো টাইমিং আরোপ করে না, নীচে বর্ণিত ঐচ্ছিক `minInterval` থ্রটল ছাড়া।

## বেসিক ব্যবহার

একটি ফ্লুয়েন্ট বিল্ডার দিয়ে প্রাইমার কনফিগার করুন এবং `present` কল করুন। ন্যূনতম সেটআপের জন্য একটি টাইটেল, একটি মেসেজ এবং দুটি বাটনের টাইটেল প্রয়োজন।

<Tabs>
<TabItem label="Swift">
```swift
import PushwooshFramework

Pushwoosh.configure.pushPrimer
    .title("Stay in the loop")
    .message("Get notified about deals and order updates first")
    .acceptButton("Enable notifications")
    .declineButton("Not now")
    .present()
```
</TabItem>
</Tabs>

<Aside type="note">
অ্যাপ UI স্ক্রিনে আসার পরে প্রাইমার কল করুন (উদাহরণস্বরূপ, লঞ্চের কিছুক্ষণ পরে, বা আপনার ফ্লো-এর একটি নির্দিষ্ট ধাপে), যাতে এটি আপনার ইন্টারফেসের উপরে প্রদর্শিত হতে পারে।
</Aside>

## স্টাইল এবং পজিশন

সিস্টেম অ্যালার্ট এবং কাস্টম শীটের মধ্যে বেছে নিতে `style` ব্যবহার করুন, এবং কাস্টম শীট স্থাপন করতে `position` ব্যবহার করুন। প্রতিটি পজিশনের নিজস্ব ডিফল্ট ডিজাইন রয়েছে।

| Value | Description |
|-------|-------------|
| `.alert` | সিস্টেম `UIAlertController`। পজিশন উপেক্ষা করা হয়। |
| `.sheet` + `.bottom` | বটম শীট যা উপরে স্লাইড করে, একটি গ্র্যাবার এবং ফুল-উইডথ বাটন সহ (ডিফল্ট)। |
| `.sheet` + `.top` | কমপ্যাক্ট ব্যানার যা উপর থেকে নোটিফিকেশনের মতো নেমে আসে। |
| `.sheet` + `.center` | কেন্দ্রীয় ডায়ালগ যা স্কেল এবং ফেইড ইন হয়। |

<Tabs>
<TabItem label="Swift">
```swift
Pushwoosh.configure.pushPrimer
    .style(.sheet)
    .position(.top)
    .title("Stay in the loop")
    .message("Get notified about deals and order updates first")
    .acceptButton("Enable notifications")
    .declineButton("Not now")
    .present()
```
</TabItem>
</Tabs>

<img src="/ios-push-primer-positions.webp" alt="পুশ প্রাইমার বটম, টপ এবং সেন্টার পজিশনে"/>

## কাস্টমাইজেশন

সমস্ত ভিজ্যুয়াল সেটিংস ঐচ্ছিক — লাইট এবং ডার্ক মোডের সাথে খাপ খাইয়ে নেওয়া নেটিভ ডিফল্টগুলি ব্যবহার করতে এগুলি বাদ দিন।

<Tabs>
<TabItem label="Swift">
```swift
Pushwoosh.configure.pushPrimer
    .style(.sheet)
    .position(.center)
    .title("Stay in the loop")
    .message("Get notified about deals and order updates first")
    .acceptButton("Enable notifications")
    .declineButton("Not now")
    .image(UIImage(named: "PrimerHero"))          // local image, or .imageURL("https://…")
    .backgroundColor(.systemBackground)
    .titleColor(.label)
    .messageColor(.secondaryLabel)
    .acceptButtonColor(.systemBlue)
    .acceptButtonTextColor(.white)
    .declineButtonColor(.clear)
    .declineButtonTextColor(.secondaryLabel)
    .cornerRadius(24)
    .buttonCornerRadius(14)
    .buttonBorderColor(.separator)
    .present()
```
</TabItem>
</Tabs>

কাস্টমাইজেশন রেফারেন্স:

| Setter | Description |
|--------|-------------|
| `image` / `imageURL` | একটি লোকাল `UIImage` বা একটি রিমোট URL। সেন্টার এবং বটম লেআউটে একটি বৃত্ত হিসাবে এবং টপ ব্যানারে আইকন হিসাবে রেন্ডার করা হয়। একটি লোকাল ইমেজ URL-এর চেয়ে অগ্রাধিকার পায়। |
| `backgroundColor` | কার্ডের সলিড ব্যাকগ্রাউন্ড রঙ। |
| `backgroundGradient` | রঙের একটি অ্যারে যা একটি সফট মাল্টি-কালার গ্রেডিয়েন্ট হিসাবে রেন্ডার করা হয়। `backgroundColor`-কে ওভাররাইড করে। |
| `titleColor` / `messageColor` | টাইটেল এবং মেসেজের টেক্সট রঙ। |
| `acceptButtonColor` / `acceptButtonTextColor` | অ্যাক্সেপ্ট বাটনের ব্যাকগ্রাউন্ড এবং টেক্সট রঙ। অ্যাক্সেপ্ট রঙটি ডিফল্ট আইকনকেও রঙিন করে। |
| `declineButtonColor` / `declineButtonTextColor` | ডিক্লাইন বাটনের ব্যাকগ্রাউন্ড এবং টেক্সট রঙ। |
| `cornerRadius` | কার্ডের কর্নার রেডিয়াস। |
| `buttonCornerRadius` / `buttonBorderColor` | উভয় বাটনের কর্নার রেডিয়াস এবং বর্ডার রঙ। |

<Aside type="note">
প্রাইমারটি ঠিক সেই স্ট্রিংগুলি দেখায় যা আপনি পাস করেন। একাধিক ভাষার জন্য, লোকালাইজড স্ট্রিং পাস করুন (উদাহরণস্বরূপ `NSLocalizedString` দিয়ে)।
</Aside>

## আচরণগত সেটিংস

### সেটিংস ফলব্যাক

ডিফল্টরূপে, যখন নোটিফিকেশনগুলি ইতিমধ্যে ডিনাই করা থাকে, তখন প্রাইমারটি দেখানো হয় এবং অ্যাক্সেপ্ট বাটনটি ব্যবহারকারীকে অ্যাপের নোটিফিকেশন সেটিংসে নিয়ে যায়। ডিনাইড স্টেটে প্রাইমারটি সম্পূর্ণরূপে দমন করতে `false` পাস করুন।

```swift
.fallbackToSettings(false)
```

### প্রদর্শনের ফ্রিকোয়েন্সি

ডিফল্টরূপে প্রাইমারের কোনো বিল্ট-ইন থ্রটলিং নেই — আপনি যখনই `present` কল করেন তখনই এটি দেখায় (এবং নোটিফিকেশন অথরাইজড হয়ে গেলে এটি স্বয়ংক্রিয়ভাবে দমন করা হয়)। প্রাইমারটি কত ঘন ঘন পুনরায় প্রদর্শিত হবে তা সীমাবদ্ধ করতে `minInterval` ব্যবহার করুন। শেষ প্রদর্শনের সময়টি লঞ্চ জুড়ে সংরক্ষিত থাকে।

```swift
.minInterval(7 * 24 * 60 * 60)   // show at most once a week
```

## ফলাফল হ্যান্ডলিং

ফলাফলের উপর প্রতিক্রিয়া জানাতে `present`-এ একটি কমপ্লিশন পাস করুন।

<Tabs>
<TabItem label="Swift">
```swift
Pushwoosh.configure.pushPrimer
    .title("Stay in the loop")
    .message("Get notified about deals and order updates first")
    .acceptButton("Enable notifications")
    .declineButton("Not now")
    .present { outcome in
        switch outcome {
        case .accepted:            break   // দেখানো হয়েছে, ব্যবহারকারী গ্রহণ করেছে, সিস্টেম প্রম্পটের জন্য অনুরোধ করা হয়েছে
        case .declined:            break   // দেখানো হয়েছে, ব্যবহারকারী প্রত্যাখ্যান করেছে
        case .suppressed:          break   // দেখানো হয়নি (ইতিমধ্যে অনুমোদিত, বা থ্রটল করা হয়েছে)
        case .redirectedToSettings: break  // ডিনাইড স্টেট, ব্যবহারকারীকে সেটিংসে পাঠানো হয়েছে
        @unknown default:          break
        }
    }
```
</TabItem>
</Tabs>

চূড়ান্ত সিস্টেম-প্রম্পটের ফলাফল (গ্রান্টেড/ডিনাইড স্টেট এবং ডিভাইস টোকেন) নিয়মিত রেজিস্ট্রেশন কলব্যাকের মাধ্যমে আসে — প্রাইমারটি অ্যাক্সেপ্ট করার সময় `registerForPushNotifications` পুনরায় ব্যবহার করে এবং সেই চেইনটি ডুপ্লিকেট করে না।

## রেফারেন্স

<CardGrid>
  <LinkCard
    title="iOS SDK API রেফারেন্স"
    description="সমস্ত পাবলিক ক্লাস, মেথড এবং প্রপার্টি কভার করে সম্পূর্ণ টেকনিক্যাল ডকুমেন্টেশন।"
    href="https://pushwoosh.github.io/pushwoosh-ios-sdk/"
  />
  <LinkCard
    title="iOS SDK কাস্টমাইজ করা"
    description="আপনার অ্যাপের জন্য Pushwoosh iOS SDK কাস্টমাইজ করার অন্যান্য উপায়।"
    href="/developer/pushwoosh-sdk/ios-sdk/customizing-ios-sdk/"
  />
</CardGrid>