# iOS 推送前置提示

推送前置提示 (push primer) 是一个在显示 iOS 系统推送权限提示**之前**展示的软性选择加入对话框。iOS 在每次安装后仅显示一次系统提示——如果用户点击**不允许**，推送功能将丢失，直到他们在“设置”中重新启用。前置提示让您可以先解释其价值，并在合适的时机请求权限，这样您就可以将仅有一次的系统提示机会用在已经同意的用户身上。

自 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>

## 工作原理

前置提示完全感知状态。它会读取当前的通知授权状态并决定如何操作，因此在每次启动时调用它都是安全的：

- **尚未决定** — 显示前置提示；接受后会触发系统权限提示。
- **已授权或临时授权** — 静默抑制前置提示（不显示任何内容）。
- **已拒绝** — 显示前置提示；接受后会将用户引导至应用的通知设置（当启用 `fallbackToSettings` 时）。

您可以决定**何时**调用前置提示（例如，在用户引导后或在关键操作后）。SDK 本身不强加任何时机，除了下面描述的可选 `minInterval` 节流阀。

## 基本用法

使用流式构建器配置前置提示并调用 `present`。最小化设置需要一个标题、一条消息和两个按钮的标题。

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

Pushwoosh.configure.pushPrimer
    .title("获取最新动态")
    .message("第一时间获取优惠和订单更新通知")
    .acceptButton("启用通知")
    .declineButton("以后再说")
    .present()
```
</TabItem>
</Tabs>

<Aside type="note">
在前置提示出现在屏幕上后（例如，在启动片刻后，或在流程中特意安排的步骤），再调用前置提示，以便它可以在您的界面之上呈现。
</Aside>

## 样式和位置

使用 `style` 在系统警报和自定义表单之间进行选择，并使用 `position` 来放置自定义表单。每个位置都有其自己的默认设计。

| 值 | 描述 |
|-------|-------------|
| `.alert` | 系统 `UIAlertController`。位置将被忽略。 |
| `.sheet` + `.bottom` | 从底部滑出的底部表单，带有一个抓手和全宽按钮（默认）。 |
| `.sheet` + `.top` | 从顶部降下的紧凑横幅，类似于通知。 |
| `.sheet` + `.center` | 居中对话框，缩放并淡入。 |

<Tabs>
<TabItem label="Swift">
```swift
Pushwoosh.configure.pushPrimer
    .style(.sheet)
    .position(.top)
    .title("获取最新动态")
    .message("第一时间获取优惠和订单更新通知")
    .acceptButton("启用通知")
    .declineButton("以后再说")
    .present()
```
</TabItem>
</Tabs>

<img src="/ios-push-primer-positions.webp" alt="推送前置提示在底部、顶部和中间位置的样式"/>

## 自定义

所有视觉设置都是可选的——省略它们以使用适应浅色和深色模式的原生默认值。

<Tabs>
<TabItem label="Swift">
```swift
Pushwoosh.configure.pushPrimer
    .style(.sheet)
    .position(.center)
    .title("获取最新动态")
    .message("第一时间获取优惠和订单更新通知")
    .acceptButton("启用通知")
    .declineButton("以后再说")
    .image(UIImage(named: "PrimerHero"))          // 本地图片，或 .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>

自定义参考：

| 设置器 | 描述 |
|--------|-------------|
| `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)   // 每周最多显示一次
```

## 处理结果

向 `present` 传递一个完成回调以对结果做出反应。

<Tabs>
<TabItem label="Swift">
```swift
Pushwoosh.configure.pushPrimer
    .title("获取最新动态")
    .message("第一时间获取优惠和订单更新通知")
    .acceptButton("启用通知")
    .declineButton("以后再说")
    .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>