切換語言為:簡體
 iOS中沒有許可權的情況下實現推送通知

iOS中沒有許可權的情況下實現推送通知

  • 爱糖宝
  • 2024-10-12
  • 2049
  • 0
  • 0

前言


在 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 選項,那麼當你呼叫這個方法時,會直接彈出授權彈窗:

 iOS中沒有許可權的情況下實現推送通知

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 秒後,會看到我們發的通知已經出現在了通知中心中了。

 iOS中沒有許可權的情況下實現推送通知

此時可以看到這條通知中下邊會出現兩個按鈕,如果使用者想繼續接受,就會點選繼續接收按鈕,如果不想繼續接受,就會點選停止按鈕。

如果使用者點了停止按鈕,那麼就相當於我們應用的通知許可權被使用者拒絕了,相反的,如果使用者點選了繼續接收按鈕,那麼就相當於我們應用的通知許可權被使用者接受了。

鼓勵使用者完全授權

因此這條通知決定了使用者是否繼續接收我們 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")
        }
    }
}

最後

在我們的應用中實現臨時通知是一種吸引使用者的好方法,這其實也是蘋果推薦的做法,建立一種尊重使用者偏好的非侵入性通知體驗,同時展示你應用通知的價值。

0則評論

您的電子郵件等資訊不會被公開,以下所有項目均必填

OK! You can skip this field.