Local Notification 예제 문의
320
投稿した質問数 21
예제를 전부 구현한 상태에서
아래 코드를 통해서 뱃지 숫자를 1씩 올려서 보내게
되어 있습니다.
func scheduleNotification() {
//notification 내용 설정
let content = UNMutableNotificationContent()
content.title = "Local Notification 테스트 1"
content.subtitle = "앱 알람 테스트 중입니다."
content.sound = .default
content.badge = NSNumber(value: UIApplication.shared.applicationIconBadgeNumber + 1)하지만 아래 코드에 의해 뱃지가 0 으로 리셋되기에
항상 1만 발송하게 됩니다.
.onChange(of: scenePhase) { newValue in
if newValue == .active {
UIApplication.shared.applicationIconBadgeNumber = 0
}
}추가적으로 5초 딜레이로 설정후 로컬노티 여러번 누른후에
앱을 종료하고 기다리면 노티가 여러개 오지만
모두 뱃지 1로 오기 때문에 앱아이콘에 뱃지는 1로 계속
옵니다.
실무에서 로컬노티에 카운터를 현재 뱃지 카운터에 + 1 해서
보내는건 실효성이 없어보이는데요.
따로 해결할 방법이 있을까요 ? 조언 부탁드립니다.
강의 관련된 질문은 언제나 환영입니다 😄
코드 관련 상세하게 작성해주시면 더 좋아요! (상세코드를 붙여넣기 해주세요)
마크다운을 사용해서 편리하게 글을 작성하세요
먼저 유사한 질문이 있었는지 먼저 검색 해보는 습관~
인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요
回答 2
1
안녕하세요 랑프님.
앱이 활성화될 때마다 UIApplication.shared.applicationIconBadgeNumber = 0으로 뱃지가 초기화되므로, 로컬 알림을 여러 번 발송해도 모든 알림이 뱃지 값이 1인 상태로 도착합니다. 이는 알림의 뱃지 값이 항상 초기화되기 때문에 발생합니다.
이를 해결하기 위해서 UserDefaults 를 사용해서 뱃지 값을 저장하고 불러오는 방법을 사용하면 됩니다.
수정된 코드는 다음과 같습니다. *수정한 부분만 사진으로 올려드리고 전체 코드는 맨아래 있습니다.
앱이 종료 되어도 뱃지값 저장하기

CancelNotifiactaion 에서 값 초기화

View에서 화면이 나타날때 reset 하는거 삭제

수정된 코드
class NotificationManager {
static let instance = NotificationManager() // 인스턴스 생성
func requestAuthorization() {
let option: UNAuthorizationOptions = [.alert, .sound, .badge]
// UserNotification 접근
UNUserNotificationCenter.current().requestAuthorization(options: option) { (success, error) in
if let error = error {
print("에러: \(error)")
} else {
print("성공")
}
}
}
func scheduleNotification() {
// UserDefaults 에다가 자장할 currentBadgeCount
let currentBadgeCount = UserDefaults.standard.integer(forKey: "badgeCount")
// 값을 1씩 증가 시킴
let newBadgeCount = currentBadgeCount + 1
// 증가한다음에서는 값을 저장
UserDefaults.standard.set(newBadgeCount, forKey: "badgeCount")
// notification 내용 설정
let content = UNMutableNotificationContent()
content.title = "Local Notification 테스트 1"
content.subtitle = "앱 알람 테스트 중입니다"
content.sound = .default
content.badge = NSNumber(value: newBadgeCount) // 1씩 증가 시킴
// Trigger 2가지 종류
// 1.시간 기준 : Interval - 몇 초 뒤에 울릴것인지 딜레이 설정 repeats 반복 여부 설정 (최소 1분이여지 반복이 돔)
let timeTrigger = UNTimeIntervalNotificationTrigger(timeInterval: 5.0, repeats: false)
// 2.날짜 기준 : DateMating 은 DateComponent 기준맞는 알림
var dateComponents = DateComponents()
dateComponents.hour = 8 // hour 를 24시간 기준
dateComponents.minute = 30
dateComponents.weekday = 1 // 1은 일요일이 되고, 6은 금요일이 됨
// let calendarTigger = UNCalendarNotificationTrigger(dateMatching: dateComponents, repeats: true)
// 설정한 값을 NotificationCenter 에 요청하기
let request = UNNotificationRequest(
identifier: UUID().uuidString, // 각각의 request ID 값 String 을 uuid 값으로 설정
content: content,
trigger: timeTrigger)
UNUserNotificationCenter.current().add(request)
}
// 생성된 Notification Cancel 하기
func cancelNotification() {
// peding notification 은 tigger 상에서 만족된 조건이 되어도 더이상 notification 되지 않게 하기
UNUserNotificationCenter.current().removeAllPendingNotificationRequests()
// 아이폰 상태바를 내렸을때 남아있는 notification 없애기
UNUserNotificationCenter.current().removeAllDeliveredNotifications()
// Cancel 하면 UserDefault 값 초기화 하기
UserDefaults.standard.set(0, forKey: "badgeCount")
UIApplication.shared.applicationIconBadgeNumber = 0
}
}
struct LocalNotificationInter: View {
@Environment(\.scenePhase) var scenePhase
var body: some View {
VStack (spacing: 40) {
Button {
NotificationManager.instance.requestAuthorization()
} label: {
Text("권한 요청하기")
.font(.title2)
.fontWeight(.semibold)
.foregroundColor(.black)
.padding()
.background(Color.green)
.cornerRadius(10)
}
Button {
NotificationManager.instance.scheduleNotification()
} label: {
Text("Time Notification")
.font(.title2)
.fontWeight(.semibold)
.foregroundColor(.black)
.padding()
.background(Color.green)
.cornerRadius(10)
}
Button {
NotificationManager.instance.scheduleNotification()
} label: {
Text("Calendar Notification")
.font(.title2)
.fontWeight(.semibold)
.foregroundColor(.black)
.padding()
.background(Color.green)
.cornerRadius(10)
}
Button {
NotificationManager.instance.cancelNotification()
} label: {
Text("Notification 취소하기")
.font(.title2)
.fontWeight(.semibold)
.foregroundColor(.black)
.padding()
.background(Color.green)
.cornerRadius(10)
}
} //: VSTACK
// schne 이 나타 날때 Badge 0 으로 초기화 하기
.onChange(of: scenePhase) { newValue in
if newValue == .active {
// 0으로 초기화 되지 않게 reset 하지 않기
// UIApplication.shared.applicationIconBadgeNumber = 0
}
}
}
}
0
안녕하세요, 인프런 AI 인턴입니다.
랑프_Langpeu님의 질문에 대해 답변 드리겠습니다.
문제의 핵심은 앱이 활성 상태로 전환될 때 뱃지 숫자가 0으로 초기화되어, 로컬 알림으로 설정한 뱃지 숫자가 기대와 다르게 작동한다는 점입니다.
이문제를 해결하기 위해서는 애플리케이션이 활성 상태가 될 때마다 뱃지 숫자를 초기화하지 않고, 알림을 확인하거나 필요한 조치를 취했을 때 명시적으로 뱃지 숫자를 조정하는 로직을 구현해야 합니다.
전송되는 알림의 뱃지 숫자를 올바르게 관리하기 위해서는 애플리케이션 내부적으로 알림이 몇 번 전송되었는지를 추적할 필요가 있습니다. 이를 위해, 앱의 로컬 저장소나 데이터 베이스를 사용하여 알림이 발송될 때마다 카운터를 증가시키고, 앱이 활성화될 때 해당 카운터를 참조하여 UIApplication.shared.applicationIconBadgeNumber을 올바르게 설정하시는 것이 좋습니다.
예를 들어, 알림 발송 함수 내에서 뱃지 숫자를 증가시키는 로직을 추가하고:
func increaseBadgeNumberByOne() {
let currentBadgeNumber = UserDefaults.standard.integer(forKey: "badgeNumber")
UserDefaults.standard.set(currentBadgeNumber + 1, forKey: "badgeNumber")
content.badge = NSNumber(value: currentBadgeNumber + 1)
}
앱이 활성 상태가 될 때 뱃지 숫자를 리셋하는 대신 사용자가 알림을 확인하였다는 가정하에 뱃지 숫자를 관리할 수 있는 로직을 추가합니다:
.onChange(of: scenePhase) { newValue in
if newValue == .active {
// 사용자가 알림을 확인했다고 가정하고 뱃지 숫자를 초기화
UserDefaults.standard.set(0, forKey: "badgeNumber")
UIApplication.shared.applicationIconBadgeNumber = 0
}
}
이렇게 변경하면 앱이 활성화될 때마다 뱃지 숫자가 초기화되는 문제를 보완할 수 있습니다. 단, 이러한 방법은 알림이 발송될 때마다 앱 내부에서 뱃지 숫자를 관리해야 한다는 추가적인 구현이 필요합니다.
실제로 이 외에도 다양한 방법과 조건에 따라 뱃지 숫자를 관리할 수 있으므로, 애플리케이션의 특성과 필요에 맞게 적절한 로직을 설계하는 것이 중요할 것입니다.
수강 기간 연장 문의
0
28
1
수강연장부탁드려도될까요..
0
42
2
Combine Playground 에서 실행 시
0
57
2
70강 - 글로벌 액터로 격리된 Protocol 을 extension 에서 conform 시 타입 본체의 격리 수준 질문
0
42
1
searchable이 화면 하단에 위치해요
0
62
2
Drawing Cycle 관련 질문
0
72
1
앱 제작 시 주로 코드로 작성하시는 이유가 있을까요?
0
95
2
델리게이트 패턴 관련 질문
0
66
2
ios 애드몹 광고
0
134
2
수강 기간 연장 부탁드릴 수 있을까요?
0
61
1
Sorted, Filter, Map - UserViewModel 부분 오류 발생
0
102
1
ViewBuilder 강의 관련 질문입니다.
0
80
1
CoreData Array의 변화에 따른 SwiftUI View 변화 적용(with @Observable Macro)
0
205
2
init-deinit의 무한루핑을 벗어나는 방법이 궁금합니다.
1
167
2
Apple 공식 문서 보는법
0
325
2
5월 업데이트 예정이었던 , iOS17 컨텐츠 SwifData 업데이트 언제 되나요 ?
0
252
1
Spacer() 를 넣으니 예제처럼 SafeArea 확보가 안됩니다.
0
490
3
Local Notification 강의 편집오류 있어요
0
236
2
강의중 코드폴딩 단축키 (커맨트+옵션+왼쪽방향키)
0
208
2
코어데이터에 중복값 입력 방지
0
313
1
Combine 관련 질문드립니다.
0
244
1
if let else 질문있습니다.
0
220
1
강의 Weak Self 코드 실행시 오류에 대해
0
653
1
SwiftData가 Core Data를 대체하는지요?
0
2111
1

