Notification quan trọng để giao tiếp với user. Cần kiểm tra trạng thái authorization trước khi gửi notification hoặc yêu cầu quyền.
UserNotifications Framework Docs
Code kiểm tra trạng thái
import UserNotifications
func checkNotificationStatus() {
let center = UNUserNotificationCenter.current()
center.getNotificationSettings { settings in
DispatchQueue.main.async {
switch settings.authorizationStatus {
case .notDetermined:
print("❓ Chưa hỏi quyền - Có thể request permission")
self.requestNotificationPermission()
case .denied:
print("❌ User từ chối - Hướng dẫn vào Settings bật")
self.showGoToSettingsAlert()
case .authorized:
print("✅ Đã cấp quyền - Có thể gửi notification")
// Tiếp tục logic gửi notification
case .provisional:
print("⚠️ Provisional authorization (iOS 12+)")
case .ephemeral:
print("⚠️ Ephemeral authorization (App Clips)")
@unknown default:
print("Trạng thái mới chưa xử lý")
}
// Thông tin chi tiết thêm
print("Alert setting: \(settings.alertSetting.rawValue)") // .enabled/.disabled
print("Badge setting: \(settings.badgeSetting.rawValue)")
print("Sound setting: \(settings.soundSetting.rawValue)")
print("Lock screen: \(settings.lockScreenSetting.rawValue)")
print("Notification Center: \(settings.notificationCenterSetting.rawValue)")
}
}
}
func requestNotificationPermission() {
UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .badge, .sound]) { granted, error in
if let error = error {
print("Lỗi request permission: \(error)")
}
print("User \(granted ? "đồng ý" : "từ chối") cấp quyền notification")
}
}
func showGoToSettingsAlert() {
let alert = UIAlertController(
title: "Cần quyền thông báo",
message: "Vui lòng bật thông báo trong Cài đặt để nhận cập nhật quan trọng",
preferredStyle: .alert
)
alert.addAction(UIAlertAction(title: "Hủy", style: .cancel))
alert.addAction(UIAlertAction(title: "Mở Cài đặt", style: .default) { _ in
guard let url = URL(string: UIApplication.openSettingsURLString) else { return }
UIApplication.shared.open(url)
})
present(alert, animated: true)
}
Mã hoàn chỉnh (copy-paste chạy được)
import UIKit
import UserNotifications
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
checkNotificationStatus()
}
func checkNotificationStatus() {
UNUserNotificationCenter.current().getNotificationSettings { settings in
DispatchQueue.main.async {
switch settings.authorizationStatus {
case .notDetermined:
self.requestNotificationPermission()
case .denied:
self.showGoToSettingsAlert()
case .authorized:
print("Đã có quyền notification")
default:
break
}
}
}
}
func requestNotificationPermission() {
UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .badge, .sound]) { granted, error in
print("Permission granted: \(granted)")
}
}
func showGoToSettingsAlert() {
let alert = UIAlertController(title: "Thông báo bị tắt",
message: "Bật trong Cài đặt để nhận tin nhắn",
preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "OK", style: .default))
alert.addAction(UIAlertAction(title: "Mở Cài đặt", style: .default) { _ in
UIApplication.shared.open(URL(string: UIApplication.openSettingsURLString)!)
})
self.present(alert, animated: true)
}
}
Khi nào nên kiểm tra?
- App launch (
application(_:didFinishLaunchingWithOptions:)) - Trước khi schedule local notification
- Khi user bật tính năng cần notification (chat, reminder...)
- Khi app trở thành foreground (
applicationDidBecomeActive)
Các loại Authorization Status (iOS 12+)
| Status | Ý nghĩa |
|---|---|
.notDetermined |
Chưa từng hỏi user |
.denied |
User chọn "Don't Allow" |
.authorized |
User chọn "Allow" |
.provisional |
Quiet delivery (iOS 12+) - notification không hiện alert/sound, chỉ vào Notification Center |
.ephemeral |
App Clips temporary authorization |
Best Practices
- Không request permission ngay khi launch - hãy giải thích lý do trước (pre-permission screen)
- Chỉ request khi user thực sự cần (contextual)
- Xử lý graceful khi denied: deep link đến Settings
- Test trên thiết bị thật - Simulator behavior khác nhau