哪位 iOS 开发还不知道,没有权限也能发推送?

这里每天分享一个 iOS 的新知识,快来关注我吧

前言


在 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")
        }
    }
}

最后

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

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

这里每天分享一个 iOS 的新知识,快来关注我吧

本文同步自微信公众号 “iOS新知”,每天准时分享一个新知识,这里只是同步,想要及时学到就来关注我吧!

阅读全文
下载说明:
1、本站所有资源均从互联网上收集整理而来,仅供学习交流之用,因此不包含技术服务请大家谅解!
2、本站不提供任何实质性的付费和支付资源,所有需要积分下载的资源均为网站运营赞助费用或者线下劳务费用!
3、本站所有资源仅用于学习及研究使用,您必须在下载后的24小时内删除所下载资源,切勿用于商业用途,否则由此引发的法律纠纷及连带责任本站和发布者概不承担!
4、本站站内提供的所有可下载资源,本站保证未做任何负面改动(不包含修复bug和完善功能等正面优化或二次开发),但本站不保证资源的准确性、安全性和完整性,用户下载后自行斟酌,我们以交流学习为目的,并不是所有的源码都100%无错或无bug!如有链接无法下载、失效或广告,请联系客服处理!
5、本站资源除标明原创外均来自网络整理,版权归原作者或本站特约原创作者所有,如侵犯到您的合法权益,请立即告知本站,本站将及时予与删除并致以最深的歉意!
6、如果您也有好的资源或教程,您可以投稿发布,成功分享后有站币奖励和额外收入!
7、如果您喜欢该资源,请支持官方正版资源,以得到更好的正版服务!
8、请您认真阅读上述内容,注册本站用户或下载本站资源即您同意上述内容!
原文链接:https://www.shuli.cc/?p=21428,转载请注明出处。
0

评论0

显示验证码
没有账号?注册  忘记密码?