Skip to content

Commit

Permalink
## Changed the way the delegate is created
Browse files Browse the repository at this point in the history
The delegate used to be created with the view controller, now it is created by the app delegate. This should help the problem that the app stops working after a while
  • Loading branch information
below committed Nov 18, 2022
1 parent ef54a16 commit 8ae8d62
Show file tree
Hide file tree
Showing 8 changed files with 83 additions and 51 deletions.
12 changes: 8 additions & 4 deletions GeofenceTester.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,10 @@
CB655F6F28534E2700EBCABA /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = CB655F6E28534E2700EBCABA /* Assets.xcassets */; };
CB655F7228534E2700EBCABA /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = CB655F7028534E2700EBCABA /* LaunchScreen.storyboard */; };
CB655F7E2856A43B00EBCABA /* RegionsListViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = CB655F7D2856A43B00EBCABA /* RegionsListViewController.swift */; };
CB97AE3F286DC6410067B1BF /* RegionsListVC+CoreLocationsDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = CB97AE3E286DC6410067B1BF /* RegionsListVC+CoreLocationsDelegate.swift */; };
CB97AE3F286DC6410067B1BF /* CoreLocationDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = CB97AE3E286DC6410067B1BF /* CoreLocationDelegate.swift */; };
CBBF88CF286F269B00E4E1F0 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = CBBF88CD286F269B00E4E1F0 /* InfoPlist.strings */; };
CBBF88D2286F269B00E4E1F0 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = CBBF88D0286F269B00E4E1F0 /* Localizable.strings */; };
CBE4CBAA2922B2B5003C0B26 /* ErrorHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = CBE4CBA92922B2B5003C0B26 /* ErrorHandler.swift */; };
CBE711EF2868EE36008F51C4 /* RegionDetailViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = CBE711EE2868EE36008F51C4 /* RegionDetailViewController.swift */; };
CBE711F1286915A8008F51C4 /* EventRecord.swift in Sources */ = {isa = PBXBuildFile; fileRef = CBE711F0286915A8008F51C4 /* EventRecord.swift */; };
CBE711F3286920FD008F51C4 /* EventsTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = CBE711F2286920FD008F51C4 /* EventsTableViewController.swift */; };
Expand All @@ -42,10 +43,11 @@
CB655F7328534E2700EBCABA /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
CB655F7D2856A43B00EBCABA /* RegionsListViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RegionsListViewController.swift; sourceTree = "<group>"; };
CB97AE3D286DB2840067B1BF /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/Main.strings; sourceTree = "<group>"; };
CB97AE3E286DC6410067B1BF /* RegionsListVC+CoreLocationsDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "RegionsListVC+CoreLocationsDelegate.swift"; sourceTree = "<group>"; };
CB97AE3E286DC6410067B1BF /* CoreLocationDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CoreLocationDelegate.swift; sourceTree = "<group>"; };
CBBF88CE286F269B00E4E1F0 /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/InfoPlist.strings; sourceTree = "<group>"; };
CBBF88D1286F269B00E4E1F0 /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/Localizable.strings; sourceTree = "<group>"; };
CBBF88D3286F29ED00E4E1F0 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = "<group>"; };
CBE4CBA92922B2B5003C0B26 /* ErrorHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ErrorHandler.swift; sourceTree = "<group>"; };
CBE711EE2868EE36008F51C4 /* RegionDetailViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RegionDetailViewController.swift; sourceTree = "<group>"; };
CBE711F0286915A8008F51C4 /* EventRecord.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EventRecord.swift; sourceTree = "<group>"; };
CBE711F2286920FD008F51C4 /* EventsTableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EventsTableViewController.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -91,12 +93,13 @@
CB655F6728534E2600EBCABA /* SceneDelegate.swift */,
CB50E6082872480A00A98D8C /* Protocols.swift */,
CB655F7D2856A43B00EBCABA /* RegionsListViewController.swift */,
CB97AE3E286DC6410067B1BF /* RegionsListVC+CoreLocationsDelegate.swift */,
CB97AE3E286DC6410067B1BF /* CoreLocationDelegate.swift */,
CBF30A54287823A700A0D173 /* RegionsListVC+CustomRotor.swift */,
CBE711EE2868EE36008F51C4 /* RegionDetailViewController.swift */,
CBE711F2286920FD008F51C4 /* EventsTableViewController.swift */,
CB0BAA5D287301BF0029E523 /* SettingsViewController.swift */,
CBE711F0286915A8008F51C4 /* EventRecord.swift */,
CBE4CBA92922B2B5003C0B26 /* ErrorHandler.swift */,
CB268B9F285A19DC00B16C3A /* PersistantStorage.swift */,
CB655F6B28534E2600EBCABA /* Main.storyboard */,
CB655F6E28534E2700EBCABA /* Assets.xcassets */,
Expand Down Expand Up @@ -190,11 +193,12 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
CB97AE3F286DC6410067B1BF /* RegionsListVC+CoreLocationsDelegate.swift in Sources */,
CB97AE3F286DC6410067B1BF /* CoreLocationDelegate.swift in Sources */,
CBE711F1286915A8008F51C4 /* EventRecord.swift in Sources */,
CB0BAA5E287301BF0029E523 /* SettingsViewController.swift in Sources */,
CBE71237286C7E7A008F51C4 /* Keys.swift in Sources */,
CB655F6628534E2600EBCABA /* AppDelegate.swift in Sources */,
CBE4CBAA2922B2B5003C0B26 /* ErrorHandler.swift in Sources */,
CBE711EF2868EE36008F51C4 /* RegionDetailViewController.swift in Sources */,
CB50E6092872480A00A98D8C /* Protocols.swift in Sources */,
CB655F6828534E2600EBCABA /* SceneDelegate.swift in Sources */,
Expand Down
19 changes: 9 additions & 10 deletions GeofenceTester/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,20 @@
* SPDX-License-Identifier: MIT
*/

