I’m having an issue with sending native notifications primarily based on the native time of the customers cellphone.
What I’m making an attempt to do, is make it so the consumer will get a notification a desired time earlier than a set time.
The app appears to be working, and it’s only the notifications that aren’t working.
Is there something I’m lacking within the code for the performance to work. I’ve made it so the app robotically asks for permission to ship notifications the primary time the consumer opens the app.
That is my present code.
Content material view:
// Created by Johannes With on 11/08/2023.
//
import SwiftUI
struct ContentView: View {
@Atmosphere(.colorScheme) var colorScheme
@State non-public var isLoading = true
@State non-public var daysSwitch: [Bool] = UserDefaults.normal.array(forKey: "daysSwitch") as? [Bool] ?? Array(repeating: false, depend: 6)
@State non-public var olsalgetSwitch: Bool = UserDefaults.normal.bool(forKey: "olsalgetSwitch")
@State non-public var vinmonopoletSwitch: Bool = UserDefaults.normal.bool(forKey: "vinmonopoletSwitch")
@State non-public var timeInterval: Int = UserDefaults.normal.integer(forKey: "timeInterval") != 0 ? UserDefaults.normal.integer(forKey: "timeInterval") : 10
let notify = NotificationHandler()
let days = ["Mandag", "Tirsdag", "Onsdag", "Torsdag", "Fredag", "Lørdag"]
let timeIntervals = Array(stride(from: 10, to: 60, by: 10))
var physique: some View {
NavigationView {
ScrollView {
VStack(spacing: 20) {
if isLoading {
// Loading view
Picture("Loader")
.resizable()
.scaledToFill()
.edgesIgnoringSafeArea(.all)
.onAppear {
// Cover loading display screen after 2 seconds
DispatchQueue.important.asyncAfter(deadline: .now() + 2) {
isLoading = false
}
}
} else {
// Fundamental content material view
Picture(colorScheme == .darkish ? "ToplogoWhite" : "ToplogoBlack")
.resizable()
.scaledToFit()
.body(top: 100)
.padding(.prime, 40)
Textual content("Velg hvilket utsalg du vil bli varslet om")
.daring()
.font(.headline)
.padding(.prime, 0)
HStack {
Textual content("Ølsalget").daring()
Toggle("", isOn: $olsalgetSwitch)
}
HStack {
Textual content("Vinmonopolet").daring()
Toggle("", isOn: $vinmonopoletSwitch)
}
Divider()
Textual content("Velg hvilke dager du vil bli varslet på")
.daring()
.font(.headline)
ForEach(0..<days.depend, id: .self) { index in
HStack
}
Divider()
Textual content("Velg når du vil bli varslet før salget stenger")
.daring()
.font(.headline)
Picker("Minutter før:", choice: $timeInterval) {
ForEach(timeIntervals, id: .self) { interval in
Textual content("(interval) minutter før").daring()
}
}
.pickerStyle(MenuPickerStyle())
Spacer()
Button("Blir du ikke varslet? Klikk her!") {
notify.askPermission()
}
.daring()
VStack {
Textual content("Rakk du salget i dag takket være meg?").daring()
Textual content("Påspander meg en øl! Vipps: #822266").daring()
}
.multilineTextAlignment(.heart)
.font(.footnote)
.padding(.backside, 40)
}
}
.padding()
.onChange(of: daysSwitch) { _ in saveSettings() }
.onChange(of: olsalgetSwitch) { _ in saveSettings() }
.onChange(of: vinmonopoletSwitch) { _ in saveSettings() }
.onChange(of: timeInterval) { _ in saveSettings() }
}
.onAppear {
notify.askPermission() // Mechanically ask for permission
scheduleNotifications() // Schedule notifications
}
}
}
non-public func saveSettings() {
UserDefaults.normal.setValue(daysSwitch, forKey: "daysSwitch")
UserDefaults.normal.setValue(olsalgetSwitch, forKey: "olsalgetSwitch")
UserDefaults.normal.setValue(vinmonopoletSwitch, forKey: "vinmonopoletSwitch")
UserDefaults.normal.setValue(timeInterval, forKey: "timeInterval")
scheduleNotifications() // Schedule notifications after saving settings
}
func scheduleNotifications() {
// The logic for scheduling notifications primarily based on the chosen choices
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
Notifications handler:
// Created by Johannes Eikrem With on 11/08/2023.
//
import UserNotifications
class NotificationHandler {
func askPermission() {
UNUserNotificationCenter.present().requestAuthorization(choices: [.alert, .badge, .sound]) { success, error in
if success {
print("Entry granted!")
} else if let error = error {
print(error.localizedDescription)
}
}
}
func scheduleNotification(for day: String, minutesBefore: Int, deadlineHour: Int, title: String, physique: String) {
// Create date elements for the desired day and time
var dateComponents = DateComponents()
dateComponents.hour = deadlineHour
dateComponents.minute = -(minutesBefore)
// Set the weekday primarily based on the desired day
change day {
case "Mandag": dateComponents.weekday = 2
case "Tirsdag": dateComponents.weekday = 3
case "Onsdag": dateComponents.weekday = 4
case "Torsdag": dateComponents.weekday = 5
case "Fredag": dateComponents.weekday = 6
case "Lørdag": dateComponents.weekday = 7
default: return
}
// Create a set off with the date elements
let set off = UNCalendarNotificationTrigger(dateMatching: dateComponents, repeats: true)
// Create the content material
let content material = UNMutableNotificationContent()
content material.title = title
content material.physique = physique
content material.sound = UNNotificationSound.default
content material.badge = 1
// Create the request
let request = UNNotificationRequest(identifier: UUID().uuidString, content material: content material, set off: set off)
// Add the request to the notification heart
UNUserNotificationCenter.present().add(request) { error in
if let error = error {
print("Error scheduling notification: (error)")
}
}
}
}