From 8ea6317f377c49d1e6f715abf369e5fe110e9a3c Mon Sep 17 00:00:00 2001 From: Rafael Setragni Date: Mon, 14 Oct 2024 15:43:50 -0300 Subject: [PATCH 1/2] Enhance Resilience Against Misconfigured Notification Service Extensions Improved resilience of the awesome core library to better handle projects that may have misconfigured Notification Service Extensions (NSE) according to the provided documentation. This ensures that even if the NSE is misconfigured, the library can gracefully handle the lack of registered events and other essencial notification informations to continue to operate without causing crashes or major failures. --- .../DismissedNotificationReceiver.swift | 6 --- .../senders/BroadcastSender.swift | 50 +++++++++++++++++++ .../Classes/managers/CreatedManager.swift | 6 +-- .../Classes/managers/DisplayedManager.swift | 2 +- .../Classes/managers/LostEventsManager.swift | 29 ++++++++--- .../models/NotificationContentModel.swift | 20 ++++---- .../models/returnedData/ActionReceived.swift | 2 + .../NotificationSenderAndScheduler.swift | 4 +- 8 files changed, 88 insertions(+), 31 deletions(-) diff --git a/IosAwnCore/Classes/broadcasters/receivers/DismissedNotificationReceiver.swift b/IosAwnCore/Classes/broadcasters/receivers/DismissedNotificationReceiver.swift index 1950e2e..e796770 100644 --- a/IosAwnCore/Classes/broadcasters/receivers/DismissedNotificationReceiver.swift +++ b/IosAwnCore/Classes/broadcasters/receivers/DismissedNotificationReceiver.swift @@ -82,12 +82,6 @@ class DismissedNotificationReceiver { detailedCode: ExceptionCode.DETAILED_INVALID_ARGUMENTS + ".addNewDismissEvent.dismissedReceived") } - dismissedReceived.registerDismissedEvent( - withLifeCycle: - LifeCycleManager - .shared - .currentLifeCycle) - BroadcastSender .shared .sendBroadcast( diff --git a/IosAwnCore/Classes/broadcasters/senders/BroadcastSender.swift b/IosAwnCore/Classes/broadcasters/senders/BroadcastSender.swift index 4db2a33..64dcc90 100644 --- a/IosAwnCore/Classes/broadcasters/senders/BroadcastSender.swift +++ b/IosAwnCore/Classes/broadcasters/senders/BroadcastSender.swift @@ -29,6 +29,14 @@ class BroadcastSender { notificationCreated notificationReceived: NotificationReceived, whenFinished completionHandler: @escaping (Bool) -> Void ){ + _ = notificationReceived.registerCreateEvent( + withLifeCycle: + LifeCycleManager + .shared + .currentLifeCycle, + fromSource: notificationReceived.createdSource ?? .Local + ) + if SwiftUtils.isRunningOnExtension() || LifeCycleManager.shared.currentLifeCycle == .AppKilled { _ = CreatedManager.shared.saveCreated( received: notificationReceived, @@ -51,6 +59,12 @@ class BroadcastSender { notificationDisplayed notificationReceived: NotificationReceived, whenFinished completionHandler: @escaping (Bool) -> Void ){ + notificationReceived.registerDisplayedEvent( + withLifeCycle: + LifeCycleManager + .shared + .currentLifeCycle) + if SwiftUtils.isRunningOnExtension() || LifeCycleManager.shared.currentLifeCycle == .AppKilled { _ = DisplayedManager.shared.saveDisplayed(received: notificationReceived) } @@ -73,6 +87,12 @@ class BroadcastSender { actionReceived: ActionReceived, whenFinished completionHandler: @escaping (Bool, Error?) -> Void ){ + actionReceived.registerActionEvent( + withLifeCycle: + LifeCycleManager + .shared + .currentLifeCycle) + if !ActionManager.shared.recovered { //LifeCycleManager.shared.currentLifeCycle == .AppKilled ActionManager.shared.saveAction(received: actionReceived) Logger.shared.d(TAG, "action saved") @@ -93,6 +113,12 @@ class BroadcastSender { notificationDismissed actionReceived: ActionReceived, whenFinished completionHandler: @escaping (Bool, Error?) -> Void ){ + actionReceived.registerDismissedEvent( + withLifeCycle: + LifeCycleManager + .shared + .currentLifeCycle) + if LifeCycleManager.shared.currentLifeCycle == .AppKilled { DismissedManager.shared.saveDismissed(received: actionReceived) } @@ -111,6 +137,12 @@ class BroadcastSender { silentAction: ActionReceived, whenFinished completionHandler: @escaping (Bool, Error?) -> Void ){ + silentAction.registerActionEvent( + withLifeCycle: + LifeCycleManager + .shared + .currentLifeCycle) + AwesomeEventsReceiver .shared .addActionEvent( @@ -124,6 +156,12 @@ class BroadcastSender { backgroundAction: ActionReceived, whenFinished completionHandler: @escaping (Bool, Error?) -> Void ){ + backgroundAction.registerActionEvent( + withLifeCycle: + LifeCycleManager + .shared + .currentLifeCycle) + AwesomeEventsReceiver .shared .addActionEvent( @@ -137,6 +175,12 @@ class BroadcastSender { silentAction actionReceived: ActionReceived, whenFinished completionHandler: @escaping (Bool, Error?) -> Void ){ + actionReceived.registerActionEvent( + withLifeCycle: + LifeCycleManager + .shared + .currentLifeCycle) + BackgroundService .shared .enqueue( @@ -148,6 +192,12 @@ class BroadcastSender { silentBackgroundAction actionReceived: ActionReceived, whenFinished completionHandler: @escaping (Bool, Error?) -> Void ){ + actionReceived.registerActionEvent( + withLifeCycle: + LifeCycleManager + .shared + .currentLifeCycle) + BackgroundService .shared .enqueue( diff --git a/IosAwnCore/Classes/managers/CreatedManager.swift b/IosAwnCore/Classes/managers/CreatedManager.swift index a8d2b95..283d83e 100644 --- a/IosAwnCore/Classes/managers/CreatedManager.swift +++ b/IosAwnCore/Classes/managers/CreatedManager.swift @@ -36,7 +36,7 @@ public class CreatedManager : EventManager { else { return false } if received.createdDate == nil { if !received.registerCreateEvent( - inLifeCycle: lifeCycle, + withLifeCycle: lifeCycle, fromSource: source ) { return false } } @@ -62,7 +62,7 @@ public class CreatedManager : EventManager { else { continue } if received.createdDate == nil { _ = received.registerCreateEvent( - inLifeCycle: .Terminated, + withLifeCycle: .Terminated, fromSource: .Local ) } @@ -82,7 +82,7 @@ public class CreatedManager : EventManager { if received.id != id { continue } if received.createdDate == nil { _ = received.registerCreateEvent( - inLifeCycle: .Terminated, + withLifeCycle: .Terminated, fromSource: .Local ) } diff --git a/IosAwnCore/Classes/managers/DisplayedManager.swift b/IosAwnCore/Classes/managers/DisplayedManager.swift index 08cf073..068abc5 100644 --- a/IosAwnCore/Classes/managers/DisplayedManager.swift +++ b/IosAwnCore/Classes/managers/DisplayedManager.swift @@ -124,7 +124,7 @@ public class DisplayedManager : EventManager { let receivedNotification = NotificationReceived(notificationScheduled.content) receivedNotification.registerDisplayedEvent( withDisplayedDate: displayedDate, - inLifeCycle: displayedDate == limitDate + withLifeCycle: displayedDate == limitDate ? .Foreground : lastLifeCycle ) diff --git a/IosAwnCore/Classes/managers/LostEventsManager.swift b/IosAwnCore/Classes/managers/LostEventsManager.swift index 01b3b26..a6b0edc 100644 --- a/IosAwnCore/Classes/managers/LostEventsManager.swift +++ b/IosAwnCore/Classes/managers/LostEventsManager.swift @@ -101,14 +101,15 @@ public class LostEventsManager { try createdNotification.validate() if (createdNotification.createdDate == nil){ _ = createdNotification.registerCreateEvent( - inLifeCycle: createdNotification.createdLifeCycle ?? .Terminated, + withLifeCycle: createdNotification.createdLifeCycle ?? .Terminated, fromSource: createdNotification.createdSource ?? .Local ) } guard let id:Int = createdNotification.id else { continue } - guard let createdDate:RealDateTime = createdNotification.createdDate - else { continue } + let createdDate:RealDateTime = createdNotification.createdDate ?? RealDateTime.init( + fromTimeZone: TimeZone(identifier: "UTC") + ) lostEvents.append(EventRegister( eventName: Definitions.EVENT_NOTIFICATION_CREATED, @@ -172,9 +173,11 @@ public class LostEventsManager { guard let id:Int = displayedNotification.id else { continue } - guard let displayedDate:RealDateTime = - displayedNotification.displayedDate ?? displayedNotification.createdDate - else { continue } + let displayedDate:RealDateTime = + displayedNotification.displayedDate ?? RealDateTime.init( + fromTimeZone: TimeZone(identifier: "UTC") + ) + displayedNotification.displayedDate = displayedDate if currentDate >= displayedDate && lastDisplayedDate <= displayedDate { do { @@ -233,12 +236,17 @@ public class LostEventsManager { .listDismissed() for dismissedNotification in lostDismissed { + let dismissedDate:RealDateTime = + dismissedNotification.dismissedDate ?? RealDateTime.init( + fromTimeZone: TimeZone(identifier: "UTC") + ) + dismissedNotification.dismissedDate = dismissedDate do { try dismissedNotification.validate() lostEvents.append(EventRegister( eventName: Definitions.EVENT_NOTIFICATION_DISMISSED, - eventDate: dismissedNotification.dismissedDate!, + eventDate: dismissedDate, notificationContent: dismissedNotification )) @@ -277,12 +285,17 @@ public class LostEventsManager { .recoverActions() for notificationAction in lostActions { + let actionDate:RealDateTime = + notificationAction.actionDate ?? RealDateTime.init( + fromTimeZone: TimeZone(identifier: "UTC") + ) + notificationAction.actionDate = actionDate do { try notificationAction.validate() lostEvents.append(EventRegister( eventName: Definitions.EVENT_DEFAULT_ACTION, - eventDate: notificationAction.actionDate!, + eventDate: actionDate, notificationContent: notificationAction )) diff --git a/IosAwnCore/Classes/models/NotificationContentModel.swift b/IosAwnCore/Classes/models/NotificationContentModel.swift index f2ee13b..df5d83d 100644 --- a/IosAwnCore/Classes/models/NotificationContentModel.swift +++ b/IosAwnCore/Classes/models/NotificationContentModel.swift @@ -65,25 +65,23 @@ public class NotificationContentModel : AbstractModel { withDisplayedDate createdDate: RealDateTime = RealDateTime.init( fromTimeZone: TimeZone(identifier: "UTC") ), - inLifeCycle lifeCycle: NotificationLifeCycle, + withLifeCycle lifeCycle: NotificationLifeCycle, fromSource createdSource: NotificationSource ) -> Bool { - if(self.createdDate == nil){ - self.createdSource = createdSource - self.createdLifeCycle = lifeCycle - self.createdDate = createdDate - - return true - } - return false + if self.createdDate != nil { return false } + self.createdSource = createdSource + self.createdLifeCycle = lifeCycle + self.createdDate = createdDate + return true } public func registerDisplayedEvent( withDisplayedDate displayedDate: RealDateTime = RealDateTime.init( fromTimeZone: TimeZone(identifier: "UTC") ), - inLifeCycle lifeCycle: NotificationLifeCycle + withLifeCycle lifeCycle: NotificationLifeCycle ){ + if self.displayedDate != nil { return } self.displayedLifeCycle = lifeCycle self.displayedDate = displayedDate } @@ -100,7 +98,7 @@ public class NotificationContentModel : AbstractModel { if schedule == nil { registerDisplayedEvent( - inLifeCycle: lifeCycle + withLifeCycle: lifeCycle ) } else { diff --git a/IosAwnCore/Classes/models/returnedData/ActionReceived.swift b/IosAwnCore/Classes/models/returnedData/ActionReceived.swift index 336f381..19c4b1c 100644 --- a/IosAwnCore/Classes/models/returnedData/ActionReceived.swift +++ b/IosAwnCore/Classes/models/returnedData/ActionReceived.swift @@ -75,11 +75,13 @@ public class ActionReceived : NotificationReceived { } public func registerActionEvent(withLifeCycle lifeCycle: NotificationLifeCycle){ + if self.actionDate != nil { return } actionDate = RealDateTime.init(fromTimeZone: RealDateTime.utcTimeZone) actionLifeCycle = lifeCycle } public func registerDismissedEvent(withLifeCycle lifeCycle: NotificationLifeCycle){ + if self.dismissedDate != nil { return } dismissedDate = RealDateTime.init(fromTimeZone: RealDateTime.utcTimeZone) dismissedLifeCycle = lifeCycle } diff --git a/IosAwnCore/Classes/threads/NotificationSenderAndScheduler.swift b/IosAwnCore/Classes/threads/NotificationSenderAndScheduler.swift index 4604c14..6d85b35 100644 --- a/IosAwnCore/Classes/threads/NotificationSenderAndScheduler.swift +++ b/IosAwnCore/Classes/threads/NotificationSenderAndScheduler.swift @@ -147,7 +147,7 @@ public class NotificationSenderAndScheduler { notificationModel .content! .registerCreateEvent( - inLifeCycle: self.appLifeCycle, + withLifeCycle: self.appLifeCycle, fromSource: self.createdSource) if notificationModel.schedule != nil { @@ -193,7 +193,7 @@ public class NotificationSenderAndScheduler { } receivedNotification = NotificationReceived(notificationModel.content) - receivedNotification?.registerDisplayedEvent(inLifeCycle: self.appLifeCycle) + receivedNotification?.registerDisplayedEvent(withLifeCycle: self.appLifeCycle) receivedNotification!.displayedLifeCycle = receivedNotification!.displayedLifeCycle ?? self.appLifeCycle From e05ec88d65a35abc773f7b965de267f8f17ae604 Mon Sep 17 00:00:00 2001 From: Rafael Setragni Date: Mon, 14 Oct 2024 15:46:13 -0300 Subject: [PATCH 2/2] Update the minimum deployment target for iOS to iOS 12 and increase the plugin version to 0.10.0 Modified the iOS deployment target setting in the project configuration to iOS 12. This change aligns with newer iOS features and improvements, ensuring better app performance and security. Updated the plugin version to 0.10.0 to mark a new milestone release with significant changes, including the increased iOS deployment target and other enhancements included in this version. --- Example/Podfile | 4 ++-- IosAwnCore.podspec | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Example/Podfile b/Example/Podfile index 30be293..ffb2e9f 100644 --- a/Example/Podfile +++ b/Example/Podfile @@ -1,6 +1,6 @@ use_frameworks! -platform :ios, '11.0' +platform :ios, '12.0' target 'IosAwnCore_Example' do pod 'IosAwnCore', :path => '../' @@ -18,7 +18,7 @@ post_install do |installer| if target.name == 'IosAwnCore' config.build_settings['BUILD_LIBRARY_FOR_DISTRIBUTION'] = 'YES' end - config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '11.0' + config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '12.0' end end end diff --git a/IosAwnCore.podspec b/IosAwnCore.podspec index 25fc50e..ead023e 100644 --- a/IosAwnCore.podspec +++ b/IosAwnCore.podspec @@ -8,7 +8,7 @@ Pod::Spec.new do |s| s.name = 'IosAwnCore' - s.version = '0.9.3' + s.version = '0.10.0' s.summary = 'Awesome Notifications iOS Core' s.description = <<-DESC @@ -24,7 +24,7 @@ Awesome Notifications Ios Core (Only iOS devices). s.static_framework = true s.platform = :ios - s.ios.deployment_target = '11.0' + s.ios.deployment_target = '12.0' s.swift_version = '5.3' s.source_files = 'IosAwnCore/Classes/**/*'