User Notification Framework
사용자의 디바이스에 알림을 주는 프레임워크로, 앱의 실행 여부에 상관없이 사용자에게 새로운 정보를 전달할 수 있다.
앱 아이콘 상단에 뜨는 뱃지와 알림 소리, 알림의 내용을 설정할 수 있으며, 이 기능은 사용자의 디바이스의 권한이 필수적이다. 따라서, 알림을 보내기 전에 사용자에게 권한을 묻는 알림창을 꼭 띄워 주어야 한다. 또한, 이 알림창의 경우에는 각 앱마다 앱의 이름만 달라질뿐, 개별적으로 문구를 설정할 수 없다.
알림은 사용자의 알림 센터에 표시되며, stack 형식으로 차례차례 쌓인다. 설정에서 사용자는 알림 센터에 알림을 줄 앱을 켜고 끌 수 있다.
알림을 사용하는 주된 이유는 여러 가지가 있지만, 앱의 재사용률에 기여하기 위해 notification을 보내는 경우가 많다.
종류를 나눠 보자면, 두 가지로 나눌 수 있다.
- Local
- Remote
Local
개발자가 알람을 등록할 때 Xcode에서 작성한 내용이다. 주로 같은 시간에 특정 알림이 가거나 비슷한 콘텐츠를 지속적으로 알림을 보내야 할 때 사용한다. 예를 들어 보자면, 시간마다, 특정 기간마다 오는 푸시 알림이 이에 속한다.
로컬 알림은 시간별로, 날짜별로, 위치별로 보낼 수 있으며 각각 timeInterval, calendar, locationNotificationTrigger를 이용해서 설정할 수 있다.
local 알림은 identifier에 따라서 최대 64개까지 쌓일 수 있다.
Remote
서버에서 사용자의 기기로 데이터를 보내는 방법을 말하며, 흔히 푸시알림이라고 하는 건 대부분 리모트에 속한다.
로컬과 달리 앱 내부에 전송할 데이터가 없고, 서버에서 컨텐츠와 정보를 담은 데이터를 전송하는 형태이다. 때문에, 매번 다른 시간에 다른 콘텐츠가 담긴 알림이 오게 된다.
다른 시간에, 다른 콘텐츠가 오게 된다면 대부분 Remote Notification을 구현한 거라고 보면 된다.
서버에서 전달한 컨텐츠가 애플의 알림 서버(APNS, Apple Push Notification Service)를 통해 기기에 전달되는 구조이기 때문에, 유료 개발자 계정이 있어야 구현할 수 있으며, 무료 개발자 계정과 시뮬레이터 환경에서는 테스트가 불가능하다.
Local 알림 구현
실제로 로컬 알림을 구현해 보자.
버튼을 눌렀을 때 알림이 오도록 하고 싶다.
그러기 위해서는...
- 사용자에게 권한을 요청해야 한다.
- 권한은 필수적으로 요청해야 하기 때문에 보통 앱을 처음 켰을 때 권한을 요청하는 경우가 많다.
- 알림을 요청한다.
- Content
- Title / Body / Badge로 나뉘며, 알림센터에서 흔히 말하는 알림에서 title / body / badge로 나뉘어 본다면... 뭔지 단번에 알 수 있을 것이다.
- Trigger
- 시간별로, 날짜별로, 위치별로 어떤 것을 매개로 하여 알림을 보낼지를 정하는 것을 말한다.
- Content
- 와! 알림을 보낸다.
생각보다 간단한 것? 같기도 하다.
먼저, 사용자에게 권한을 요청해 보자.
class AppDelegate: UIResponder, UIApplicationDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
UNUserNotificationCenter.current().delegate = self
// 알림 권한 설정
UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound, .badge]) { success, error in // 사용자가 허용했을 때와 안 햇을때
print(success, error)
} // 내 알림만 컨트롤할 수 있음
return true
}
... ...
}
AppDelegate에서 알림 권한을 설정했다. 먼저, UIApplicationDelegate 프로토콜을 추가해 준 후, 딜리게이트를 연결해 준다.
이후, 원하는 곳에서 알림을 주는 버튼을 만들어 주면 된다.
알림을 만들어주는 건 앞서 말했듯 Content와 Trigger 두 가지 내용으로 나뉘는데, Content는 말 그대로 알림을 보낼 내용을 말하고, Trigger는 그 알림을 언제 보낼지 설정해 주면 된다.
각각의 예시를 모두 들어보자면...
func sendNotiFirst() {
let content = UNMutableNotificationContent()
content.title = "알림 제목이에용"
content.body = "알림 몸통이에용"
content.badge = 100
// 얼마 간격으로 보낼 건지! 반복은 할 건지?
// 86400 => 하루에 한 번씩
let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 86400, repeats: false)
let request = UNNotificationRequest(identifier: "\(Date())", content: content, trigger: trigger)
UNUserNotificationCenter.current().add(request) { error in
print(error)
}
}
@IBAction func sendNotification(_ sender: UIButton) {
// 포그라운드에서 알림이 안 뜨는 게 디폴트임 ㅇㅇ
// 백그라운드 상태로 가면 알림이 온다.
let content = UNMutableNotificationContent()
content.title = "알림 제목입니다"
content.body = "알림 몸통이에용"
content.badge = 100
// 2. 언제(알림 언제 보냄?)
// DateComponents() 는 구조체기 땜에 바꿔주려면 변수로 선언해 주어야 함
var component = DateComponents()
component.minute = 5
component.hour = 10
// 일케 대면 매 시간 10시 5분마다 옴~
// weekday => 주에 대한 설정도 가능함
let trigger = UNCalendarNotificationTrigger(dateMatching: component, repeats: false)
// 알림마다도 고유한 identifier가 있당
// 앞서 말했듯 identifier마다 정해진 갯수가 있음
let request = UNNotificationRequest(identifier: "\(Date())", content: content, trigger: trigger)
// 교체하고 싶은 건 identifier로 구현해 주면 댐
// 하나만 선택하면 하나만 사라지는 게 default
// 뱃지 사라지는 것도 구현해야 함!!'
UNUserNotificationCenter.current().add(request) { error in
print(error)
}
}
공부해서 locationNotification도 구현하까 싶었는데 지금껏 뭔가 사용했던 앱들을 생각했을 때 잘 사용되지 않는 것 같아서 패스~~ 하도록 하겠당.
실제 알림 화면은 요렇다.
알림센터에 쌓인 알림을 지우는 방법
알림 센터에 쌓인 알림을 지우는 방법은 뭐가 있을까?
일단 기본적으로 생각해 보면, 클릭해서 들어간 특정한 알림 하나만 지우는 방법이 있을 것이다. 아니면 그와 관련된 알림들을 지워주거나!
또 다른 방법으로는 앱을 켰을 때, 알림 센터에 있는 알림을 한 번에 지워줄 수도 있겠다. 이는 카카오톡에 적용되어 있는 방법이다. 카카오톡의 경우 하나의 알림을 클릭해서 앱에 들어가기만 해도 알림 센터에 있는 전체 알림이 사라진다.
고럼, 요 방법들을 알아보자.
SceneDelegate에서 설정해 주면 된다.
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
var window: UIWindow?
... ...
func sceneDidBecomeActive(_ scene: UIScene) {
UIApplication.shared.applicationIconBadgeNumber = 0
// 사용자에게 이미 전달된 notification
// 카카오톡에서 사용하는 방법으로, 앱을 켰을 때 모든 알림을 지워주는 방법을 말한다!
UNUserNotificationCenter.current().removeAllDeliveredNotifications()
// 대기 중인 알림 중 특정한 알림을 제거할 때 사용할 수 있을 것이다.
// 투두 알림 받기를 해놨는데 그걸 제거하게 되면 우리가 대기해놨던 알림도 제거해줘야 할 것이다.
// 요건 특정한 알림을 제거해 주는 method이고...
// UNUserNotificationCenter.current().removePendingNotificationRequests(withIdentifiers: <#T##[String]#>)
// 사용자에게 전돨될 예정인 notification
// 요건 전달될 예정인 notification을 전체 삭제해 주는 방법이다.
UNUserNotificationCenter.current().removeAllPendingNotificationRequests()
}
... ...
}
'iOS > App' 카테고리의 다른 글
[iOS] NavigationBar BackgroundColor 노치까지 채우기 (0) | 2023.12.02 |
---|---|
[RxSwift] Single (1) | 2023.11.21 |
[iOS] Push Notification 보내기 (1) | 2023.11.13 |
[iOS] URLSession (0) | 2023.09.01 |
[CoreLocation] Location (1) | 2023.08.28 |