import UIKit
import AppCenter
import AppCenterAnalytics
import AppCenterCrashes
import AppCenterDistribute
import CoreLocation
import UIKit

@main
class AppDelegate: UIResponder, UIApplicationDelegate {



var locationManager = CLLocationManager()
var locationDelegate = CoreLocationDelegate()
var errorHandler = ErrorHandler()

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {

AppCenter.start(withAppSecret: AppCenterKey,
Expand All @@ -33,6 +36,9 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
])
UserDefaults.standard.register(defaults: [PausesVisitAutomatically: true])

self.locationDelegate.errorHandler = errorHandler
self.locationManager.delegate = self.locationDelegate

return true
}

Expand All @@ -44,12 +50,5 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
}

func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set<UISceneSession>) {
// Called when the user discards a scene session.
// If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions.
// Use this method to release any resources that were specific to the discarded scenes, as they will not return.
}


}

Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*
* telekom / geo-test-ios
*
* RegionsListVC+CoreLocationsDelegate.swift
* CoreLocationDelegate.swift
* Created by Alexander von Below on 30.06.22.
* Copyright (c) 2022 Deutsche Telekom AG
*
Expand All @@ -15,7 +15,12 @@
import UIKit
import CoreLocation

extension RegionsListViewController: CLLocationManagerDelegate {
class CoreLocationDelegate: NSObject, CLLocationManagerDelegate {

var storage = PersistantStorage<EventRecord>()
var errorHandler = ErrorHandler()
var authorisationSuccessful: (()-> Void)?

func locationManager(_ manager: CLLocationManager, didEnterRegion region: CLRegion) {
process(event: .ENTER, info: region.identifier)
}
Expand All @@ -28,7 +33,7 @@ extension RegionsListViewController: CLLocationManagerDelegate {
let visitLocation = CLLocation(latitude: visit.coordinate.latitude,
longitude: visit.coordinate.longitude)
let info: String
if let matchingRegion = locationManager.monitoredRegions.first(where:{ region in
if let matchingRegion = manager.monitoredRegions.first(where:{ region in
guard let region = region as? CLCircularRegion else {
return false
}
Expand Down Expand Up @@ -73,7 +78,7 @@ extension RegionsListViewController: CLLocationManagerDelegate {
try storage.store(eventRecord)
}
catch let error {
self.handleError(error)
self.errorHandler.handleError(error)
}
let request = UNNotificationRequest(identifier: UUID().uuidString,
content: content,
Expand All @@ -85,27 +90,30 @@ extension RegionsListViewController: CLLocationManagerDelegate {
monitoringDidFailFor region: CLRegion?,
withError error: Error
) {
self.handleError(error)
self.errorHandler.handleError(error)
}

func locationManager(_ manager: CLLocationManager,
didChangeAuthorization status: CLAuthorizationStatus) {
switch status {
case .restricted, .denied:
// Disable your app's location features
self.handleError("Warning: Location restricted or denied")
self.errorHandler.handleError("Warning: Location restricted or denied")

case .authorizedWhenInUse:
// Enable your app's location features.
self.handleError("Warning: Location InUse Only")
self.errorHandler.handleError("Warning: Location InUse Only")

case .authorizedAlways:
self.startLocationServices()
if let authorisationSuccessful = self.authorisationSuccessful {
authorisationSuccessful()
}
// self.startLocationServices()

case .notDetermined:
self.handleError("Warning: Location Not Determined")
self.errorHandler.handleError("Warning: Location Not Determined")
default:
self.handleError("Warning: Switch fell through")
self.errorHandler.handleError("Warning: Switch fell through")
}
}
}
23 changes: 23 additions & 0 deletions GeofenceTester/ErrorHandler.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
//
// ErrorHandler.swift
// GeofenceTester
//
// Created by Alexander von Below on 14.11.22.
//

import Foundation
import AppCenterAnalytics
import os.log

struct ErrorHandler {
internal var logger = os.Logger()

public func handleError (_ error: Error) {
handleError(error.localizedDescription)
}

public func handleError (_ error: String) {
Analytics.trackEvent(error, withProperties: [:], flags: .critical)
logger.error("\(error)")
}
}
8 changes: 4 additions & 4 deletions GeofenceTester/RegionsListVC+CustomRotor.swift
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,11 @@ extension RegionsListViewController {

// which element is currently highlighted
if (predicate.currentItem.targetElement == nil) {
self.logger.info("Current Item Target Element is nil")
self.errorHandler.logger.info("Current Item Target Element is nil")
}
let currentAnnotationView = predicate.currentItem.targetElement as? MKAnnotationView
if (currentAnnotationView == nil) {
self.logger.error("Target Element is \(predicate.currentItem.targetElement.debugDescription)")
self.errorHandler.logger.error("Target Element is \(predicate.currentItem.targetElement.debugDescription)")
}
let currentAnnotation = (currentAnnotationView?.annotation as? MKAnnotation)

Expand Down Expand Up @@ -63,13 +63,13 @@ extension RegionsListViewController {
self.mapView.setCenter(requestedAnnotation.coordinate, animated: false)
if let annotationView = self.mapView.view(for: requestedAnnotation) {
let title: String = (requestedAnnotation.title ?? "Unknown") ?? "Unknown"
self.logger.info("We want to be returning \(title) Index \(currentIndex)")
self.errorHandler.logger.info("We want to be returning \(title) Index \(currentIndex)")
return UIAccessibilityCustomRotorItemResult(targetElement: annotationView, targetRange: nil)
}

currentIndex = nextIndex(currentIndex)
}
self.logger.info("We have nothing")
self.errorHandler.logger.info("We have nothing")
return nil
}
self.mapView.accessibilityCustomRotors = [markerRotor]
Expand Down
31 changes: 10 additions & 21 deletions GeofenceTester/RegionsListViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,16 @@

import UIKit
import MapKit
import os.log
import AppCenterAnalytics

let PausesVisitAutomatically = "PausesVisitAutomatically"

class RegionsListViewController: UIViewController {

public static let UpdateNotificationName = Notification.Name.init("updateRegions")

var locationManager: CLLocationManager = CLLocationManager()
var storage = PersistantStorage<EventRecord>()
internal var logger = os.Logger()
var locationManager: CLLocationManager!
var errorHandler: ErrorHandler!

var firstUse = true

@IBOutlet var mapView: MKMapView!
Expand All @@ -37,8 +35,6 @@ class RegionsListViewController: UIViewController {

addButton.accessibilityLabel = NSLocalizedString("Add Monitored Region at current location", comment: "Accessibilty label for add button")
addButton.accessibilityLabel = NSLocalizedString("Settings", comment: "Accessibilty label for settings button")

locationManager.delegate = self

self.mapView.setCenter(
self.mapView.userLocation.coordinate,
Expand Down Expand Up @@ -72,6 +68,7 @@ class RegionsListViewController: UIViewController {
self.mapView.showsUserLocation = true
mapView.setCenter(mapView.userLocation.coordinate, animated: true)
locationManager.startMonitoringVisits()
locationManager.startMonitoringSignificantLocationChanges()

let pauses = UserDefaults.standard.bool(forKey: PausesVisitAutomatically)
locationManager.pausesLocationUpdatesAutomatically = pauses
Expand Down Expand Up @@ -113,7 +110,7 @@ class RegionsListViewController: UIViewController {
UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound]) { [self] granted, error in

if let error = error {
self.handleError("Error in requestAuthorization: \(error.localizedDescription)")
self.errorHandler.handleError("Error in requestAuthorization: \(error.localizedDescription)")
return
}

Expand All @@ -129,7 +126,7 @@ class RegionsListViewController: UIViewController {

private func registerRegion(identifier: String, center: CLLocationCoordinate2D) {
guard CLLocationManager.isMonitoringAvailable(for: CLCircularRegion.self) else {
self.handleError("Circular Region Monitoring not available")
self.errorHandler.handleError("Circular Region Monitoring not available")
return
}
// Register the region.
Expand Down Expand Up @@ -171,15 +168,6 @@ class RegionsListViewController: UIViewController {
mapView.showAnnotations(mapAnnotations, animated: true)
}

internal func handleError (_ error: Error) {
handleError(error.localizedDescription)
}

internal func handleError (_ error: String) {
Analytics.trackEvent(error, withProperties: [:], flags: .critical)
logger.error("\(error)")
}

// MARK: - Navigation

// In a storyboard-based application, you will often want to do a little preparation before navigation
Expand All @@ -190,12 +178,12 @@ class RegionsListViewController: UIViewController {
}

if var destination = segue.destination as? Loggable {
destination.logger = logger
destination.logger = self.errorHandler.logger
}

if let destination = segue.destination as? RegionDetailViewController {
guard let annotation = sender as? MKAnnotation else {
self.handleError("Sender was not MKAnnotation")
self.errorHandler.handleError("Sender was not MKAnnotation")
return
}
guard let identifier = annotation.title,
Expand All @@ -210,7 +198,8 @@ class RegionsListViewController: UIViewController {
}

if let destination = segue.destination as? EventsTableViewController {
destination.storage = storage
guard let lcd = locationManager.delegate as? CoreLocationDelegate else { return }
destination.storage = lcd.storage
}
}
}
Expand Down
9 changes: 8 additions & 1 deletion GeofenceTester/SceneDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,14 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate {
// Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.
// If using a storyboard, the `window` property will automatically be initialized and attached to the scene.
// This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).
guard let _ = (scene as? UIWindowScene) else { return }
guard let windowScene = (scene as? UIWindowScene) else { return }

guard let nvc = windowScene.windows.first?.rootViewController as? UINavigationController else { return }
guard let vc = nvc.topViewController as? RegionsListViewController else { return }
guard let ad = UIApplication.shared.delegate as? AppDelegate else { return }

vc.locationManager = ad.locationManager
vc.errorHandler = ad.errorHandler
}

func sceneDidDisconnect(_ scene: UIScene) {
Expand Down
4 changes: 3 additions & 1 deletion GeofenceTester/SettingsViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,9 @@ class SettingsViewController: UIViewController, LocationUser {
message: NSLocalizedString(
"Are you sure you want to delete the complete log?",
comment: ""),
buttonTitle: "Clear Log",
buttonTitle: NSLocalizedString(
"Clear Log",
comment: ""),
handler: { _ in
do {
let storage = PersistantStorage<EventRecord>()
Expand Down

0 comments on commit 8ae8d62

Please sign in to comment.