• 作者:老汪软件技巧
  • 发表时间:2024-10-12 21:03
  • 浏览量:

前言

在 iOS App 开发中,推送通知是一个非常有效地触答和吸引用户的措施,通知可以成为让用户保持用户的参与度。

但大家都知道,苹果上每个 App 想要发推送给用户,都需要首先申请对应的权限,只有用户明确点了允许之后才可以。

大部分的 App 都是在启动时直接申请权限,这样的话,用户可能会因为不了解 App 的情况而拒绝授权,就会导致 App 无法发送通知。

其实在 iOS 12 中有个方案叫做临时通知。这功能允许应用在没有申请到权限的情况下发送通知。

今天就来聊聊这个不为人知的隐藏功能。

请求临时授权

要请求临时授权,我们需要使用与请求完全授权相同的方法 requestAuthorization(options:completionHandler:),但需要添加 provisional 选项。

let center = UNUserNotificationCenter.current()
center.requestAuthorization(options: [.alert, .sound, .badge, .provisional]) { isSuccess, error in
    if let error {
        print("Error requesting notification authorization: \(error)")
    } else if isSuccess {
        print("Requesting notification authorization is successed")
    } else {
        print("Requesting notification authorization is failed")
    }
}

如果不加 provisional 选项,那么当你调用这个方法时,会直接弹出授权弹窗:

加 provisional 选项后这段代码不会触发对话框来提示用户允许通知。它会在首次调用时静默地授予我们的应用通知权限。

由于用户无感知,所以我们不必等待合适的时机来请求授权,可以在应用一启动时就调用。

发送通知

为了展示我们应用通知对用户的确是有价值的,我们可以开始通过本地或远程通知来定位用户。这里我们将发送一个本地通知作为示例,但如果你想尝试远程推送通知,可以查看我之前的几篇文章。

打开推送权限_打开推送授权后才能推送_

使用 iOS 模拟器测试推送

Xcode 14 模拟器支持远程推送

为了测试临时通知流程,以下是发送一个将在设置后 10 秒触发的本地通知的示例:

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
    
    let center = UNUserNotificationCenter.current()
    center.requestAuthorization(options: [.alert, .sound, .badge, .provisional]) { isSuccess, error in
        if let error {
            print("Error requesting notification authorization: \(error)")
        } else if isSuccess {
            print("Requesting notification authorization is successed")
            self.scheduleTestNotification()
        } else {
            print("Requesting notification authorization is failed")
        }
    }
    
    return true
}
func scheduleTestNotification() {
    let content = UNMutableNotificationContent()
    content.title = "发现新事物!"
    content.body = "点击探索你还未尝试的功能。"
    
    let trigger = UNTimeIntervalNotificationTrigger(
        timeInterval: 10,
        repeats: false
    )
    let request = UNNotificationRequest(
        identifier: UUID().uuidString,
        content: content,
        trigger: trigger
    )
    
    UNUserNotificationCenter.current().add(request) { error in
        if let error = error {
            print("Error scheduling notification: \(error)")
        }
    }
}

启动 App 后,我们退回到后台,等待 10 秒后,会看到我们发的通知已经出现在了通知中心中了。

此时可以看到这条通知中下边会出现两个按钮,如果用户想继续接受,就会点击继续接收按钮,如果不想继续接受,就会点击停止按钮。

如果用户点了停止按钮,那么就相当于我们应用的通知权限被用户拒绝了,相反的,如果用户点击了继续接收按钮,那么就相当于我们应用的通知权限被用户接受了。

鼓励用户完全授权

因此这条通知决定了用户是否继续接收我们 App 的通知,那么我们就需要慎重考虑这条通知的文案和时机,在用户体验到我们通知的好处之后,再发送这个通知,这样用户大概率就会选择继续接收通知。

如果用户仍然选择拒绝授权,我们还可以在 App 内的合适位置引导用户到设置页面去手动开启。

我这里写一个简单的示例,大家可以参考,先判断是否有权限,然后引导用户去设置页面。

class EnableNotificationsViewController: UIViewController {
    
    private let titleLabel: UILabel = {
        let label = UILabel()
        label.text = "启用通知提示"
        label.textAlignment = .center
        label.font = UIFont.systemFont(ofSize: 20, weight: .bold)
        label.translatesAutoresizingMaskIntoConstraints = false
        return label
    }()
    
    private let descriptionLabel: UILabel = {
        let label = UILabel()
        label.text = "启用通知横幅和声音,保持最新了解我们的应用提供的一切。"
        label.textAlignment = .center
        label.numberOfLines = 0
        label.translatesAutoresizingMaskIntoConstraints = false
        return label
    }()
    
    private let settingsButton: UIButton = {
        let button = UIButton(type: .system)
        button.setTitle("去设置", for: .normal)
        button.setTitleColor(.white, for: .normal)
        button.backgroundColor = .systemBlue
        button.layer.cornerRadius = 8
        button.translatesAutoresizingMaskIntoConstraints = false
        return button
    }()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        setupUI()
    }
    
    private func setupUI() {
        view.backgroundColor = .white
        
        view.addSubview(titleLabel)
        view.addSubview(descriptionLabel)
        view.addSubview(settingsButton)
        
        NSLayoutConstraint.activate([
            titleLabel.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 20),
            titleLabel.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 20),
            titleLabel.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -20),
            
            descriptionLabel.topAnchor.constraint(equalTo: titleLabel.bottomAnchor, constant: 20),
            descriptionLabel.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 20),
            descriptionLabel.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -20),
            
            settingsButton.topAnchor.constraint(equalTo: descriptionLabel.bottomAnchor, constant: 30),
            settingsButton.centerXAnchor.constraint(equalTo: view.centerXAnchor),
            settingsButton.widthAnchor.constraint(equalToConstant: 120),
            settingsButton.heightAnchor.constraint(equalToConstant: 44)
        ])
        
        settingsButton.addTarget(self, action: #selector(openSettings), for: .touchUpInside)
    }
    
    @objc private func openSettings() {
        if let url = URL(string: UIApplication.openSettingsURLString) {
            UIApplication.shared.open(url)
        }
    }
}
// 检查通知权限
func checkNotificationAuthorization() {
    let center = UNUserNotificationCenter.current()
    center.getNotificationSettings { settings in
        if settings.authorizationStatus == .authorized {
            print("Notification authorization is authorized")
        } else {
            print("Notification authorization is not authorized")
        }
    }
}

最后

在我们的应用中实现临时通知是一种吸引用户的好方法,这其实也是苹果推荐的做法,创建一种尊重用户偏好的非侵入性通知体验,同时展示你应用通知的价值。

希望这篇文章对你有所帮助,如果你喜欢这篇文章,欢迎点赞、收藏、评论和转发,我们下期再见。