Swift로 로컬에서 푸쉬 알림을 어떻게 띄우게 구현하는지 알아보도록 하겠습니다.
기본 구조
Local Notification은 크게 3가지 파트로 나뉩니다. content
, trigger
, request
입니다. 이 세가지를 통하여 Local Notification을 쉽게 구현할 수 있습니다.
Content
content
는 사용자에게 어떤 내용을 보여줄지에 대한 정보를 담고 있습니다. title
, body
, badge number
, userInfo
, attachments
등이 있습니다. userInfo
는 예상하다시피 원하는 정보를 모두 담을 수 있는 Dictionary
입니다. 알림을 사용자가 눌렀을 때, userInfo
에 들어있는 정보를 접근하여 활용할 수 있습니다.
Trigger
trigger
에는 3가지 타입이 있습니다. time
, calendar
, location
입니다. 이름과 같은 역할을 한다고 보면 쉽습니다. 일정 시간이 지난 후에 작동되길 원한다면 time
, 특정한 날짜에 작동하기 원한다면 calendar
, 특정 위치에 진입할 경우 혹은 나갈 경우에 작동하기 원한다면 location
을 활용할 수 있습니다.
Request
request
는 content
와 trigger
를 가지고 로컬 푸쉬를 등록하기 위해 생성해야 합니다. 또한 identifier
를 꼭 지정해야 합니다. 나중에 해당 알림을 취소하거나 핸들링할 때 쓰이게 됩니다.
구현 방법
이제 구현을 시작해보도록 하겠습니다.
import UserNotifications
Local Notification을 구현하기 위해서 UserNotifications을 사용합니다.
let userNotificationCenter = UNUserNotificationCenter.current()
override func viewDidLoad() {
super.viewDidLoad()
requestNotificationAuthorization()
sendNotification(seconds: 10)
}
func requestNotificationAuthorization() {
}
func sendNotification(seconds: Double) {
}
사용자에게 알림 권한을 요청할 requestNotificationAuthoriztion과 알림을 보낼 sendNotification 함수를 구현할 것입니다.
func requestNotificationAuthorization() {
let authOptions = UNAuthorizationOptions(arrayLiteral: .alert, .badge, .sound)
userNotificationCenter.requestAuthorization(options: authOptions) { success, error in
if let error = error {
print("Error: \(error)")
}
}
}
이 함수를 호출하게 되면 사용자에게 알림 권한에 대한 허용 여부를 묻는 팝업이 나오게 됩니다. 🙆♂️
func sendNotification(seconds: Double) {
let notificationContent = UNMutableNotificationContent()
notificationContent.title = "알림 테스트"
notificationContent.body = "이것은 알림을 테스트 하는 것이다"
let trigger = UNTimeIntervalNotificationTrigger(timeInterval: seconds, repeats: false)
let request = UNNotificationRequest(identifier: "testNotification",
content: notificationContent,
trigger: trigger)
userNotificationCenter.add(request) { error in
if let error = error {
print("Notification Error: ", error)
}
}
}
content
에 title
과 body
를 담았습니다. 이외에도 attachments
에 이미지 등의 rich content를 담을 수 있습니다. 어떤 데이터 타입을 담을 수 있는지는 UNNotificationAttachment를 참고하시면 됩니다. trigger
에는 단순하게 전달받은 시간 이후에 알림이 전달되도록 구현하였습니다.
이제 알림을 받고난 후의 이벤트를 핸들링해야겠죠? UNUserNotificationCenterDelegate를 conform 함으로써 해결할 수 있습니다.
override func viewDidLoad() {
super.viewDidLoad()
userNotificationCenter.delegate = self
requestNotificationAuthorization()
sendNotification(seconds: 10)
}
extension ViewController: UNUserNotificationCenterDelegate {
func userNotificationCenter(_ center: UNUserNotificationCenter,
didReceive response: UNNotificationResponse,
withCompletionHandler completionHandler: @escaping () -> Void) {
completionHandler()
}
func userNotificationCenter(_ center: UNUserNotificationCenter,
willPresent notification: UNNotification,
withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
completionHandler([.alert, .badge, .sound])
}
}
userNotificationCenter의 delegate에 현재 ViewController를 할당하였습니다. 테스트를 위하여 이렇게 구현하였지만 실제로 사용시에는 옳은 방법은 아닙니다. ✅ 실제로 이 delegate는 앱이 완전히 기동되기 전에 할당되어야 합니다.
AppDelegate의 함수인 application(_:willFinishLaunchingWithOptions:) 나 application(_:didFinishLaunchingWithOptions:) 에서 할당을 해야만 한다는 뜻입니다. 만약 이 함수가 호출된 이후에 delegate를 할당하게 된다면 인입되는 알림을 놓칠 수 있습니다.
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
UNUserNotificationCenter.current().delegate = self
return true
}
extension AppDelegate: UNUserNotificationCenterDelegate {
func userNotificationCenter(_ center: UNUserNotificationCenter,
didReceive response: UNNotificationResponse,
withCompletionHandler completionHandler: @escaping () -> Void) {
completionHandler()
}
func userNotificationCenter(_ center: UNUserNotificationCenter,
willPresent notification: UNNotification,
withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
completionHandler([.alert, .badge, .sound])
}
}
이제 앱이 백그라운드에 있어도, 앱이 닫아져 있어도, 폰 화면이 꺼져있어도 알림이 뜨는 것을 확인할 수 있을 것 입니다. 😎
'iOS' 카테고리의 다른 글
[iOS] NSPredicate 문법 정리 (1) | 2020.01.27 |
---|---|
[iOS] fullScreen? overFullScreen? over가 붙으면 무엇이 다를까 (UIModalPresentationStyle) (0) | 2020.01.15 |
[iOS] 웹뷰에서 숫자 키패드로 뜨지 않을 경우 해결방법 (0) | 2019.12.16 |
[iOS] Keyframe Animation으로 애니메이션 구현하는 방법 (0) | 2019.12.15 |
[iOS] UIView Animation으로 애니메이션 구현하는 방법 (0) | 2019.12.15 |