[Swift] UNUserNotificationCenter 시스템알림 삭제(특정알림만) 알아보기



# [Swift] UNUserNotificationCenter 시스템알림 삭제(특정알림만) 알아보기

안녕하세요 __물먹고하자__ 입니다 :)
최근에 앱의 알림(시스템알림)영역을 앱을 켰을때 초기화 하는부분이 정책이였는데,
앱을 켜도 초기화 되지 않게 해달라는 니즈가 생겨 수정하는중에
__시스템알림__에서 클릭한 내용이 아닌 앱내에서 클릭(읽음처리) 했을때
시스템알림에 __항목을 지워보려고__ 알아봤습니다.

테스트 했던부분에 대해서 공유드립니다.

---
## 1. UNUserNotificationCenter remove 관련 알아보기
> 💡 <a href="https://developer.apple.com/documentation/usernotifications/unusernotificationcenter/removedeliverednotifications%28withidentifiers:%29" target="_blank">removeDeliveredNotifications(withIdentifiers:)</a> : 등록된 특정(id)알림 삭제
💡 <a href="https://developer.apple.com/documentation/usernotifications/unusernotificationcenter/removealldeliverednotifications%28%29" target="_blank">removeAllDeliveredNotifications()</a> : 등록된 모든알림 삭제
💡 그 외 <a href="https://developer.apple.com/documentation/usernotifications/unusernotificationcenter/removependingnotificationrequests%28withidentifiers:%29" target="_blank">removePendingNotificationRequests(withIdentifiers:)</a> : 보류 배달중인(?) 특정(id)알림 삭제
일단 활용부분에서는 __"전체삭제", "특정알림삭제"__ 두가지를 전부 쓸예정입니다.
- 해당기기에서 로그아웃시 : __전체삭제__
- 알림에 해당되는 내용을 읽을었시 : __특정알림삭제__

``` swift
/// 로그아웃, 다른계정 로그인시에는 직전에 있던 알림들을 싹 날려주기.
func removeAllUserNotificationCenter() {
    // 노출된 알림 전부 삭제
    UNUserNotificationCenter.current().removeAllDeliveredNotifications()
}

/// 알림센터 특정 알림만 지우는 로직
/// - Parameter targetIds: [String]
private func removeTargetUserNotificationCenter(targetIds:[String]) {
    UNUserNotificationCenter.current().removeDeliveredNotifications(withIdentifiers: targetIds) // 등록된알림 삭제
    UNUserNotificationCenter.current().removePendingNotificationRequests(withIdentifiers: targetIds) // 예약된 알림도 삭제
}
```

__removePendingNotificationRequests__ 부분은 알림이 조금더 늦게 오는경우도 있다보니 같이 호출해주었습니다.


---
## 2. Identifiers는 어떻게 구하지?
>💡 <a href="https://developer.apple.com/documentation/usernotifications/unusernotificationcenter/getdeliverednotifications%28completionhandler:%29" target="_blank">getDeliveredNotifications</a> : 알림센터에 등록된 알림가져오기(내껏만) __async 지원__


``` swift
/// 시스템에 등록되어있는 알림 리스트 체크하기.
func fetchDeliveredNotifications() {
    let notificationCenter = UNUserNotificationCenter.current()
    notificationCenter.getDeliveredNotifications { notifications in
        for notification in notifications {
            let identifier = notification.request.identifier
            let title = notification.request.content.title
            let body = notification.request.content.body
            let userInfo = notification.request.content.userInfo

            print("Identifier: \(identifier)") // 알림을 제어하는 키값
            print("Title: \(title)")
            print("Body: \(body)")
            print("UserInfo: \(userInfo)")
            print("---")
        }
    }
}
```

>💡저는 아래와 같이 __async 형식__으로 구성을 하였고, __userInfo의 해당되는 키__가 담겨져 있어서 비교해서 가져오는 로직으로 구성하였습니다.

``` swift
// 특정 메뉴의 알림만 지울때
func removeTargetId(_ menuId:String) {
    Task {
        let notifications = await UNUserNotificationCenter.current().deliveredNotifications()
        var targetIds = [String]()
        
        // 1. 특정메뉴기준 필터링 하기
        _ = notifications.filter({
            if let data:[String:Any] = $0.request.content.userInfo["규약된정보"] as? [String:Any],
               let targetMenuId:String = data["menuId"] as? String,
               menuId == targetMenuId {
                // 조건에 맞다면, targetIds 담아주기.
                targetIds.append($0.request.identifier)
                return true
            } else {
                return false
            }
        })
        
        // 2. 대상부분 삭제처리.
        if 0 < targetIds.count {
            self.removeTargetUserNotificationCenter(targetIds: targetIds)
        }
    }
}
```

---
## 마무리
저도 iOS 오래 개발한티가 났던 부분인데, __알림센터는 제어할수 없다가 기본__이였는데 ㅠㅠ
함수부분들도 거의 iOS 10대 다 추가되었던 부분이네요.
__알림이 누적이 얼마만큼 쌓였을때 문제가 없나__ 까지는 테스트 하지 못하였습니다.

시스템 알림영역을 가져오고, 특정 부분만 제거 하는부분 공유드립니다.

오늘은 이만~

즐거운 코딩 되게요.

끝.


댓글