I have cobbled together for my first swift app the following code, If i am at the location coordinates with the app closed when the notification event is fired the notification is delivered correctly, in every other scenario it fails, i have Location Updates and Background Fetch enabled in the Background Modes section.
Any pointers hugely appreciated, thank you.
import SwiftUI
import WebKit
import CoreLocation
import UserNotifications
let locationManager = CLLocationManager()
struct ContentView: View {
@StateObject private var locationManager = LocationManager()
var body: some View {
WebView(url: URL(string: "https://www.website.uk")!)
.edgesIgnoringSafeArea(.all)
.onAppear {
locationManager.requestPermissions()
}
}
}
struct WebView: UIViewRepresentable {
var url: URL
func makeUIView(context: Context) -> WKWebView {
WKWebView()
}
func updateUIView(_ uiView: WKWebView, context: Context) {
let request = URLRequest(url: url)
uiView.load(request)
}
}
@main
struct NotificationTestApp: App {
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
class LocationManager: NSObject, CLLocationManagerDelegate, ObservableObject {
private var locationManager = CLLocationManager()
override init() {
super.init()
locationManager.delegate = self
}
func triggerNotification(_ password: String)
{
let center = UNUserNotificationCenter.current()
let content = UNMutableNotificationContent()
content.title = "My First Notification"
content.body = password
content.sound = UNNotificationSound.default
content.subtitle = "Hello World"
content.userInfo = ["value": "Data with local notification"]
let fireDate = Calendar.current.dateComponents([.day, .month, .year, .hour, .minute, .second], from: Date().addingTimeInterval(10))
let trigger = UNCalendarNotificationTrigger(dateMatching: fireDate, repeats: true)
let request = UNNotificationRequest(identifier: "reminder", content: content, trigger: trigger)
center.add(request)
{
(error) in
if error != nil
{
print("Error = (error?.localizedDescription ?? "error in local notification") ")
}
}
}
func locationManager(_ manager: CLLocationManager, didEnterRegion region: CLRegion) {
if region.identifier == "LOC1"
{
triggerNotification("Boo: " + Date().formatted())
}
}
func locationManager(_ manager: CLLocationManager, didExitRegion region: CLRegion) {
if region.identifier == "LOC1"
{
//reset the region state
locationManager.stopMonitoring(for: region)
locationManager.startMonitoring(for: region)
}
}
func locationManager(_ manager: CLLocationManager, monitoringDidFailFor region: CLRegion?, withError error: Error) {
print("Failed to monitor region: (error.localizedDescription)")
}
func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
print("Location manager failed: (error.localizedDescription)")
}
func requestPermissions() {
locationManager.requestWhenInUseAuthorization()
UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .badge, .sound]) { granted, error in
if granted {
print("Notification permission granted.")
//self.triggerNotification("Test")
} else if let error = error {
print("Notification permission denied with error: (error.localizedDescription)")
}
}
//Setup Geofence
let locationCoordinates = CLLocationCoordinate2D(latitude: 50.1234, longitude: -1.2345)
let geofenceRegion = CLCircularRegion(center: locationCoordinates, radius: 500, identifier: "LOC1")
geofenceRegion.notifyOnEntry = true
geofenceRegion.notifyOnEntry = true
locationManager.startMonitoring(for: geofenceRegion)
}
}