前言
在 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
選項後這段程式碼不會觸發對話方塊來提示使用者允許通知。它會在首次呼叫時靜默地授予我們的應用通知許可權。
由於使用者無感知,所以我們不必等待合適的時機來請求授權,可以在應用一啟動時就呼叫。
傳送通知
爲了展示我們應用通知對使用者的確是有價值的,我們可以開始透過本地或遠端通知來定位使用者。
爲了測試臨時通知流程,以下是傳送一個將在設定後 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") } } }
最後
在我們的應用中實現臨時通知是一種吸引使用者的好方法,這其實也是蘋果推薦的做法,建立一種尊重使用者偏好的非侵入性通知體驗,同時展示你應用通知的價值。