diff --git a/.swiftlint.yml b/.swiftlint.yml index 6841848..3f74ead 100644 --- a/.swiftlint.yml +++ b/.swiftlint.yml @@ -5,6 +5,15 @@ disabled_rules: - vertical_whitespace - redundant_objc_attribute - nesting + - large_tuple + - line_length + - vertical_parameter_alignment + - void_function_in_ternary + - for_where + - function_body_length + - comma + - blanket_disable_command + - colon excluded: - Carthage - Pods diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..9c6a59a --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2023 PushEngage + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/Podfile b/Podfile index ddefab0..fed1124 100644 --- a/Podfile +++ b/Podfile @@ -8,16 +8,12 @@ target 'PushEngage' do pod 'SwiftLint' target 'PushEngageTests' do - # uncomment this line to use the local SDK dependency and comment out next line - # pod 'PushEngage', :path => "<>/pushengage-ios-sdk" - pod 'PushEngage' + pod 'PushEngage', :path => "../pushengage-ios-sdk-internal" end end target 'PushNotificationDemo' do - # uncomment this line to use the local SDK dependency and comment out next line - # pod 'PushEngage', :path => "<>/pushengage-ios-sdk" - pod 'PushEngage' + pod 'PushEngage', :path => "../pushengage-ios-sdk-internal" post_install do |installer| installer.pods_project.targets.each do |target| @@ -28,33 +24,23 @@ target 'PushNotificationDemo' do end target 'PushEngageNotificationExtension' do - # uncomment this line to use the local SDK dependency and comment out next line - # pod 'PushEngage', :path => "<>/pushengage-ios-sdk" - pod 'PushEngage' + pod 'PushEngage', :path => "../pushengage-ios-sdk-internal" end target 'PushEngageNotificationContentExtenstion' do - # uncomment this line to use the local SDK dependency and comment out next line - # pod 'PushEngage', :path => "<>/pushengage-ios-sdk" - pod 'PushEngage' + pod 'PushEngage', :path => "../pushengage-ios-sdk-internal" end end target 'PushNotificationObjcSample' do - # uncomment this line to use the local SDK dependency and comment out next line - # pod 'PushEngage', :path => "<>/pushengage-ios-sdk" - pod 'PushEngage' + pod 'PushEngage', :path => "../pushengage-ios-sdk-internal" target 'PushEngageObjcNotificationExtension' do - # uncomment this line to use the local SDK dependency and comment out next line - # pod 'PushEngage', :path => "<>/pushengage-ios-sdk" - pod 'PushEngage' + pod 'PushEngage', :path => "../pushengage-ios-sdk-internal" end target 'NotificationContentExtensionObjcSample' do - # uncomment this line to use the local SDK dependency and comment out next line - # pod 'PushEngage', :path => "<>/pushengage-ios-sdk" - pod 'PushEngage' + pod 'PushEngage', :path => "../pushengage-ios-sdk-internal" end end diff --git a/PushEngage.podspec b/PushEngage.podspec index f91e8f5..f0a7763 100644 --- a/PushEngage.podspec +++ b/PushEngage.podspec @@ -1,14 +1,12 @@ Pod::Spec.new do |spec| spec.name = "PushEngage" - spec.version = "0.0.1" - spec.summary = "iOS Framework which provides easy way to start with Push - notification in you native iOS Applications." - spec.description = "To make your users interact your application even they are not using you application. Push Notifications plays most important role - our product will make this very easy for you to integrate with you new or existing applications." - spec.homepage = "https://github.com/awesomemotive/pushengage-ios-sdk" + spec.version = "0.0.2" + spec.summary = "iOS Framework which provides easy way to start with Push notification in your native iOS Applications." + spec.description = "To make your users interact with your application even when they are not using your application, push notifications plays the most important role and our product will make this very easy for you to integrate with your applications." + spec.homepage = "https://github.com/awesomemotive/pushengage-ios-sdk.git" spec.license = { :type => "MIT", :file => "LICENSE" } - spec.author = { "PushEngage" => "care@pushengage.com" } + spec.author = { "PushEngage" => "care@pushengage.com" } spec.platform = :ios spec.ios.deployment_target = '9.0' spec.requires_arc = true @@ -17,7 +15,7 @@ Pod::Spec.new do |spec| } spec.ios.framework = "UIKit" spec.dependency 'SwiftLint' - # spec.vendored_frameworks = "Framework/PushEngage.framework" + #spec.vendored_frameworks = "Framework/PushEngage.framework" spec.pod_target_xcconfig = { 'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'arm64' } spec.user_target_xcconfig = { 'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'arm64' } spec.source_files = "PushEngage/**/*.{swift}" diff --git a/PushEngage.xcodeproj/project.pbxproj b/PushEngage.xcodeproj/project.pbxproj index 117c6ee..1b4e1bf 100644 --- a/PushEngage.xcodeproj/project.pbxproj +++ b/PushEngage.xcodeproj/project.pbxproj @@ -3,14 +3,16 @@ archiveVersion = 1; classes = { }; - objectVersion = 51; + objectVersion = 54; objects = { /* Begin PBXBuildFile section */ - 22658405514E6D0A01053CB9 /* Pods_PushEngage_PushEngageTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DA68AA88317B509208E1D5D9 /* Pods_PushEngage_PushEngageTests.framework */; }; - 28724128DF1733F0DCF87DBA /* libPods-PushNotificationObjcSample-PushEngageObjcNotificationExtension.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 83C98F2B64E7AB5F71A44E17 /* libPods-PushNotificationObjcSample-PushEngageObjcNotificationExtension.a */; }; - 318A8668F5042DE19CEAA3DF /* libPods-PushNotificationDemo.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F1D12DE856CAAC870A6B14D6 /* libPods-PushNotificationDemo.a */; }; - 448F73A97F9663261EF7F464 /* libPods-PushNotificationObjcSample-NotificationContentExtensionObjcSample.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 06429593F5F0480815C29A15 /* libPods-PushNotificationObjcSample-NotificationContentExtensionObjcSample.a */; }; + 050AD7EFCA738A7663F37CCD /* libPods-PushNotificationObjcSample-PushEngageObjcNotificationExtension.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DACAF9672E2AB2206D139D51 /* libPods-PushNotificationObjcSample-PushEngageObjcNotificationExtension.a */; }; + 09A0C6F55F4A856FCF933870 /* libPods-PushNotificationObjcSample.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 36087ABD7F73FF63E00D585D /* libPods-PushNotificationObjcSample.a */; }; + 1D01CFD62ACAD4CA008C5892 /* PEManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D01CFD52ACAD4CA008C5892 /* PEManager.swift */; }; + 1D4944D32ACE925700370E47 /* TextInputViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D4944D22ACE925700370E47 /* TextInputViewController.swift */; }; + 1DAC1FCB2B05DE2200538064 /* File.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1DAC1FCA2B05DE2200538064 /* File.swift */; }; + 40466AA499CE4A692C09E4F6 /* libPods-PushNotificationDemo-PushEngageNotificationExtension.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 52921EE35743583EB3F05230 /* libPods-PushNotificationDemo-PushEngageNotificationExtension.a */; }; 4623217C26583862005634FB /* PushEngageUNUserNotificationCenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4623217B26583862005634FB /* PushEngageUNUserNotificationCenter.swift */; }; 4627676D2660242A00DF854B /* PENotification.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4627676C2660242A00DF854B /* PENotification.swift */; }; 46293E5C265B8AF9001353EB /* NotificationSettingsManageriOS9.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46293E5B265B8AF9001353EB /* NotificationSettingsManageriOS9.swift */; }; @@ -59,7 +61,6 @@ 46BA8E53261D6B160028D000 /* EnumTypes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46BA8E4D261D6B160028D000 /* EnumTypes.swift */; }; 46BA8E76261D6B380028D000 /* PushEngage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46BA8E59261D6B380028D000 /* PushEngage.swift */; }; 46BA8E78261D6B380028D000 /* Observable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46BA8E5C261D6B380028D000 /* Observable.swift */; }; - 46BA8E79261D6B380028D000 /* PEViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46BA8E5E261D6B380028D000 /* PEViewModel.swift */; }; 46BA8E7A261D6B380028D000 /* NetworkResponse.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46BA8E60261D6B380028D000 /* NetworkResponse.swift */; }; 46BA8E7B261D6B380028D000 /* PEPayLoad.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46BA8E61261D6B380028D000 /* PEPayLoad.swift */; }; 46BA8E7C261D6B380028D000 /* Subscription.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46BA8E62261D6B380028D000 /* Subscription.swift */; }; @@ -70,7 +71,7 @@ 46BA8E81261D6B380028D000 /* URLParameterEncoder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46BA8E6B261D6B380028D000 /* URLParameterEncoder.swift */; }; 46BA8E82261D6B380028D000 /* JSONParameterEncoder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46BA8E6C261D6B380028D000 /* JSONParameterEncoder.swift */; }; 46BA8E83261D6B380028D000 /* NetworkReachablity.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46BA8E6E261D6B380028D000 /* NetworkReachablity.swift */; }; - 46BA8E84261D6B380028D000 /* NetworkRouter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46BA8E70261D6B380028D000 /* NetworkRouter.swift */; }; + 46BA8E84261D6B380028D000 /* NetworkRouterType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46BA8E70261D6B380028D000 /* NetworkRouterType.swift */; }; 46BA8E85261D6B380028D000 /* HTTPMethod.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46BA8E71261D6B380028D000 /* HTTPMethod.swift */; }; 46BA8E86261D6B380028D000 /* Router.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46BA8E72261D6B380028D000 /* Router.swift */; }; 46BA8EB1261D6B520028D000 /* WKWebViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46BA8E8C261D6B520028D000 /* WKWebViewController.swift */; }; @@ -82,25 +83,22 @@ 46BA8EBA261D6B520028D000 /* NotificationSettingsManageriOS10.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46BA8E99261D6B520028D000 /* NotificationSettingsManageriOS10.swift */; }; 46BA8EBC261D6B520028D000 /* NotificationExtensionManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46BA8E9B261D6B520028D000 /* NotificationExtensionManager.swift */; }; 46BA8EBD261D6B520028D000 /* ApplicationService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46BA8E9C261D6B520028D000 /* ApplicationService.swift */; }; - 46BA8EBF261D6B520028D000 /* LocationManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46BA8E9E261D6B520028D000 /* LocationManager.swift */; }; 46BA8EC0261D6B520028D000 /* SubscriberServiceManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46BA8E9F261D6B520028D000 /* SubscriberServiceManager.swift */; }; 46BA8EC1261D6B520028D000 /* AsyncResultOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46BA8EA1261D6B520028D000 /* AsyncResultOperation.swift */; }; 46BA8EC2261D6B520028D000 /* ChainedAsyncResultOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46BA8EA2261D6B520028D000 /* ChainedAsyncResultOperation.swift */; }; 46BA8EC3261D6B520028D000 /* AsyncOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46BA8EA3261D6B520028D000 /* AsyncOperation.swift */; }; 46BA8EC4261D6B520028D000 /* PEOperations.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46BA8EA4261D6B520028D000 /* PEOperations.swift */; }; - 46BA8EC7261D6B520028D000 /* NotificationProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46BA8EA8261D6B520028D000 /* NotificationProtocol.swift */; }; + 46BA8EC7261D6B520028D000 /* NotificationServiceType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46BA8EA8261D6B520028D000 /* NotificationServiceType.swift */; }; 46BA8EC8261D6B520028D000 /* DatasourceProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46BA8EA9261D6B520028D000 /* DatasourceProtocol.swift */; }; - 46BA8ECA261D6B520028D000 /* NotificationLifeCycleService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46BA8EAB261D6B520028D000 /* NotificationLifeCycleService.swift */; }; - 46BA8ECB261D6B520028D000 /* LocationInfoProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46BA8EAC261D6B520028D000 /* LocationInfoProtocol.swift */; }; - 46BA8ECC261D6B520028D000 /* NotificationExtensionProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46BA8EAD261D6B520028D000 /* NotificationExtensionProtocol.swift */; }; - 46BA8ECD261D6B520028D000 /* SubscriberService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46BA8EAE261D6B520028D000 /* SubscriberService.swift */; }; - 46BA8ECE261D6B520028D000 /* ApplicationProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46BA8EAF261D6B520028D000 /* ApplicationProtocol.swift */; }; - 46BA8ECF261D6B520028D000 /* UserDefaultProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46BA8EB0261D6B520028D000 /* UserDefaultProtocol.swift */; }; + 46BA8ECA261D6B520028D000 /* NotificationLifeCycleServiceType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46BA8EAB261D6B520028D000 /* NotificationLifeCycleServiceType.swift */; }; + 46BA8ECC261D6B520028D000 /* NotificationExtensionType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46BA8EAD261D6B520028D000 /* NotificationExtensionType.swift */; }; + 46BA8ECD261D6B520028D000 /* SubscriberServiceType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46BA8EAE261D6B520028D000 /* SubscriberServiceType.swift */; }; + 46BA8ECE261D6B520028D000 /* ApplicationServiceType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46BA8EAF261D6B520028D000 /* ApplicationServiceType.swift */; }; + 46BA8ECF261D6B520028D000 /* UserDefaultsType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46BA8EB0261D6B520028D000 /* UserDefaultsType.swift */; }; 46BA8EF0261D93DB0028D000 /* TriggerModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46BA8EEF261D93DB0028D000 /* TriggerModel.swift */; }; 46BA8F0B261DF7EB0028D000 /* TriggerCampaignManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46BA8F0A261DF7EB0028D000 /* TriggerCampaignManager.swift */; }; - 46BA8F0F261E09DF0028D000 /* TriggerCampaignProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46BA8F0E261E09DF0028D000 /* TriggerCampaignProtocol.swift */; }; + 46BA8F0F261E09DF0028D000 /* TriggerCampaignType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46BA8F0E261E09DF0028D000 /* TriggerCampaignType.swift */; }; 46CD64E226393B8D00CD88D5 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46CD64E126393B8D00CD88D5 /* ContentView.swift */; }; - 46E3073C26768FF800C5D8B7 /* File.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46E3073B26768FF800C5D8B7 /* File.swift */; }; 46F0B2AB26D756D100A1BEE9 /* UserNotifications.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 467D68F02636A5A00081CC36 /* UserNotifications.framework */; }; 46F0B2AC26D756D100A1BEE9 /* UserNotificationsUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 467D68F22636A5A00081CC36 /* UserNotificationsUI.framework */; }; 46F0B2B026D756D100A1BEE9 /* NotificationViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 46F0B2AF26D756D100A1BEE9 /* NotificationViewController.m */; }; @@ -111,10 +109,11 @@ 46FC139126794BCC0015D679 /* PushEngageObjcNotificationExtension.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = 46FC138926794BCC0015D679 /* PushEngageObjcNotificationExtension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; 46FC139826794C380015D679 /* File.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46FC139726794C380015D679 /* File.swift */; }; 46FCDAE126A1C9ED0068C45D /* PEPay.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46FCDAE026A1C9ED0068C45D /* PEPay.swift */; }; - 5C40FB256420E519FF06F183 /* libPods-PushNotificationDemo-PushEngageNotificationExtension.a in Frameworks */ = {isa = PBXBuildFile; fileRef = C0AB42B5A19218E7DE77FEDC /* libPods-PushNotificationDemo-PushEngageNotificationExtension.a */; }; - 5D4868B11D2CEC7D0BE843C2 /* Pods_PushEngage.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F2670840514C633C80E15858 /* Pods_PushEngage.framework */; }; - C26381C38E79EF3F1AA4882C /* libPods-PushNotificationDemo-PushEngageNotificationContentExtenstion.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 7530636B46E9FEB1AA56CA2C /* libPods-PushNotificationDemo-PushEngageNotificationContentExtenstion.a */; }; - FEC3B18D6DFEA1A81C438FA2 /* libPods-PushNotificationObjcSample.a in Frameworks */ = {isa = PBXBuildFile; fileRef = BE8F736DAFB82572897E387A /* libPods-PushNotificationObjcSample.a */; }; + 78B987FA6DBC341612AE118E /* libPods-PushNotificationObjcSample-NotificationContentExtensionObjcSample.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 267EBA8C7A502BC630B58CE7 /* libPods-PushNotificationObjcSample-NotificationContentExtensionObjcSample.a */; }; + 7E3D8F82021CBC8958AA60EC /* Pods_PushEngage.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0A22AA9AC06DAD5610802BCD /* Pods_PushEngage.framework */; }; + A055A2FECB086D4C0F8B6855 /* libPods-PushNotificationDemo-PushEngageNotificationContentExtenstion.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 200D4BD1D21FCB056A5E3A71 /* libPods-PushNotificationDemo-PushEngageNotificationContentExtenstion.a */; }; + B701908B2744B0EEDD935E76 /* Pods_PushEngage_PushEngageTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6AC94ADCB599F38717BB6512 /* Pods_PushEngage_PushEngageTests.framework */; }; + C7EC9A5C7E5A7AB87A605A26 /* libPods-PushNotificationDemo.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 481EA6B214B07AC8084AEACC /* libPods-PushNotificationDemo.a */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -190,12 +189,18 @@ /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ - 06429593F5F0480815C29A15 /* libPods-PushNotificationObjcSample-NotificationContentExtensionObjcSample.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-PushNotificationObjcSample-NotificationContentExtensionObjcSample.a"; sourceTree = BUILT_PRODUCTS_DIR; }; - 168EF663653182D68B78AC9D /* Pods-PushEngage.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-PushEngage.release.xcconfig"; path = "Target Support Files/Pods-PushEngage/Pods-PushEngage.release.xcconfig"; sourceTree = ""; }; - 232EA0EAE97C1E5D7FD00C27 /* Pods-PushNotificationObjcSample-PushEngageObjcNotificationExtension.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-PushNotificationObjcSample-PushEngageObjcNotificationExtension.release.xcconfig"; path = "Target Support Files/Pods-PushNotificationObjcSample-PushEngageObjcNotificationExtension/Pods-PushNotificationObjcSample-PushEngageObjcNotificationExtension.release.xcconfig"; sourceTree = ""; }; - 2C668A9E47CB4555C382F33C /* Pods-PushNotificationDemo-PushEngageNotificationExtension.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-PushNotificationDemo-PushEngageNotificationExtension.debug.xcconfig"; path = "Target Support Files/Pods-PushNotificationDemo-PushEngageNotificationExtension/Pods-PushNotificationDemo-PushEngageNotificationExtension.debug.xcconfig"; sourceTree = ""; }; - 34FE1855D2A72DD3855A5B85 /* Pods-PushNotificationDemo.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-PushNotificationDemo.release.xcconfig"; path = "Target Support Files/Pods-PushNotificationDemo/Pods-PushNotificationDemo.release.xcconfig"; sourceTree = ""; }; - 4167CEFEAEA512D9EE7C6178 /* Pods-PushNotificationDemo-PushEngageNotificationContentExtenstion.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-PushNotificationDemo-PushEngageNotificationContentExtenstion.release.xcconfig"; path = "Target Support Files/Pods-PushNotificationDemo-PushEngageNotificationContentExtenstion/Pods-PushNotificationDemo-PushEngageNotificationContentExtenstion.release.xcconfig"; sourceTree = ""; }; + 04CEFCCEAF5A5FFBBB3A89E5 /* Pods-PushEngage.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-PushEngage.release.xcconfig"; path = "Target Support Files/Pods-PushEngage/Pods-PushEngage.release.xcconfig"; sourceTree = ""; }; + 083F2A7D996439CA7B455F56 /* Pods-PushNotificationDemo-PushEngageNotificationExtension.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-PushNotificationDemo-PushEngageNotificationExtension.release.xcconfig"; path = "Target Support Files/Pods-PushNotificationDemo-PushEngageNotificationExtension/Pods-PushNotificationDemo-PushEngageNotificationExtension.release.xcconfig"; sourceTree = ""; }; + 0A22AA9AC06DAD5610802BCD /* Pods_PushEngage.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_PushEngage.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 17D15684AC37C760CEF34059 /* Pods-PushNotificationObjcSample-PushEngageObjcNotificationExtension.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-PushNotificationObjcSample-PushEngageObjcNotificationExtension.release.xcconfig"; path = "Target Support Files/Pods-PushNotificationObjcSample-PushEngageObjcNotificationExtension/Pods-PushNotificationObjcSample-PushEngageObjcNotificationExtension.release.xcconfig"; sourceTree = ""; }; + 1A513C68E66FFE9526A7D23A /* Pods-PushNotificationObjcSample-NotificationContentExtensionObjcSample.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-PushNotificationObjcSample-NotificationContentExtensionObjcSample.release.xcconfig"; path = "Target Support Files/Pods-PushNotificationObjcSample-NotificationContentExtensionObjcSample/Pods-PushNotificationObjcSample-NotificationContentExtensionObjcSample.release.xcconfig"; sourceTree = ""; }; + 1D01CFD52ACAD4CA008C5892 /* PEManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PEManager.swift; sourceTree = ""; }; + 1D4944D22ACE925700370E47 /* TextInputViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextInputViewController.swift; sourceTree = ""; }; + 1DAC1FCA2B05DE2200538064 /* File.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = File.swift; sourceTree = ""; }; + 200D4BD1D21FCB056A5E3A71 /* libPods-PushNotificationDemo-PushEngageNotificationContentExtenstion.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-PushNotificationDemo-PushEngageNotificationContentExtenstion.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + 2676215DBBA448F9F89F3AAC /* Pods-PushNotificationObjcSample-NotificationContentExtensionObjcSample.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-PushNotificationObjcSample-NotificationContentExtensionObjcSample.debug.xcconfig"; path = "Target Support Files/Pods-PushNotificationObjcSample-NotificationContentExtensionObjcSample/Pods-PushNotificationObjcSample-NotificationContentExtensionObjcSample.debug.xcconfig"; sourceTree = ""; }; + 267EBA8C7A502BC630B58CE7 /* libPods-PushNotificationObjcSample-NotificationContentExtensionObjcSample.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-PushNotificationObjcSample-NotificationContentExtensionObjcSample.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + 36087ABD7F73FF63E00D585D /* libPods-PushNotificationObjcSample.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-PushNotificationObjcSample.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 46152EE2263AC48800A48DCC /* PushEngageNotificationContentExtenstion.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = PushEngageNotificationContentExtenstion.entitlements; sourceTree = ""; }; 4623217B26583862005634FB /* PushEngageUNUserNotificationCenter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PushEngageUNUserNotificationCenter.swift; sourceTree = ""; }; 4627676C2660242A00DF854B /* PENotification.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PENotification.swift; sourceTree = ""; }; @@ -260,7 +265,6 @@ 46BA8E4D261D6B160028D000 /* EnumTypes.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EnumTypes.swift; sourceTree = ""; }; 46BA8E59261D6B380028D000 /* PushEngage.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PushEngage.swift; sourceTree = ""; }; 46BA8E5C261D6B380028D000 /* Observable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Observable.swift; sourceTree = ""; }; - 46BA8E5E261D6B380028D000 /* PEViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PEViewModel.swift; sourceTree = ""; }; 46BA8E60261D6B380028D000 /* NetworkResponse.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NetworkResponse.swift; sourceTree = ""; }; 46BA8E61261D6B380028D000 /* PEPayLoad.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PEPayLoad.swift; sourceTree = ""; }; 46BA8E62261D6B380028D000 /* Subscription.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Subscription.swift; sourceTree = ""; }; @@ -271,7 +275,7 @@ 46BA8E6B261D6B380028D000 /* URLParameterEncoder.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = URLParameterEncoder.swift; sourceTree = ""; }; 46BA8E6C261D6B380028D000 /* JSONParameterEncoder.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = JSONParameterEncoder.swift; sourceTree = ""; }; 46BA8E6E261D6B380028D000 /* NetworkReachablity.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NetworkReachablity.swift; sourceTree = ""; }; - 46BA8E70261D6B380028D000 /* NetworkRouter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NetworkRouter.swift; sourceTree = ""; }; + 46BA8E70261D6B380028D000 /* NetworkRouterType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NetworkRouterType.swift; sourceTree = ""; }; 46BA8E71261D6B380028D000 /* HTTPMethod.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HTTPMethod.swift; sourceTree = ""; }; 46BA8E72261D6B380028D000 /* Router.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Router.swift; sourceTree = ""; }; 46BA8E8C261D6B520028D000 /* WKWebViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WKWebViewController.swift; sourceTree = ""; }; @@ -283,26 +287,23 @@ 46BA8E99261D6B520028D000 /* NotificationSettingsManageriOS10.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NotificationSettingsManageriOS10.swift; sourceTree = ""; }; 46BA8E9B261D6B520028D000 /* NotificationExtensionManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NotificationExtensionManager.swift; sourceTree = ""; }; 46BA8E9C261D6B520028D000 /* ApplicationService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ApplicationService.swift; sourceTree = ""; }; - 46BA8E9E261D6B520028D000 /* LocationManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LocationManager.swift; sourceTree = ""; }; 46BA8E9F261D6B520028D000 /* SubscriberServiceManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SubscriberServiceManager.swift; sourceTree = ""; }; 46BA8EA1261D6B520028D000 /* AsyncResultOperation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AsyncResultOperation.swift; sourceTree = ""; }; 46BA8EA2261D6B520028D000 /* ChainedAsyncResultOperation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ChainedAsyncResultOperation.swift; sourceTree = ""; }; 46BA8EA3261D6B520028D000 /* AsyncOperation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AsyncOperation.swift; sourceTree = ""; }; 46BA8EA4261D6B520028D000 /* PEOperations.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PEOperations.swift; sourceTree = ""; }; - 46BA8EA8261D6B520028D000 /* NotificationProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NotificationProtocol.swift; sourceTree = ""; }; + 46BA8EA8261D6B520028D000 /* NotificationServiceType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NotificationServiceType.swift; sourceTree = ""; }; 46BA8EA9261D6B520028D000 /* DatasourceProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DatasourceProtocol.swift; sourceTree = ""; }; - 46BA8EAB261D6B520028D000 /* NotificationLifeCycleService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NotificationLifeCycleService.swift; sourceTree = ""; }; - 46BA8EAC261D6B520028D000 /* LocationInfoProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LocationInfoProtocol.swift; sourceTree = ""; }; - 46BA8EAD261D6B520028D000 /* NotificationExtensionProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NotificationExtensionProtocol.swift; sourceTree = ""; }; - 46BA8EAE261D6B520028D000 /* SubscriberService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SubscriberService.swift; sourceTree = ""; }; - 46BA8EAF261D6B520028D000 /* ApplicationProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ApplicationProtocol.swift; sourceTree = ""; }; - 46BA8EB0261D6B520028D000 /* UserDefaultProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UserDefaultProtocol.swift; sourceTree = ""; }; + 46BA8EAB261D6B520028D000 /* NotificationLifeCycleServiceType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NotificationLifeCycleServiceType.swift; sourceTree = ""; }; + 46BA8EAD261D6B520028D000 /* NotificationExtensionType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NotificationExtensionType.swift; sourceTree = ""; }; + 46BA8EAE261D6B520028D000 /* SubscriberServiceType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SubscriberServiceType.swift; sourceTree = ""; }; + 46BA8EAF261D6B520028D000 /* ApplicationServiceType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ApplicationServiceType.swift; sourceTree = ""; }; + 46BA8EB0261D6B520028D000 /* UserDefaultsType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UserDefaultsType.swift; sourceTree = ""; }; 46BA8EEF261D93DB0028D000 /* TriggerModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TriggerModel.swift; sourceTree = ""; }; 46BA8F0A261DF7EB0028D000 /* TriggerCampaignManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TriggerCampaignManager.swift; sourceTree = ""; }; - 46BA8F0E261E09DF0028D000 /* TriggerCampaignProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TriggerCampaignProtocol.swift; sourceTree = ""; }; + 46BA8F0E261E09DF0028D000 /* TriggerCampaignType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TriggerCampaignType.swift; sourceTree = ""; }; 46CD64E126393B8D00CD88D5 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = ""; }; 46E3073A26768FF800C5D8B7 /* PushNotificationObjcSample-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "PushNotificationObjcSample-Bridging-Header.h"; sourceTree = ""; }; - 46E3073B26768FF800C5D8B7 /* File.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = File.swift; sourceTree = ""; }; 46F0B2AA26D756D100A1BEE9 /* NotificationContentExtensionObjcSample.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = NotificationContentExtensionObjcSample.appex; sourceTree = BUILT_PRODUCTS_DIR; }; 46F0B2AE26D756D100A1BEE9 /* NotificationViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = NotificationViewController.h; sourceTree = ""; }; 46F0B2AF26D756D100A1BEE9 /* NotificationViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = NotificationViewController.m; sourceTree = ""; }; @@ -318,24 +319,21 @@ 46FC139726794C380015D679 /* File.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = File.swift; sourceTree = ""; }; 46FC139926794F900015D679 /* PushEngageObjcNotificationExtension.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = PushEngageObjcNotificationExtension.entitlements; sourceTree = ""; }; 46FCDAE026A1C9ED0068C45D /* PEPay.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PEPay.swift; sourceTree = ""; }; - 490E3179B48DB51C0AF8B10B /* Pods-PushNotificationObjcSample-NotificationContentExtensionObjcSample.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-PushNotificationObjcSample-NotificationContentExtensionObjcSample.debug.xcconfig"; path = "Target Support Files/Pods-PushNotificationObjcSample-NotificationContentExtensionObjcSample/Pods-PushNotificationObjcSample-NotificationContentExtensionObjcSample.debug.xcconfig"; sourceTree = ""; }; - 63265847E94DDB9BB9B706B0 /* Pods-PushNotificationObjcSample-PushEngageObjcNotificationExtension.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-PushNotificationObjcSample-PushEngageObjcNotificationExtension.debug.xcconfig"; path = "Target Support Files/Pods-PushNotificationObjcSample-PushEngageObjcNotificationExtension/Pods-PushNotificationObjcSample-PushEngageObjcNotificationExtension.debug.xcconfig"; sourceTree = ""; }; - 6D5AD816108C6CCE589EBD24 /* Pods-PushEngage.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-PushEngage.debug.xcconfig"; path = "Target Support Files/Pods-PushEngage/Pods-PushEngage.debug.xcconfig"; sourceTree = ""; }; - 7530636B46E9FEB1AA56CA2C /* libPods-PushNotificationDemo-PushEngageNotificationContentExtenstion.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-PushNotificationDemo-PushEngageNotificationContentExtenstion.a"; sourceTree = BUILT_PRODUCTS_DIR; }; - 7CC94958AB96C609578D7D58 /* Pods-PushNotificationObjcSample-NotificationContentExtensionObjcSample.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-PushNotificationObjcSample-NotificationContentExtensionObjcSample.release.xcconfig"; path = "Target Support Files/Pods-PushNotificationObjcSample-NotificationContentExtensionObjcSample/Pods-PushNotificationObjcSample-NotificationContentExtensionObjcSample.release.xcconfig"; sourceTree = ""; }; - 83C98F2B64E7AB5F71A44E17 /* libPods-PushNotificationObjcSample-PushEngageObjcNotificationExtension.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-PushNotificationObjcSample-PushEngageObjcNotificationExtension.a"; sourceTree = BUILT_PRODUCTS_DIR; }; - 8E2F4A6DFD49B034E809D0F4 /* Pods-PushEngage-PushEngageTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-PushEngage-PushEngageTests.debug.xcconfig"; path = "Target Support Files/Pods-PushEngage-PushEngageTests/Pods-PushEngage-PushEngageTests.debug.xcconfig"; sourceTree = ""; }; - A7F452EE0484497C407415F4 /* Pods-PushNotificationObjcSample.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-PushNotificationObjcSample.debug.xcconfig"; path = "Target Support Files/Pods-PushNotificationObjcSample/Pods-PushNotificationObjcSample.debug.xcconfig"; sourceTree = ""; }; - A879F4B44990EC79AC3AABCD /* Pods-PushNotificationDemo-PushEngageNotificationContentExtenstion.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-PushNotificationDemo-PushEngageNotificationContentExtenstion.debug.xcconfig"; path = "Target Support Files/Pods-PushNotificationDemo-PushEngageNotificationContentExtenstion/Pods-PushNotificationDemo-PushEngageNotificationContentExtenstion.debug.xcconfig"; sourceTree = ""; }; - ABD54A8D77DAE36BCCCD2B07 /* Pods-PushEngage-PushEngageTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-PushEngage-PushEngageTests.release.xcconfig"; path = "Target Support Files/Pods-PushEngage-PushEngageTests/Pods-PushEngage-PushEngageTests.release.xcconfig"; sourceTree = ""; }; - BE8F736DAFB82572897E387A /* libPods-PushNotificationObjcSample.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-PushNotificationObjcSample.a"; sourceTree = BUILT_PRODUCTS_DIR; }; - C0AB42B5A19218E7DE77FEDC /* libPods-PushNotificationDemo-PushEngageNotificationExtension.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-PushNotificationDemo-PushEngageNotificationExtension.a"; sourceTree = BUILT_PRODUCTS_DIR; }; - CC5926D08F1A5A84B6CE6EA8 /* Pods-PushNotificationDemo.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-PushNotificationDemo.debug.xcconfig"; path = "Target Support Files/Pods-PushNotificationDemo/Pods-PushNotificationDemo.debug.xcconfig"; sourceTree = ""; }; - D7334B14E67A8941C42A138A /* Pods-PushNotificationObjcSample.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-PushNotificationObjcSample.release.xcconfig"; path = "Target Support Files/Pods-PushNotificationObjcSample/Pods-PushNotificationObjcSample.release.xcconfig"; sourceTree = ""; }; - DA68AA88317B509208E1D5D9 /* Pods_PushEngage_PushEngageTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_PushEngage_PushEngageTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - F1D12DE856CAAC870A6B14D6 /* libPods-PushNotificationDemo.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-PushNotificationDemo.a"; sourceTree = BUILT_PRODUCTS_DIR; }; - F2670840514C633C80E15858 /* Pods_PushEngage.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_PushEngage.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - F2C64E569C23FDEB4CD8EF0F /* Pods-PushNotificationDemo-PushEngageNotificationExtension.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-PushNotificationDemo-PushEngageNotificationExtension.release.xcconfig"; path = "Target Support Files/Pods-PushNotificationDemo-PushEngageNotificationExtension/Pods-PushNotificationDemo-PushEngageNotificationExtension.release.xcconfig"; sourceTree = ""; }; + 481EA6B214B07AC8084AEACC /* libPods-PushNotificationDemo.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-PushNotificationDemo.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + 4C52C00297192C65144FC544 /* Pods-PushNotificationDemo.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-PushNotificationDemo.release.xcconfig"; path = "Target Support Files/Pods-PushNotificationDemo/Pods-PushNotificationDemo.release.xcconfig"; sourceTree = ""; }; + 52921EE35743583EB3F05230 /* libPods-PushNotificationDemo-PushEngageNotificationExtension.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-PushNotificationDemo-PushEngageNotificationExtension.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + 6AC94ADCB599F38717BB6512 /* Pods_PushEngage_PushEngageTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_PushEngage_PushEngageTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 765536D1BBD42367EDCCE01D /* Pods-PushNotificationDemo-PushEngageNotificationContentExtenstion.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-PushNotificationDemo-PushEngageNotificationContentExtenstion.debug.xcconfig"; path = "Target Support Files/Pods-PushNotificationDemo-PushEngageNotificationContentExtenstion/Pods-PushNotificationDemo-PushEngageNotificationContentExtenstion.debug.xcconfig"; sourceTree = ""; }; + 86BC3A417D3BF43CAECDCF48 /* Pods-PushEngage-PushEngageTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-PushEngage-PushEngageTests.debug.xcconfig"; path = "Target Support Files/Pods-PushEngage-PushEngageTests/Pods-PushEngage-PushEngageTests.debug.xcconfig"; sourceTree = ""; }; + CD1CCFC59CC88B1D03D374AC /* Pods-PushEngage-PushEngageTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-PushEngage-PushEngageTests.release.xcconfig"; path = "Target Support Files/Pods-PushEngage-PushEngageTests/Pods-PushEngage-PushEngageTests.release.xcconfig"; sourceTree = ""; }; + D93783276389C2BFBFCB4EEC /* Pods-PushNotificationObjcSample.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-PushNotificationObjcSample.debug.xcconfig"; path = "Target Support Files/Pods-PushNotificationObjcSample/Pods-PushNotificationObjcSample.debug.xcconfig"; sourceTree = ""; }; + DACAF9672E2AB2206D139D51 /* libPods-PushNotificationObjcSample-PushEngageObjcNotificationExtension.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-PushNotificationObjcSample-PushEngageObjcNotificationExtension.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + DD60E59423AF3716B9BB1A28 /* Pods-PushNotificationObjcSample-PushEngageObjcNotificationExtension.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-PushNotificationObjcSample-PushEngageObjcNotificationExtension.debug.xcconfig"; path = "Target Support Files/Pods-PushNotificationObjcSample-PushEngageObjcNotificationExtension/Pods-PushNotificationObjcSample-PushEngageObjcNotificationExtension.debug.xcconfig"; sourceTree = ""; }; + E25265661730DA0E6687F6ED /* Pods-PushEngage.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-PushEngage.debug.xcconfig"; path = "Target Support Files/Pods-PushEngage/Pods-PushEngage.debug.xcconfig"; sourceTree = ""; }; + E6F6FCFDAD9A3EC95E168C75 /* Pods-PushNotificationDemo-PushEngageNotificationExtension.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-PushNotificationDemo-PushEngageNotificationExtension.debug.xcconfig"; path = "Target Support Files/Pods-PushNotificationDemo-PushEngageNotificationExtension/Pods-PushNotificationDemo-PushEngageNotificationExtension.debug.xcconfig"; sourceTree = ""; }; + E833FE914BCE1F47F42ACE2F /* Pods-PushNotificationObjcSample.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-PushNotificationObjcSample.release.xcconfig"; path = "Target Support Files/Pods-PushNotificationObjcSample/Pods-PushNotificationObjcSample.release.xcconfig"; sourceTree = ""; }; + F0493026DC42BFAE849A81A7 /* Pods-PushNotificationDemo.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-PushNotificationDemo.debug.xcconfig"; path = "Target Support Files/Pods-PushNotificationDemo/Pods-PushNotificationDemo.debug.xcconfig"; sourceTree = ""; }; + F780225089630E597F328676 /* Pods-PushNotificationDemo-PushEngageNotificationContentExtenstion.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-PushNotificationDemo-PushEngageNotificationContentExtenstion.release.xcconfig"; path = "Target Support Files/Pods-PushNotificationDemo-PushEngageNotificationContentExtenstion/Pods-PushNotificationDemo-PushEngageNotificationContentExtenstion.release.xcconfig"; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -343,7 +341,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 318A8668F5042DE19CEAA3DF /* libPods-PushNotificationDemo.a in Frameworks */, + C7EC9A5C7E5A7AB87A605A26 /* libPods-PushNotificationDemo.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -351,7 +349,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 5C40FB256420E519FF06F183 /* libPods-PushNotificationDemo-PushEngageNotificationExtension.a in Frameworks */, + 40466AA499CE4A692C09E4F6 /* libPods-PushNotificationDemo-PushEngageNotificationExtension.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -359,7 +357,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - FEC3B18D6DFEA1A81C438FA2 /* libPods-PushNotificationObjcSample.a in Frameworks */, + 09A0C6F55F4A856FCF933870 /* libPods-PushNotificationObjcSample.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -369,7 +367,7 @@ files = ( 467D68F32636A5A00081CC36 /* UserNotificationsUI.framework in Frameworks */, 467D68F12636A5A00081CC36 /* UserNotifications.framework in Frameworks */, - C26381C38E79EF3F1AA4882C /* libPods-PushNotificationDemo-PushEngageNotificationContentExtenstion.a in Frameworks */, + A055A2FECB086D4C0F8B6855 /* libPods-PushNotificationDemo-PushEngageNotificationContentExtenstion.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -377,7 +375,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 5D4868B11D2CEC7D0BE843C2 /* Pods_PushEngage.framework in Frameworks */, + 7E3D8F82021CBC8958AA60EC /* Pods_PushEngage.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -386,7 +384,7 @@ buildActionMask = 2147483647; files = ( 46BA8E32261D6AE30028D000 /* PushEngage.framework in Frameworks */, - 22658405514E6D0A01053CB9 /* Pods_PushEngage_PushEngageTests.framework in Frameworks */, + B701908B2744B0EEDD935E76 /* Pods_PushEngage_PushEngageTests.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -396,7 +394,7 @@ files = ( 46F0B2AC26D756D100A1BEE9 /* UserNotificationsUI.framework in Frameworks */, 46F0B2AB26D756D100A1BEE9 /* UserNotifications.framework in Frameworks */, - 448F73A97F9663261EF7F464 /* libPods-PushNotificationObjcSample-NotificationContentExtensionObjcSample.a in Frameworks */, + 78B987FA6DBC341612AE118E /* libPods-PushNotificationObjcSample-NotificationContentExtensionObjcSample.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -404,7 +402,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 28724128DF1733F0DCF87DBA /* libPods-PushNotificationObjcSample-PushEngageObjcNotificationExtension.a in Frameworks */, + 050AD7EFCA738A7663F37CCD /* libPods-PushNotificationObjcSample-PushEngageObjcNotificationExtension.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -416,14 +414,14 @@ children = ( 467D68F02636A5A00081CC36 /* UserNotifications.framework */, 467D68F22636A5A00081CC36 /* UserNotificationsUI.framework */, - F2670840514C633C80E15858 /* Pods_PushEngage.framework */, - DA68AA88317B509208E1D5D9 /* Pods_PushEngage_PushEngageTests.framework */, - F1D12DE856CAAC870A6B14D6 /* libPods-PushNotificationDemo.a */, - 7530636B46E9FEB1AA56CA2C /* libPods-PushNotificationDemo-PushEngageNotificationContentExtenstion.a */, - C0AB42B5A19218E7DE77FEDC /* libPods-PushNotificationDemo-PushEngageNotificationExtension.a */, - BE8F736DAFB82572897E387A /* libPods-PushNotificationObjcSample.a */, - 06429593F5F0480815C29A15 /* libPods-PushNotificationObjcSample-NotificationContentExtensionObjcSample.a */, - 83C98F2B64E7AB5F71A44E17 /* libPods-PushNotificationObjcSample-PushEngageObjcNotificationExtension.a */, + 0A22AA9AC06DAD5610802BCD /* Pods_PushEngage.framework */, + 6AC94ADCB599F38717BB6512 /* Pods_PushEngage_PushEngageTests.framework */, + 481EA6B214B07AC8084AEACC /* libPods-PushNotificationDemo.a */, + 200D4BD1D21FCB056A5E3A71 /* libPods-PushNotificationDemo-PushEngageNotificationContentExtenstion.a */, + 52921EE35743583EB3F05230 /* libPods-PushNotificationDemo-PushEngageNotificationExtension.a */, + 36087ABD7F73FF63E00D585D /* libPods-PushNotificationObjcSample.a */, + 267EBA8C7A502BC630B58CE7 /* libPods-PushNotificationObjcSample-NotificationContentExtensionObjcSample.a */, + DACAF9672E2AB2206D139D51 /* libPods-PushNotificationObjcSample-PushEngageObjcNotificationExtension.a */, ); name = Frameworks; sourceTree = ""; @@ -431,22 +429,22 @@ 1DC28814D4332E576F4B84C0 /* Pods */ = { isa = PBXGroup; children = ( - 6D5AD816108C6CCE589EBD24 /* Pods-PushEngage.debug.xcconfig */, - 168EF663653182D68B78AC9D /* Pods-PushEngage.release.xcconfig */, - 8E2F4A6DFD49B034E809D0F4 /* Pods-PushEngage-PushEngageTests.debug.xcconfig */, - ABD54A8D77DAE36BCCCD2B07 /* Pods-PushEngage-PushEngageTests.release.xcconfig */, - CC5926D08F1A5A84B6CE6EA8 /* Pods-PushNotificationDemo.debug.xcconfig */, - 34FE1855D2A72DD3855A5B85 /* Pods-PushNotificationDemo.release.xcconfig */, - A879F4B44990EC79AC3AABCD /* Pods-PushNotificationDemo-PushEngageNotificationContentExtenstion.debug.xcconfig */, - 4167CEFEAEA512D9EE7C6178 /* Pods-PushNotificationDemo-PushEngageNotificationContentExtenstion.release.xcconfig */, - 2C668A9E47CB4555C382F33C /* Pods-PushNotificationDemo-PushEngageNotificationExtension.debug.xcconfig */, - F2C64E569C23FDEB4CD8EF0F /* Pods-PushNotificationDemo-PushEngageNotificationExtension.release.xcconfig */, - A7F452EE0484497C407415F4 /* Pods-PushNotificationObjcSample.debug.xcconfig */, - D7334B14E67A8941C42A138A /* Pods-PushNotificationObjcSample.release.xcconfig */, - 490E3179B48DB51C0AF8B10B /* Pods-PushNotificationObjcSample-NotificationContentExtensionObjcSample.debug.xcconfig */, - 7CC94958AB96C609578D7D58 /* Pods-PushNotificationObjcSample-NotificationContentExtensionObjcSample.release.xcconfig */, - 63265847E94DDB9BB9B706B0 /* Pods-PushNotificationObjcSample-PushEngageObjcNotificationExtension.debug.xcconfig */, - 232EA0EAE97C1E5D7FD00C27 /* Pods-PushNotificationObjcSample-PushEngageObjcNotificationExtension.release.xcconfig */, + E25265661730DA0E6687F6ED /* Pods-PushEngage.debug.xcconfig */, + 04CEFCCEAF5A5FFBBB3A89E5 /* Pods-PushEngage.release.xcconfig */, + 86BC3A417D3BF43CAECDCF48 /* Pods-PushEngage-PushEngageTests.debug.xcconfig */, + CD1CCFC59CC88B1D03D374AC /* Pods-PushEngage-PushEngageTests.release.xcconfig */, + F0493026DC42BFAE849A81A7 /* Pods-PushNotificationDemo.debug.xcconfig */, + 4C52C00297192C65144FC544 /* Pods-PushNotificationDemo.release.xcconfig */, + 765536D1BBD42367EDCCE01D /* Pods-PushNotificationDemo-PushEngageNotificationContentExtenstion.debug.xcconfig */, + F780225089630E597F328676 /* Pods-PushNotificationDemo-PushEngageNotificationContentExtenstion.release.xcconfig */, + E6F6FCFDAD9A3EC95E168C75 /* Pods-PushNotificationDemo-PushEngageNotificationExtension.debug.xcconfig */, + 083F2A7D996439CA7B455F56 /* Pods-PushNotificationDemo-PushEngageNotificationExtension.release.xcconfig */, + D93783276389C2BFBFCB4EEC /* Pods-PushNotificationObjcSample.debug.xcconfig */, + E833FE914BCE1F47F42ACE2F /* Pods-PushNotificationObjcSample.release.xcconfig */, + 2676215DBBA448F9F89F3AAC /* Pods-PushNotificationObjcSample-NotificationContentExtensionObjcSample.debug.xcconfig */, + 1A513C68E66FFE9526A7D23A /* Pods-PushNotificationObjcSample-NotificationContentExtensionObjcSample.release.xcconfig */, + DD60E59423AF3716B9BB1A28 /* Pods-PushNotificationObjcSample-PushEngageObjcNotificationExtension.debug.xcconfig */, + 17D15684AC37C760CEF34059 /* Pods-PushNotificationObjcSample-PushEngageObjcNotificationExtension.release.xcconfig */, ); path = Pods; sourceTree = ""; @@ -475,6 +473,7 @@ 46358D3F262EF6F100D40FBE /* LaunchScreen.storyboard */, 46358D42262EF6F100D40FBE /* Info.plist */, 46FCDAE026A1C9ED0068C45D /* PEPay.swift */, + 1D4944D22ACE925700370E47 /* TextInputViewController.swift */, ); path = PushNotificationDemo; sourceTree = ""; @@ -508,6 +507,7 @@ 465367A62677B08200DFEBF6 /* AddToCart.m */, 465367A82677FF0400DFEBF6 /* SportsViewcontroller.h */, 465367A92677FF0400DFEBF6 /* SportsViewcontroller.m */, + 1DAC1FCA2B05DE2200538064 /* File.swift */, ); path = PushNotificationObjcSample; sourceTree = ""; @@ -527,7 +527,6 @@ 46BA8E1E261D6AE30028D000 = { isa = PBXGroup; children = ( - 46E3073B26768FF800C5D8B7 /* File.swift */, 46BA8E2A261D6AE30028D000 /* PushEngage */, 46BA8E35261D6AE30028D000 /* PushEngageTests */, 46358D33262EF6F000D40FBE /* PushNotificationDemo */, @@ -643,7 +642,7 @@ 46BA8E5D261D6B380028D000 /* PEViewModel */ = { isa = PBXGroup; children = ( - 46BA8E5E261D6B380028D000 /* PEViewModel.swift */, + 1D01CFD52ACAD4CA008C5892 /* PEManager.swift */, ); path = PEViewModel; sourceTree = ""; @@ -710,7 +709,7 @@ 46BA8E6F261D6B380028D000 /* Service */ = { isa = PBXGroup; children = ( - 46BA8E70261D6B380028D000 /* NetworkRouter.swift */, + 46BA8E70261D6B380028D000 /* NetworkRouterType.swift */, 46BA8E71261D6B380028D000 /* HTTPMethod.swift */, 46BA8E72261D6B380028D000 /* Router.swift */, ); @@ -756,7 +755,6 @@ 46BA8E99261D6B520028D000 /* NotificationSettingsManageriOS10.swift */, 46BA8E9B261D6B520028D000 /* NotificationExtensionManager.swift */, 46BA8E9C261D6B520028D000 /* ApplicationService.swift */, - 46BA8E9E261D6B520028D000 /* LocationManager.swift */, 46BA8E9F261D6B520028D000 /* SubscriberServiceManager.swift */, 46BA8F0A261DF7EB0028D000 /* TriggerCampaignManager.swift */, 46293E5B265B8AF9001353EB /* NotificationSettingsManageriOS9.swift */, @@ -778,15 +776,14 @@ 46BA8EA5261D6B520028D000 /* Protocols */ = { isa = PBXGroup; children = ( - 46BA8EA8261D6B520028D000 /* NotificationProtocol.swift */, + 46BA8EA8261D6B520028D000 /* NotificationServiceType.swift */, 46BA8EA9261D6B520028D000 /* DatasourceProtocol.swift */, - 46BA8EAB261D6B520028D000 /* NotificationLifeCycleService.swift */, - 46BA8EAC261D6B520028D000 /* LocationInfoProtocol.swift */, - 46BA8EAD261D6B520028D000 /* NotificationExtensionProtocol.swift */, - 46BA8EAE261D6B520028D000 /* SubscriberService.swift */, - 46BA8EAF261D6B520028D000 /* ApplicationProtocol.swift */, - 46BA8EB0261D6B520028D000 /* UserDefaultProtocol.swift */, - 46BA8F0E261E09DF0028D000 /* TriggerCampaignProtocol.swift */, + 46BA8EAB261D6B520028D000 /* NotificationLifeCycleServiceType.swift */, + 46BA8EAD261D6B520028D000 /* NotificationExtensionType.swift */, + 46BA8EAE261D6B520028D000 /* SubscriberServiceType.swift */, + 46BA8EAF261D6B520028D000 /* ApplicationServiceType.swift */, + 46BA8EB0261D6B520028D000 /* UserDefaultsType.swift */, + 46BA8F0E261E09DF0028D000 /* TriggerCampaignType.swift */, ); path = Protocols; sourceTree = ""; @@ -845,7 +842,7 @@ isa = PBXNativeTarget; buildConfigurationList = 46358D45262EF6F100D40FBE /* Build configuration list for PBXNativeTarget "PushNotificationDemo" */; buildPhases = ( - 3783948EE9806BC376886B19 /* [CP] Check Pods Manifest.lock */, + 4FA7E16117FE79BD486B7AF1 /* [CP] Check Pods Manifest.lock */, 46358D2E262EF6F000D40FBE /* Sources */, 46358D2F262EF6F000D40FBE /* Frameworks */, 46358D30262EF6F000D40FBE /* Resources */, @@ -866,7 +863,7 @@ isa = PBXNativeTarget; buildConfigurationList = 46358D55262EF76F00D40FBE /* Build configuration list for PBXNativeTarget "PushEngageNotificationExtension" */; buildPhases = ( - B668E7512E3F02C22FFD4893 /* [CP] Check Pods Manifest.lock */, + EDB8F679FD4A1138A8C9864B /* [CP] Check Pods Manifest.lock */, 46358D49262EF76F00D40FBE /* Sources */, 46358D4A262EF76F00D40FBE /* Frameworks */, 46358D4B262EF76F00D40FBE /* Resources */, @@ -884,7 +881,7 @@ isa = PBXNativeTarget; buildConfigurationList = 465E0E3926768F320097F04F /* Build configuration list for PBXNativeTarget "PushNotificationObjcSample" */; buildPhases = ( - 8097C16450F6225B99C2594E /* [CP] Check Pods Manifest.lock */, + E88E4C0550374F2E304147AF /* [CP] Check Pods Manifest.lock */, 465E0E1D26768F310097F04F /* Sources */, 465E0E1E26768F310097F04F /* Frameworks */, 465E0E1F26768F310097F04F /* Resources */, @@ -905,7 +902,7 @@ isa = PBXNativeTarget; buildConfigurationList = 467D69002636A5A00081CC36 /* Build configuration list for PBXNativeTarget "PushEngageNotificationContentExtenstion" */; buildPhases = ( - 3A54A6A04C06B7758DF75BFD /* [CP] Check Pods Manifest.lock */, + DA90C05439326411DE0786F7 /* [CP] Check Pods Manifest.lock */, 467D68EB2636A5A00081CC36 /* Sources */, 467D68EC2636A5A00081CC36 /* Frameworks */, 467D68ED2636A5A00081CC36 /* Resources */, @@ -923,7 +920,7 @@ isa = PBXNativeTarget; buildConfigurationList = 46BA8E3C261D6AE30028D000 /* Build configuration list for PBXNativeTarget "PushEngage" */; buildPhases = ( - 9E5FC606C9470AC39C8A758E /* [CP] Check Pods Manifest.lock */, + 34F045BF07D680BC05E54D4F /* [CP] Check Pods Manifest.lock */, 46BA8E23261D6AE30028D000 /* Headers */, 4662531F26299B8200CE1234 /* ShellScript */, 46BA8E24261D6AE30028D000 /* Sources */, @@ -943,11 +940,11 @@ isa = PBXNativeTarget; buildConfigurationList = 46BA8E3F261D6AE30028D000 /* Build configuration list for PBXNativeTarget "PushEngageTests" */; buildPhases = ( - 1E7DC21DEAA1FA0BC5D0E73A /* [CP] Check Pods Manifest.lock */, + 81489670CBFDA1EBF6F854AA /* [CP] Check Pods Manifest.lock */, 46BA8E2D261D6AE30028D000 /* Sources */, 46BA8E2E261D6AE30028D000 /* Frameworks */, 46BA8E2F261D6AE30028D000 /* Resources */, - 6097CD4A591DE79B2D3C5540 /* [CP] Embed Pods Frameworks */, + EC78D508B420F1E5E84AD8EA /* [CP] Embed Pods Frameworks */, ); buildRules = ( ); @@ -964,7 +961,7 @@ isa = PBXNativeTarget; buildConfigurationList = 46F0B2BA26D756D100A1BEE9 /* Build configuration list for PBXNativeTarget "NotificationContentExtensionObjcSample" */; buildPhases = ( - 92368AB6E3FDB25F42D53F9C /* [CP] Check Pods Manifest.lock */, + 5FC887F917F6F0805F1D825A /* [CP] Check Pods Manifest.lock */, 46F0B2A626D756D100A1BEE9 /* Sources */, 46F0B2A726D756D100A1BEE9 /* Frameworks */, 46F0B2A826D756D100A1BEE9 /* Resources */, @@ -982,7 +979,7 @@ isa = PBXNativeTarget; buildConfigurationList = 46FC139526794BCC0015D679 /* Build configuration list for PBXNativeTarget "PushEngageObjcNotificationExtension" */; buildPhases = ( - 8D7EC2914D16EA6098E372D0 /* [CP] Check Pods Manifest.lock */, + AD597B49F1BA5D9AAB9B57E9 /* [CP] Check Pods Manifest.lock */, 46FC138526794BCC0015D679 /* Sources */, 46FC138626794BCC0015D679 /* Frameworks */, 46FC138726794BCC0015D679 /* Resources */, @@ -1132,7 +1129,7 @@ /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ - 1E7DC21DEAA1FA0BC5D0E73A /* [CP] Check Pods Manifest.lock */ = { + 34F045BF07D680BC05E54D4F /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( @@ -1147,14 +1144,14 @@ outputFileListPaths = ( ); outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-PushEngage-PushEngageTests-checkManifestLockResult.txt", + "$(DERIVED_FILE_DIR)/Pods-PushEngage-checkManifestLockResult.txt", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; - 3783948EE9806BC376886B19 /* [CP] Check Pods Manifest.lock */ = { + 4662531F26299B8200CE1234 /* ShellScript */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( @@ -1162,21 +1159,16 @@ inputFileListPaths = ( ); inputPaths = ( - "${PODS_PODFILE_DIR_PATH}/Podfile.lock", - "${PODS_ROOT}/Manifest.lock", ); - name = "[CP] Check Pods Manifest.lock"; outputFileListPaths = ( ); outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-PushNotificationDemo-checkManifestLockResult.txt", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; - showEnvVarsInLog = 0; + shellScript = "# Type a script or drag a script file from your workspace to insert its path.\n\"${PODS_ROOT}/SwiftLint/swiftlint\"\n"; }; - 3A54A6A04C06B7758DF75BFD /* [CP] Check Pods Manifest.lock */ = { + 4FA7E16117FE79BD486B7AF1 /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( @@ -1191,14 +1183,14 @@ outputFileListPaths = ( ); outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-PushNotificationDemo-PushEngageNotificationContentExtenstion-checkManifestLockResult.txt", + "$(DERIVED_FILE_DIR)/Pods-PushNotificationDemo-checkManifestLockResult.txt", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; - 4662531F26299B8200CE1234 /* ShellScript */ = { + 5FC887F917F6F0805F1D825A /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( @@ -1206,33 +1198,43 @@ inputFileListPaths = ( ); inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", ); + name = "[CP] Check Pods Manifest.lock"; outputFileListPaths = ( ); outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-PushNotificationObjcSample-NotificationContentExtensionObjcSample-checkManifestLockResult.txt", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "# Type a script or drag a script file from your workspace to insert its path.\n\"${PODS_ROOT}/SwiftLint/swiftlint\"\n"; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; }; - 6097CD4A591DE79B2D3C5540 /* [CP] Embed Pods Frameworks */ = { + 81489670CBFDA1EBF6F854AA /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-PushEngage-PushEngageTests/Pods-PushEngage-PushEngageTests-frameworks-${CONFIGURATION}-input-files.xcfilelist", ); - name = "[CP] Embed Pods Frameworks"; + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; outputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-PushEngage-PushEngageTests/Pods-PushEngage-PushEngageTests-frameworks-${CONFIGURATION}-output-files.xcfilelist", + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-PushEngage-PushEngageTests-checkManifestLockResult.txt", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-PushEngage-PushEngageTests/Pods-PushEngage-PushEngageTests-frameworks.sh\"\n"; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; - 8097C16450F6225B99C2594E /* [CP] Check Pods Manifest.lock */ = { + AD597B49F1BA5D9AAB9B57E9 /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( @@ -1247,14 +1249,14 @@ outputFileListPaths = ( ); outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-PushNotificationObjcSample-checkManifestLockResult.txt", + "$(DERIVED_FILE_DIR)/Pods-PushNotificationObjcSample-PushEngageObjcNotificationExtension-checkManifestLockResult.txt", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; - 8D7EC2914D16EA6098E372D0 /* [CP] Check Pods Manifest.lock */ = { + DA90C05439326411DE0786F7 /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( @@ -1269,14 +1271,14 @@ outputFileListPaths = ( ); outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-PushNotificationObjcSample-PushEngageObjcNotificationExtension-checkManifestLockResult.txt", + "$(DERIVED_FILE_DIR)/Pods-PushNotificationDemo-PushEngageNotificationContentExtenstion-checkManifestLockResult.txt", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; - 92368AB6E3FDB25F42D53F9C /* [CP] Check Pods Manifest.lock */ = { + E88E4C0550374F2E304147AF /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( @@ -1291,36 +1293,31 @@ outputFileListPaths = ( ); outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-PushNotificationObjcSample-NotificationContentExtensionObjcSample-checkManifestLockResult.txt", + "$(DERIVED_FILE_DIR)/Pods-PushNotificationObjcSample-checkManifestLockResult.txt", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; - 9E5FC606C9470AC39C8A758E /* [CP] Check Pods Manifest.lock */ = { + EC78D508B420F1E5E84AD8EA /* [CP] Embed Pods Frameworks */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-PushEngage-PushEngageTests/Pods-PushEngage-PushEngageTests-frameworks-${CONFIGURATION}-input-files.xcfilelist", ); - inputPaths = ( - "${PODS_PODFILE_DIR_PATH}/Podfile.lock", - "${PODS_ROOT}/Manifest.lock", - ); - name = "[CP] Check Pods Manifest.lock"; + name = "[CP] Embed Pods Frameworks"; outputFileListPaths = ( - ); - outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-PushEngage-checkManifestLockResult.txt", + "${PODS_ROOT}/Target Support Files/Pods-PushEngage-PushEngageTests/Pods-PushEngage-PushEngageTests-frameworks-${CONFIGURATION}-output-files.xcfilelist", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-PushEngage-PushEngageTests/Pods-PushEngage-PushEngageTests-frameworks.sh\"\n"; showEnvVarsInLog = 0; }; - B668E7512E3F02C22FFD4893 /* [CP] Check Pods Manifest.lock */ = { + EDB8F679FD4A1138A8C9864B /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( @@ -1353,6 +1350,7 @@ 46358DA2262F053D00D40FBE /* PushServiceTestSample.swift in Sources */, 46358DA3262F053D00D40FBE /* NotificationApiTestViewconttoller.swift in Sources */, 46358D37262EF6F000D40FBE /* SceneDelegate.swift in Sources */, + 1D4944D32ACE925700370E47 /* TextInputViewController.swift in Sources */, 46358D9B262F052B00D40FBE /* SportViewController.swift in Sources */, 46FCDAE126A1C9ED0068C45D /* PEPay.swift in Sources */, ); @@ -1370,9 +1368,9 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 46E3073C26768FF800C5D8B7 /* File.swift in Sources */, 465367AA2677FF0400DFEBF6 /* SportsViewcontroller.m in Sources */, 465E0E2B26768F310097F04F /* ViewController.m in Sources */, + 1DAC1FCB2B05DE2200538064 /* File.swift in Sources */, 465E0E2526768F310097F04F /* AppDelegate.m in Sources */, 465E0E3626768F320097F04F /* main.m in Sources */, 465367A72677B08300DFEBF6 /* AddToCart.m in Sources */, @@ -1393,7 +1391,6 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 46BA8ECB261D6B520028D000 /* LocationInfoProtocol.swift in Sources */, 463D94CE2642AC790023FE7E /* PushEngageAppdelegate.swift in Sources */, 4675207E26447226001576C3 /* PESelectorHelper.swift in Sources */, 46BA8E76261D6B380028D000 /* PushEngage.swift in Sources */, @@ -1401,7 +1398,6 @@ 46BA8E7B261D6B380028D000 /* PEPayLoad.swift in Sources */, 46BA8EC8261D6B520028D000 /* DatasourceProtocol.swift in Sources */, 463DB643267A2639003FDDC8 /* SyncAPIResponse.swift in Sources */, - 46BA8E79261D6B380028D000 /* PEViewModel.swift in Sources */, 46BA8EC4261D6B520028D000 /* PEOperations.swift in Sources */, 46BA8EC2261D6B520028D000 /* ChainedAsyncResultOperation.swift in Sources */, 46BA8EBC261D6B520028D000 /* NotificationExtensionManager.swift in Sources */, @@ -1409,10 +1405,9 @@ 46BA8EB9261D6B520028D000 /* NotificationLifeCycleManager.swift in Sources */, 46BA8E7E261D6B380028D000 /* Postback.swift in Sources */, 46BA8E53261D6B160028D000 /* EnumTypes.swift in Sources */, - 46BA8EC7261D6B520028D000 /* NotificationProtocol.swift in Sources */, + 46BA8EC7261D6B520028D000 /* NotificationServiceType.swift in Sources */, 46BA8E7F261D6B380028D000 /* PEError.swift in Sources */, 46BA8EC0261D6B520028D000 /* SubscriberServiceManager.swift in Sources */, - 46BA8EBF261D6B520028D000 /* LocationManager.swift in Sources */, 46BA8EB3261D6B520028D000 /* PELogger.swift in Sources */, 46BA8E81261D6B380028D000 /* URLParameterEncoder.swift in Sources */, 463DB641267A04E4003FDDC8 /* Configuration.swift in Sources */, @@ -1424,32 +1419,33 @@ 46BA8EB6261D6B520028D000 /* DataManager.swift in Sources */, 46293E5C265B8AF9001353EB /* NotificationSettingsManageriOS9.swift in Sources */, 46BA8EB7261D6B520028D000 /* UserDefaultManager.swift in Sources */, - 46BA8ECC261D6B520028D000 /* NotificationExtensionProtocol.swift in Sources */, + 46BA8ECC261D6B520028D000 /* NotificationExtensionType.swift in Sources */, 464E163326AF1DBB006BE648 /* EntitlementReader.swift in Sources */, 46BA8E50261D6B160028D000 /* DependencyProtocol.swift in Sources */, 465C44EB26401C3900462632 /* BackgroundTaskHandler.swift in Sources */, - 46BA8ECF261D6B520028D000 /* UserDefaultProtocol.swift in Sources */, + 46BA8ECF261D6B520028D000 /* UserDefaultsType.swift in Sources */, 46BA8E85261D6B380028D000 /* HTTPMethod.swift in Sources */, 4623217C26583862005634FB /* PushEngageUNUserNotificationCenter.swift in Sources */, 46BA8EBA261D6B520028D000 /* NotificationSettingsManageriOS10.swift in Sources */, 46BA8F0B261DF7EB0028D000 /* TriggerCampaignManager.swift in Sources */, + 1D01CFD62ACAD4CA008C5892 /* PEManager.swift in Sources */, 46BA8E4F261D6B160028D000 /* DependencyContainer.swift in Sources */, 4627676D2660242A00DF854B /* PENotification.swift in Sources */, 46BA8E86261D6B380028D000 /* Router.swift in Sources */, 46BA8E80261D6B380028D000 /* PERouter.swift in Sources */, - 46BA8ECD261D6B520028D000 /* SubscriberService.swift in Sources */, + 46BA8ECD261D6B520028D000 /* SubscriberServiceType.swift in Sources */, 46BA8EC3261D6B520028D000 /* AsyncOperation.swift in Sources */, 46BA8EB2261D6B520028D000 /* Utility.swift in Sources */, - 46BA8ECA261D6B520028D000 /* NotificationLifeCycleService.swift in Sources */, + 46BA8ECA261D6B520028D000 /* NotificationLifeCycleServiceType.swift in Sources */, 46BA8E7A261D6B380028D000 /* NetworkResponse.swift in Sources */, 46BA8EB1261D6B520028D000 /* WKWebViewController.swift in Sources */, 46BA8E51261D6B160028D000 /* DependencyInitialize.swift in Sources */, 46BA8EBD261D6B520028D000 /* ApplicationService.swift in Sources */, 46BA8E4E261D6B160028D000 /* Extension.swift in Sources */, - 46BA8ECE261D6B520028D000 /* ApplicationProtocol.swift in Sources */, - 46BA8F0F261E09DF0028D000 /* TriggerCampaignProtocol.swift in Sources */, + 46BA8ECE261D6B520028D000 /* ApplicationServiceType.swift in Sources */, + 46BA8F0F261E09DF0028D000 /* TriggerCampaignType.swift in Sources */, 46BA8E82261D6B380028D000 /* JSONParameterEncoder.swift in Sources */, - 46BA8E84261D6B380028D000 /* NetworkRouter.swift in Sources */, + 46BA8E84261D6B380028D000 /* NetworkRouterType.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1560,16 +1556,17 @@ /* Begin XCBuildConfiguration section */ 46358D43262EF6F100D40FBE /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = CC5926D08F1A5A84B6CE6EA8 /* Pods-PushNotificationDemo.debug.xcconfig */; + baseConfigurationReference = F0493026DC42BFAE849A81A7 /* Pods-PushNotificationDemo.debug.xcconfig */; buildSettings = { ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = "$(inherited)"; APPLICATION_EXTENSION_API_ONLY = YES; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = YES; CODE_SIGN_ENTITLEMENTS = PushNotificationDemo/PushNotificationDemo.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 5; + CURRENT_PROJECT_VERSION = 4; DEVELOPMENT_TEAM = 38PU74KZ48; INFOPLIST_FILE = PushNotificationDemo/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 9.0; @@ -1577,10 +1574,12 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 0.0.4; + MARKETING_VERSION = 0.0.2; PRODUCT_BUNDLE_IDENTIFIER = com.pushengage.PushNotificationDemo; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; + SUPPORTS_MACCATALYST = NO; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; }; @@ -1588,16 +1587,17 @@ }; 46358D44262EF6F100D40FBE /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 34FE1855D2A72DD3855A5B85 /* Pods-PushNotificationDemo.release.xcconfig */; + baseConfigurationReference = 4C52C00297192C65144FC544 /* Pods-PushNotificationDemo.release.xcconfig */; buildSettings = { ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = "$(inherited)"; APPLICATION_EXTENSION_API_ONLY = YES; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = YES; CODE_SIGN_ENTITLEMENTS = PushNotificationDemo/PushNotificationDemo.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 5; + CURRENT_PROJECT_VERSION = 4; DEVELOPMENT_TEAM = 38PU74KZ48; INFOPLIST_FILE = PushNotificationDemo/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 9.0; @@ -1605,10 +1605,12 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 0.0.4; + MARKETING_VERSION = 0.0.2; PRODUCT_BUNDLE_IDENTIFIER = com.pushengage.PushNotificationDemo; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; + SUPPORTS_MACCATALYST = NO; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; }; @@ -1616,7 +1618,7 @@ }; 46358D56262EF76F00D40FBE /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 2C668A9E47CB4555C382F33C /* Pods-PushNotificationDemo-PushEngageNotificationExtension.debug.xcconfig */; + baseConfigurationReference = E6F6FCFDAD9A3EC95E168C75 /* Pods-PushNotificationDemo-PushEngageNotificationExtension.debug.xcconfig */; buildSettings = { APPLICATION_EXTENSION_API_ONLY = YES; CODE_SIGN_ENTITLEMENTS = PushEngageNotificationExtension/PushEngageNotificationExtension.entitlements; @@ -1624,7 +1626,7 @@ CURRENT_PROJECT_VERSION = 5; DEVELOPMENT_TEAM = 38PU74KZ48; INFOPLIST_FILE = PushEngageNotificationExtension/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 9.0; + IPHONEOS_DEPLOYMENT_TARGET = 10.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -1641,7 +1643,7 @@ }; 46358D57262EF76F00D40FBE /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = F2C64E569C23FDEB4CD8EF0F /* Pods-PushNotificationDemo-PushEngageNotificationExtension.release.xcconfig */; + baseConfigurationReference = 083F2A7D996439CA7B455F56 /* Pods-PushNotificationDemo-PushEngageNotificationExtension.release.xcconfig */; buildSettings = { APPLICATION_EXTENSION_API_ONLY = YES; CODE_SIGN_ENTITLEMENTS = PushEngageNotificationExtension/PushEngageNotificationExtension.entitlements; @@ -1650,7 +1652,7 @@ CURRENT_PROJECT_VERSION = 5; DEVELOPMENT_TEAM = 38PU74KZ48; INFOPLIST_FILE = PushEngageNotificationExtension/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 9.0; + IPHONEOS_DEPLOYMENT_TARGET = 10.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -1668,17 +1670,18 @@ }; 465E0E3726768F320097F04F /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = A7F452EE0484497C407415F4 /* Pods-PushNotificationObjcSample.debug.xcconfig */; + baseConfigurationReference = D93783276389C2BFBFCB4EEC /* Pods-PushNotificationObjcSample.debug.xcconfig */; buildSettings = { ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = "$(inherited)"; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = YES; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = PushNotificationObjcSample/PushNotificationObjcSample.entitlements; CODE_SIGN_STYLE = Automatic; DEVELOPMENT_TEAM = 38PU74KZ48; INFOPLIST_FILE = PushNotificationObjcSample/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 14.5; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -1694,17 +1697,18 @@ }; 465E0E3826768F320097F04F /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = D7334B14E67A8941C42A138A /* Pods-PushNotificationObjcSample.release.xcconfig */; + baseConfigurationReference = E833FE914BCE1F47F42ACE2F /* Pods-PushNotificationObjcSample.release.xcconfig */; buildSettings = { ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = "$(inherited)"; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = YES; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = PushNotificationObjcSample/PushNotificationObjcSample.entitlements; CODE_SIGN_STYLE = Automatic; DEVELOPMENT_TEAM = 38PU74KZ48; INFOPLIST_FILE = PushNotificationObjcSample/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 14.5; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -1719,7 +1723,7 @@ }; 467D68FE2636A5A00081CC36 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = A879F4B44990EC79AC3AABCD /* Pods-PushNotificationDemo-PushEngageNotificationContentExtenstion.debug.xcconfig */; + baseConfigurationReference = 765536D1BBD42367EDCCE01D /* Pods-PushNotificationDemo-PushEngageNotificationContentExtenstion.debug.xcconfig */; buildSettings = { CODE_SIGN_ENTITLEMENTS = PushEngageNotificationContentExtenstion/PushEngageNotificationContentExtenstion.entitlements; CODE_SIGN_STYLE = Automatic; @@ -1743,7 +1747,7 @@ }; 467D68FF2636A5A00081CC36 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 4167CEFEAEA512D9EE7C6178 /* Pods-PushNotificationDemo-PushEngageNotificationContentExtenstion.release.xcconfig */; + baseConfigurationReference = F780225089630E597F328676 /* Pods-PushNotificationDemo-PushEngageNotificationContentExtenstion.release.xcconfig */; buildSettings = { CODE_SIGN_ENTITLEMENTS = PushEngageNotificationContentExtenstion/PushEngageNotificationContentExtenstion.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; @@ -1819,7 +1823,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 14.4; + IPHONEOS_DEPLOYMENT_TARGET = 17.0; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; ONLY_ACTIVE_ARCH = YES; @@ -1877,7 +1881,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 14.4; + IPHONEOS_DEPLOYMENT_TARGET = 17.0; MTL_ENABLE_DEBUG_INFO = NO; MTL_FAST_MATH = YES; SDKROOT = iphoneos; @@ -1891,7 +1895,7 @@ }; 46BA8E3D261D6AE30028D000 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 6D5AD816108C6CCE589EBD24 /* Pods-PushEngage.debug.xcconfig */; + baseConfigurationReference = E25265661730DA0E6687F6ED /* Pods-PushEngage.debug.xcconfig */; buildSettings = { APPLICATION_EXTENSION_API_ONLY = NO; "CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development"; @@ -1920,7 +1924,7 @@ }; 46BA8E3E261D6AE30028D000 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 168EF663653182D68B78AC9D /* Pods-PushEngage.release.xcconfig */; + baseConfigurationReference = 04CEFCCEAF5A5FFBBB3A89E5 /* Pods-PushEngage.release.xcconfig */; buildSettings = { APPLICATION_EXTENSION_API_ONLY = NO; CODE_SIGN_IDENTITY = "Apple Development"; @@ -1952,7 +1956,7 @@ }; 46BA8E40261D6AE30028D000 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 8E2F4A6DFD49B034E809D0F4 /* Pods-PushEngage-PushEngageTests.debug.xcconfig */; + baseConfigurationReference = 86BC3A417D3BF43CAECDCF48 /* Pods-PushEngage-PushEngageTests.debug.xcconfig */; buildSettings = { ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = "$(inherited)"; BUNDLE_LOADER = "$(TEST_HOST)"; @@ -1974,7 +1978,7 @@ }; 46BA8E41261D6AE30028D000 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = ABD54A8D77DAE36BCCCD2B07 /* Pods-PushEngage-PushEngageTests.release.xcconfig */; + baseConfigurationReference = CD1CCFC59CC88B1D03D374AC /* Pods-PushEngage-PushEngageTests.release.xcconfig */; buildSettings = { ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = "$(inherited)"; BUNDLE_LOADER = "$(TEST_HOST)"; @@ -1996,13 +2000,13 @@ }; 46F0B2B826D756D100A1BEE9 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 490E3179B48DB51C0AF8B10B /* Pods-PushNotificationObjcSample-NotificationContentExtensionObjcSample.debug.xcconfig */; + baseConfigurationReference = 2676215DBBA448F9F89F3AAC /* Pods-PushNotificationObjcSample-NotificationContentExtensionObjcSample.debug.xcconfig */; buildSettings = { CLANG_ENABLE_MODULES = YES; CODE_SIGN_STYLE = Automatic; DEVELOPMENT_TEAM = 38PU74KZ48; INFOPLIST_FILE = NotificationContentExtensionObjcSample/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 14.5; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -2020,13 +2024,13 @@ }; 46F0B2B926D756D100A1BEE9 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 7CC94958AB96C609578D7D58 /* Pods-PushNotificationObjcSample-NotificationContentExtensionObjcSample.release.xcconfig */; + baseConfigurationReference = 1A513C68E66FFE9526A7D23A /* Pods-PushNotificationObjcSample-NotificationContentExtensionObjcSample.release.xcconfig */; buildSettings = { CLANG_ENABLE_MODULES = YES; CODE_SIGN_STYLE = Automatic; DEVELOPMENT_TEAM = 38PU74KZ48; INFOPLIST_FILE = NotificationContentExtensionObjcSample/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 14.5; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -2043,14 +2047,14 @@ }; 46FC139326794BCC0015D679 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 63265847E94DDB9BB9B706B0 /* Pods-PushNotificationObjcSample-PushEngageObjcNotificationExtension.debug.xcconfig */; + baseConfigurationReference = DD60E59423AF3716B9BB1A28 /* Pods-PushNotificationObjcSample-PushEngageObjcNotificationExtension.debug.xcconfig */; buildSettings = { CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = PushEngageObjcNotificationExtension/PushEngageObjcNotificationExtension.entitlements; CODE_SIGN_STYLE = Automatic; DEVELOPMENT_TEAM = 38PU74KZ48; INFOPLIST_FILE = PushEngageObjcNotificationExtension/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 14.5; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -2068,14 +2072,14 @@ }; 46FC139426794BCC0015D679 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 232EA0EAE97C1E5D7FD00C27 /* Pods-PushNotificationObjcSample-PushEngageObjcNotificationExtension.release.xcconfig */; + baseConfigurationReference = 17D15684AC37C760CEF34059 /* Pods-PushNotificationObjcSample-PushEngageObjcNotificationExtension.release.xcconfig */; buildSettings = { CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = PushEngageObjcNotificationExtension/PushEngageObjcNotificationExtension.entitlements; CODE_SIGN_STYLE = Automatic; DEVELOPMENT_TEAM = 38PU74KZ48; INFOPLIST_FILE = PushEngageObjcNotificationExtension/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 14.5; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", diff --git a/PushEngage/Constants/Constants.swift b/PushEngage/Constants/Constants.swift index 3b32b51..93f63a6 100644 --- a/PushEngage/Constants/Constants.swift +++ b/PushEngage/Constants/Constants.swift @@ -46,7 +46,7 @@ internal struct NetworkConstants { // MARK: - SDK version - static let sdkVersion = "0.0.1" + static let sdkVersion = "0.0.2" // MARK: - URL relative - path static let addSubscriberPath = "subscriber/add" @@ -56,7 +56,7 @@ internal struct NetworkConstants { static let getSubscriberAttribute = "subscriber/%@/attributes" static let updateSubscriberStatus = "subscriber/updatesubscriberstatus" static let addProfileId = "subscriber/profile-id/add" - static let upgarde = "subscriber/upgrade" + static let subscriberUpgrade = "subscriber/upgrade" static let timeZone = "subscriber/timezone/add" static let addSegment = "subscriber/segments/add" static let removeSegment = "subscriber/segments/remove" @@ -81,7 +81,6 @@ internal struct NetworkConstants { } struct PayloadConstants { - static let attachmentKey = "att" static let launchUrlKey = "u" static let custom = "pe" @@ -102,7 +101,7 @@ struct PayloadConstants { static let customBody = "b" } -struct InfoPlistConstants { +struct InfoPlistConstants { static let PushEngageInAppEnabled = "PushEngageInAppEnabled" static let locationWhenInUse = "NSLocationAlwaysAndWhenInUseUsageDescription" static let loactionAllow = "NSLocationWhenInUseUsageDescription" @@ -110,29 +109,28 @@ struct InfoPlistConstants { } struct UserDefaultConstant { - - static let deviceToken = "deviceToken" - static let subscriberHash = "subscriberHash" - static let permissionState = "notitficationPermission" - static let appId = "AppId" + static let environment = "environment" + static let deviceToken = "device_token" + static let subscriberHash = "subscriber_hash" + static let permissionState = "notification_permission" + static let appId = "app_id" static let country = "country" static let state = "state" static let city = "city" - static let notificationId = "notificationId" - static let badgeCount = "badgeCount" - static let lastSmartSubscribeDate = "lastSmartSubscribeDate" - static let appIsStarting = "appIsStarting" - static let pushEngageSyncApi = "pushengageSyncApi" - static let ispermissionAlertedKey = "ispermissionAlerted" + static let notificationId = "notification_id" + static let badgeCount = "badge_count" + static let lastSmartSubscribeDate = "last_smart_subscribe_date" + static let appIsStarting = "app_is_starting" + static let pushEngageSyncApi = "pushengage_sync_api" + static let ispermissionAlertedKey = "is_permission_alerted" static let profileId = "pe_host_profile_id" static let siteStatus = "pe_host_site_status" static let siteKey = "pe_site_key" static let locationCoordinates = "location_coordinates" static let isSubscriberDeleted = "is_subscriber_deleted" - static let istriedFirstTime = "istriedFirstTime" - static let sponsered = "pesponser" - static let isSwizziled = "is_swizziled" - + static let isTriedFirstTime = "is_tried_first_time" + static let sponsered = "pe_sponser" + static let isSwizzled = "is_swizzled" } // MARK: - Query parms key @@ -151,8 +149,7 @@ struct ParsingConstants { // MARK: - PEErrorMessages - extension String { - +extension String { static let contentNotFound = "Content not found" static let network = "Network faliure" static let downloadAttachmentfailed = "Failed to download attachment" @@ -163,23 +160,23 @@ struct ParsingConstants { static let invalidStatusCode = "Invalid status code:- %@" static let dataEncodeingFailed = "Failed data encoding" static let networkNotReachable = "Network reachablity Error" - static let canceled = "Canceled the operation in operationQueue" + static let canceled = "Cancelled the operation in operationQueue" static let missingInputURL = "Input URL is missing" - static let missingRedirectURL = "Redirecting url is missing" + static let missingRedirectURL = "Redirecting URL is missing" static let sponseredfailWithContent = "Failed with previous mutable content" static let incorrectParameter = "Parameter for type method(:) call is invalid please verify the input parameter" static let tiggerfailure = "Trigger failure" - static let mediaLengthExceeded = "media length is greater than 5 mb" + static let mediaLengthExceeded = "Media length is greater than 5 mb" static let urlRequestException = "URL request Exeception." - static let dataNotFound = "Data not found after api call." - static let networkResponseFaliure = "status code:- %@ \n reason:- %@." + static let dataNotFound = "Data not found after API call." + static let networkResponseFaliure = "Status code:- %@ \n reason:- %@." static let dataTypeCastingError = "Data type casting error." static let requestTimeOut = "Network request time is out please check the internet connection." - static let failedToLogError = "failed to log error to server." - static let siteStatusNotActive = "site status is not Active" + static let failedToLogError = "Failed to log error to server." + static let siteStatusNotActive = "Site status is not Active" static let subscriberNotAvailable = "Subscriber is not active." static let profileAlreadyExist = "User profile already exist. In server" - static let siteKeyNotAvailable = "site key is not available." + static let siteKeyNotAvailable = "Site key is not available." static let permissionNotDetermine = "Notification Permission is not Determined." static let notificationUserActionFailed = "Notification user action failed which is not retry able message: - %@." static let defaultActionIdentifer = "com.apple.UNNotificationDefaultActionIdentifier" @@ -190,7 +187,7 @@ struct ParsingConstants { // MARK: - Registration Messages. -struct RegisterationMessages { +struct RegistrationMessages { static let appIDNotFound = "Please provide proper App ID." static let notificationDisable = "To access the notification api please allow the notifications from." static let registerationFailed = "Please check App ID or re-visit setup instructions." diff --git a/PushEngage/DependencyInjectionSetup/DependencyInitialize.swift b/PushEngage/DependencyInjectionSetup/DependencyInitialize.swift index 7dcec7a..2491925 100644 --- a/PushEngage/DependencyInjectionSetup/DependencyInitialize.swift +++ b/PushEngage/DependencyInjectionSetup/DependencyInitialize.swift @@ -28,35 +28,27 @@ internal final class DependencyInitialize { container = Container() - // MARK: - LocationProtocol - // this locationInfoProtocol is beign registered with its manager - // which is location manager. As you can see there is no dependency to initialize the - // location manager. So no need to resolve the dependencies - .register(LocationInfoProtocol.self) { _ in - LocationManager() - } - // MARK: - UserDefaultProtocol - .register(UserDefaultProtocol.self) {_ in + .register(UserDefaultsType.self) {_ in UserDefaultManager() } // MARK: - NetworkRouter - .register(NetworkRouter.self) { _ in + .register(NetworkRouterType.self) { _ in Router() } // MARK: - DataSourceProtocol - .register(DataSourceProtocol.self) { resolver in - let userDefault = resolver.resolve(UserDefaultProtocol.self) + .register(DataSourceType.self) { resolver in + let userDefault = resolver.resolve(UserDefaultsType.self) return DataManager(userDefault: userDefault) } // MARK: - NotificationProtocol - .register(NotificationProtocol.self) { resolved in - let userDefaultServices = resolved.resolve(UserDefaultProtocol.self) + .register(NotificationServiceType.self) { resolved in + let userDefaultServices = resolved.resolve(UserDefaultsType.self) if #available(iOS 10.0, *) { return NotificationSettingsManageriOS10(userDefaultService: userDefaultServices) } else { @@ -74,20 +66,20 @@ internal final class DependencyInitialize { // So we are resolving it and you and notice this that DataSourceProtocol and other dependencies // are already registered with the container. - .register(SubscriberService.self) { resolver in - let datasource = resolver.resolve(DataSourceProtocol.self) - let networkRouter = resolver.resolve(NetworkRouter.self) - let userDefault = resolver.resolve(UserDefaultProtocol.self) + .register(SubscriberServiceType.self) { resolver in + let datasource = resolver.resolve(DataSourceType.self) + let networkRouter = resolver.resolve(NetworkRouterType.self) + let userDefault = resolver.resolve(UserDefaultsType.self) return SubscriberServiceManager(datasourceProtocol: datasource, networkRouter: networkRouter, userDefault: userDefault) } // MARK: - NotificationLifeCycleService - .register(NotificationLifeCycleService.self) { resolver in - let networkRouter = resolver.resolve(NetworkRouter.self) - let datasource = resolver.resolve(DataSourceProtocol.self) - let userdefault = resolver.resolve(UserDefaultProtocol.self) + .register(NotificationLifeCycleServiceType.self) { resolver in + let networkRouter = resolver.resolve(NetworkRouterType.self) + let datasource = resolver.resolve(DataSourceType.self) + let userdefault = resolver.resolve(UserDefaultsType.self) return NotificationLifeCycleManager(networkRouter: networkRouter, datasource: datasource, userDefault: userdefault) @@ -95,11 +87,11 @@ internal final class DependencyInitialize { // MARK: - ApplicationProtocol - .register(ApplicationProtocol.self) { resolve in - let userDefault = resolve.resolve(UserDefaultProtocol.self) - let subscriberService = resolve.resolve(SubscriberService.self) - let notificationLifeCycleService = resolve.resolve(NotificationLifeCycleService.self) - let networkService = resolve.resolve(NetworkRouter.self) + .register(ApplicationServiceType.self) { resolve in + let userDefault = resolve.resolve(UserDefaultsType.self) + let subscriberService = resolve.resolve(SubscriberServiceType.self) + let notificationLifeCycleService = resolve.resolve(NotificationLifeCycleServiceType.self) + let networkService = resolve.resolve(NetworkRouterType.self) return ApplicationService(userDefault: userDefault, subscriberService: subscriberService, notificationLifeCycleService: notificationLifeCycleService, @@ -108,10 +100,10 @@ internal final class DependencyInitialize { // MARK: - NotificationExtensionProtocol - .register(NotificationExtensionProtocol.self) { resolver in - let networkRouter = resolver.resolve(NetworkRouter.self) - let userDefaultService = resolver.resolve(UserDefaultProtocol.self) - let notificationCycleService = resolver.resolve(NotificationLifeCycleService.self) + .register(NotificationExtensionType.self) { resolver in + let networkRouter = resolver.resolve(NetworkRouterType.self) + let userDefaultService = resolver.resolve(UserDefaultsType.self) + let notificationCycleService = resolver.resolve(NotificationLifeCycleServiceType.self) return NotificationExtensionManager(networkService: networkRouter, notifcationLifeCycleService: notificationCycleService, userDefaultDatasource: userDefaultService) @@ -119,44 +111,43 @@ internal final class DependencyInitialize { // MARK: - TriggerCampaignProtocol - .register(TriggerCampaignProtocol.self) { resolver in - let networkRouter = resolver.resolve(NetworkRouter.self) - let userDefaultService = resolver.resolve(UserDefaultProtocol.self) + .register(TriggerCampaignType.self) { resolver in + let networkRouter = resolver.resolve(NetworkRouterType.self) + let userDefaultService = resolver.resolve(UserDefaultsType.self) return TriggerCampaignManager(userDefaultService: userDefaultService, networkService: networkRouter) } // MARK: - PEViewModel - .register(PEViewModel.self) { resolver in - let applicationService = resolver.resolve(ApplicationProtocol.self) - let notificationService = resolver.resolve(NotificationProtocol.self) - let notificationExtensionService = resolver.resolve(NotificationExtensionProtocol.self) - let subsciberService = resolver.resolve(SubscriberService.self) - let userDefaultService = resolver.resolve(UserDefaultProtocol.self) - let notificationLifeCycleService = resolver.resolve(NotificationLifeCycleService.self) - let locationService = resolver.resolve(LocationInfoProtocol.self) - let triggerCampaiginService = resolver.resolve(TriggerCampaignProtocol.self) - return PEViewModel(applicationService: applicationService, + .register(PEManagerType.self) { resolver in + let applicationService = resolver.resolve(ApplicationServiceType.self) + let notificationService = resolver.resolve(NotificationServiceType.self) + let notificationExtensionService = resolver.resolve(NotificationExtensionType.self) + let subscriberService = resolver.resolve(SubscriberServiceType.self) + let userDefaultService = resolver.resolve(UserDefaultsType.self) + let notificationLifeCycleService = resolver.resolve(NotificationLifeCycleServiceType.self) + let triggerCampaiginService = resolver.resolve(TriggerCampaignType.self) + + return PEManager(applicationService: applicationService, notificationService: notificationService, notificationExtensionService: notificationExtensionService, - subscriberService: subsciberService, + subscriberService: subscriberService, userDefaultService: userDefaultService, notificationLifeCycleService: notificationLifeCycleService, - locationService: locationService, triggerCamapaiginService: triggerCampaiginService) } } - class func getPEViewModelDependency() -> PEViewModel { - return sharedInstance.container.resolve(PEViewModel.self) + class func getPEManagerDependency() -> PEManagerType { + return sharedInstance.container.resolve(PEManagerType.self) } - class func getUserDefaults() -> UserDefaultProtocol { - return sharedInstance.container.resolve(UserDefaultProtocol.self) + class func getUserDefaults() -> UserDefaultsType { + return sharedInstance.container.resolve(UserDefaultsType.self) } - class func getRouter() -> NetworkRouter { - return sharedInstance.container.resolve(NetworkRouter.self) + class func getRouter() -> NetworkRouterType { + return sharedInstance.container.resolve(NetworkRouterType.self) } } diff --git a/PushEngage/Extensions/Extension.swift b/PushEngage/Extensions/Extension.swift index aaf7336..05ada3d 100644 --- a/PushEngage/Extensions/Extension.swift +++ b/PushEngage/Extensions/Extension.swift @@ -94,9 +94,8 @@ extension Dictionary { extension UserDefaults { - static var shared: UserDefaults { - let combined = UserDefaults.standard - combined.addSuite(named: Utility.getAppGroupInfo) + static var shared: UserDefaults? { + let combined = UserDefaults(suiteName: Utility.getAppGroupInfo) return combined } @@ -131,6 +130,10 @@ extension UserDefaults.Key { return .init(name: UserDefaultConstant.deviceToken) } + static var sdkEnvironment: UserDefaults.Key { + return .init(name: UserDefaultConstant.environment) + } + static var badgeCount: UserDefaults.Key { return .init(name: UserDefaultConstant.badgeCount) } @@ -168,7 +171,7 @@ extension UserDefaults.Key { } static var istriedFirstTime: UserDefaults.Key { - return .init(name: UserDefaultConstant.istriedFirstTime) + return .init(name: UserDefaultConstant.isTriedFirstTime) } static var isSponseredIdKey: UserDefaults.Key { @@ -176,6 +179,6 @@ extension UserDefaults.Key { } static var isSwizzled: UserDefaults.Key { - return .init(name: UserDefaultConstant.isSwizziled) + return .init(name: UserDefaultConstant.isSwizzled) } } diff --git a/PushEngage/HelperTypes/EnumTypes.swift b/PushEngage/HelperTypes/EnumTypes.swift index 023d139..adfda58 100644 --- a/PushEngage/HelperTypes/EnumTypes.swift +++ b/PushEngage/HelperTypes/EnumTypes.swift @@ -7,7 +7,7 @@ import Foundation -public enum PermissonStatus: String { +public enum PermissionStatus: String { /// The application is authorized to post user notifications. diff --git a/PushEngage/Interface/PushEngage.swift b/PushEngage/Interface/PushEngage.swift index 7897c3a..b6133cf 100644 --- a/PushEngage/Interface/PushEngage.swift +++ b/PushEngage/Interface/PushEngage.swift @@ -7,7 +7,7 @@ import UIKit -public typealias PEnotificationOpenHandler = (PENotificationOpenResult) -> Void +public typealias PENotificationOpenHandler = (PENotificationOpenResult) -> Void public typealias PEBackgroundTaskCompletionBlock = ((UIBackgroundFetchResult) -> Void) @@ -15,311 +15,537 @@ public typealias PESilentPushBackgroundHandler = (PENotification, PEBackgroundTa public typealias PENotificationDisplayNotification = (_ notification: PENotification?) -> Void -public typealias PENotificationWillShowInForground +public typealias PENotificationWillShowInForeground = (PENotification, _ completion: PENotificationDisplayNotification) -> Void @objcMembers @objc final public class PushEngage: NSObject { - // MARK: - public variable + // MARK: - Private properties - /// This computed variable is flag to enable or disable the logging implementaion to debug and trouble-shooting - /// with in the sdk. please disble the logging when host application is in production. - public static var enableLogs: Bool { - get { - PELogger.isLoggingEnable - } - set { - PELogger.isLoggingEnable = newValue - } - } - - // MARK: - private variable private static let shared = PushEngage() - // MARK: - Dependency Injection for the view model in PushEngageServices - - internal static let viewModel = DependencyInitialize.getPEViewModelDependency() + private static let runOnce: Any? = { + loadRequiredSizzling() + _ = shared + return nil + }() - // MARK: - private initialization method + /// Dependency injection for PushEngage manager + internal static let manager = DependencyInitialize.getPEManagerDependency() private override init() { - super.init() } - private static let runOnce: Any? = { - loadRequriedSizzling() - _ = shared - return nil - }() + // MARK: - Public properties - // MARK: - public methods + /// A boolean flag to enable or disable logging within the SDK for debugging and troubleshooting purposes. + /// It is recommended to disable logging when the host application is in production to improve performance. + public static var enableLogging: Bool { + get { + PELogger.isLoggingEnable + } + set { + PELogger.isLoggingEnable = newValue + } + } + // MARK: - Public methods - /// This is very important method to call for the setup of the SDK - /// if developer doesn't want to take the over head to handle the setup call this - /// method in init method of the Application appdelegate. other wise developer has - /// to set up the SDK manually. + /// This method is crucial for setting up the SDK. If the developer prefers not to handle the setup manually, + /// calling this method in the `init` method of the Application AppDelegate is essential. Otherwise, the SDK + /// must be set up manually. + /// + /// - Parameters: + /// - isEnabled: A boolean value indicating whether to enable the SDK setup through method swizzling. @objc public static func swizzleInjection(isEnabled: Bool) { if isEnabled { _ = Self.runOnce } - viewModel.updateSwizzledStatus(with: isEnabled) + manager.updateSwizzledStatus(with: isEnabled) } - /// Use this static method to set the notification open block which is create while sdk initilization - /// so when notification is opened this handler will take requried action and provide deeplinking requried user info - /// - Parameter block: pass the block type PEnotificationOpenHandler to the parameter - /// so that when notification click action take place. - @objc public static func setNotificationOpenHandler(block: PEnotificationOpenHandler?) { - viewModel.setNotificationOpenHandler(block: block) + /// Use this static method to set the notification open handler, which is created during SDK initialization. + /// When a notification is opened, this handler will take the necessary action and provide the required + /// user information for deep linking. + /// + /// - Parameter block: The block of type `PENotificationOpenHandler` to be set as the notification open handler. + @objc public static func setNotificationOpenHandler(block: PENotificationOpenHandler?) { + manager.setNotificationOpenHandler(block: block) } - - /// Use this static method to set the notifiction handler when notification recives when app is in forground mode. - /// - Parameter block: pass the notificationForgroundHandler from the appdelegate. - @objc public static func setNotificationWillShowInForgroundHandler(block: PENotificationWillShowInForground?) { - viewModel.setNotificationWillShowInForgroundHandler(block: block) + /// Use this static method to set the notification handler for when notifications are received while the app is in foreground mode. + /// + /// - Parameter block: Pass the `PENotificationWillShowInForeground` block from the `AppDelegate` to handle notifications when the app is active. + @objc public static func setNotificationWillShowInForegroundHandler(block: PENotificationWillShowInForeground?) { + manager.setNotificationWillShowInForgroundHandler(block: block) } - - /// call this method in appdelegate - /// to set the app push id to the SDK to register the subsciber to that app push id. - /// - Parameter key: App push id. - @objc public static func setAppId(key: String) { - - viewModel.setAppId(key: key) + /// Call this method in the `AppDelegate` to set the app push ID in the SDK, registering the subscriber to that specific app push ID. + /// + /// - Parameter key: The app push ID to be set. + @objc public static func setAppID(id: String) { + manager.setAppId(key: id) } - @objc public static func setEnv(enviroment: Environment) { - Configuration.enviroment = enviroment + /// Set the environment for the SDK, allowing developers to switch between different environments (e.g., staging, production). + /// + /// - Parameter environment: The desired environment to be set (e.g., .staging, .production). + @objc public static func setEnvironment(environment: Environment) { + manager.setEnvironment(environment) } - - /// call this method in appdelegate to start the notification services in the application. - /// and provide some pre-requisite information to the - /// SDK to handle the SDK internal setup. + /// Provide necessary pre-requisite information to the SDK for internal setup. + /// /// - Parameters: - /// - application: UIApplication instance - /// - launchOptions: UiApplication launch options. - @objc public static func startNotificationServices(for application: UIApplication, + /// - application: The UIApplication instance of the host application. + /// - launchOptions: The launch options passed to the application during launch. + @objc public static func setInitialInfo(for application: UIApplication, with launchOptions: [UIApplication.LaunchOptionsKey: Any]?) { - viewModel.setIntialInfo(for: application, with: launchOptions) - viewModel.startNotificationServices() - } - /// Description:- This method provides the Notification service extension feature to - /// modify the content to the application. This api will invoke if mutable content = 1 - /// - Parameter request: Parameter is passed from the parent application so that method can modifiy the content. - @available(iOS 10.0, *) - @objc public static func didReceiveNotificationExtensionRequest(_ request: UNNotificationRequest, - bestContentHandler: UNMutableNotificationContent) { - viewModel.didReceiveNotificationExtensionRequest(request, bestContentHandler: bestContentHandler) + manager.setInitialInfo(for: application, with: launchOptions) } - // update Subsciber Attributes + /// Request notification permission + @objc public static func requestNotificationPermission() { + manager.handleNotificationPermission() + } - /// use this api call to update or add the attribute of the subscriber + /// Updates attributes of a subscriber. If an attribute with the specified key already exists, the existing value + /// will be replaced. + /// /// - Parameters: - /// - attributes: attribute supports [String: Any] type. eg.(["name": "bob"]) like that - /// - completionHandler: call back response which provide the response as bool true and false with error. - @objc public static func add(attributes: Parameters, + /// - attributes: Attributes to be added. Should be in the format ["attributeName": attributeValue]. + /// - completionHandler: A closure that gets called after the update operation is completed. + /// Provides a response boolean indicating success or failure and an optional error. + /// + /// - Note: The `attributes` parameter supports [String: Any] type, for example: ["name": "Bob"]. + /// + /// - Example usage: + /// ``` + /// let attributes = ["name": "Bob", "age": 30] + /// PushEngage.add(attributes: attributes) { success, error in + /// if success { + /// print("Attributes added/updated successfully.") + /// } else { + /// if let error = error { + /// print("Error occurred: \(error.localizedDescription)") + /// } else { + /// print("Unknown error occurred.") + /// } + /// } + /// } + /// ``` + @objc public static func add(attributes: Parameters, completionHandler: ((_ response: Bool, _ error: Error?) -> Void)?) { - viewModel.add(attributes: attributes, completionHandler: completionHandler) + manager.add(attributes: attributes, completionHandler: completionHandler) } - // get-subscriber-attributes + /// Sets attributes of a subscriber replacing any previously associated attributes. + /// + /// - Parameters: + /// - attributes: Attributes to be added. Should be in the format ["attributeName": attributeValue]. + /// - completionHandler: A closure that gets called after the update operation is completed. + /// Provides a response boolean indicating success or failure and an optional error. + /// + /// - Note: The `attributes` parameter supports [String: Any] type, for example: ["name": "Bob"]. + /// + /// - Example usage: + /// ``` + /// let attributes = ["name": "Bob", "age": 30] + /// PushEngage.set(attributes: attributes) { success, error in + /// if success { + /// print("Attributes added/updated successfully.") + /// } else { + /// if let error = error { + /// print("Error occurred: \(error.localizedDescription)") + /// } else { + /// print("Unknown error occurred.") + /// } + /// } + /// } + /// ``` + @objc public static func set(attributes: Parameters, + completionHandler: ((_ response: Bool, + _ error: Error?) -> Void)?) { + manager.set(attributes: attributes, completionHandler: completionHandler) + } - /// use this method to get the attribute of the subscriber. - /// - Parameter completionHandler: call back provide the atttribute information which is [String: Any]? type and error. - @objc public static func getAttribute(completionHandler: @escaping(_ info: [String: Any]?, + /// Retrieve the attributes of the subscriber. + /// + /// Use this method to get the attributes associated with the subscriber. + /// + /// - Parameters: + /// - completionHandler: A completion handler that provides the attribute information as [String: Any]?, + /// along with an optional error if the operation fails. + /// + @objc public static func getSubscriberAttributes(completionHandler: @escaping(_ info: [String: Any]?, _ error: Error?) -> Void) { - viewModel.getAttribute(completionHandler: completionHandler) + manager.getAttribute(completionHandler: completionHandler) } - // add-profile-id - - /// This api is used to set the subscriber id to the server if sdk is successfully initialized in host application. + /// Add a subscriber profile ID. + /// + /// Use this method to associate a subscriber ID (e.g., the username of the subscriber in the host application) with the SDK. + /// /// - Parameters: - /// - id: subsciber id aka (user name of the subcriber in host application.) - /// - completionHandler: call this block to get the response of the api call which is bool. + /// - id: The subscriber ID to associate with the SDK. + /// - completionHandler: A completion handler that provides the response of the method call as a boolean value, + /// along with an optional error if the operation fails. + /// + /// Example usage: + /// ``` + /// PushEngage.addProfile(for: "your-unique-ID") { response, error in + /// if response { + /// print("Subscriber profile added successfully.") + /// } else { + /// if let error = error { + /// print("Failed to add subscriber profile: \(error.localizedDescription)") + /// } else { + /// print("Unknown error occurred while adding subscriber profile.") + /// } + /// } + /// } + /// + /// ``` @objc public static func addProfile(for id: String, completionHandler: ((_ response: Bool, _ error: Error?) -> Void)?) { - viewModel.addProfile(for: id, completionHandler: completionHandler) + manager.addProfile(for: id, completionHandler: completionHandler) } - // delete Attributes - - - /// This API used to delete the subscriber attriburtes from the pushengage server. + /// Delete Subscriber Attributes. + /// + /// Use this method to remove specific subscriber attributes from the PushEngage server. + /// /// - Parameters: - /// - values: Array of string with attribute value or pass empty array to remove compelete info. - /// - completionHandler: response call back for the user. - @objc public static func deleteAttribute(values: [String], - completionHandler: ((_ response: Bool, - _ error: Error?) -> Void)?) { - viewModel.deleteAttribute(values: values, completionHandler: completionHandler) + /// - keys: An array of strings representing the attribute keys to be removed. + /// Pass an empty array to remove all subscriber attributes associated with the device. + /// - completionHandler: A completion handler that provides the response of the API call as a boolean value, + /// along with an optional error if the operation fails. + /// + /// Example usage: + /// ``` + /// PushEngage.deleteSubscriberAttributes(["AttributeKeyToDelete"]) { response, error in + /// if response { + /// print("Attributes deleted successfully.") + /// } else { + /// if let error = error { + /// print("Failed to delete attributes: \(error.localizedDescription)") + /// } else { + /// print("Unknown error occurred while deleting attributes.") + /// } + /// } + /// } + /// + /// ``` + @objc public static func deleteSubscriberAttributes(for keys: [String], + completionHandler: ((_ response: Bool, + _ error: Error?) -> Void)?) { + manager.deleteAttribute(values: keys, completionHandler: completionHandler) } - - /// This Api used to remove the segments. + /// Remove Segments for Subscriber. + /// + /// Use this method to remove specific segments associated with the subscriber. + /// /// - Parameters: - /// - segments: Array of String hold the information of segments to be removed. - /// - completionHandler: call back with boolean if true operation - /// completed sucessfully with error if any error occurs. - @objc public static func remove(segments: [String], completionHandler: ((_ response: Bool, + /// - segments: An array of strings representing the segment names to be removed from the subscriber. + /// - completionHandler: A completion handler that provides the response of the method call as a boolean value, + /// along with an optional error if the operation fails. + /// Example usage: + /// ``` + /// PushEngage.removeSegments(["SegmentToRemove"]) { response, error in + /// if response { + /// print("Segments removed successfully.") + /// } else { + /// if let error = error { + /// print("Failed to remove segments: \(error.localizedDescription)") + /// } else { + /// print("Unknown error occurred while removing segments.") + /// } + /// } + /// } + /// + /// ``` + @objc public static func removeSegments(_ segments: [String], completionHandler: ((_ response: Bool, _ error: Error?) -> Void)?) { - viewModel.update(segments: segments, with: .remove, completionHandler: completionHandler) + manager.update(segments: segments, with: .remove, completionHandler: completionHandler) } - /// This Api used to add the segments. + /// Adds subscriber to segments. + /// + /// This method is used to add the subscriber to segments. + /// /// - Parameters: - /// - segments: Array of String hold the information of segments to be added. - /// - completionHandler: call back with boolean if true operation - /// completed sucessfully with error if any error occurs. - @objc public static func add(segments: [String], + /// - segments: An array of strings containing segment information to be added to the subscriber's profile. + /// - completionHandler: A closure that provides a response indicating whether the operation was successful (`true` if successful, `false` otherwise) and an optional error object if any error occurs during the operation. + /// - response: A boolean value indicating the success of the operation. + /// - error: An optional error object describing the error that occurred during the operation, if any. + /// + /// Example usage: + /// ``` + /// PushEngage.addSegments(["Segment1", "Segment2"]) { response, error in + /// if response { + /// print("Segments added successfully.") + /// } else { + /// if let error = error { + /// print("Failed to add segments: \(error.localizedDescription)") + /// } else { + /// print("Unknown error occurred while adding segments.") + /// } + /// } + /// } + /// + /// ``` + @objc public static func addSegments(_ segments: [String], completionHandler: ((_ response: Bool, _ error: Error?) -> Void)?) { - viewModel.update(segments: segments, with: .add, + manager.update(segments: segments, with: .add, completionHandler: completionHandler) } - // update dynamic segments - - /// update the dynamic segement which is created from the pushengage dash board. + /// Add subscriber to dynamic segments + /// + /// Use this method to add subscriber to segments created from the PushEngage dashboard for a particular duration. + /// /// - Parameters: - /// - segments: Array of dictionary value where key is string type and value can be Any type. - /// - completionHandler: call back provide response boolean and Error type. - @objc public static func add(dynamic segments: [[String: Any]], + /// - dynamicSegments: An array of dictionaries where the keys are strings and the values can be of any type. + /// - completionHandler: A closure that provides a boolean response indicating whether the operation was successful (`true` if successful, `false` otherwise) and an optional error object if any error occurs during the operation. + /// + /// Example usage: + /// ``` + /// let dynamicSegments: [[String: Any]] = [ + /// ["name": "Cricket", "duration": 3], + /// ["name": "Tennis", "duration": 7], + /// ] + /// + /// PushEngage.addDynamicSegments(dynamicSegments) { response, error in + /// if response { + /// print("Dynamic segments updated successfully.") + /// } else { + /// if let error = error { + /// print("Failed to update dynamic segments: \(error.localizedDescription)") + /// } else { + /// print("Unknown error occurred while updating dynamic segments.") + /// } + /// } + /// } + /// ``` + @objc public static func addDynamicSegments(_ dynamicSegments: [[String: Any]], completionHandler: ((_ response: Bool, _ error: Error?) -> Void)?) { - viewModel.add(dynamic: segments, completionHandler: completionHandler) + manager.add(dynamic: dynamicSegments, completionHandler: completionHandler) } - // update trigger status - - + /// Update trigger status /// Update the trigger status of the notification /// - Parameters: /// - status: boolean flag wheather user has accepted for trigger enabled or not /// - completionHandler: call back provide response boolean and Error type. - @objc public static func updateTrigger(status: Bool, + /// Private for now + @objc private static func updateTrigger(status: Bool, completionHandler: ((_ response: Bool, _ error: Error?) -> Void)?) { - viewModel.updateTrigger(status: status, completionHandler: completionHandler) + manager.updateTrigger(status: status, completionHandler: completionHandler) } - // get subscriber details - - - /// Api provides the registered subscriber information. + /// Get Subscriber Details + /// + /// Use this method to retrieve information about the registered subscriber. + /// /// - Parameters: - /// - fields: provide the fields if need field specific information like country to get only country information - /// if no fields are provided then api will give complete Subscriber details - /// - completionHandler: Call back provides the response as Subscriber details - @objc public static func getSubscriberDetails(for fields: [String]?, - completionHandler: ((_ response: SubscriberDetailsData? , + /// - keys: An optional array of strings specifying the specific keys of information to retrieve for the subscriber. + /// If no keys are provided, the API will return complete subscriber details. (Optional) + /// - completionHandler: A closure that provides the response as a `SubscriberDetailsData` object representing the subscriber details, or an optional error object if any error occurs during the operation. + /// + /// Example usage: + /// ``` + /// let specificKeys = ["country", "age"] // Optional: Retrieve specific keys like country and age. + /// + /// PushEngage.getSubscriberDetails(for: specificKeys) { response, error in + /// if let subscriberDetails = response { + /// print("Subscriber Details: \(subscriberDetails)") + /// } else { + /// if let error = error { + /// print("Failed to retrieve subscriber details: \(error.localizedDescription)") + /// } else { + /// print("Unknown error occurred while retrieving subscriber details.") + /// } + /// } + /// } + /// ``` + @objc public static func getSubscriberDetails(for keys: [String]?, + completionHandler: ((_ response: SubscriberDetailsData?, _ error: Error?) -> Void)?) { - viewModel.getSubscriberDetails(for: fields, completionHandler: completionHandler) + manager.getSubscriberDetails(for: keys, completionHandler: completionHandler) } // Trigger Campiagn Handler - /// Use this method to create the trigger for the campiagn /// - Parameters: /// - details: provide the insctance of the Trigger campaign object and pass the details on /// - completionHandler: call back provides the response as true or false. - @objc public static func createTriggerCampaign(for details: TriggerCampaign, + /// Private for now + @objc private static func createTriggerCampaign(for details: TriggerCampaign, completionHandler: ((_ response: Bool) -> Void)?) { - viewModel.createCampaign(for: details, completionHandler: completionHandler) + manager.createCampaign(for: details, completionHandler: completionHandler) } - // best attempt handled + /// Silent Push Notification Handler + /// + /// Use this method to set the silent notification handler to handle silent push notifications. + /// It will give 30 seconds of time frame to the app so that any app update can be done. + /// + /// - Parameter completion: A closure that provides the silent push notification content. + /// + /// Use this method in your application to handle silent push notifications. Silent push notifications are notifications + /// that don't display any visible content to the user but allow your app to perform tasks in the background. When a silent + /// push notification is received, the provided closure will be called, allowing you to process the notification's content + /// and perform necessary background tasks. + @objc public static func silentPushHandler(_ completion: PESilentPushBackgroundHandler?) { + manager.setbackGroundSilentPushHandler(block: completion) + } + // MARK: Notification Content Extension methods - /// Use this api in notification service extension for bes attempt to deliver the notification to the device. - /// - Parameters: - /// - request: Notification Request - /// - content: Content for the notification - /// - Returns: returns the UNMutableNotificationContent. + /// Get Custom UI Payload for Notification + /// + /// Use this method to get the custom UI payload associated with a notification request. + /// + /// - Parameter request: The UNNotificationRequest object for which you want to retrieve the custom UI payload. + /// - Returns: A CustomUIModel object containing the custom UI payload for the given notification request. @available(iOS 10.0, *) - @objc public static func serviceExtensionTimeWillExpire(_ request: UNNotificationRequest, - content: UNMutableNotificationContent?) - -> UNMutableNotificationContent? { - return viewModel.serviceExtensionTimeWillExpire(request, content: content) + @objc public static func getCustomUIPayLoad(for request: UNNotificationRequest) -> CustomUIModel { + manager.getCustomUIPayLoad(for: request) } - /// Use this api to set the silent notification to handle silent push as it will give 30 sec of time frame to app so that - /// any app update can be done. - /// - Parameter completion: pass the silent notification handler to the method if developer doesn't - /// set the completion - @objc public static func silentPushHandler(_ completion: PESilentPushBackgroundHandler?) { - viewModel.setbackGroundSilentPushHandler(block: completion) - } + // MARK: Notification Service Extension methods + /// Modify the notification content received from the parent application in the Notification Service Extension. + /// + /// - Parameters: + /// - request: The UNNotificationRequest received from the parent application. + /// - bestContentHandler: The UNMutableNotificationContent that can be modified to customize the notification. @available(iOS 10.0, *) - @objc public static func getCustomUIPayLoad(for request: UNNotificationRequest) -> CustomUIModel { - viewModel.getCustomUIPayLoad(for: request) + @objc public static func didReceiveNotificationExtensionRequest(_ request: UNNotificationRequest, + bestContentHandler: UNMutableNotificationContent) { + manager.didReceiveNotificationExtensionRequest(request, bestContentHandler: bestContentHandler) } - // MARK: - Remote Notification Manually setup methods - // if developer has not added swizzling in there appdelegate init method the developers - // has use remote notification manually setup mathods. - - // MARK: - Register Device with server method. + /// Service Extension Time Will Expire Handler + /// + /// Use this method in the notification service extension to handle best attempts to deliver the notification to the device. + /// + /// - Parameters: + /// - request: The original `UNNotificationRequest` received by the extension. + /// - content: The mutable content for the notification. This content can be modified as needed before delivery. + /// + /// - Returns: The modified `UNMutableNotificationContent` that will be delivered to the user + /// + /// When the notification service extension time is about to expire, this method should be called to allow the SDK to modify the + /// notification content before delivery. + @available(iOS 10.0, *) + @objc public static func serviceExtensionTimeWillExpire(_ request: UNNotificationRequest, + content: UNMutableNotificationContent?) + -> UNMutableNotificationContent? { + return manager.serviceExtensionTimeWillExpire(request, content: content) + } - /// User has to register the device token to the server. - /// - Parameter deviceToken: send token as data type. + // MARK: - Remote Notification manual setup methods + + /// Register Device Token Manually + /// + /// Use this method to manually register the device token with the PushEngage server if swizzling is not used. + /// + /// - Parameter deviceToken: The device token obtained from Apple Push Notification service (APNs) as Data. + /// + /// Call this method in your app delegate's `application(_:didRegisterForRemoteNotificationsWithDeviceToken:)` method + /// to register the device token with the PushEngage server manually. + /// + /// Example usage: + /// ``` + /// func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) { + /// PushEngage.registerDeviceToServer(with: deviceToken) + /// } + /// ``` + /// + /// - Note: If you are using swizzling, you do not need to manually register the device token. @objc public static func registerDeviceToServer(with deviceToken: Data) { - viewModel.registerDeviceToServer(with: deviceToken) + manager.registerDeviceToServer(with: deviceToken) } - // didReciveRemoteNotification silent features. - - - /// Use To handle the remote notification setup from SDK from the manual integration + /// Handle Remote Notifications Manually + /// + /// Use this method to handle remote notifications manually if swizzling is not used or if you want to + /// customize the notification handling behavior. + /// /// - Parameters: - /// - application: UIApplication instance - /// - userInfo: information while get notifiation userinfo to pass to SDK. - /// - completionHandler: this is UIBackgroundFetchResult handler user has to send the handler from application. - /// - Returns:Boolean value as result like any backgound work started if true otherwise false. + /// - application: UIApplication instance. + /// - userInfo: The remote notification payload received from APNs as [AnyHashable: Any]. + /// - completionHandler: The completion handler provided by the host application for background fetch completion. + /// This handler must be called after processing the notification. + /// + /// - Returns: A boolean value indicating if any background work was started by the SDK. + /// + /// Call this method in your app delegate's `application(_:didReceiveRemoteNotification:fetchCompletionHandler:)` method. + /// + /// Example usage: + /// ``` + /// func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any], + /// fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) { + /// let didStartBackgroundWork = PushEngage.receivedRemoteNotification(application: application, + /// userInfo: userInfo, + /// completionHandler: completionHandler) + /// if !didStartBackgroundWork { + /// // Handle the notification in the foreground, if required. + /// } + /// } + /// ``` + /// + /// - Note: If you are using swizzling, you do not need to manually handle remote notifications. @discardableResult - @objc public static func recivedRemoteNotification(application: UIApplication, + @objc public static func receivedRemoteNotification(application: UIApplication, userInfo: [AnyHashable: Any], completionHandler: ((UIBackgroundFetchResult) -> Void)?) -> Bool { - viewModel.recivedRemoteNotification(application: application, + manager.receivedRemoteNotification(application: application, userInfo: userInfo, completionHandler: completionHandler) } - // These methods developer has to call if they are going to - // implements the UNUsernotification Delegate method by them and disable swizzling. - - /// Setup method need to integrate in UNNotification delegate method to process the notification after - /// subscriber performs any action to the notification. - /// - Parameter notification: UNNotificationresponse of the notification delivered on device only for iOS 10+ + /** + Handles the remote notification interaction for devices running iOS 10.0 and above. + + This method should be implemented in the application's UNUserNotificationCenterDelegate to process the user's response to a remote notification. + When a user interacts with a notification, this method should be called to handle the response and perform appropriate actions based on the user's interaction. + + - Note: This method should only be implemented if the application chooses to handle UNNotificationResponse objects manually and has disabled method swizzling for notification handling. + + - Parameter notification: The UNNotificationResponse object representing the user's response to a remote notification. It contains information about the notification. + */ @available(iOS 10.0, *) - @objc public static func didRecivedRemoteNotification(with notification: UNNotificationResponse) { - viewModel.processiOS10Open(response: notification) + @objc public static func didReceiveRemoteNotification(with notification: UNNotificationResponse) { + manager.processiOS10Open(response: notification) } } // MARK: - Method Swizzling - extension PushEngage { - - private static func loadRequriedSizzling() { - - // PushEngage selector tagmethod is implemented for checking is whether - // UIApplication is not loaded twice in runtime for the previous version check. - // This will not happen in swift because implemented runOnce swift lazy - // Using Swift's lazy evaluation of a static property we get the same - // thread-safety and called-once guarantees as dispatch_once provided. - + /** + Loads the required method swizzling for PushEngage SDK during the application's runtime initialization. + + This method performs method swizzling to ensure proper integration of PushEngage SDK within the application. + It checks if the swizzling has already been performed to prevent duplicating the process. + */ + private static func loadRequiredSizzling() { + /** + Checks if the `UIApplication` delegate methods are loaded twice during runtime, ensuring proper version compatibility. + + The implementation utilizes Swift's lazy evaluation of a static property, ensuring thread-safety and guaranteeing that the code within the property is executed only once, providing similar behavior to `dispatch_once`. + */ let isExisting = PESelectorHelper.shared .injectSelectorAtRuntime(PushEngageAppDelegate.self, #selector(PushEngageAppDelegate.pushEngageSELTag), @@ -340,6 +566,12 @@ extension PushEngage { } + /** + Sets the delegate for UNUserNotificationCenter, enabling the handling of notifications for devices running iOS 10 and above. + + This method checks if the UNUserNotificationCenter class is available (introduced in iOS 10) to ensure compatibility. + If the class is available, it initializes and sets up the PushEngageUNUserNotificationCenter, enabling the app to handle notifications using the User Notifications framework. + */ @available(iOS 10.0, *) private static func setUNUserNotificationCenterDelegate() { if NSClassFromString("UNUserNotificationCenter") == nil { diff --git a/PushEngage/Model/DomainModels/PENotification.swift b/PushEngage/Model/DomainModels/PENotification.swift index ebd2927..78e32b5 100644 --- a/PushEngage/Model/DomainModels/PENotification.swift +++ b/PushEngage/Model/DomainModels/PENotification.swift @@ -41,6 +41,7 @@ import Foundation init(userInfo: [AnyHashable: Any]) { var parsedValue: PEPayload? = Utility.parse(typeof: PEPayload.self, payload: userInfo) + self.threadId = parsedValue?.aps?.threadID self.rawPayload = userInfo self.mutableContent = parsedValue?.aps?.mutableContent ?? 0 self.contentAvailable = parsedValue?.aps?.contentAvailable ?? 0 @@ -95,7 +96,7 @@ import Foundation message: "PENotification is deinitalized") } - // MARK: - will show in forground + // MARK: - will show in foreground func timeOutTimerSetup() { timeoutTimer = Timer.init(timeInterval: 25.0, diff --git a/PushEngage/Model/NetworkResponse.swift b/PushEngage/Model/NetworkResponse.swift index bf38f96..9fba32e 100644 --- a/PushEngage/Model/NetworkResponse.swift +++ b/PushEngage/Model/NetworkResponse.swift @@ -8,7 +8,6 @@ import Foundation // This struct is for the all the api call which is having not data in the response. - struct NetworkResponse: Codable { let errorCode: Int? let errorMessage: String? @@ -21,7 +20,7 @@ struct NetworkResponse: Codable { } } -struct NetworkError: Codable { +struct NetworkError: Codable { let message: String let code: Int @@ -36,9 +35,9 @@ struct NetworkError: Codable { @objcMembers @objc public class SubsciberDetailsResponse: NSObject, Codable { - public var errorCode: Int? - public var data: SubscriberDetailsData? - public var errorMessage: String? + public let errorCode: Int? + public let data: SubscriberDetailsData? + public let errorMessage: String? enum CodingKeys: String, CodingKey { case errorCode = "error_code" @@ -50,11 +49,12 @@ struct NetworkError: Codable { // MARK: - SubscriberDetailsData @objcMembers @objc public class SubscriberDetailsData: NSObject, Codable { - public var city, device, host, userAgent: String? - public var deviceType: String? - public var segments: [String]? - public var timezone, country, tsCreated, state: String? - public var subscriptionURL: String? + public let city, device, host, userAgent: String? + public let deviceType: String? + public let segments: [String]? + public let timezone, country, tsCreated, state: String? + public let subscriptionURL: String? + public let profileId: String? enum CodingKeys: String, CodingKey { case city, device, host @@ -64,6 +64,7 @@ struct NetworkError: Codable { case tsCreated = "ts_created" case state case subscriptionURL = "subscription_url" + case profileId = "profile_id" } } diff --git a/PushEngage/Model/PEPayLoad.swift b/PushEngage/Model/PEPayLoad.swift index 6f114d2..ceb2671 100644 --- a/PushEngage/Model/PEPayLoad.swift +++ b/PushEngage/Model/PEPayLoad.swift @@ -6,12 +6,12 @@ // import Foundation -import UIKit +import UIKit // MARK: - PEPayload struct PEPayload: Codable { - var aps: Aps? - var custom: Custom? + let aps: Aps? + let custom: Custom? enum CodingKeys: String, CodingKey { case custom = "pe" @@ -21,11 +21,11 @@ struct PEPayload: Codable { // MARK: - Aps struct Aps: Codable { - var alert: Alert? - var badge: Int? - var sound: String? - var mutableContent, contentAvailable: Int? - var category, threadID, targetContentID: String? + let alert: Alert? + let badge: Int? + let sound: String? + let mutableContent, contentAvailable: Int? + let category, threadID, targetContentID: String? enum CodingKeys: String, CodingKey { case alert, badge, sound @@ -39,21 +39,21 @@ struct Aps: Codable { // MARK: - Alert struct Alert: Codable { - var title, subtitle, body: String? + let title, subtitle, body: String? } // MARK: - Custom struct Custom: Codable { - var tag, attachmentURL, launchURL: String? - var isSponsered: Int? - var postback: AnyCodable? - var badgeIncrement: Int? - var title, body: String? - var badge: Int? - var sound, subtitle: String? - var actionButtons: [ActionButtonInfo]? + let tag, attachmentURL, launchURL: String? + let isSponsered: Int? + let postback: AnyCodable? + let badgeIncrement: Int? + let title, body: String? + let badge: Int? + let sound, subtitle: String? + let actionButtons: [ActionButtonInfo]? var additionalData: [String: String]? - var deeplinking: String? + let deeplinking: String? enum CodingKeys: String, CodingKey { case tag @@ -69,13 +69,12 @@ struct Custom: Codable { case subtitle = "sb" case actionButtons = "ab" case deeplinking = "dl" - } } // MARK: - ActionButtonInfo struct ActionButtonInfo: Codable { - var id, text: String + let id, text: String enum CodingKeys: String, CodingKey { case id = "a" diff --git a/PushEngage/Model/Postback.swift b/PushEngage/Model/Postback.swift index e1adbfd..c6f9d40 100644 --- a/PushEngage/Model/Postback.swift +++ b/PushEngage/Model/Postback.swift @@ -10,7 +10,7 @@ import Foundation // MARK: - SponsoredPush struct SponsoredPush: Codable { - var tag: String + var tag: String? var postback: AnyCodable? } @@ -38,7 +38,7 @@ struct SponsoredPush: Codable { // MARK: - SponsoredResponse struct SponsoredResponse: Codable { - var errorCode: Int + var errorCode: Int? var data: SponsoredData? var errorMessage: String? var error: NetworkError? @@ -53,12 +53,11 @@ struct SponsoredResponse: Codable { // MARK: - SponsoredData struct SponsoredData: Codable { - - var title: String - var body: String - var icon: String - var tag: String - var launchURL: String + var title: String? + var body: String? + var icon: String? + var tag: String? + var launchURL: String? var sponseredActionButton: [SButton]? enum CodingKeys: String, CodingKey { @@ -73,7 +72,7 @@ struct SponsoredData: Codable { extension SponsoredData { struct SButton: Codable { - var slabel: String + var slabel: String? enum CodingKeys: String, CodingKey { case slabel = "b" diff --git a/PushEngage/Model/Subscription.swift b/PushEngage/Model/Subscription.swift index ae1f992..bfe31d1 100644 --- a/PushEngage/Model/Subscription.swift +++ b/PushEngage/Model/Subscription.swift @@ -13,9 +13,8 @@ struct SubscriptionInfo: Codable { var subscription: Subscription? var deviceType, device, deviceVersion, deviceModel: String? var deviceManufacturer: String? - var latitude, longitude: String? var timezone: String? - var language, userAgent, totalScrWidthHeight, host: String? + var language, userAgent, totalScreenWidthHeight, host: String? var attributes: [String: String]? var profileID: String? var isNotificationEnable: Int? @@ -29,10 +28,10 @@ struct SubscriptionInfo: Codable { case deviceVersion = "device_version" case deviceModel = "device_model" case deviceManufacturer = "device_manufacturer" - case latitude, longitude, timezone + case timezone case language case userAgent = "user_agent" - case totalScrWidthHeight = "total_scr_width_height" + case totalScreenWidthHeight = "total_screen_width_height" case host, attributes case profileID = "profile_id" case isNotificationEnable = "notification_disabled" diff --git a/PushEngage/NetworkLayer/PERouter/PERouter.swift b/PushEngage/NetworkLayer/PERouter/PERouter.swift index 00d83aa..ce31b55 100644 --- a/PushEngage/NetworkLayer/PERouter/PERouter.swift +++ b/PushEngage/NetworkLayer/PERouter/PERouter.swift @@ -7,7 +7,7 @@ import Foundation -enum NotificationLifeAction { +enum NotificationAction { case viewed case clicked } @@ -15,7 +15,7 @@ enum NotificationLifeAction { public typealias Parameters = [String: Any] typealias NotificationCycleStatus = (hash: String, notificationId: String, - action: NotificationLifeAction, + action: NotificationAction, id: String?) typealias UpdateSubcriberInfoList = (hash: String, info: SubscriptionInfo, @@ -26,8 +26,9 @@ enum PERouter { case getImage(String) case getSubscriberForfields((hash: String, fields: [String]?)) case checkSubscriberHash(String) - case subscriberAttribute((hash: String, attributes: [String: Any])) - case getSubsciberAttribute(String) + case setSubscriberAttributes((hash: String, attributes: [String: Any])) + case addSubscriberAttributes((hash: String, attributes: [String: Any])) + case getSubscriberAttribute(String) case updateSubscriberStatus(SubscriberDetails) case addProfile(SubscriberDetails) case deleteAttributes((hash: String, attributes: [String])) @@ -93,7 +94,9 @@ enum PERouter { try URLParameterEncoder.encode(urlRequest: &urlRequest, with: value.params) case .getSubscriberForfields: try URLParameterEncoder.encode(urlRequest: &urlRequest, with: params ?? [:]) - case .subscriberAttribute: + case .setSubscriberAttributes: + try JSONParameterEncoder.encode(urlRequest: &urlRequest, for: params ?? [:]) + case .addSubscriberAttributes: try JSONParameterEncoder.encode(urlRequest: &urlRequest, for: params ?? [:]) case .deleteAttributes(let info): let data = try JSONSerialization.data(withJSONObject: info.attributes) @@ -150,7 +153,7 @@ enum PERouter { private func httpMethod() -> HTTPMethod { switch self { case .addSubscriber, - .subscriberAttribute, + .setSubscriberAttributes, .updateSubscriberStatus, .addProfile, .addTimeZone, @@ -166,7 +169,7 @@ enum PERouter { case .getImage, .getSubscriberForfields, .checkSubscriberHash, - .getSubsciberAttribute, + .getSubscriberAttribute, .notificationCycleStatus, .subscriberSync: return .get @@ -174,6 +177,7 @@ enum PERouter { return .delete case .updateSubsciber, .triggerCampaigning, + .addSubscriberAttributes, .subscriberUpgrade: return .put default: @@ -190,7 +194,9 @@ enum PERouter { let queryParameterValue = fields.joined(separator: ",") let parameter = ["fields": queryParameterValue] return parameter - case .subscriberAttribute(let value): + case .addSubscriberAttributes(let value): + return value.attributes + case .setSubscriberAttributes(let value): return value.attributes case .subscriberUpgrade(let value): let parameter = ["subscription": value] @@ -200,7 +206,7 @@ enum PERouter { "bv": Utility.getOSInfo] return parameter case .notificationCycleStatus(let notificationInfo): - var parameter: [String: Any] = ["device_token_hash": notificationInfo.hash , + var parameter: [String: Any] = ["device_token_hash": notificationInfo.hash, "tag": notificationInfo.notificationId, "device_type": Utility.getOSInfo, "swv": NetworkConstants.sdkVersion, @@ -236,10 +242,11 @@ enum PERouter { let url = try Utility.urlUnWrapper(for: path) return url } catch let error { - switch Configuration.enviroment { - case .dev: + let userDefaults = DependencyInitialize.getUserDefaults() + switch userDefaults.environment { + case .staging: fatalError("URL missing please check in debuging") - case .prod: + case .production: let error = error as? PEError PELogger.error(className: String(describing: PERouter.self), message: error?.errorDescription ?? "") @@ -252,9 +259,11 @@ enum PERouter { relativePath = String(format: NetworkConstants.getHashPath, fields.hash) case .checkSubscriberHash(let hash): relativePath = String(format: NetworkConstants.checkSubscriberHash, hash) - case .subscriberAttribute(let attributeHash): + case .addSubscriberAttributes(let attributeHash): + relativePath = String(format: NetworkConstants.subscriberAttribute, attributeHash.hash) + case .setSubscriberAttributes(let attributeHash): relativePath = String(format: NetworkConstants.subscriberAttribute, attributeHash.hash) - case .getSubsciberAttribute(let hash): + case .getSubscriberAttribute(let hash): relativePath = String(format: NetworkConstants.getSubscriberAttribute, hash) case .updateSubscriberStatus: relativePath = NetworkConstants.updateSubscriberStatus @@ -263,7 +272,7 @@ enum PERouter { case .deleteAttributes(let deleteInfo): relativePath = String(format: NetworkConstants.subscriberAttribute, deleteInfo.hash) case .subscriberUpgrade: - relativePath = NetworkConstants.upgarde + relativePath = NetworkConstants.subscriberUpgrade case .addTimeZone: relativePath = NetworkConstants.timeZone case .addSegments: @@ -320,8 +329,9 @@ enum PERouter { .addSubscriber, .getSubscriberForfields, .checkSubscriberHash, - .subscriberAttribute, - .getSubsciberAttribute, + .setSubscriberAttributes, + .addSubscriberAttributes, + .getSubscriberAttribute, .updateSubscriberStatus, .addProfile, .deleteAttributes, .subscriberUpgrade, @@ -333,14 +343,10 @@ enum PERouter { .removeDynamicSegment, .updateTrigger, .updateSubsciber, - // MARK: - Trigger Campaigining + .notificationCycleStatus, + // MARK: - Trigger Campaigning .triggerCampaigning: return myHeaders - case .notificationCycleStatus(let actionStatus): - if case .viewed = actionStatus.action { - myHeaders[NetworkConstants.requestHeaderRefererKey] = NetworkConstants.requestHeaderRefererValue - } - return myHeaders case .sponseredNotification: return myHeaders default: diff --git a/PushEngage/NetworkLayer/Reachablity/NetworkReachablity.swift b/PushEngage/NetworkLayer/Reachablity/NetworkReachablity.swift index 30eb7d5..9800375 100644 --- a/PushEngage/NetworkLayer/Reachablity/NetworkReachablity.swift +++ b/PushEngage/NetworkLayer/Reachablity/NetworkReachablity.swift @@ -8,7 +8,6 @@ import Foundation import SystemConfiguration - class NetworkConnectivity { class var isConnectedToInternet: Bool { return NetworkReachabilityManager()?.isReachable ?? false diff --git a/PushEngage/NetworkLayer/Service/HTTPMethod.swift b/PushEngage/NetworkLayer/Service/HTTPMethod.swift index 19e8777..418cfeb 100644 --- a/PushEngage/NetworkLayer/Service/HTTPMethod.swift +++ b/PushEngage/NetworkLayer/Service/HTTPMethod.swift @@ -10,7 +10,6 @@ import Foundation public typealias HTTPHeaders = [String: String] public enum HTTPMethod: String { - case get = "GET" case post = "POST" case patch = "PATCH" diff --git a/PushEngage/NetworkLayer/Service/NetworkRouter.swift b/PushEngage/NetworkLayer/Service/NetworkRouterType.swift similarity index 94% rename from PushEngage/NetworkLayer/Service/NetworkRouter.swift rename to PushEngage/NetworkLayer/Service/NetworkRouterType.swift index 7948cfb..25f6d02 100644 --- a/PushEngage/NetworkLayer/Service/NetworkRouter.swift +++ b/PushEngage/NetworkLayer/Service/NetworkRouterType.swift @@ -10,7 +10,7 @@ import Foundation typealias NetworkRouterCompletion = (Result) -> Void typealias NetworkRouterDownloadCompletion = (Result<(URL, URLResponse), PEError>) -> Void -protocol NetworkRouter { +protocol NetworkRouterType { func request(_ route: PERouter, completion: @escaping NetworkRouterCompletion) func requestDownload(_ route: PERouter, completion: @escaping NetworkRouterDownloadCompletion) func cancel() diff --git a/PushEngage/NetworkLayer/Service/Router.swift b/PushEngage/NetworkLayer/Service/Router.swift index d7fb9eb..dacaddf 100644 --- a/PushEngage/NetworkLayer/Service/Router.swift +++ b/PushEngage/NetworkLayer/Service/Router.swift @@ -7,7 +7,7 @@ import Foundation -class Router: NetworkRouter { +class Router: NetworkRouterType { private static let sessionManager: URLSession = { let config = URLSessionConfiguration.ephemeral diff --git a/PushEngage/Obserables/Observable.swift b/PushEngage/Obserables/Observable.swift index b2dbece..74239e1 100644 --- a/PushEngage/Obserables/Observable.swift +++ b/PushEngage/Obserables/Observable.swift @@ -7,7 +7,7 @@ import Foundation -// Custom Generic ObseravleType. +// Custom Generic ObservableType. protocol ObservableType { associatedtype DataType diff --git a/PushEngage/PEError/PEError.swift b/PushEngage/PEError/PEError.swift index 1f854b8..f282402 100644 --- a/PushEngage/PEError/PEError.swift +++ b/PushEngage/PEError/PEError.swift @@ -19,7 +19,7 @@ import Foundation case dataEncodeingFailed case errorResponse(String) case networkNotReachable - case canceled + case cancelled case missingInputURL case missingRedirectURL case underlying(error: Swift.Error) @@ -38,8 +38,7 @@ import Foundation case siteKeyNotAvailable case permissionNotDetermined case notificationUserActionFailed(String?) - @available(iOS 10.0, *) - case sponseredfailWithContent(DownloadOperationInput) + case sponseredfailWithContent(attachmentString: String?, networkService: NetworkRouterType) } extension PEError: LocalizedError { @@ -68,7 +67,7 @@ extension PEError: LocalizedError { return errorMessage case .networkNotReachable: return .networkNotReachable - case .canceled: + case .cancelled: return .canceled case .missingInputURL: return .missingInputURL diff --git a/PushEngage/PEViewModel/PEViewModel.swift b/PushEngage/PEViewModel/PEManager.swift similarity index 62% rename from PushEngage/PEViewModel/PEViewModel.swift rename to PushEngage/PEViewModel/PEManager.swift index f45aa7e..6735cbe 100644 --- a/PushEngage/PEViewModel/PEViewModel.swift +++ b/PushEngage/PEViewModel/PEManager.swift @@ -9,63 +9,156 @@ import Foundation import UserNotifications import UIKit -class PEViewModel { +protocol DeviceManagerType { + func getDeviceToken() -> String + func setDeviceToken(token: String) + func getDeviceHash() -> String + func registerDeviceToServer(with deviceToken: Data) + func setEnvironment(_ environment: Environment) +} + +protocol SubscriberManagerType { + func getSubscriberId() -> String + func getSubscriberHash() -> String + func checkSubscriber(completionHandler: ((_ response: CheckSubscriberData?, _ error: PEError?) -> Void)?) + func getSubscriberDetails(for fields: [String]?, + completionHandler: ((_ response: SubscriberDetailsData?, _ error: PEError?) -> Void)?) +} + +protocol AppInfoManagerType { + func getAppId() -> Int? + func setAppId(key: String) + func onClickRedirect(to launchURL: String?) +} + +protocol NotificationManagerType { + var notificationPermissionStatus: NotificationServiceType { get } + func handleNotificationPermission() + func setInitialInfo(for application: UIApplication, with launchOptions: [UIApplication.LaunchOptionsKey: Any]?) + func getNotificationPermissionStatus() -> PermissionStatus + func update(notificationType: Int) + func setNotificationPermissionStatus(status: PermissionStatus) + func setNotificationOpenHandler(block: PENotificationOpenHandler?) + func setNotificationWillShowInForgroundHandler(block: PENotificationWillShowInForeground?) + func receivedNotification(with userInfo: [AnyHashable: Any], isOpened: Bool) + func handleWillPresentNotificationInForeground(with payLoad: [AnyHashable: Any], + completionHandler: @escaping PENotificationDisplayNotification) + @available(iOS 10.0, *) + func processiOS10Open(response: UNNotificationResponse) + @available(iOS 10.0, *) + func didReceiveNotificationExtensionRequest(_ request: UNNotificationRequest, + bestContentHandler: UNMutableNotificationContent) + @available(iOS 10.0, *) + func serviceExtensionTimeWillExpire(_ request: UNNotificationRequest, + content: UNMutableNotificationContent?) -> UNMutableNotificationContent? + func receivedRemoteNotification(application: UIApplication, + userInfo: [AnyHashable: Any], + completionHandler: ((UIBackgroundFetchResult) -> Void)?) -> Bool + func setbackGroundSilentPushHandler(block: PESilentPushBackgroundHandler?) +} + +protocol AttributeManagerType { + func set(attributes: Parameters, completionHandler: ((_ response: Bool, _ error: PEError?) -> Void)?) + func add(attributes: Parameters, completionHandler: ((_ response: Bool, _ error: PEError?) -> Void)?) + func getAttribute(completionHandler: @escaping(_ info: [String: Any]?, _ error: PEError?) -> Void) + func deleteAttribute(values: [String], + completionHandler: ((_ response: Bool, _ error: PEError?) -> Void)?) + func addProfile(for id: String, completionHandler: ((_ response: Bool, _ error: PEError?) -> Void)?) +} + +protocol SegmentManagerType { + func update(segments: [String], with action: SegmentActions, + completionHandler: ((_ response: Bool, _ error: PEError?) -> Void)?) + func add(dynamic segments: [[String: Any]], + completionHandler: ((_ response: Bool, _ error: PEError?) -> Void)?) + func updateHashArray(for segmentId: Int, + completionHandler: ((_ response: Bool, _ error: PEError?) -> Void)?) +} + +protocol CampaignManagerType { + func createCampaign(for details: TriggerCampaign, + completionHandler: ((_ response: Bool) -> Void)?) + func updateTrigger(status: Bool, + completionHandler: ((_ response: Bool, _ error: PEError?) -> Void)?) +} + +protocol CustomUIManagerType { + @available(iOS 10.0, *) + func getCustomUIPayLoad(for request: UNNotificationRequest) -> CustomUIModel +} + +protocol SwizzleManagerType { + func updateSwizzledStatus(with status: Bool) +} + +protocol PEManagerType: DeviceManagerType, + SubscriberManagerType, + AppInfoManagerType, + NotificationManagerType, + AttributeManagerType, + SegmentManagerType, + CampaignManagerType, + CustomUIManagerType, + SwizzleManagerType {} + +final class PEManager: PEManagerType { // MARK: - private variables - private var applicationService: ApplicationProtocol - private var notificationService: NotificationProtocol - private var subscriberService: SubscriberService - private var userDefaultService: UserDefaultProtocol - private var notificationLifeCycleService: NotificationLifeCycleService - private var notificationExtensionService: NotificationExtensionProtocol - private var locationService: LocationInfoProtocol - private var triggerCamapaiginService: TriggerCampaignProtocol + private var applicationService: ApplicationServiceType + private let notificationService: NotificationServiceType + private let subscriberService: SubscriberServiceType + private var userDefaultsService: UserDefaultsType + private let notificationLifeCycleService: NotificationLifeCycleServiceType + private let notificationExtensionService: NotificationExtensionType + private let triggerCamapaiginService: TriggerCampaignType private var application: UIApplication? private var launchOptions: [UIApplication.LaunchOptionsKey: Any]? - var notificationPermissionStatus: NotificationProtocol { - return notificationService - } - private let disposeBag = DisposeBag() - private static var notificationWillShowInForground: PENotificationWillShowInForground? - private static var notificationOpenHandler: PEnotificationOpenHandler? - private var lastNotifyPayload: [AnyHashable: Any]? - private var lastNonActiveNotifyRecivedId: String? - private var lastNotifyIdFromAction: String? + private var lastNotificationPayload: [AnyHashable: Any]? + private var lastNonActiveNotificationReceivedId: String? + private var lastNotificationIdFromAction: String? private var unprocessedNotification: [PENotificationOpenResult]? private var silentPushNotificationHandler: PESilentPushBackgroundHandler? private var silentCompletionTask: PEBackgroundTaskCompletionBlock? private var timer: Timer? + private static var notificationWillShowInForeground: PENotificationWillShowInForeground? + private static var notificationOpenHandler: PENotificationOpenHandler? + private let disposeBag = DisposeBag() + + var notificationPermissionStatus: NotificationServiceType { + return notificationService + } - init(applicationService: ApplicationProtocol, - notificationService: NotificationProtocol, - notificationExtensionService: NotificationExtensionProtocol, - subscriberService: SubscriberService, - userDefaultService: UserDefaultProtocol, - notificationLifeCycleService: NotificationLifeCycleService, - locationService: LocationInfoProtocol, - triggerCamapaiginService: TriggerCampaignProtocol) { + init(applicationService: ApplicationServiceType, + notificationService: NotificationServiceType, + notificationExtensionService: NotificationExtensionType, + subscriberService: SubscriberServiceType, + userDefaultService: UserDefaultsType, + notificationLifeCycleService: NotificationLifeCycleServiceType, + triggerCamapaiginService: TriggerCampaignType) { self.applicationService = applicationService self.notificationService = notificationService self.subscriberService = subscriberService - self.userDefaultService = userDefaultService + self.userDefaultsService = userDefaultService self.notificationLifeCycleService = notificationLifeCycleService self.notificationExtensionService = notificationExtensionService - self.locationService = locationService self.triggerCamapaiginService = triggerCamapaiginService self.applicationService.notifydelegate = self - setupBinding() + self.setupBindings() + self.addObservers() + } + + // MARK: - private func + + private func addObservers() { NotificationCenter.default.addObserver(self, selector: #selector(smartResubscriber), name: UIApplication.didEnterBackgroundNotification, object: nil) - NotificationCenter.default.addObserver(self, selector: #selector(retryForSiteSyncIfFailedforFirstTime), + NotificationCenter.default.addObserver(self, selector: #selector(retrySiteSyncIfFailedFirstTime), name: UIApplication.willEnterForegroundNotification, object: nil) } - deinit { - disposeBag.disposedValue() - Self.notificationOpenHandler = nil - Self.notificationWillShowInForground = nil + private func removeObservers() { NotificationCenter.default.removeObserver(self, name: UIApplication.didEnterBackgroundNotification, object: nil) @@ -73,51 +166,53 @@ class PEViewModel { name: UIApplication.willEnterForegroundNotification, object: nil) } - - // MARK: - private func - - /* Weekly Sync operation will try to call after every week if diff btw curr sync date - and last sync date is greater than 7 then it will call the weekly sync api */ - + + /// Does weekly subscriber sync + /// - Parameters: + /// - backgroundHandler: Background operation handler + /// - currentData: Current device date private func weeklySyncOperation(backgroundHandler: BackgroundTaskExpirationHandler, - now: Date) { + currentData: Date) { let dispatchGroup = DispatchGroup() - guard let siteKey = userDefaultService.siteKey else { - PELogger.debug(className: String(describing: PEViewModel.self), + guard let siteKey = userDefaultsService.siteKey else { + PELogger.debug(className: String(describing: PEManager.self), message: "site key is not available") backgroundHandler.end() return } dispatchGroup.enter() - let deleteOnDisablePrev = userDefaultService.isDeleteSubscriberOnDisable + let deleteOnDisablePrev = userDefaultsService.isDeleteSubscriberOnDisable subscriberService.syncSiteInfo(for: siteKey) { _, _ in dispatchGroup.leave() } _ = dispatchGroup.wait(timeout: DispatchTime.now() + NetworkConstants.requestTimeout) - let siteStatus = SiteStatus(rawValue: userDefaultService.siteStatus) + let siteStatus = SiteStatus(rawValue: userDefaultsService.siteStatus) if siteStatus != .active { backgroundHandler.end() return } - let result = isDeleteSubscriberOnDisableDiffer(backgroundHandler: backgroundHandler, + let shouldDeleteSubscriberOnDisable = shouldDeleteSubscriberOnDisableDiffer(backgroundHandler: backgroundHandler, deleteOnDisablePrev, - now: now) - result ? updateSubscriberaction(backgroundHandler: backgroundHandler, now: now) - : PELogger.error(className: String(describing: PEViewModel.self), - message: "Subscriber was not available so it is added so " - + "not needed to update subscriber.") + now: currentData) + if shouldDeleteSubscriberOnDisable { + self.updateSubscriberAction(backgroundHandler: backgroundHandler, now: currentData) + } else { + PELogger.error(className: String(describing: PEManager.self), + message: "Subscriber was not available so it is added so " + + "not needed to update subscriber.") + } } - private func isDeleteSubscriberOnDisableDiffer(backgroundHandler: BackgroundTaskExpirationHandler, + private func shouldDeleteSubscriberOnDisableDiffer(backgroundHandler: BackgroundTaskExpirationHandler, _ deleteOnDisablePrev: Bool?, - now: Date) -> Bool { + now: Date) -> Bool { var continueFlag = false let dispatchGroup = DispatchGroup() dispatchGroup.enter() - if deleteOnDisablePrev != userDefaultService.isDeleteSubscriberOnDisable { - let status = userDefaultService.notificationPermissionState == .granted ? 0 : 1 + if deleteOnDisablePrev != userDefaultsService.isDeleteSubscriberOnDisable { + let status = userDefaultsService.notificationPermissionState == .granted ? 0 : 1 subscriberService.updateSubscriberStatus(status: status) { [weak self] _, error in if case .invalidStatusCode(_, let code) = error, code == 404 { self?.subscriberService.retryAddSubscriberProcess(completion: { _ in @@ -137,13 +232,13 @@ class PEViewModel { return continueFlag } - private func updateSubscriberaction(backgroundHandler: BackgroundTaskExpirationHandler, + private func updateSubscriberAction(backgroundHandler: BackgroundTaskExpirationHandler, now: Date) { - subscriberService.updateSubsciber { [weak self] _, error in - PELogger.debug(className: String(describing: PEViewModel.self), + subscriberService.updateSubscriber { [weak self] _, error in + PELogger.debug(className: String(describing: PEManager.self), message: error == nil ? "successfully updated subsciber." : "failed to update subscriber.") - self?.userDefaultService.lastSmartSubscribeDate = now + self?.userDefaultsService.lastSmartSubscribeDate = now backgroundHandler.end() } } @@ -153,24 +248,24 @@ class PEViewModel { @objc private func smartResubscriber() { DispatchQueue.global(qos: .background).async { [weak self] in - let now = Date() + let currentDate = Date() guard let application = self?.application else { return } - if self?.userDefaultService.istriedFirstTime == false { - PELogger.debug(className: String(describing: PEViewModel.self), + if self?.userDefaultsService.istriedFirstTime == false { + PELogger.debug(className: String(describing: PEManager.self), message: "As first try is not done so no need to do smart-resusbcribe") return } BackgroundTaskExpirationHandler.run(application: application) { [weak self] backgroundHandler in - let lastResubDate = self?.userDefaultService.lastSmartSubscribeDate - if lastResubDate == nil || (lastResubDate != nil && now.days(from: lastResubDate!) >= 7) { - self?.weeklySyncOperation(backgroundHandler: backgroundHandler, now: now) + let lastResubDate = self?.userDefaultsService.lastSmartSubscribeDate + if lastResubDate == nil || (lastResubDate != nil && currentDate.days(from: lastResubDate!) >= 7) { + self?.weeklySyncOperation(backgroundHandler: backgroundHandler, currentData: currentDate) } else { - PELogger.debug(className: String(describing: PEViewModel.self), + PELogger.debug(className: String(describing: PEManager.self), message: "Weekly subsciber is" + " not called because this is day ->" - + " \(lastResubDate != nil ? "\(now.days(from: lastResubDate!))" : "not valid")" + + " \(lastResubDate != nil ? "\(currentDate.days(from: lastResubDate!))" : "not valid")" + " after last update.") backgroundHandler.end() } @@ -178,105 +273,109 @@ class PEViewModel { } } - // if site sync failed for first time - - @objc private func retryForSiteSyncIfFailedforFirstTime() { - if userDefaultService.istriedFirstTime - && !userDefaultService.deviceToken.isEmpty - && userDefaultService.getObject(for: SyncAPIData.self, + /// Retry site sync if failed the first time + @objc private func retrySiteSyncIfFailedFirstTime() { + if userDefaultsService.istriedFirstTime + && !userDefaultsService.deviceToken.isEmpty + && userDefaultsService.getObject(for: SyncAPIData.self, key: UserDefaultConstant.pushEngageSyncApi) == nil { - guard let siteKey = userDefaultService.siteKey else { + guard let siteKey = userDefaultsService.siteKey else { return } subscriberService.syncSiteInfo(for: siteKey) { _, error in if error != nil { - PELogger.debug(className: String(describing: PEViewModel.self), + PELogger.debug(className: String(describing: PEManager.self), message: error?.localizedDescription ?? "") } } } else { - PELogger.debug(className: String(describing: PEViewModel.self), + PELogger.debug(className: String(describing: PEManager.self), message: "retryForSiteSyncIfFailedforFirstTime not needed") } } - private func notificationSettingsOperation(status: PermissonStatus) { + /// Determine notification subscriber changes + /// - Parameters: + /// - status: Notification permission status + private func determineNotificationSubscriberChanges(status: PermissionStatus) { - let previousStatus = userDefaultService.notificationPermissionState - userDefaultService.notificationPermissionState = status - if userDefaultService.notificationPermissionState == .notYetRequested { - PELogger.debug(className: String(describing: PEViewModel.self), + let previousStatus = userDefaultsService.notificationPermissionState + userDefaultsService.notificationPermissionState = status + if userDefaultsService.notificationPermissionState == .notYetRequested { + PELogger.debug(className: String(describing: PEManager.self), message: "Permission not determined so" + "Notification permission alert will prompt.") return } - if userDefaultService.notificationPermissionState == .granted, - userDefaultService.isSubscriberDeleted { + if userDefaultsService.notificationPermissionState == .granted, + userDefaultsService.isSubscriberDeleted { subscriberService.retryAddSubscriberProcess { error in if error != nil { - PELogger.error(className: String(describing: PEViewModel.self), + PELogger.error(className: String(describing: PEManager.self), message: "failed to add subscriber") } } return } - if previousStatus != userDefaultService.notificationPermissionState { - if userDefaultService.ispermissionAlerted == true { + if previousStatus != userDefaultsService.notificationPermissionState { + if userDefaultsService.ispermissionAlerted == true { subscriberService.updateSettingPermission(status: status) } else { - PELogger.debug(className: String(describing: PEViewModel.self), + PELogger.debug(className: String(describing: PEManager.self), message: "Alert hasn't prompted.") } } } - private func setupBinding() { + private func setupBindings() { notificationService .notificationPermissionStatus.subscribe { [weak self] (status) in - PELogger.info(className: String(describing: PEViewModel.self), message: status.rawValue) - self?.notificationSettingsOperation(status: status) - }.disposed(by: disposeBag) - // Observer for location update. - locationService.locationInfoObserver.subscribe { [weak self] (geoInfo) in - self?.userDefaultService.save(object: geoInfo, - for: UserDefaultConstant.locationCoordinates) + PELogger.info(className: String(describing: PEManager.self), message: status.rawValue) + self?.determineNotificationSubscriberChanges(status: status) }.disposed(by: disposeBag) - + } + + func setEnvironment(_ environment: Environment) { + userDefaultsService.environment = environment } func getDeviceToken() -> String { - return userDefaultService.deviceToken + return userDefaultsService.deviceToken } func setDeviceToken(token: String) { - userDefaultService.deviceToken = token + userDefaultsService.deviceToken = token + } + + func getSubscriberId() -> String { + userDefaultsService.subscriberHash } - func getSubsciberHash() -> String { - return userDefaultService.subscriberHash + func getSubscriberHash() -> String { + return userDefaultsService.subscriberHash } func getAppId() -> Int? { - return userDefaultService.appId + return userDefaultsService.appId } func setAppId(key: String) { - userDefaultService.siteKey = key + userDefaultsService.siteKey = key } - func startNotificationServices() { + func handleNotificationPermission() { guard let application = application else { - PELogger.debug(className: String(describing: PEViewModel.self), + PELogger.debug(className: String(describing: PEManager.self), message: "application is not available...") return } notificationService - .startRemoteNotificationService(for: application) + .handleNotificationPermission(for: application) } - func setIntialInfo(for application: UIApplication, + func setInitialInfo(for application: UIApplication, with launchOptions: [UIApplication.LaunchOptionsKey: Any]?) { self.application = application self.launchOptions = launchOptions @@ -293,7 +392,7 @@ class PEViewModel { Utility.loadWKWebView(with: url) } } else { - PELogger.debug(className: String(describing: PEViewModel.self), + PELogger.debug(className: String(describing: PEManager.self), message: "invalid URL..") } } @@ -302,10 +401,10 @@ class PEViewModel { /// prerequesite check for the api calls to happen for the developers /// - Parameter block: after prevalidation success case block will be called. @discardableResult - func prerequesiteNetworkCallCheck(block : () -> Void) -> PEError? { - let siteStatus = SiteStatus(rawValue: userDefaultService.siteStatus) - let permissionStatus = userDefaultService.notificationPermissionState - let subscriberDeletedStatus = userDefaultService.isSubscriberDeleted + private func prerequesiteNetworkCallCheck(block: () -> Void) -> PEError? { + let siteStatus = SiteStatus(rawValue: userDefaultsService.siteStatus) + let permissionStatus = userDefaultsService.notificationPermissionState + let subscriberDeletedStatus = userDefaultsService.isSubscriberDeleted if case .active = siteStatus, permissionStatus == .granted || permissionStatus == .denied, subscriberDeletedStatus == false { @@ -317,15 +416,15 @@ class PEViewModel { } func getDeviceHash() -> String { - return userDefaultService.subscriberHash + return userDefaultsService.subscriberHash } - func getNotificationPermissionStatus() -> PermissonStatus { - return userDefaultService.notificationPermissionState + func getNotificationPermissionStatus() -> PermissionStatus { + return userDefaultsService.notificationPermissionState } - func setNotificationPermissionStatus(status: PermissonStatus) { - userDefaultService.notificationPermissionState = status + func setNotificationPermissionStatus(status: PermissionStatus) { + userDefaultsService.notificationPermissionState = status } @@ -336,11 +435,20 @@ class PEViewModel { bestContentHandler: bestContentHandler) } - // MARK: - add Subsciber Attributes + // MARK: - add Subscriber Attributes + + func set(attributes: Parameters, completionHandler: ((_ response: Bool, _ error: PEError?) -> Void)?) { + let error = prerequesiteNetworkCallCheck { + subscriberService.setSubscriberAttributes(attributes: attributes, completionHandler: completionHandler) + } + if error != nil { + completionHandler?(false, error) + } + } func add(attributes: Parameters, completionHandler: ((_ response: Bool, _ error: PEError?) -> Void)?) { let error = prerequesiteNetworkCallCheck { - subscriberService.update(attributes: attributes, completionHandler: completionHandler) + subscriberService.addSubscriberAttributes(attributes: attributes, completionHandler: completionHandler) } if error != nil { completionHandler?(false, error) @@ -472,48 +580,56 @@ class PEViewModel { func getCustomUIPayLoad(for request: UNNotificationRequest) -> CustomUIModel { notificationExtensionService.getContentExtensionInfo(for: request) } + + deinit { + disposeBag.disposedValue() + Self.notificationOpenHandler = nil + Self.notificationWillShowInForeground = nil + self.removeObservers() + } + } // MARK: - Swizzling and manually setup methods. -extension PEViewModel { +extension PEManager { func registerDeviceToServer(with deviceToken: Data) { applicationService.registerDeviceToServer(with: deviceToken) } - func recivedRemoteNotification(application: UIApplication, + func receivedRemoteNotification(application: UIApplication, userInfo: [AnyHashable: Any], completionHandler: ((UIBackgroundFetchResult) -> Void)?) -> Bool { - applicationService.recivedRemoteNotification(application: application, + applicationService.receivedRemoteNotification(application: application, userInfo: userInfo, completionHandler: completionHandler) } - public func setNotificationOpenHandler(block: PEnotificationOpenHandler?) { + public func setNotificationOpenHandler(block: PENotificationOpenHandler?) { Self.notificationOpenHandler = block self.handleNotificationForUnprocessedEvent() } - public func setNotificationWillShowInForgroundHandler(block: PENotificationWillShowInForground?) { - Self.notificationWillShowInForground = block + public func setNotificationWillShowInForgroundHandler(block: PENotificationWillShowInForeground?) { + Self.notificationWillShowInForeground = block } - public func recivedNotification(with userInfo: [AnyHashable: Any], isOpened: Bool) { + public func receivedNotification(with userInfo: [AnyHashable: Any], isOpened: Bool) { guard Utility.isPEPayload(userInfo: userInfo) else { - PELogger.debug(className: String(describing: PEViewModel.self), + PELogger.debug(className: String(describing: PEManager.self), message: "Notification is not pushengage payload") return } - PELogger.debug(className: String(describing: PEViewModel.self), message: "\(isOpened)") - self.lastNotifyPayload = userInfo + PELogger.debug(className: String(describing: PEManager.self), message: "\(isOpened)") + self.lastNotificationPayload = userInfo if isOpened { let newNotifyId = Utility.checkForDuplicateProcess(infoDict: userInfo, - lastRecivedNotifyId: lastNonActiveNotifyRecivedId ?? "") + lastRecivedNotifyId: lastNonActiveNotificationReceivedId ?? "") if newNotifyId == PayloadConstants.duplicate { - PELogger.debug(className: String(describing: PEViewModel.self), message: "duplicate notifications.") + PELogger.debug(className: String(describing: PEManager.self), message: "duplicate notifications.") return } - lastNonActiveNotifyRecivedId = newNotifyId + lastNonActiveNotificationReceivedId = newNotifyId var type: ActionType = .opened if userInfo[userInfo: PayloadConstants .custom]?[userInfo: PayloadConstants @@ -524,7 +640,7 @@ extension PEViewModel { } } - public func handleWillPresentNotificationInForground(with payLoad: [AnyHashable: Any], + public func handleWillPresentNotificationInForeground(with payLoad: [AnyHashable: Any], completionHandler: @escaping PENotificationDisplayNotification) { if !Utility.isPEPayload(userInfo: payLoad) || application?.applicationState == .background { @@ -533,23 +649,23 @@ extension PEViewModel { let notification = PENotification(userInfo: payLoad) if notification.isSponsered == 1 { - self.handleWillShowInForgoundHandler(for: notification) { _ in + self.handleWillShowInForegoundHandler(for: notification) { _ in completionHandler(notification) } } else { - self.handleWillShowInForgoundHandler(for: notification, with: completionHandler) + self.handleWillShowInForegoundHandler(for: notification, with: completionHandler) } } - private func handleWillShowInForgoundHandler(for notification: PENotification, + private func handleWillShowInForegoundHandler(for notification: PENotification, with completionHandler: @escaping PENotificationDisplayNotification) { notification.setCompletion(for: completionHandler) - if Self.notificationWillShowInForground != nil { + if Self.notificationWillShowInForeground != nil { notification.timeOutTimerSetup() notification.startTimeoutTimer() let block = notification.getCompletionBlock() - Self.notificationWillShowInForground?(notification, block) + Self.notificationWillShowInForeground?(notification, block) } else { completionHandler(notification) } @@ -562,21 +678,21 @@ extension PEViewModel { private func handleNotificationOpened(_ customDict: [AnyHashable: Any], with actionType: ActionType) { let notifId = customDict[userInfo: PayloadConstants.custom]?[string: PayloadConstants.tag] ?? "" let appState = application?.applicationState == .active - PELogger.debug(className: String(describing: PEViewModel.self), + PELogger.debug(className: String(describing: PEManager.self), message: "notification opened for id \(notifId) and appstate is \(appState)") let launchURL = customDict[userInfo: PayloadConstants.custom]?[string: PayloadConstants.launchUrlKey] var actionId: String? if actionType == .taken { - actionId = customDict[userInfo:PayloadConstants - .custom]?[userInfo:PayloadConstants - .additionalData]?[string:PayloadConstants + actionId = customDict[userInfo: PayloadConstants + .custom]?[userInfo: PayloadConstants + .additionalData]?[string: PayloadConstants .actionSelected] } - self.lastNotifyPayload = customDict + self.lastNotificationPayload = customDict if actionId == .defaultActionIdentifer { - PELogger.debug(className: String(describing: PEViewModel.self), - message: "__DEFAUTL_ACTION__") + PELogger.debug(className: String(describing: PEManager.self), + message: "__DEFAULT_ACTION__") if let deepLink = customDict[userInfo: PayloadConstants.custom]?[string: PayloadConstants.deeplinking] { if deepLink.contains(NetworkConstants.https) || deepLink.contains(NetworkConstants.http) { self.onClickRedirect(to: deepLink) @@ -600,7 +716,7 @@ extension PEViewModel { private func handleNotificationAction(for actionType: ActionType, actionId: String?) { var clickedButton: String? - let notification = PENotification(userInfo: lastNotifyPayload ?? [:]) + let notification = PENotification(userInfo: lastNotificationPayload ?? [:]) if let buttons = notification.actionButtons, let id = actionId, notification.isSponsered == 0 { @@ -610,14 +726,14 @@ extension PEViewModel { } } notificationLifeCycleService.withRetrynotificationLifecycleUpdate(with: .clicked, - deviceHash: userDefaultService.subscriberHash, + deviceHash: userDefaultsService.subscriberHash, notificationId: notification.tag, actionid: clickedButton, completionHandler: nil) - if actionId == userDefaultService.sponseredIdKey , + if actionId == userDefaultsService.sponseredIdKey , notification.isSponsered == 1 { self.onClickRedirect(to: notification.launchURL) - PELogger.debug(className: String(describing: PEViewModel.self), + PELogger.debug(className: String(describing: PEManager.self), message: "Sponsered Notification.") return } @@ -625,10 +741,10 @@ extension PEViewModel { let actionCreated = PEnotificationAction(actionID: actionId, actionType: actionType) let notificationResult = PENotificationOpenResult(notification: notification, notficationAction: actionCreated) - if notification.tag == lastNotifyIdFromAction { + if notification.tag == lastNotificationIdFromAction { return } - lastNotifyIdFromAction = notification.tag + lastNotificationIdFromAction = notification.tag if Self.notificationOpenHandler == nil { self.addUnprocessedNotification(result: notificationResult) return @@ -647,7 +763,7 @@ extension PEViewModel { if Self.notificationOpenHandler == nil { return } - for value in unprocessedNotification ?? [] { + for value in unprocessedNotification ?? [] { Self.notificationOpenHandler?(value) } unprocessedNotification = [] @@ -674,20 +790,20 @@ extension PEViewModel { parseuserInfo[userInfo: PayloadConstants.custom]? .updateValue(identifier, forKey: PayloadConstants.additionalData) } - self.recivedNotification(with: parseuserInfo, isOpened: true) + self.receivedNotification(with: parseuserInfo, isOpened: true) } } // MARK: - LastNotificationSetDelagate -extension PEViewModel: LastNotificationSetDelagate { +extension PEManager: LastNotificationSetDelegate { func silentRemoteNotificationRecivedNotification(with userInfo: [AnyHashable: Any], isOpened: Bool) { - self.recivedNotification(with: userInfo, isOpened: true) + self.receivedNotification(with: userInfo, isOpened: true) } func setLast(notification infoDict: [AnyHashable: Any], completionHandler: ((UIBackgroundFetchResult) -> Void)?) { - self.lastNotifyPayload = infoDict + self.lastNotificationPayload = infoDict let notification = PENotification(userInfo: infoDict) if notification.contentAvailable == 1 && application?.applicationState == .background @@ -714,12 +830,12 @@ extension PEViewModel: LastNotificationSetDelagate { } } -extension PEViewModel { +extension PEManager { private func startTimerForSilentPush() { guard let unWrappedTimer = timer else { - PELogger.debug(className: String(describing: PEViewModel.self), + PELogger.debug(className: String(describing: PEManager.self), message: "Timer for silent push is nil") return } @@ -730,7 +846,7 @@ extension PEViewModel { if silentCompletionTask != nil { silentCompletionTask?(.noData) silentCompletionTask = nil - PELogger.debug(className: String(describing: PEViewModel.self), + PELogger.debug(className: String(describing: PEManager.self), message: "As developer didn't set the completion(UIBackgroundFetchResult) auto release has done.") } resetTimer() @@ -743,7 +859,7 @@ extension PEViewModel { private func getSilentNotificationTaskBlock() -> PEBackgroundTaskCompletionBlock? { let block = { [weak self] (result: UIBackgroundFetchResult) -> Void in self?.silentCompletionTask?(result) - PELogger.debug(className: String(describing: PEViewModel.self), + PELogger.debug(className: String(describing: PEManager.self), message: "Developer provided the completion()") self?.resetTimer() } @@ -762,16 +878,16 @@ extension PEViewModel { // MARK: - iOS 9 version work around. -extension PEViewModel { +extension PEManager { func update(notificationType: Int) { - PELogger.debug(className: String(describing: PEViewModel.self), + PELogger.debug(className: String(describing: PEManager.self), message: "For iOS version less then 9 is asked") self.notificationService.registerToApns(for: application) self.notificationService.onNotificationPromptResponse(notification: notificationType) } func updateSwizzledStatus(with status: Bool) { - userDefaultService.isSwizziled = status + userDefaultsService.isSwizzled = status } } diff --git a/PushEngage/Services/Managers/ApplicationService.swift b/PushEngage/Services/Managers/ApplicationService.swift index f7fb0f7..ec8ba04 100644 --- a/PushEngage/Services/Managers/ApplicationService.swift +++ b/PushEngage/Services/Managers/ApplicationService.swift @@ -9,25 +9,24 @@ import Foundation import UIKit import UserNotifications -protocol LastNotificationSetDelagate: AnyObject { +protocol LastNotificationSetDelegate: AnyObject { func setLast(notification infoDict: [AnyHashable: Any], completionHandler: ((UIBackgroundFetchResult) -> Void)?) func silentRemoteNotificationRecivedNotification(with userInfo: [AnyHashable: Any], isOpened: Bool) } -class ApplicationService: ApplicationProtocol { - - private var userDefault: UserDefaultProtocol - private let subscriberService: SubscriberService - private let notificationLifeCycleService: NotificationLifeCycleService - private let networkService: NetworkRouter +final class ApplicationService: ApplicationServiceType { + private var userDefault: UserDefaultsType + private let subscriberService: SubscriberServiceType + private let notificationLifeCycleService: NotificationLifeCycleServiceType + private let networkService: NetworkRouterType private let operationQueue: OperationQueue - weak var notifydelegate: LastNotificationSetDelagate? + weak var notifydelegate: LastNotificationSetDelegate? - init(userDefault: UserDefaultProtocol, - subscriberService: SubscriberService, - notificationLifeCycleService: NotificationLifeCycleService, - networkService: NetworkRouter) { + init(userDefault: UserDefaultsType, + subscriberService: SubscriberServiceType, + notificationLifeCycleService: NotificationLifeCycleServiceType, + networkService: NetworkRouterType) { self.userDefault = userDefault self.subscriberService = subscriberService self.notificationLifeCycleService = notificationLifeCycleService @@ -60,9 +59,9 @@ class ApplicationService: ApplicationProtocol { } } - func recivedRemoteNotification(application: UIApplication, - userInfo: [AnyHashable: Any], - completionHandler: ((UIBackgroundFetchResult) -> Void)?) -> Bool { + func receivedRemoteNotification(application: UIApplication, + userInfo: [AnyHashable: Any], + completionHandler: ((UIBackgroundFetchResult) -> Void)?) -> Bool { var backgroundJobFired = false let peNotification = PENotification(userInfo: userInfo) @@ -90,7 +89,7 @@ class ApplicationService: ApplicationProtocol { return backgroundJobFired } - @available(iOS, deprecated:9.0) + @available(iOS, deprecated: 9.0) private func notificationForiOS9(_ notification: PENotification) { let notification = Utility.createUILocalNotification(for: notification) UIApplication.shared.scheduleLocalNotification(notification) @@ -132,9 +131,9 @@ class ApplicationService: ApplicationProtocol { let content = UNMutableNotificationContent() content.sound = UNNotificationSound.default content.userInfo = notification.rawPayload - let sponseredInput: SponseredNotificationInput = (nil , - content , - self.notificationLifeCycleService , + let sponseredInput: SponseredNotificationInput = (nil, + content, + self.notificationLifeCycleService, self.networkService, notification) let sponserOperation = SponseredNotifictaionOperation(input: sponseredInput) diff --git a/PushEngage/Services/Managers/DataManager.swift b/PushEngage/Services/Managers/DataManager.swift index f1807d3..b375aa6 100644 --- a/PushEngage/Services/Managers/DataManager.swift +++ b/PushEngage/Services/Managers/DataManager.swift @@ -8,56 +8,53 @@ import Foundation import UIKit - -class DataManager: DataSourceProtocol { +/// `DataManager` class provides methods to retrieve subscription and subscriber details, as well as handling sponsored push notifications. +final class DataManager: DataSourceType { - var userDefault: UserDefaultProtocol + /// The UserDefaults manager responsible for handling data persistence. + private let userDefaults: UserDefaultsType - init(userDefault: UserDefaultProtocol) { - self.userDefault = userDefault + /// Initializes the `DataManager` with the provided `UserDefaultsType` instance. + /// - Parameter userDefault: An instance conforming to `UserDefaultsType` used for data storage and retrieval. + init(userDefault: UserDefaultsType) { + self.userDefaults = userDefault } func getSubscriptionData() -> SubscriptionInfo { - let locationCoordinates = userDefault.getObject(for: LocationCoordinates.self, - key: UserDefaultConstant.locationCoordinates) - let permisionStatus = userDefault.notificationPermissionState - let result = permisionStatus == .denied ? (userDefault.isDeleteSubscriberOnDisable ?? false ? 1 : 0) : nil + let permisionStatus = userDefaults.notificationPermissionState + let result = permisionStatus == .denied ? (userDefaults.isDeleteSubscriberOnDisable ?? false ? 1 : 0) : nil var env: String? - if let certEnv = UIApplication.shared.entitlements.value(forKey: .apsEnvironment) as? String { + if let certEnv = UIApplication.shared.entitlements.value(forKey: .apsEnvironment) as? String { if certEnv == "development" { env = "dev" } else if certEnv == "production" { env = "prod" } } - let subcriptionInfo = SubscriptionInfo(siteID: userDefault.appId, - subscription: Subscription(endpoint: userDefault.deviceToken, + let subscriptionInfo = SubscriptionInfo(siteID: userDefaults.appId, + subscription: Subscription(endpoint: userDefaults.deviceToken, projectID: Utility.getBundleIdentifier), deviceType: "ios", device: Utility.getDevice, deviceVersion: Utility.getOSInfo, deviceModel: Utility.getPhoneName, deviceManufacturer: "Apple", - latitude: String(format: "%.2f", - locationCoordinates?.latitude ?? 0), - longitude: String(format: "%.2f", - locationCoordinates?.longitude ?? 0), timezone: Utility.timeOffSet, language: Locale.current.languageCode, userAgent: "Apple \(Utility.getPhoneName)", - totalScrWidthHeight: Utility.totalScrWidthHeight, + totalScreenWidthHeight: Utility.totalScrWidthHeight, host: Utility.getBundleIdentifier, - profileID: userDefault.profileID, + profileID: userDefaults.profileID, isNotificationEnable: result, certEnv: env) - return subcriptionInfo + return subscriptionInfo } func getSubscriptionStatus() -> SubscriberDetails { - let status = SubscriberDetails(siteID: userDefault.appId, - deviceTokenHash: userDefault.subscriberHash) + let status = SubscriberDetails(siteID: userDefaults.appId, + deviceTokenHash: userDefaults.subscriberHash) return status } @@ -68,10 +65,10 @@ class DataManager: DataSourceProtocol { } func getSubsriberUpgradeData() -> SubscriberUpgrade { - let subscription = Subscription(endpoint: userDefault.deviceToken, + let subscription = Subscription(endpoint: userDefaults.deviceToken, projectID: Utility.getBundleIdentifier) - return SubscriberUpgrade(deviceTokenHash: userDefault.subscriberHash, + return SubscriberUpgrade(deviceTokenHash: userDefaults.subscriberHash, subscription: subscription, - siteId: userDefault.appId ?? -100) + siteId: userDefaults.appId ?? -100) } } diff --git a/PushEngage/Services/Managers/LocationManager.swift b/PushEngage/Services/Managers/LocationManager.swift deleted file mode 100644 index ba4529e..0000000 --- a/PushEngage/Services/Managers/LocationManager.swift +++ /dev/null @@ -1,79 +0,0 @@ -// -// LocationManager.swift -// PushEngage -// -// Created by Abhishek on 14/03/21. -// - -import Foundation -import CoreLocation - -struct LocationCoordinates: Codable { - - var latitude, longitude: Double - var error: LocationError? - - enum LocationError: String, Codable { - case failed - case denied - } -} - - -class LocationManager: NSObject, CLLocationManagerDelegate, LocationInfoProtocol { - - private var locationManager: CLLocationManager? - - var locationInfoObserver = Variable(nil) - - override init() { - super.init() - self.locationSetup() - } - - private func locationSetup() { - - if Utility.isLocationPrivcyEnabled { - locationManager = CLLocationManager() - locationManager?.delegate = self - locationManager?.desiredAccuracy = kCLLocationAccuracyBest - locationManager?.distanceFilter = CLLocationDistanceMax - } else { - PELogger.debug(className: String(describing: LocationManager.self), - message: "Location privacy is not enabled by host application.") - } - } - - func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) { - guard let last = locations.last else { - return - } - let locationCoordinates = LocationCoordinates(latitude: last.coordinate.latitude, - longitude: last.coordinate.longitude) - locationInfoObserver.value = locationCoordinates - - } - - func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) { - switch status { - case .authorizedAlways, .authorizedWhenInUse: - locationManager?.startUpdatingLocation() - PELogger.debug(className: String(describing: LocationManager.self), - message: "location services authorized.") - case .denied: - locationInfoObserver.value?.error = .denied - PELogger.debug(className: String(describing: LocationManager.self), - message: "Location services denied") - case .notDetermined, .restricted: - PELogger.debug(className: String(describing: LocationManager.self), - message: "Location services notDetermined") - @unknown default: - PELogger.debug(className: String(describing: LocationManager.self), - message: "unknown") - } - } - - func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) { - locationInfoObserver.value?.error = .failed - } -} diff --git a/PushEngage/Services/Managers/NotificationExtensionManager.swift b/PushEngage/Services/Managers/NotificationExtensionManager.swift index fc9cd6b..c9a036c 100644 --- a/PushEngage/Services/Managers/NotificationExtensionManager.swift +++ b/PushEngage/Services/Managers/NotificationExtensionManager.swift @@ -9,17 +9,16 @@ import Foundation import UserNotifications import UIKit - -class NotificationExtensionManager: NotificationExtensionProtocol { +final class NotificationExtensionManager: NotificationExtensionType { - var networkService: NetworkRouter - var notifcationLifeCycleService: NotificationLifeCycleService - var userDefaultDatasource: UserDefaultProtocol - private var operationQueue: OperationQueue + private let networkService: NetworkRouterType + private let notifcationLifeCycleService: NotificationLifeCycleServiceType + private let operationQueue: OperationQueue + private var userDefaultDatasource: UserDefaultsType - init(networkService: NetworkRouter, - notifcationLifeCycleService: NotificationLifeCycleService, - userDefaultDatasource: UserDefaultProtocol) { + init(networkService: NetworkRouterType, + notifcationLifeCycleService: NotificationLifeCycleServiceType, + userDefaultDatasource: UserDefaultsType) { self.networkService = networkService self.notifcationLifeCycleService = notifcationLifeCycleService self.userDefaultDatasource = userDefaultDatasource @@ -115,7 +114,7 @@ class NotificationExtensionManager: NotificationExtensionProtocol { image: images.first, buttons: buttons) } - // MARK: - upate badge count handler method implmentation + // MARK: - update badge count handler method implementation @available(iOS 10.0, *) private func updateBadgeCount(with notification: PENotification? , diff --git a/PushEngage/Services/Managers/NotificationLifeCycleManager.swift b/PushEngage/Services/Managers/NotificationLifeCycleManager.swift index 77af2c3..caef4fa 100644 --- a/PushEngage/Services/Managers/NotificationLifeCycleManager.swift +++ b/PushEngage/Services/Managers/NotificationLifeCycleManager.swift @@ -8,22 +8,21 @@ import Foundation import UIKit -class NotificationLifeCycleManager: NotificationLifeCycleService { +final class NotificationLifeCycleManager: NotificationLifeCycleServiceType { + private let networkRouter: NetworkRouterType + private let datasource: DataSourceType + private let userDefault: UserDefaultsType - let networkRouter: NetworkRouter - let datasource: DataSourceProtocol - let userDefault: UserDefaultProtocol - - init(networkRouter: NetworkRouter, - datasource: DataSourceProtocol, - userDefault: UserDefaultProtocol) { + init(networkRouter: NetworkRouterType, + datasource: DataSourceType, + userDefault: UserDefaultsType) { self.networkRouter = networkRouter self.datasource = datasource self.userDefault = userDefault } - func withRetrynotificationLifecycleUpdate(with action: NotificationLifeAction, + func withRetrynotificationLifecycleUpdate(with action: NotificationAction, deviceHash: String, notificationId: String, actionid: String?, @@ -66,7 +65,7 @@ class NotificationLifeCycleManager: NotificationLifeCycleService { completionHandler(.failure(error)) PELogger.logError(message: error.localizedDescription, name: .notificationRefetchFailed, - tag: sponseredData.tag, + tag: sponseredData.tag ?? "", subscriberHash: self?.userDefault.subscriberHash ?? "") background.end() @@ -75,7 +74,7 @@ class NotificationLifeCycleManager: NotificationLifeCycleService { } } - private func notificationLifecycleUpdate(with action: NotificationLifeAction, + private func notificationLifecycleUpdate(with action: NotificationAction, deviceHash: String, notificationId: String, actionid: String?, @@ -162,7 +161,7 @@ class NotificationLifeCycleManager: NotificationLifeCycleService { } } - func canceled() { + func cancelled() { networkRouter.cancel() } } diff --git a/PushEngage/Services/Managers/NotificationSettingsManageriOS10.swift b/PushEngage/Services/Managers/NotificationSettingsManageriOS10.swift index 05b2d35..5521c26 100644 --- a/PushEngage/Services/Managers/NotificationSettingsManageriOS10.swift +++ b/PushEngage/Services/Managers/NotificationSettingsManageriOS10.swift @@ -9,30 +9,25 @@ import UserNotifications import UIKit @available(iOS 10.0, *) -class NotificationSettingsManageriOS10: NotificationProtocol { - - // MARK: - private Enum. +final class NotificationSettingsManageriOS10: NotificationServiceType { private enum StartRemoteNotifyStatus { case isCalled case notCalled - case canCallForground + case canCallForeground } + + private (set) var notificationPermissionStatus = Variable(.notYetRequested) - // MARK: - private handler. - - private (set) var notificationPermissionStatus = Variable(.notYetRequested) - - // MARK: - private varibale. - - private var notificationDefault = NotificationCenter.default + // MARK: - Private varibles. + private let notificationDefault = NotificationCenter.default + private let serialQueue: DispatchQueue + private let nativeNotificattionInstance = UNUserNotificationCenter.current() private var useCachedState: Bool = false - private var serialQueue: DispatchQueue - private var nativeNotificatInstance = UNUserNotificationCenter.current() - private var userDefaultService: UserDefaultProtocol + private var userDefaultService: UserDefaultsType private var isStartNotificationCalled: StartRemoteNotifyStatus = .notCalled - init(userDefaultService: UserDefaultProtocol) { + init(userDefaultService: UserDefaultsType) { self.userDefaultService = userDefaultService self.serialQueue = DispatchQueue(label: "com.pushengage.notification.settings.iOS10") notificationDefault.addObserver(self, @@ -41,28 +36,23 @@ class NotificationSettingsManageriOS10: NotificationProtocol { object: nil) } - deinit { - notificationDefault.removeObserver(UIApplication.willEnterForegroundNotification) - } - - @objc func willEnterForeground() { + @objc private func willEnterForeground() { if isStartNotificationCalled == .isCalled { - isStartNotificationCalled = .canCallForground + isStartNotificationCalled = .canCallForeground } - if isStartNotificationCalled == .canCallForground { + if isStartNotificationCalled == .canCallForeground { checkPermissionStatus() } } - /// method provide the permission status Syncronysly. /// - Returns: enum PermissionStatus. - func getNotificationPermissionState() -> PermissonStatus { + func getNotificationPermissionState() -> PermissionStatus { if self.useCachedState { return self.notificationPermissionStatus.value } - var returnStatus: PermissonStatus = .notYetRequested + var returnStatus: PermissionStatus = .notYetRequested let semaphore = DispatchSemaphore(value: 0) serialQueue.sync { [weak self] in self?.getNotificationPermissionState { (status) in @@ -75,15 +65,15 @@ class NotificationSettingsManageriOS10: NotificationProtocol { } // provides the notification permission in completion block - func getNotificationPermissionState(completionHandler:@escaping ((PermissonStatus) -> Void)) { + func getNotificationPermissionState(completionHandler:@escaping ((PermissionStatus) -> Void)) { if self.useCachedState { completionHandler(self.notificationPermissionStatus.value) return } - var permission: PermissonStatus = .notYetRequested + var permission: PermissionStatus = .notYetRequested serialQueue.async { [weak self] in - self?.nativeNotificatInstance.getNotificationSettings { [weak self] (settings) in + self?.nativeNotificattionInstance.getNotificationSettings { [weak self] (settings) in switch settings.authorizationStatus { case .authorized: permission = .granted @@ -113,17 +103,17 @@ class NotificationSettingsManageriOS10: NotificationProtocol { } } let option: UNAuthorizationOptions = [.alert, .badge, .sound] - nativeNotificatInstance.requestAuthorization(options: option, completionHandler: responseBlock) + nativeNotificattionInstance.requestAuthorization(options: option, completionHandler: responseBlock) PELogger.debug(className: String(describing: NotificationSettingsManageriOS10.self), message: "promted Notification authorization request alert.") } - @discardableResult /// this method handled the senerio where our sdk goes as the update to the application /// that time we are trying to prompt the alert even if notification is already allowed so that /// our SDK also know the status of permission and register the user so this will be custom alert will be /// shown if func return response value as true. - private func checkPermissionStatus() -> (response: Bool, status: PermissonStatus) { + @discardableResult + private func checkPermissionStatus() -> (response: Bool, status: PermissionStatus) { let status = getNotificationPermissionState() switch status { case .denied, .granted: @@ -140,7 +130,7 @@ class NotificationSettingsManageriOS10: NotificationProtocol { } /// This method is responsible to start the remote notification services for the application - func startRemoteNotificationService(for application: UIApplication) { + func handleNotificationPermission(for application: UIApplication) { if isStartNotificationCalled == .notCalled { isStartNotificationCalled = .isCalled } @@ -164,7 +154,7 @@ class NotificationSettingsManageriOS10: NotificationProtocol { switch self?.notificationPermissionStatus.value { case .notYetRequested : self?.promptAuthorizationForNotification(with: application) { [weak self] response in - if self?.userDefaultService.isSwizziled == false { + if self?.userDefaultService.isSwizzled == false { self?.notificationPermissionStatus.value = response ? .granted : .denied } self?.registerToApns(for: application) @@ -201,7 +191,7 @@ class NotificationSettingsManageriOS10: NotificationProtocol { } /// Show the custom alert to the subcribers. - func showPermissionAlert(custom message: String, for permissionStatus: PermissonStatus) { + func showPermissionAlert(custom message: String, for permissionStatus: PermissionStatus) { let alert = UIAlertController(title: "\(Utility.getApplicationName) Would like to send you " + "Notifications", message: message, preferredStyle: .alert) let allowButton = UIAlertAction(title: "Allow", style: .default) { [weak self] _ in @@ -219,7 +209,7 @@ class NotificationSettingsManageriOS10: NotificationProtocol { // only available for iOS 10+ alert.addAction(self.settingsButton()) alert.title = "Notifications are not allowed" - alert.message = "please go to settings and enable the notifications permission." + alert.message = "Please go to Settings and enable the notification permission." alert.addAction(dismiss) } else { @@ -233,7 +223,7 @@ class NotificationSettingsManageriOS10: NotificationProtocol { } private func settingsButton() -> UIAlertAction { - return UIAlertAction(title: "settings", style: .default) { (_) in + return UIAlertAction(title: "Settings", style: .default) { (_) in guard let settingsUrl = URL(string: UIApplication.openSettingsURLString) else { return } @@ -245,4 +235,8 @@ class NotificationSettingsManageriOS10: NotificationProtocol { // hanlded for notificationSetting iOS 9. func onNotificationPromptResponse(notification type: Int) { } + + deinit { + notificationDefault.removeObserver(UIApplication.willEnterForegroundNotification) + } } diff --git a/PushEngage/Services/Managers/NotificationSettingsManageriOS9.swift b/PushEngage/Services/Managers/NotificationSettingsManageriOS9.swift index 06370a5..f8e9363 100644 --- a/PushEngage/Services/Managers/NotificationSettingsManageriOS9.swift +++ b/PushEngage/Services/Managers/NotificationSettingsManageriOS9.swift @@ -8,8 +8,8 @@ import Foundation import UIKit -@available(iOS, deprecated:9.0) -class NotificationSettingsManageriOS9: NotificationProtocol { +@available(iOS, deprecated: 9.0) +final class NotificationSettingsManageriOS9: NotificationServiceType { // MARK: - private Enum. @@ -21,7 +21,7 @@ class NotificationSettingsManageriOS9: NotificationProtocol { // MARK: - private handler. - private (set) var notificationPermissionStatus = Variable(.notYetRequested) + private (set) var notificationPermissionStatus = Variable(.notYetRequested) // MARK: - private static handler. @@ -33,11 +33,11 @@ class NotificationSettingsManageriOS9: NotificationProtocol { private var application: UIApplication? private let settings: UIUserNotificationSettings private var isStartNotificationCalled: StartRemoteNotifyStatus = .notCalled - private var userDefaultService: UserDefaultProtocol + private var userDefaultService: UserDefaultsType // MARK: - initialization - init(userDefaultService: UserDefaultProtocol) { + init(userDefaultService: UserDefaultsType) { self.settings = UIUserNotificationSettings(types: [.alert, .badge, .sound], categories: nil) self.userDefaultService = userDefaultService notificationDefault.addObserver(self, @@ -46,10 +46,6 @@ class NotificationSettingsManageriOS9: NotificationProtocol { object: nil) } - deinit { - notificationDefault.removeObserver(UIApplication.willEnterForegroundNotification) - } - @objc func willEnterForeground() { if isStartNotificationCalled == .isCalled { isStartNotificationCalled = .canCallForground @@ -61,7 +57,7 @@ class NotificationSettingsManageriOS9: NotificationProtocol { } @discardableResult - private func checkPermissionStatus() -> (response: Bool, status: PermissonStatus) { + private func checkPermissionStatus() -> (response: Bool, status: PermissionStatus) { let status = self.getNotificationPermissionState() switch status { case .denied, .granted: @@ -77,7 +73,7 @@ class NotificationSettingsManageriOS9: NotificationProtocol { } } - func startRemoteNotificationService(for application: UIApplication) { + func handleNotificationPermission(for application: UIApplication) { self.application = application if isStartNotificationCalled == .notCalled { isStartNotificationCalled = .isCalled @@ -96,7 +92,7 @@ class NotificationSettingsManageriOS9: NotificationProtocol { } switch self?.notificationPermissionStatus.value { - case .notYetRequested : + case .notYetRequested: self?.promptForNotification(application) { [weak self] (response: Bool) -> Void in self?.notificationPermissionStatus.value = response ? .granted : .denied self?.registerToApns(for: application) @@ -115,7 +111,7 @@ class NotificationSettingsManageriOS9: NotificationProtocol { } } - func getNotificationPermissionState() -> PermissonStatus { + func getNotificationPermissionState() -> PermissionStatus { if application?.currentUserNotificationSettings?.types.contains(.alert) == true { return .granted @@ -159,7 +155,7 @@ class NotificationSettingsManageriOS9: NotificationProtocol { Self.notifiationPromptResponseBlock = completionHandler } - func showPermissionAlert(custom message: String, for permissionStatus: PermissonStatus) { + func showPermissionAlert(custom message: String, for permissionStatus: PermissionStatus) { let alert = UIAlertController(title: "PushNotificationDemo would like to send you " + "Notifications", message: message, preferredStyle: .alert) let allowButton = UIAlertAction(title: "Allow", style: .default) { [weak self] _ in @@ -185,4 +181,9 @@ class NotificationSettingsManageriOS9: NotificationProtocol { .rootViewController?.present(alert, animated: true, completion: nil) } } + + deinit { + notificationDefault.removeObserver(UIApplication.willEnterForegroundNotification) + } + } diff --git a/PushEngage/Services/Managers/SubscriberServiceManager.swift b/PushEngage/Services/Managers/SubscriberServiceManager.swift index 0249074..a7f04e1 100644 --- a/PushEngage/Services/Managers/SubscriberServiceManager.swift +++ b/PushEngage/Services/Managers/SubscriberServiceManager.swift @@ -14,15 +14,14 @@ import UIKit case none } -class SubscriberServiceManager: SubscriberService { +final class SubscriberServiceManager: SubscriberServiceType { + private let datasourceProtocol: DataSourceType + private let networkRouter: NetworkRouterType + private var userDefault: UserDefaultsType - var datasourceProtocol: DataSourceProtocol - var networkRouter: NetworkRouter - var userDefault: UserDefaultProtocol - - init(datasourceProtocol: DataSourceProtocol, - networkRouter: NetworkRouter, - userDefault: UserDefaultProtocol) { + init(datasourceProtocol: DataSourceType, + networkRouter: NetworkRouterType, + userDefault: UserDefaultsType) { self.datasourceProtocol = datasourceProtocol self.networkRouter = networkRouter self.userDefault = userDefault @@ -33,6 +32,7 @@ class SubscriberServiceManager: SubscriberService { .isEuKey: userDefault.isGDPR, .geoFetch: userDefault.isLocationEnabled] } + func addSubscriber(completionHandler: ServiceCallBackObjects?) { let data = (object: datasourceProtocol.getSubscriptionData(), params: queryParms) @@ -66,7 +66,7 @@ class SubscriberServiceManager: SubscriberService { } } - func updateSubsciber(completionHandler: ServiceCallBackObjects?) { + func updateSubscriber(completionHandler: ServiceCallBackObjects?) { var data = datasourceProtocol.getSubscriptionData() data.subscription = nil let value = (userDefault.subscriberHash, data, queryParms) @@ -121,8 +121,8 @@ class SubscriberServiceManager: SubscriberService { case .success(let data): PELogger.debug(className: String(describing: SubscriberServiceManager.self), data: data) do { - let decodedObject = try JSONDecoder().decode(SubsciberDetailsResponse.self, from: data) - decodedObject.errorCode == 0 ? completionHandler?(decodedObject.data, nil) + let decodedObject = try JSONDecoder().decode(SubsciberDetailsResponse.self, from: data) + decodedObject.errorCode == 0 ? completionHandler?(decodedObject.data, nil) : completionHandler?(nil, .networkResponseFaliure(decodedObject.errorCode, decodedObject.errorMessage)) } catch { @@ -139,8 +139,30 @@ class SubscriberServiceManager: SubscriberService { } } - func update(attributes: Parameters, completionHandler: SubscriberBoolCallBack?) { - networkRouter.request(.subscriberAttribute((userDefault.subscriberHash, attributes))) { [weak self] (result) in + func setSubscriberAttributes(attributes: Parameters, completionHandler: SubscriberBoolCallBack?) { + networkRouter.request(.setSubscriberAttributes((userDefault.subscriberHash, attributes))) { [weak self] (result) in + switch result { + case .success(let data): + do { + let decodedData = try JSONDecoder().decode(NetworkResponse.self, from: data) + decodedData.error == nil && decodedData.errorCode == 0 ? + completionHandler?(true, nil) : + completionHandler?(false, PEError.networkResponseFaliure(decodedData.errorCode, + decodedData.errorMessage)) + } catch { + completionHandler?(false, PEError.parsingError) + } + case .failure(let error): + self?.retryFor404(error: error, completion: { result, error in + result ? self?.setSubscriberAttributes(attributes: attributes, completionHandler: completionHandler) + : completionHandler?(false, error) + }) + } + } + } + + func addSubscriberAttributes(attributes: Parameters, completionHandler: SubscriberBoolCallBack?) { + networkRouter.request(.addSubscriberAttributes((userDefault.subscriberHash, attributes))) { [weak self] (result) in switch result { case .success(let data): do { @@ -154,7 +176,7 @@ class SubscriberServiceManager: SubscriberService { } case .failure(let error): self?.retryFor404(error: error, completion: { result, error in - result ? self?.update(attributes: attributes, completionHandler: completionHandler) + result ? self?.addSubscriberAttributes(attributes: attributes, completionHandler: completionHandler) : completionHandler?(false, error) }) } @@ -162,7 +184,7 @@ class SubscriberServiceManager: SubscriberService { } func getAttribute(completionHandler: @escaping ServiceCallBack) { - networkRouter.request(.getSubsciberAttribute(userDefault.subscriberHash)) { [weak self] (result) in + networkRouter.request(.getSubscriberAttribute(userDefault.subscriberHash)) { [weak self] (result) in switch result { case .success(let data): do { @@ -564,13 +586,13 @@ extension SubscriberServiceManager { let siteStatus = SiteStatus(rawValue: userDefault.siteStatus) if siteStatus != .active { userDefault.isSubscriberDeleted = true - PELogger.debug(className: String(describing: SubscriberService.self), + PELogger.debug(className: String(describing: SubscriberServiceType.self), message: "site status is not active.") completion?(.stiteStatusNotActive) return } if userDefault.notificationPermissionState == .notYetRequested { - PELogger.debug(className: String(describing: SubscriberService.self), + PELogger.debug(className: String(describing: SubscriberServiceType.self), message: "permission is not determined.") completion?(.permissionNotDetermined) return @@ -595,7 +617,7 @@ extension SubscriberServiceManager { } } - func updateSettingPermission(status: PermissonStatus) { + func updateSettingPermission(status: PermissionStatus) { let dispatchGroup = DispatchGroup() dispatchGroup.enter() self.syncSiteInfo(for: userDefault.siteKey ?? "") { _, _ in diff --git a/PushEngage/Services/Managers/TriggerCampaignManager.swift b/PushEngage/Services/Managers/TriggerCampaignManager.swift index d9642e3..548a86f 100644 --- a/PushEngage/Services/Managers/TriggerCampaignManager.swift +++ b/PushEngage/Services/Managers/TriggerCampaignManager.swift @@ -7,7 +7,7 @@ import Foundation -class TriggerCampaignManager: TriggerCampaignProtocol { +final class TriggerCampaignManager: TriggerCampaignType { enum CampaignKeys: String { case title = "title" @@ -21,11 +21,11 @@ class TriggerCampaignManager: TriggerCampaignProtocol { case siteId = "site_id" } - let userDefaultService: UserDefaultProtocol - let networkService: NetworkRouter + private let userDefaultService: UserDefaultsType + private let networkService: NetworkRouterType - init(userDefaultService: UserDefaultProtocol, - networkService: NetworkRouter) { + init(userDefaultService: UserDefaultsType, + networkService: NetworkRouterType) { self.userDefaultService = userDefaultService self.networkService = networkService } diff --git a/PushEngage/Services/Managers/UserDefaultManager.swift b/PushEngage/Services/Managers/UserDefaultManager.swift index ce6695d..2802618 100644 --- a/PushEngage/Services/Managers/UserDefaultManager.swift +++ b/PushEngage/Services/Managers/UserDefaultManager.swift @@ -7,49 +7,55 @@ import Foundation - -class UserDefaultManager: UserDefaultProtocol { +class UserDefaultManager: UserDefaultsType { + + private let userDefaultSharedContainer: UserDefaults? = .shared - private let userDefaultSharedContainer: UserDefaults = .shared + var environment: Environment { + get { + Environment(rawValue: userDefaultSharedContainer?[.sdkEnvironment] ?? 1) ?? .production + } + set(value) { + userDefaultSharedContainer?[.sdkEnvironment] = (value == .production) ? 1 : 0 + } + } var badgeCount: Int? { get { - userDefaultSharedContainer[.badgeCount] + userDefaultSharedContainer?[.badgeCount] } set (value) { - userDefaultSharedContainer[.badgeCount] = value + userDefaultSharedContainer?[.badgeCount] = value } } var deviceToken: String { get { - userDefaultSharedContainer[.deviceToken] ?? "" + userDefaultSharedContainer?[.deviceToken] ?? "" } set (value) { - userDefaultSharedContainer[.deviceToken] = value + userDefaultSharedContainer?[.deviceToken] = value } } var subscriberHash: String { get { - userDefaultSharedContainer[.subscriberHash] ?? "" + userDefaultSharedContainer?[.subscriberHash] ?? "" } - set(value) { - userDefaultSharedContainer[.subscriberHash] = value + userDefaultSharedContainer?[.subscriberHash] = value } } - var notificationPermissionState: PermissonStatus { + var notificationPermissionState: PermissionStatus { get { - let rawValue = userDefaultSharedContainer[.permissionState] ?? "notYetRequested" - return PermissonStatus(rawValue: rawValue) ?? PermissonStatus.notYetRequested + let rawValue = userDefaultSharedContainer?[.permissionState] ?? "notYetRequested" + return PermissionStatus(rawValue: rawValue) ?? PermissionStatus.notYetRequested } - set (value) { - userDefaultSharedContainer[.permissionState] = value.rawValue + userDefaultSharedContainer?[.permissionState] = value.rawValue } } @@ -59,25 +65,25 @@ class UserDefaultManager: UserDefaultProtocol { var lastSmartSubscribeDate: Date? { get { - userDefaultSharedContainer[.lastSmartSubscribeDate] + userDefaultSharedContainer?[.lastSmartSubscribeDate] } set (value) { - userDefaultSharedContainer[.lastSmartSubscribeDate] = value + userDefaultSharedContainer?[.lastSmartSubscribeDate] = value } } var ispermissionAlerted: Bool { get { - userDefaultSharedContainer[.ispermissionAlerted] ?? false + userDefaultSharedContainer?[.ispermissionAlerted] ?? false } set (value) { - userDefaultSharedContainer[.ispermissionAlerted] = value + userDefaultSharedContainer?[.ispermissionAlerted] = value } } var profileID: String? { get { - userDefaultSharedContainer[.profileID] + userDefaultSharedContainer?[.profileID] } set (value) { - userDefaultSharedContainer[.profileID] = value + userDefaultSharedContainer?[.profileID] = value } } @@ -88,9 +94,9 @@ class UserDefaultManager: UserDefaultProtocol { var siteKey: String? { get { - userDefaultSharedContainer[.siteKey] + userDefaultSharedContainer?[.siteKey] } set { - userDefaultSharedContainer[.siteKey] = newValue + userDefaultSharedContainer?[.siteKey] = newValue } } @@ -106,11 +112,10 @@ class UserDefaultManager: UserDefaultProtocol { var isSubscriberDeleted: Bool { get { - userDefaultSharedContainer[.isSubscriberDeleted] ?? false + userDefaultSharedContainer?[.isSubscriberDeleted] ?? false } - set { - userDefaultSharedContainer[.isSubscriberDeleted] = newValue + userDefaultSharedContainer?[.isSubscriberDeleted] = newValue } } @@ -122,38 +127,35 @@ class UserDefaultManager: UserDefaultProtocol { var istriedFirstTime: Bool { get { - userDefaultSharedContainer[.istriedFirstTime] ?? false + userDefaultSharedContainer?[.istriedFirstTime] ?? false } set { - userDefaultSharedContainer[.istriedFirstTime] = newValue + userDefaultSharedContainer?[.istriedFirstTime] = newValue } } - func setsponseredID(id: String) { - userDefaultSharedContainer[.isSponseredIdKey] = id + userDefaultSharedContainer?[.isSponseredIdKey] = id } var sponseredIdKey: String? { - userDefaultSharedContainer[.isSponseredIdKey] + userDefaultSharedContainer?[.isSponseredIdKey] } - var isSwizziled: Bool { - + var isSwizzled: Bool { get { - userDefaultSharedContainer[.isSwizzled] ?? false + userDefaultSharedContainer?[.isSwizzled] ?? false } - set { - userDefaultSharedContainer[.isSwizzled] = newValue + userDefaultSharedContainer?[.isSwizzled] = newValue } } func save(object: T, for key: String) { do { let data = try JSONEncoder().encode(object) - userDefaultSharedContainer.setValue(data, forKey: key) + userDefaultSharedContainer?.setValue(data, forKey: key) } catch { PELogger.error(className: String(describing: UserDefaultManager.self), message: PEError.parsingError.errorDescription ?? "") @@ -161,7 +163,7 @@ class UserDefaultManager: UserDefaultProtocol { } func getObject(for typeof: T.Type, key: String) -> T? { - guard let data = userDefaultSharedContainer.data(forKey: key) else { + guard let data = userDefaultSharedContainer?.data(forKey: key) else { return nil } return Utility.decodeData(tyeof: T.self, data: data) diff --git a/PushEngage/Services/PEOperationQueue/AsyncResultOperation.swift b/PushEngage/Services/PEOperationQueue/AsyncResultOperation.swift index 9f4694b..1e3aaf1 100644 --- a/PushEngage/Services/PEOperationQueue/AsyncResultOperation.swift +++ b/PushEngage/Services/PEOperationQueue/AsyncResultOperation.swift @@ -47,8 +47,8 @@ extension AsyncResultOperation: ChainedOperationOutputProviding { return nil } switch failureError { - case .sponseredfailWithContent(let newValue): - return newValue + case .sponseredfailWithContent(var attachmentString?, let networkService): + return (attachmentString, networkService) default: return nil } diff --git a/PushEngage/Services/PEOperationQueue/PEOperations.swift b/PushEngage/Services/PEOperationQueue/PEOperations.swift index d4dba06..239166c 100644 --- a/PushEngage/Services/PEOperationQueue/PEOperations.swift +++ b/PushEngage/Services/PEOperationQueue/PEOperations.swift @@ -13,7 +13,7 @@ import UserNotifications @available(iOS 10.0, *) typealias DownloadOperationInput = (attachmentString: String?, contentToModifiy: UNMutableNotificationContent, - networkService: NetworkRouter) + networkService: NetworkRouterType) @available(iOS 10.0, *) final class DownloadAttachmentOperation: ChainedAsyncResultOperation { @@ -74,7 +74,7 @@ final class DownloadAttachmentOperation: ChainedAsyncResultOperation Void)?) -> Bool - var notifydelegate: LastNotificationSetDelagate? { get set } - -} - - diff --git a/PushEngage/Services/Protocols/ApplicationServiceType.swift b/PushEngage/Services/Protocols/ApplicationServiceType.swift new file mode 100644 index 0000000..88a0283 --- /dev/null +++ b/PushEngage/Services/Protocols/ApplicationServiceType.swift @@ -0,0 +1,19 @@ +// +// ApplicationProtocol.swift +// PushEngage +// +// Created by Abhishek on 03/02/21. +// + +import Foundation +import UIKit + +protocol ApplicationServiceType { + func registerDeviceToServer(with deviceToken: Data) + func receivedRemoteNotification(application: UIApplication, + userInfo: [AnyHashable: Any], + completionHandler: ((UIBackgroundFetchResult) -> Void)?) -> Bool + var notifydelegate: LastNotificationSetDelegate? { get set } +} + + diff --git a/PushEngage/Services/Protocols/DatasourceProtocol.swift b/PushEngage/Services/Protocols/DatasourceProtocol.swift index cf3bb6e..c69c424 100644 --- a/PushEngage/Services/Protocols/DatasourceProtocol.swift +++ b/PushEngage/Services/Protocols/DatasourceProtocol.swift @@ -7,10 +7,18 @@ import Foundation -protocol DataSourceProtocol { - +protocol DataSourceType { + /// Retrieves subscription data including device information and user preferences. + /// - Returns: A `SubscriptionInfo` object containing user subscription data and device details. func getSubscriptionData() -> SubscriptionInfo + /// Retrieves subscriber details such as site ID and device token hash. + /// - Returns: A `SubscriberDetails` object containing site ID and subscriber information. func getSubscriptionStatus() -> SubscriberDetails + /// Prepares sponsored push notification data for postback. + /// - Parameter notification: The `PENotification` object representing the received push notification. + /// - Returns: A `SponsoredPush` object containing tag and postback information for sponsored push. func getPostBackSubscriptionData(for notification: PENotification) -> SponsoredPush + /// Retrieves subscriber upgrade data including device token and site ID. + /// - Returns: A `SubscriberUpgrade` object containing device token hash, subscription details, and site ID. func getSubsriberUpgradeData() -> SubscriberUpgrade } diff --git a/PushEngage/Services/Protocols/LocationInfoProtocol.swift b/PushEngage/Services/Protocols/LocationInfoProtocol.swift deleted file mode 100644 index 928eacf..0000000 --- a/PushEngage/Services/Protocols/LocationInfoProtocol.swift +++ /dev/null @@ -1,12 +0,0 @@ -// -// LocationInfoProtocol.swift -// PushEngage -// -// Created by Abhishek on 15/03/21. -// - -import Foundation - -protocol LocationInfoProtocol { - var locationInfoObserver: Variable { get set } -} diff --git a/PushEngage/Services/Protocols/NotificationExtensionProtocol.swift b/PushEngage/Services/Protocols/NotificationExtensionType.swift similarity index 93% rename from PushEngage/Services/Protocols/NotificationExtensionProtocol.swift rename to PushEngage/Services/Protocols/NotificationExtensionType.swift index ec9677f..f5cafcf 100644 --- a/PushEngage/Services/Protocols/NotificationExtensionProtocol.swift +++ b/PushEngage/Services/Protocols/NotificationExtensionType.swift @@ -7,9 +7,7 @@ import UserNotifications - - -protocol NotificationExtensionProtocol { +protocol NotificationExtensionType { @available(iOS 10.0, *) func didReceiveNotificationExtensionRequest(_ request: UNNotificationRequest, diff --git a/PushEngage/Services/Protocols/NotificationLifeCycleService.swift b/PushEngage/Services/Protocols/NotificationLifeCycleServiceType.swift similarity index 90% rename from PushEngage/Services/Protocols/NotificationLifeCycleService.swift rename to PushEngage/Services/Protocols/NotificationLifeCycleServiceType.swift index 8801e9b..8ec58a4 100644 --- a/PushEngage/Services/Protocols/NotificationLifeCycleService.swift +++ b/PushEngage/Services/Protocols/NotificationLifeCycleServiceType.swift @@ -9,8 +9,8 @@ import Foundation typealias NotificationCallResponse = (Result) -> Void -protocol NotificationLifeCycleService { - func withRetrynotificationLifecycleUpdate(with action: NotificationLifeAction, +protocol NotificationLifeCycleServiceType { + func withRetrynotificationLifecycleUpdate(with action: NotificationAction, deviceHash: String, notificationId: String, actionid: String?, @@ -18,5 +18,5 @@ protocol NotificationLifeCycleService { func withRetrysponseredNotification(with notification: PENotification, completionHandler: @escaping NotificationCallResponse) - func canceled() + func cancelled() } diff --git a/PushEngage/Services/Protocols/NotificationProtocol.swift b/PushEngage/Services/Protocols/NotificationProtocol.swift deleted file mode 100644 index 2322c1b..0000000 --- a/PushEngage/Services/Protocols/NotificationProtocol.swift +++ /dev/null @@ -1,18 +0,0 @@ -// -// NotificationDataSource.swift -// PushEngage -// -// Created by Abhishek on 25/01/21. -// - -import Foundation -import UserNotifications -import UIKit - -protocol NotificationProtocol { - func startRemoteNotificationService(for application: UIApplication) - var notificationPermissionStatus: Variable { get } - func getNotificationPermissionState() -> PermissonStatus - func registerToApns(for application: UIApplication?) - func onNotificationPromptResponse(notification type: Int) -} diff --git a/PushEngage/Services/Protocols/NotificationServiceType.swift b/PushEngage/Services/Protocols/NotificationServiceType.swift new file mode 100644 index 0000000..e0ff60d --- /dev/null +++ b/PushEngage/Services/Protocols/NotificationServiceType.swift @@ -0,0 +1,18 @@ +// +// NotificationDataSource.swift +// PushEngage +// +// Created by Abhishek on 25/01/21. +// + +import Foundation +import UserNotifications +import UIKit + +protocol NotificationServiceType { + func handleNotificationPermission(for application: UIApplication) + func getNotificationPermissionState() -> PermissionStatus + func registerToApns(for application: UIApplication?) + func onNotificationPromptResponse(notification type: Int) + var notificationPermissionStatus: Variable { get } +} diff --git a/PushEngage/Services/Protocols/SubscriberService.swift b/PushEngage/Services/Protocols/SubscriberServiceType.swift similarity index 80% rename from PushEngage/Services/Protocols/SubscriberService.swift rename to PushEngage/Services/Protocols/SubscriberServiceType.swift index 45f6b8e..0e87ed0 100644 --- a/PushEngage/Services/Protocols/SubscriberService.swift +++ b/PushEngage/Services/Protocols/SubscriberServiceType.swift @@ -10,10 +10,11 @@ import Foundation typealias ServiceCallBack = (_ responseObject: Parameters?, _ error: PEError?) -> Void typealias SubscriberBoolCallBack = (_ : Bool, _ error: PEError?) -> Void typealias ServiceCallBackObjects = (_ response: T?, _ error: PEError?) -> Void -protocol SubscriberService { +protocol SubscriberServiceType { func addSubscriber(completionHandler: ServiceCallBackObjects?) func getSubscriber(for fields: [String]?, completionHandler: ServiceCallBackObjects?) - func update(attributes: Parameters, completionHandler: SubscriberBoolCallBack?) + func addSubscriberAttributes(attributes: Parameters, completionHandler: SubscriberBoolCallBack?) + func setSubscriberAttributes(attributes: Parameters, completionHandler: SubscriberBoolCallBack?) func getAttribute(completionHandler: @escaping ServiceCallBack) func updateSubscriberStatus(status: Int, completionHandler: SubscriberBoolCallBack?) func addProfile(id: String, completionHandler: SubscriberBoolCallBack?) @@ -24,10 +25,10 @@ protocol SubscriberService { func segmentHashArray(for segmentId: Int, completionHandler: SubscriberBoolCallBack?) func updateTrigger(status: Bool, completionHandler: SubscriberBoolCallBack?) func checkSubscriber(completionHandler: ServiceCallBackObjects?) - func updateSubsciber(completionHandler: ServiceCallBackObjects?) + func updateSubscriber(completionHandler: ServiceCallBackObjects?) func syncSiteInfo(for siteKey: String, completionHandler: ServiceCallBackObjects?) func retryAddSubscriberProcess(completion: ((PEError?) -> Void)?) - func updateSettingPermission(status: PermissonStatus) + func updateSettingPermission(status: PermissionStatus) } diff --git a/PushEngage/Services/Protocols/TriggerCampaignProtocol.swift b/PushEngage/Services/Protocols/TriggerCampaignType.swift similarity index 88% rename from PushEngage/Services/Protocols/TriggerCampaignProtocol.swift rename to PushEngage/Services/Protocols/TriggerCampaignType.swift index b835c49..e102f58 100644 --- a/PushEngage/Services/Protocols/TriggerCampaignProtocol.swift +++ b/PushEngage/Services/Protocols/TriggerCampaignType.swift @@ -9,6 +9,6 @@ import Foundation typealias TiggerWithBoolCallBack = (_ response: Bool) -> Void -protocol TriggerCampaignProtocol { +protocol TriggerCampaignType { func createCampaign(for tigger: TriggerCampaign, completionHandler: TiggerWithBoolCallBack?) } diff --git a/PushEngage/Services/Protocols/UserDefaultProtocol.swift b/PushEngage/Services/Protocols/UserDefaultsType.swift similarity index 83% rename from PushEngage/Services/Protocols/UserDefaultProtocol.swift rename to PushEngage/Services/Protocols/UserDefaultsType.swift index bd779fe..288e104 100644 --- a/PushEngage/Services/Protocols/UserDefaultProtocol.swift +++ b/PushEngage/Services/Protocols/UserDefaultsType.swift @@ -7,16 +7,16 @@ import Foundation -protocol UserDefaultProtocol { - +protocol UserDefaultsType { + func save(object: T, for key: String) + func getObject(for typeof: T.Type, key: String) -> T? + func setsponseredID(id: String) var deviceToken: String { get set } var subscriberHash: String { get set } - var notificationPermissionState: PermissonStatus { get set } + var notificationPermissionState: PermissionStatus { get set } var appId: Int? { get } var badgeCount: Int? { get set } var lastSmartSubscribeDate: Date? { get set } - func save(object: T, for key: String) - func getObject(for typeof: T.Type, key: String) -> T? var ispermissionAlerted: Bool { get set } var profileID: String? { get set } var siteStatus: String { get } @@ -27,6 +27,6 @@ protocol UserDefaultProtocol { var isDeleteSubscriberOnDisable: Bool? { get } var istriedFirstTime: Bool { get set } var sponseredIdKey: String? { get } - var isSwizziled: Bool { get set } - func setsponseredID(id: String) + var isSwizzled: Bool { get set } + var environment: Environment { get set } } diff --git a/PushEngage/SupportingFiles/Configuration.swift b/PushEngage/SupportingFiles/Configuration.swift index f8dc271..fe1b3dc 100644 --- a/PushEngage/SupportingFiles/Configuration.swift +++ b/PushEngage/SupportingFiles/Configuration.swift @@ -7,13 +7,9 @@ import Foundation -struct Configuration { - static var enviroment: Environment = .prod -} - @objc public enum Environment: Int { - case dev - case prod + case staging = 0 + case production = 1 } struct PENetworkURLs { @@ -26,8 +22,8 @@ struct PENetworkURLs { static let stagingTriggerURL = "https://x9dlvh1zcg.execute-api.us-east-1.amazonaws.com/beta/streams/staging-trigger/records" static let stagingBackendURL = "https://staging-dexter.pushengage.com/p/v1/" - static let stagingBackendCdnURL = "https://staging-dexter1.pushengage.com/p/v1/" - static let stagingNotifAnalyticURL = "https://staging-dexter1.pushengage.com/p/v1/" + static let stagingBackendCdnURL = "https://staging-dexter.pushengage.com/p/v1/" + static let stagingNotifAnalyticURL = "https://staging-dexter.pushengage.com/p/v1/" static let stagingLoggerURL = "https://cwlvm0dw8e.execute-api.us-east-1.amazonaws.com/staging/v1/" // not using currently for future. @@ -49,46 +45,51 @@ struct PENetworkURLs { static var backendCdnBaseURL: String { - switch Configuration.enviroment { - case .dev: + let userDefaults = DependencyInitialize.getUserDefaults() + switch userDefaults.environment { + case .staging: return syncapiObject?.api?.backendCloud ?? stagingBackendCdnURL - case .prod: + case .production: return syncapiObject?.api?.backendCloud ?? productionBackendCdnURL } } static var backendBaseURL: String { - switch Configuration.enviroment { - case .dev: + let userDefaults = DependencyInitialize.getUserDefaults() + switch userDefaults.environment { + case .staging: return syncapiObject?.api?.backend ?? stagingBackendURL - case .prod: + case .production: return syncapiObject?.api?.backend ?? productionBackendURL } } static var notifyAnalyticsBaseURL: String { - switch Configuration.enviroment { - case .dev: + let userDefaults = DependencyInitialize.getUserDefaults() + switch userDefaults.environment { + case .staging: return syncapiObject?.api?.analytics ?? stagingNotifAnalyticURL - case .prod: + case .production: return syncapiObject?.api?.analytics ?? productionNotifyAnalyticURL } } static var triggerBaseURL: String { - switch Configuration.enviroment { - case .dev: + let userDefaults = DependencyInitialize.getUserDefaults() + switch userDefaults.environment { + case .staging: return syncapiObject?.api?.trigger ?? stagingTriggerURL - case .prod: + case .production: return syncapiObject?.api?.trigger ?? productionTriggerURL } } static var loggingBaseURL: String { - switch Configuration.enviroment { - case .dev: + let userDefaults = DependencyInitialize.getUserDefaults() + switch userDefaults.environment { + case .staging: return syncapiObject?.api?.log ?? stagingLoggerURL - case .prod: + case .production: return syncapiObject?.api?.log ?? productionLoggingURL } } diff --git a/PushEngage/SupportingFiles/PushEngageAppdelegate.swift b/PushEngage/SupportingFiles/PushEngageAppdelegate.swift index d3efb1b..4f25855 100644 --- a/PushEngage/SupportingFiles/PushEngageAppdelegate.swift +++ b/PushEngage/SupportingFiles/PushEngageAppdelegate.swift @@ -9,11 +9,10 @@ import Foundation import UIKit /* - * This class is PushEngageAppdelegate which is swizzlied with the UIApplicationDelegate so that we can reduce the - * the integartion step for the SDK integration for the host application. + * This class is PushEngageAppdelegate which is swizzled with the UIApplicationDelegate so that + we can reduce the the integration steps for the host application. */ - // This class hooks into the UIApplicationDelegate selectors to receive iOS 9. // - UNUserNotificationCenter is used for iOS 10 // - Orignal implementations are called so other plugins and the developers AppDelegate is still called. @@ -27,7 +26,7 @@ class PushEngageAppDelegate: NSObject { // But rather in one of the subclasses private static var delegateSubclasses: [AnyClass]? - private static let viewModel = PushEngage.viewModel + private static let manager = PushEngage.manager private let selectorHelper = PESelectorHelper.shared @@ -39,10 +38,10 @@ class PushEngageAppDelegate: NSObject { @objc dynamic public func pushEngageSELTag() {} - /// this method selector do the first step by swizzlie the UIApplication + /// this method selector do the first step by swizzling the UIApplication /// Delegate selectors with the PushEngageAppDelegate selector. /// - Parameter delegate: provide the delegate - /// you want to swizzil the methods and as this is specifc designed for the UIApplicationDelegate only. + /// you want to swizzle the methods and as this is specifc designed for the UIApplicationDelegate only. @objc dynamic public func setPushEngageDelegate(_ delegate: UIApplicationDelegate) { PELogger.debug(className: String(describing: PushEngageAppDelegate.self), @@ -68,7 +67,7 @@ class PushEngageAppDelegate: NSObject { Self.delegateSubclasses ?? [], newClass, unWrappedDelegateClass) if Utility.lesserThaniOS(version: "10.0") { - self.swizzileMethodBeforeiOS10(delegate) + self.swizzleMethodBeforeiOS10(delegate) } // inject selector for pushEngageApplication(_:didRegisterForRemoteNotificationsWithDeviceToken:) @@ -103,42 +102,42 @@ class PushEngageAppDelegate: NSObject { /// And that time device gets device token from the APNS and we register to the PushEngage server. @objc dynamic private func pushEngageApplication(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) { - Self.viewModel.registerDeviceToServer(with: deviceToken) + Self.manager.registerDeviceToServer(with: deviceToken) if self.responds(to: #selector(pushEngageApplication(_:didRegisterForRemoteNotificationsWithDeviceToken:))) { pushEngageApplication(application, didRegisterForRemoteNotificationsWithDeviceToken: deviceToken) } } - /// Fires when a notication is opened or recieved while the app is in focus. + /// Fires when a notification is opened or received while the app is in focus. /// - Also fires when the app is in the background and a notificaiton with content-available=1 is received. @objc dynamic private func pushEngageApplication(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) { - let firedExisitingSelector = self.responds(to: + let firedExistingSelector = self.responds(to: #selector( pushEngageApplication(_:didReceiveRemoteNotification:fetchCompletionHandler:))) var initiateBackgroundtask = false - if Self.viewModel.getAppId() != nil { - let isAlertNotiification = userInfo[userInfo: "aps"]?[userInfo: "alert"] != nil + if Self.manager.getAppId() != nil { + let isAlertNotification = userInfo[userInfo: "aps"]?[userInfo: "alert"] != nil let appState = application.applicationState - if Utility.lesserThaniOS(version: "10.0") && appState == .inactive && isAlertNotiification { - Self.viewModel.recivedNotification(with: userInfo, isOpened: true) - } else if appState == .active && isAlertNotiification { - Self.viewModel.recivedNotification(with: userInfo, isOpened: false) + if Utility.lesserThaniOS(version: "10.0") && appState == .inactive && isAlertNotification { + Self.manager.receivedNotification(with: userInfo, isOpened: true) + } else if appState == .active && isAlertNotification { + Self.manager.receivedNotification(with: userInfo, isOpened: false) } else { - initiateBackgroundtask = Self.viewModel - .recivedRemoteNotification(application: application, + initiateBackgroundtask = Self.manager + .receivedRemoteNotification(application: application, userInfo: userInfo, completionHandler: - firedExisitingSelector ? nil : completionHandler) + firedExistingSelector ? nil : completionHandler) } } - if firedExisitingSelector { + if firedExistingSelector { self.pushEngageApplication(application, didReceiveRemoteNotification: userInfo, fetchCompletionHandler: completionHandler) @@ -151,8 +150,8 @@ class PushEngageAppDelegate: NSObject { } // Back work compatiblity - @available(iOS, deprecated:9.0) - func swizzileMethodBeforeiOS10(_ delegate: UIApplicationDelegate) { + @available(iOS, deprecated: 9.0) + func swizzleMethodBeforeiOS10(_ delegate: UIApplicationDelegate) { if Self.delegateClass == nil { PELogger.debug(className: String(describing: PushEngageAppDelegate.self), message: "delegate class is nil") @@ -174,12 +173,12 @@ class PushEngageAppDelegate: NSObject { } } - @available(iOS, deprecated:9.0) + @available(iOS, deprecated: 9.0) @objc dynamic func pushEngageLocalNotificationOpend(_ application: UIApplication, handleActionWithIdentifier identifier: String?, for notification: UILocalNotification, completionHandler: @escaping () -> Void) { - if Self.viewModel.getAppId() != nil { + if Self.manager.getAppId() != nil { self.operationForLocalActionBased(notification: notification, with: identifier ?? "") } @@ -193,7 +192,7 @@ class PushEngageAppDelegate: NSObject { completionHandler() } - @available(iOS, deprecated:9.0) + @available(iOS, deprecated: 9.0) private func operationForLocalActionBased(notification: UILocalNotification, with identifier: String) { @@ -205,7 +204,7 @@ class PushEngageAppDelegate: NSObject { .updateValue(identifier, forKey: "actionSelected") // let applicationStateisActive = UIApplication.shared.applicationState == .active - Self.viewModel.recivedNotification(with: userInfo, isOpened: true) + Self.manager.receivedNotification(with: userInfo, isOpened: true) // commented just because of the reference @@ -216,12 +215,12 @@ class PushEngageAppDelegate: NSObject { // implemented for the iOS 9 compatible notification settings - @available(iOS, deprecated:9.0) + @available(iOS, deprecated: 9.0) @objc dynamic func pushEngageDidRegisterUserNotifications(_ application: UIApplication, didRegister notificationSettings: UIUserNotificationSettings) { - if Self.viewModel.getAppId() != nil { - Self.viewModel.update(notificationType: Int(notificationSettings.types.rawValue)) + if Self.manager.getAppId() != nil { + Self.manager.update(notificationType: Int(notificationSettings.types.rawValue)) } if self.responds(to: #selector(pushEngageDidRegisterUserNotifications(_:didRegister:))) { @@ -229,7 +228,7 @@ class PushEngageAppDelegate: NSObject { } } - @available(iOS, deprecated:9.0) + @available(iOS, deprecated: 9.0) private func swizzleForiOS9(_ delegate: UIApplicationDelegate) { if Self.delegateClass == nil { PELogger.debug(className: String(describing: PushEngageAppDelegate.self), message: "delegate class is nil") @@ -249,10 +248,10 @@ class PushEngageAppDelegate: NSObject { } } - @available(iOS, deprecated:9.0) + @available(iOS, deprecated: 9.0) @objc dynamic func pushEngageLocalNotificationOpened(_ application: UIApplication, didReceive notification: UILocalNotification) { - if Self.viewModel.getAppId() != nil { + if Self.manager.getAppId() != nil { self.operationForLocalActionBased(notification: notification, with: "__DEFAULT__") } @@ -263,8 +262,8 @@ class PushEngageAppDelegate: NSObject { @objc dynamic func pushEngageReciveRemoteNotification(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any]) { - if Self.viewModel.getAppId() != nil { - Self.viewModel.recivedNotification(with: userInfo, isOpened: true) + if Self.manager.getAppId() != nil { + Self.manager.receivedNotification(with: userInfo, isOpened: true) } if self.responds(to: #selector(pushEngageReciveRemoteNotification(_:didReceiveRemoteNotification:))) { diff --git a/PushEngage/SupportingFiles/PushEngageUNUserNotificationCenter.swift b/PushEngage/SupportingFiles/PushEngageUNUserNotificationCenter.swift index 8163a6a..4ad2317 100644 --- a/PushEngage/SupportingFiles/PushEngageUNUserNotificationCenter.swift +++ b/PushEngage/SupportingFiles/PushEngageUNUserNotificationCenter.swift @@ -8,7 +8,7 @@ import UIKit import UserNotifications -// method Swizzling of UNUsernotificationCenterDelegate method for OS 10 + +// method Swizzling of UNUsernotificationCenterDelegate method for iOS 10+ class PEUNUserNotificationCenterDelegate: NSObject, UNUserNotificationCenterDelegate { static var singleInstance: PEUNUserNotificationCenterDelegate? @@ -61,7 +61,7 @@ class PushEngageUNUserNotificationCenter: NSObject { private static let selector = PESelectorHelper.shared - private static let viewModel = PushEngage.viewModel + private static let viewModel = PushEngage.manager private static var iOS10work = true @@ -220,7 +220,7 @@ class PushEngageUNUserNotificationCenter: NSObject { return } - Self.viewModel.handleWillPresentNotificationInForground(with: parseuserInfo) { [weak self] (responseNotification) in + Self.viewModel.handleWillPresentNotificationInForeground(with: parseuserInfo) { [weak self] (responseNotification) in let notifiyDisplayType = responseNotification != nil ? UNNotificationPresentationOptions(rawValue: 7) : UNNotificationPresentationOptions(rawValue: 0) self?.finishProcessingNotification(notification: notification, @@ -257,7 +257,7 @@ class PushEngageUNUserNotificationCenter: NSObject { instance: PushEngageUNUserNotificationCenter?) { let completionHandlerOptions = displayType if Self.viewModel.getAppId() != nil { - Self.viewModel.recivedNotification(with: notification.request.content.userInfo, isOpened: false) + Self.viewModel.receivedNotification(with: notification.request.content.userInfo, isOpened: false) } self.proceedNotificationWithCenter(center, notification: notification, pushEngageCenter: instance, @@ -294,7 +294,7 @@ class PushEngageUNUserNotificationCenter: NSObject { let isTextReply = response.isKind(of: classValue) let userText: String? = isTextReply ? response.value(forKey: "userText") as? String : nil self.oldAppDelegateSelector(notification: response.notification, - isTextReply: isTextReply , + isTextReply: isTextReply, actionIdentifier: response.actionIdentifier, userText: userText, fromPresentNotification: false, diff --git a/PushEngage/Utility/BackgroundTaskHandler.swift b/PushEngage/Utility/BackgroundTaskHandler.swift index e192bea..518bf69 100644 --- a/PushEngage/Utility/BackgroundTaskHandler.swift +++ b/PushEngage/Utility/BackgroundTaskHandler.swift @@ -8,7 +8,6 @@ import Foundation import UIKit - // This class is handling the Background task with expiration // of task when any task take place in the backgound mode diff --git a/PushEngage/Utility/PESelectorHelper.swift b/PushEngage/Utility/PESelectorHelper.swift index da34b16..5c3d11c 100644 --- a/PushEngage/Utility/PESelectorHelper.swift +++ b/PushEngage/Utility/PESelectorHelper.swift @@ -7,7 +7,7 @@ import Foundation -// Selector helpers are implemenated to provide the helper class to achive method swizzling. +// Selector helpers are implemenated to provide the helper class to achieve method swizzling. final class PESelectorHelper { @@ -89,10 +89,10 @@ final class PESelectorHelper { let methodTypeEncoding = String(cString: unWrappedTypeEncoding) // check weather the selector which you want your new selector work like. for the addToClass. - let isExisiting = class_getInstanceMethod(addToClass, makeLikeSel) != nil + let isExisting = class_getInstanceMethod(addToClass, makeLikeSel) != nil // if exist - if isExisiting { + if isExisting { // then add the method to the class with help of selector method impl and encoding. class_addMethod(addToClass, newSel, newMethodImplementation, methodTypeEncoding) guard let unWrappedInstanceMethod = class_getInstanceMethod(addToClass, newSel) else { @@ -111,7 +111,7 @@ final class PESelectorHelper { newMethodImplementation, methodTypeEncoding) } - return isExisiting + return isExisting } /// this method is combination of the checkIfClassInstanceOverridesSelector and diff --git a/PushEngage/Utility/Utility.swift b/PushEngage/Utility/Utility.swift index 4b767d5..75c4e8d 100644 --- a/PushEngage/Utility/Utility.swift +++ b/PushEngage/Utility/Utility.swift @@ -103,7 +103,7 @@ struct Utility { .main.object(forInfoDictionaryKey: InfoPlistConstants.pushEngageAppGroupKey) as? String { return appGroup } else { - return String(format: "group.%@.pushEngage", Utility.getBundleIdentifier) + return "" } } @@ -254,7 +254,7 @@ struct Utility { mutableAction.isAuthenticationRequired = false actionArray.append(mutableAction) // iOS 8 shows notification buttons in reverse in all cases but alerts. - // This flips it so the frist button is on the left. + // This flips it so the first button is on the left. if actionArray.count == 2 { category.setActions([actionArray[1], actionArray[0]], for: .minimal) } @@ -287,13 +287,16 @@ struct Utility { @available(iOS 10.0, *) static func createUNNotificationRequest(notification: PENotification, - networkService: NetworkRouter?) -> UNNotificationRequest? { + networkService: NetworkRouterType?) -> UNNotificationRequest? { let content = UNMutableNotificationContent() addButtonTo(withNotification: notification, content: content) content.title = notification.title ?? "" content.subtitle = notification.subtitle ?? "" content.body = notification.body ?? "" content.userInfo = notification.rawPayload + if let threadId = notification.threadId { + content.threadIdentifier = threadId + } if let sound = notification.sound { content.sound = UNNotificationSound(named: UNNotificationSoundName(sound)) } else { diff --git a/PushEngageNotificationExtension/Info.plist b/PushEngageNotificationExtension/Info.plist index 5361ede..3e5c004 100644 --- a/PushEngageNotificationExtension/Info.plist +++ b/PushEngageNotificationExtension/Info.plist @@ -2,6 +2,8 @@ + PushEngage_App_Group_Key + group.appGroup.test.com CFBundleDevelopmentRegion $(DEVELOPMENT_LANGUAGE) CFBundleDisplayName diff --git a/PushEngageObjcNotificationExtension/Info.plist b/PushEngageObjcNotificationExtension/Info.plist index 9795cd3..5b1b3fb 100644 --- a/PushEngageObjcNotificationExtension/Info.plist +++ b/PushEngageObjcNotificationExtension/Info.plist @@ -27,5 +27,7 @@ NSExtensionPrincipalClass NotificationService + PushEngage_App_Group_Key + group.app.com.pushengage.userDefaultS diff --git a/PushNotificationDemo/AppDelegate.swift b/PushNotificationDemo/AppDelegate.swift index d760301..2be10a6 100644 --- a/PushNotificationDemo/AppDelegate.swift +++ b/PushNotificationDemo/AppDelegate.swift @@ -8,40 +8,41 @@ import UIKit import UserNotifications import PushEngage -@main -// swiftlint:disable all +@main class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate { var window: UIWindow? - override init() { super.init() - // method Swizzing enable for the application. + // enable method swizzling for the application. PushEngage.swizzleInjection(isEnabled: true) } func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { - let storyboard = UIStoryboard(name: "Main", bundle: nil) - window = UIWindow() - self.window?.rootViewController = storyboard.instantiateInitialViewController() + self.window = UIWindow() + self.window?.rootViewController = UINavigationController(rootViewController: PushServiceTestSample()) self.window?.makeKeyAndVisible() if #available(iOSApplicationExtension 10.0, *) { UNUserNotificationCenter.current().delegate = self } - application.applicationIconBadgeNumber = 0 - PushEngage.setEnv(enviroment: .dev) - PushEngage.setAppId(key: "2d1b475e-cc73-42a1-8f13-58c944e3") - PushEngage.startNotificationServices(for: application, - with: launchOptions) + if #available(iOS 17, *) { + UNUserNotificationCenter.current().setBadgeCount(0) + } else { + application.applicationIconBadgeNumber = 0 + } - // Notification handler when notification deliver's and app is in foreground. + PushEngage.setEnvironment(environment: .staging) + PushEngage.setAppID(id: "3ca8257d-1f40-41e0-88bc-ea28dc6495ef") + PushEngage.setInitialInfo(for: application, + with: launchOptions) - PushEngage.setNotificationWillShowInForgroundHandler { notification, completion in + // Notification handler when notification delivers and app is in foreground. + PushEngage.setNotificationWillShowInForegroundHandler { notification, completion in if notification.contentAvailable == 1 { // in case developer failed to set completion handler. After 25 sec handler will call. completion(nil) @@ -77,13 +78,12 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD } // Silent notification Handler. - - PushEngage.silentPushHandler { notification , completion in + PushEngage.silentPushHandler {notification, completion in // in case developer failed to set completion handler. After 25 sec handler will call and set. completion?(.newData) } - PushEngage.enableLogs = true + PushEngage.enableLogging = true return true } @@ -92,17 +92,20 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD @available(iOSApplicationExtension 10.0, *) func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) { print("HOST implemented the notification didRecive notification.") -// PushEngage.didRecivedRemoteNotification(with: response) + // Uncomment below line if swizzling is not used + // PushEngage.didReceiveRemoteNotification(with: response) completionHandler() } func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) { print("HOST didRegisterForRemoteNotificationsWithDeviceToken is implemented device Token: -, \(deviceToken)") -// PushEngage.registerDeviceToServer(with: deviceToken) + // Uncomment below line if swizzling is not used + // PushEngage.registerDeviceToServer(with: deviceToken) } -// func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) { -// PushEngage.recivedRemoteNotification(application: application, userInfo: userInfo, completionHandler: completionHandler) -// } + func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) { + // Uncomment below line if swizzling is not used + // PushEngage.receivedRemoteNotification(application: application, userInfo: userInfo, completionHandler: completionHandler) + } } diff --git a/PushNotificationDemo/Assets.xcassets/AppIcon.appiconset/167.png b/PushNotificationDemo/Assets.xcassets/AppIcon.appiconset/167.png new file mode 100644 index 0000000..b55992e Binary files /dev/null and b/PushNotificationDemo/Assets.xcassets/AppIcon.appiconset/167.png differ diff --git a/PushNotificationDemo/Assets.xcassets/AppIcon.appiconset/76.png b/PushNotificationDemo/Assets.xcassets/AppIcon.appiconset/76.png new file mode 100644 index 0000000..d52a2ac Binary files /dev/null and b/PushNotificationDemo/Assets.xcassets/AppIcon.appiconset/76.png differ diff --git a/PushNotificationDemo/Assets.xcassets/AppIcon.appiconset/Contents.json b/PushNotificationDemo/Assets.xcassets/AppIcon.appiconset/Contents.json index 0b84e52..b460fb9 100644 --- a/PushNotificationDemo/Assets.xcassets/AppIcon.appiconset/Contents.json +++ b/PushNotificationDemo/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -1,111 +1,101 @@ { "images" : [ { - "filename" : "image.png", - "idiom" : "iphone", + "idiom" : "universal", + "platform" : "ios", "scale" : "2x", "size" : "20x20" }, { - "filename" : "image-1.png", - "idiom" : "iphone", + "idiom" : "universal", + "platform" : "ios", "scale" : "3x", "size" : "20x20" }, { - "filename" : "image-2.png", - "idiom" : "iphone", + "idiom" : "universal", + "platform" : "ios", "scale" : "2x", "size" : "29x29" }, { - "filename" : "image-3.png", - "idiom" : "iphone", + "idiom" : "universal", + "platform" : "ios", "scale" : "3x", "size" : "29x29" }, { - "filename" : "image-4.png", - "idiom" : "iphone", + "filename" : "76.png", + "idiom" : "universal", + "platform" : "ios", "scale" : "2x", - "size" : "40x40" + "size" : "38x38" }, { - "filename" : "image-5.png", - "idiom" : "iphone", + "idiom" : "universal", + "platform" : "ios", "scale" : "3x", - "size" : "40x40" + "size" : "38x38" }, { - "filename" : "image-6.png", - "idiom" : "iphone", + "idiom" : "universal", + "platform" : "ios", "scale" : "2x", - "size" : "60x60" + "size" : "40x40" }, { - "filename" : "image-7.png", - "idiom" : "iphone", + "idiom" : "universal", + "platform" : "ios", "scale" : "3x", - "size" : "60x60" - }, - { - "filename" : "image-15.png", - "idiom" : "ipad", - "scale" : "1x", - "size" : "20x20" + "size" : "40x40" }, { - "filename" : "image-14.png", - "idiom" : "ipad", + "idiom" : "universal", + "platform" : "ios", "scale" : "2x", - "size" : "20x20" + "size" : "60x60" }, { - "filename" : "image-16.png", - "idiom" : "ipad", - "scale" : "1x", - "size" : "29x29" + "idiom" : "universal", + "platform" : "ios", + "scale" : "3x", + "size" : "60x60" }, { - "filename" : "image-17.png", - "idiom" : "ipad", + "idiom" : "universal", + "platform" : "ios", "scale" : "2x", - "size" : "29x29" + "size" : "64x64" }, { - "filename" : "image-11.png", - "idiom" : "ipad", - "scale" : "1x", - "size" : "40x40" + "idiom" : "universal", + "platform" : "ios", + "scale" : "3x", + "size" : "64x64" }, { - "filename" : "image-10.png", - "idiom" : "ipad", + "idiom" : "universal", + "platform" : "ios", "scale" : "2x", - "size" : "40x40" - }, - { - "filename" : "image-9.png", - "idiom" : "ipad", - "scale" : "1x", - "size" : "76x76" + "size" : "68x68" }, { - "filename" : "image-12.png", - "idiom" : "ipad", + "idiom" : "universal", + "platform" : "ios", "scale" : "2x", "size" : "76x76" }, { - "filename" : "image-13.png", - "idiom" : "ipad", + "filename" : "167.png", + "idiom" : "universal", + "platform" : "ios", "scale" : "2x", "size" : "83.5x83.5" }, { - "filename" : "image-8.png", - "idiom" : "ios-marketing", - "scale" : "1x", + "filename" : "pe_icon.png", + "idiom" : "universal", + "platform" : "ios", "size" : "1024x1024" } ], diff --git a/PushNotificationDemo/Assets.xcassets/AppIcon.appiconset/image-1.png b/PushNotificationDemo/Assets.xcassets/AppIcon.appiconset/image-1.png deleted file mode 100644 index cd102c4..0000000 Binary files a/PushNotificationDemo/Assets.xcassets/AppIcon.appiconset/image-1.png and /dev/null differ diff --git a/PushNotificationDemo/Assets.xcassets/AppIcon.appiconset/image-10.png b/PushNotificationDemo/Assets.xcassets/AppIcon.appiconset/image-10.png deleted file mode 100644 index ea2c3a9..0000000 Binary files a/PushNotificationDemo/Assets.xcassets/AppIcon.appiconset/image-10.png and /dev/null differ diff --git a/PushNotificationDemo/Assets.xcassets/AppIcon.appiconset/image-11.png b/PushNotificationDemo/Assets.xcassets/AppIcon.appiconset/image-11.png deleted file mode 100644 index 31f79ef..0000000 Binary files a/PushNotificationDemo/Assets.xcassets/AppIcon.appiconset/image-11.png and /dev/null differ diff --git a/PushNotificationDemo/Assets.xcassets/AppIcon.appiconset/image-12.png b/PushNotificationDemo/Assets.xcassets/AppIcon.appiconset/image-12.png deleted file mode 100644 index 46e4b65..0000000 Binary files a/PushNotificationDemo/Assets.xcassets/AppIcon.appiconset/image-12.png and /dev/null differ diff --git a/PushNotificationDemo/Assets.xcassets/AppIcon.appiconset/image-13.png b/PushNotificationDemo/Assets.xcassets/AppIcon.appiconset/image-13.png deleted file mode 100644 index 93d33a7..0000000 Binary files a/PushNotificationDemo/Assets.xcassets/AppIcon.appiconset/image-13.png and /dev/null differ diff --git a/PushNotificationDemo/Assets.xcassets/AppIcon.appiconset/image-14.png b/PushNotificationDemo/Assets.xcassets/AppIcon.appiconset/image-14.png deleted file mode 100644 index 31f79ef..0000000 Binary files a/PushNotificationDemo/Assets.xcassets/AppIcon.appiconset/image-14.png and /dev/null differ diff --git a/PushNotificationDemo/Assets.xcassets/AppIcon.appiconset/image-15.png b/PushNotificationDemo/Assets.xcassets/AppIcon.appiconset/image-15.png deleted file mode 100644 index 96a188c..0000000 Binary files a/PushNotificationDemo/Assets.xcassets/AppIcon.appiconset/image-15.png and /dev/null differ diff --git a/PushNotificationDemo/Assets.xcassets/AppIcon.appiconset/image-16.png b/PushNotificationDemo/Assets.xcassets/AppIcon.appiconset/image-16.png deleted file mode 100644 index 9ebb741..0000000 Binary files a/PushNotificationDemo/Assets.xcassets/AppIcon.appiconset/image-16.png and /dev/null differ diff --git a/PushNotificationDemo/Assets.xcassets/AppIcon.appiconset/image-17.png b/PushNotificationDemo/Assets.xcassets/AppIcon.appiconset/image-17.png deleted file mode 100644 index 4e6f010..0000000 Binary files a/PushNotificationDemo/Assets.xcassets/AppIcon.appiconset/image-17.png and /dev/null differ diff --git a/PushNotificationDemo/Assets.xcassets/AppIcon.appiconset/image-2.png b/PushNotificationDemo/Assets.xcassets/AppIcon.appiconset/image-2.png deleted file mode 100644 index ae7ce57..0000000 Binary files a/PushNotificationDemo/Assets.xcassets/AppIcon.appiconset/image-2.png and /dev/null differ diff --git a/PushNotificationDemo/Assets.xcassets/AppIcon.appiconset/image-3.png b/PushNotificationDemo/Assets.xcassets/AppIcon.appiconset/image-3.png deleted file mode 100644 index f7e2e78..0000000 Binary files a/PushNotificationDemo/Assets.xcassets/AppIcon.appiconset/image-3.png and /dev/null differ diff --git a/PushNotificationDemo/Assets.xcassets/AppIcon.appiconset/image-4.png b/PushNotificationDemo/Assets.xcassets/AppIcon.appiconset/image-4.png deleted file mode 100644 index c9f7594..0000000 Binary files a/PushNotificationDemo/Assets.xcassets/AppIcon.appiconset/image-4.png and /dev/null differ diff --git a/PushNotificationDemo/Assets.xcassets/AppIcon.appiconset/image-5.png b/PushNotificationDemo/Assets.xcassets/AppIcon.appiconset/image-5.png deleted file mode 100644 index 630bfa2..0000000 Binary files a/PushNotificationDemo/Assets.xcassets/AppIcon.appiconset/image-5.png and /dev/null differ diff --git a/PushNotificationDemo/Assets.xcassets/AppIcon.appiconset/image-6.png b/PushNotificationDemo/Assets.xcassets/AppIcon.appiconset/image-6.png deleted file mode 100644 index 630bfa2..0000000 Binary files a/PushNotificationDemo/Assets.xcassets/AppIcon.appiconset/image-6.png and /dev/null differ diff --git a/PushNotificationDemo/Assets.xcassets/AppIcon.appiconset/image-7.png b/PushNotificationDemo/Assets.xcassets/AppIcon.appiconset/image-7.png deleted file mode 100644 index ecef3fb..0000000 Binary files a/PushNotificationDemo/Assets.xcassets/AppIcon.appiconset/image-7.png and /dev/null differ diff --git a/PushNotificationDemo/Assets.xcassets/AppIcon.appiconset/image-8.png b/PushNotificationDemo/Assets.xcassets/AppIcon.appiconset/image-8.png deleted file mode 100644 index e133a8c..0000000 Binary files a/PushNotificationDemo/Assets.xcassets/AppIcon.appiconset/image-8.png and /dev/null differ diff --git a/PushNotificationDemo/Assets.xcassets/AppIcon.appiconset/image-9.png b/PushNotificationDemo/Assets.xcassets/AppIcon.appiconset/image-9.png deleted file mode 100644 index 97ca39c..0000000 Binary files a/PushNotificationDemo/Assets.xcassets/AppIcon.appiconset/image-9.png and /dev/null differ diff --git a/PushNotificationDemo/Assets.xcassets/AppIcon.appiconset/image.png b/PushNotificationDemo/Assets.xcassets/AppIcon.appiconset/image.png deleted file mode 100644 index 03a691b..0000000 Binary files a/PushNotificationDemo/Assets.xcassets/AppIcon.appiconset/image.png and /dev/null differ diff --git a/PushNotificationDemo/Assets.xcassets/AppIcon.appiconset/pe_icon.png b/PushNotificationDemo/Assets.xcassets/AppIcon.appiconset/pe_icon.png new file mode 100644 index 0000000..d01a82b Binary files /dev/null and b/PushNotificationDemo/Assets.xcassets/AppIcon.appiconset/pe_icon.png differ diff --git a/PushNotificationDemo/Assets.xcassets/Logo.imageset/Contents.json b/PushNotificationDemo/Assets.xcassets/Logo.imageset/Contents.json deleted file mode 100644 index 7105162..0000000 --- a/PushNotificationDemo/Assets.xcassets/Logo.imageset/Contents.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "images" : [ - { - "filename" : "Logo.jpeg", - "idiom" : "universal", - "scale" : "1x" - }, - { - "idiom" : "universal", - "scale" : "2x" - }, - { - "idiom" : "universal", - "scale" : "3x" - } - ], - "info" : { - "author" : "xcode", - "version" : 1 - } -} diff --git a/PushNotificationDemo/Assets.xcassets/Logo.imageset/Logo.jpeg b/PushNotificationDemo/Assets.xcassets/Logo.imageset/Logo.jpeg deleted file mode 100644 index 0baef04..0000000 Binary files a/PushNotificationDemo/Assets.xcassets/Logo.imageset/Logo.jpeg and /dev/null differ diff --git a/PushNotificationDemo/Assets.xcassets/image.imageset/Contents.json b/PushNotificationDemo/Assets.xcassets/banner.imageset/Contents.json similarity index 61% rename from PushNotificationDemo/Assets.xcassets/image.imageset/Contents.json rename to PushNotificationDemo/Assets.xcassets/banner.imageset/Contents.json index 24c474e..2d35e94 100644 --- a/PushNotificationDemo/Assets.xcassets/image.imageset/Contents.json +++ b/PushNotificationDemo/Assets.xcassets/banner.imageset/Contents.json @@ -1,15 +1,17 @@ { "images" : [ { - "filename" : "image.png", + "filename" : "PushEngage-Logo-Future(2021).png", "idiom" : "universal", "scale" : "1x" }, { + "filename" : "PushEngage-Logo-Future(2021) 1.png", "idiom" : "universal", "scale" : "2x" }, { + "filename" : "PushEngage-Logo-Future(2021) 2.png", "idiom" : "universal", "scale" : "3x" } diff --git a/PushNotificationDemo/Assets.xcassets/banner.imageset/PushEngage-Logo-Future(2021) 1.png b/PushNotificationDemo/Assets.xcassets/banner.imageset/PushEngage-Logo-Future(2021) 1.png new file mode 100644 index 0000000..d07846d Binary files /dev/null and b/PushNotificationDemo/Assets.xcassets/banner.imageset/PushEngage-Logo-Future(2021) 1.png differ diff --git a/PushNotificationDemo/Assets.xcassets/banner.imageset/PushEngage-Logo-Future(2021) 2.png b/PushNotificationDemo/Assets.xcassets/banner.imageset/PushEngage-Logo-Future(2021) 2.png new file mode 100644 index 0000000..d07846d Binary files /dev/null and b/PushNotificationDemo/Assets.xcassets/banner.imageset/PushEngage-Logo-Future(2021) 2.png differ diff --git a/PushNotificationDemo/Assets.xcassets/banner.imageset/PushEngage-Logo-Future(2021).png b/PushNotificationDemo/Assets.xcassets/banner.imageset/PushEngage-Logo-Future(2021).png new file mode 100644 index 0000000..d07846d Binary files /dev/null and b/PushNotificationDemo/Assets.xcassets/banner.imageset/PushEngage-Logo-Future(2021).png differ diff --git a/PushNotificationDemo/Assets.xcassets/image.imageset/image.png b/PushNotificationDemo/Assets.xcassets/image.imageset/image.png deleted file mode 100644 index 236e776..0000000 Binary files a/PushNotificationDemo/Assets.xcassets/image.imageset/image.png and /dev/null differ diff --git a/PushNotificationDemo/Assets.xcassets/sport.imageset/Contents.json b/PushNotificationDemo/Assets.xcassets/sport.imageset/Contents.json index a991edf..2d35e94 100644 --- a/PushNotificationDemo/Assets.xcassets/sport.imageset/Contents.json +++ b/PushNotificationDemo/Assets.xcassets/sport.imageset/Contents.json @@ -1,15 +1,17 @@ { "images" : [ { - "filename" : "sport.jpeg", + "filename" : "PushEngage-Logo-Future(2021).png", "idiom" : "universal", "scale" : "1x" }, { + "filename" : "PushEngage-Logo-Future(2021) 1.png", "idiom" : "universal", "scale" : "2x" }, { + "filename" : "PushEngage-Logo-Future(2021) 2.png", "idiom" : "universal", "scale" : "3x" } diff --git a/PushNotificationDemo/Assets.xcassets/sport.imageset/PushEngage-Logo-Future(2021) 1.png b/PushNotificationDemo/Assets.xcassets/sport.imageset/PushEngage-Logo-Future(2021) 1.png new file mode 100644 index 0000000..d07846d Binary files /dev/null and b/PushNotificationDemo/Assets.xcassets/sport.imageset/PushEngage-Logo-Future(2021) 1.png differ diff --git a/PushNotificationDemo/Assets.xcassets/sport.imageset/PushEngage-Logo-Future(2021) 2.png b/PushNotificationDemo/Assets.xcassets/sport.imageset/PushEngage-Logo-Future(2021) 2.png new file mode 100644 index 0000000..d07846d Binary files /dev/null and b/PushNotificationDemo/Assets.xcassets/sport.imageset/PushEngage-Logo-Future(2021) 2.png differ diff --git a/PushNotificationDemo/Assets.xcassets/sport.imageset/PushEngage-Logo-Future(2021).png b/PushNotificationDemo/Assets.xcassets/sport.imageset/PushEngage-Logo-Future(2021).png new file mode 100644 index 0000000..d07846d Binary files /dev/null and b/PushNotificationDemo/Assets.xcassets/sport.imageset/PushEngage-Logo-Future(2021).png differ diff --git a/PushNotificationDemo/Assets.xcassets/sport.imageset/sport.jpeg b/PushNotificationDemo/Assets.xcassets/sport.imageset/sport.jpeg deleted file mode 100644 index 9cbca6f..0000000 Binary files a/PushNotificationDemo/Assets.xcassets/sport.imageset/sport.jpeg and /dev/null differ diff --git a/PushNotificationDemo/Base.lproj/LaunchScreen.storyboard b/PushNotificationDemo/Base.lproj/LaunchScreen.storyboard index 1b3b6d1..9382234 100644 --- a/PushNotificationDemo/Base.lproj/LaunchScreen.storyboard +++ b/PushNotificationDemo/Base.lproj/LaunchScreen.storyboard @@ -1,9 +1,9 @@ - + - + @@ -17,17 +17,19 @@ - - + + + + + + - - - - + + @@ -37,7 +39,7 @@ - + diff --git a/PushNotificationDemo/Info.plist b/PushNotificationDemo/Info.plist index c53aeed..fbf7a4c 100644 --- a/PushNotificationDemo/Info.plist +++ b/PushNotificationDemo/Info.plist @@ -11,7 +11,7 @@ CFBundleInfoDictionaryVersion 6.0 CFBundleName - $(PRODUCT_NAME) + PushEngage CFBundlePackageType $(PRODUCT_BUNDLE_PACKAGE_TYPE) CFBundleShortVersionString @@ -20,10 +20,6 @@ $(CURRENT_PROJECT_VERSION) LSRequiresIPhoneOS - NSLocationAlwaysAndWhenInUseUsageDescription - Need to access location - NSLocationWhenInUseUsageDescription - Need to access location PushEngageInAppEnabled PushEngage_App_Group_Key @@ -63,15 +59,13 @@ UISupportedInterfaceOrientations UIInterfaceOrientationPortrait - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight UISupportedInterfaceOrientations~ipad - UIInterfaceOrientationPortrait - UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown diff --git a/PushNotificationDemo/Main.storyboard b/PushNotificationDemo/Main.storyboard index 15c2dd5..a493fd6 100644 --- a/PushNotificationDemo/Main.storyboard +++ b/PushNotificationDemo/Main.storyboard @@ -1,8 +1,9 @@ - + - + + @@ -16,71 +17,101 @@ - - - - - - - - + + + + + + + + - + + - + + + + + + + + @@ -98,7 +129,7 @@ - + - - @@ -48,12 +60,16 @@ - + + + + + @@ -68,7 +84,7 @@ - + @@ -88,5 +104,8 @@ + + + diff --git a/File.swift b/PushNotificationObjcSample/File.swift similarity index 62% rename from File.swift rename to PushNotificationObjcSample/File.swift index c33ba37..6da0044 100644 --- a/File.swift +++ b/PushNotificationObjcSample/File.swift @@ -2,7 +2,7 @@ // File.swift // PushNotificationObjcSample // -// Created by Abhishek on 14/06/21. +// Created by Himshikhar Gayan on 16/11/23. // import Foundation diff --git a/PushNotificationObjcSample/Info.plist b/PushNotificationObjcSample/Info.plist index 521100b..c3468b6 100644 --- a/PushNotificationObjcSample/Info.plist +++ b/PushNotificationObjcSample/Info.plist @@ -20,6 +20,8 @@ 1 LSRequiresIPhoneOS + PushEngage_App_Group_Key + group.app.com.pushengage.userDefaultS UIApplicationSceneManifest UIApplicationSupportsMultipleScenes @@ -47,7 +49,7 @@ remote-notification UILaunchStoryboardName - LaunchScreen + LaunchScreen.storyboard UIMainStoryboardFile Main UIRequiredDeviceCapabilities @@ -57,15 +59,6 @@ UISupportedInterfaceOrientations UIInterfaceOrientationPortrait - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - UISupportedInterfaceOrientations~ipad - - UIInterfaceOrientationPortrait - UIInterfaceOrientationPortraitUpsideDown - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight diff --git a/PushNotificationObjcSample/ViewController.h b/PushNotificationObjcSample/ViewController.h index e3b86d6..8d4ede2 100644 --- a/PushNotificationObjcSample/ViewController.h +++ b/PushNotificationObjcSample/ViewController.h @@ -9,6 +9,7 @@ @interface ViewController : UIViewController +@property (weak, nonatomic) IBOutlet UIButton *requestPermissionButton; @property (strong, nonatomic) IBOutlet UITableView *tableView; @property (strong, nonatomic) IBOutlet UITextView *textView; typedef NS_ENUM(NSUInteger, ApiAction) { @@ -17,10 +18,11 @@ typedef NS_ENUM(NSUInteger, ApiAction) { addDynamicSegement, addAttribute, deleteAttribute, - trigger, +// trigger, addProfileId, getSubscriberDetails, - getAttribute + getAttribute, + setAttributes }; @end diff --git a/PushNotificationObjcSample/ViewController.m b/PushNotificationObjcSample/ViewController.m index 5c2495b..c064bb8 100644 --- a/PushNotificationObjcSample/ViewController.m +++ b/PushNotificationObjcSample/ViewController.m @@ -20,20 +20,28 @@ - (void)viewDidLoad { self.tableView.delegate = self; self.tableView.dataSource = self; self.navigationItem.title = @"PushEngage Demo"; - self.datalist = @[@"Add Segment", @"Remove segment",@"Add dynamic", - @"AddAttribute", @"Delete attribute",@"Trigger", @"add profileId", @"getSubscriberDetails", - @"getAttribute", @"check subscriber" ]; + self.datalist = @[@"Add Segment", + @"Remove segments", + @"Add Dynamic Segments", + @"Add Subscriber Attributes", + @"Delete Attributes", + @"Add Profile Id", + @"Get Subscriber Details", + @"Get Subscriber Attributes", + @"Set Subscriber Attributes" ]; self.textView.text = nil; self.textView.layer.borderWidth = 0.5; self.textView.layer.borderColor = UIColor.blackColor.CGColor; UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(dismiss:)]; tapGesture.cancelsTouchesInView = NO; [self.view addGestureRecognizer: tapGesture]; - UIBarButtonItem *button = [[UIBarButtonItem alloc] initWithTitle:@"next" - style:UIBarButtonItemStylePlain - target:self - action:@selector(nextView:)]; - self.navigationItem.rightBarButtonItem = button; + UITapGestureRecognizer *tapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(requestPermissionTapped:)]; + [self.requestPermissionButton addGestureRecognizer:tapGestureRecognizer]; +} + +- (void)requestPermissionTapped:(UITapGestureRecognizer *)sender { + [self.requestPermissionButton sendActionsForControlEvents:UIControlEventTouchUpInside]; + [PushEngage requestNotificationPermission]; } - (void) navigateToAddToCart { @@ -74,7 +82,7 @@ - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath completionHandler:^(BOOL response, NSError * _Nullable error) { dispatch_async(dispatch_get_main_queue(), ^{ if (response) { - blockSelf.textView.text = @"added attribute succesfully"; + blockSelf.textView.text = @"Attribute(s) updated for subscriber successfully"; } else { blockSelf.textView.text = [error debugDescription]; } @@ -84,11 +92,11 @@ - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath break; } case addSegment: { - [PushEngage addWithSegments:@[@"segmentTest1"] + [PushEngage addSegments:@[@"segmentTest1"] completionHandler:^(BOOL response, NSError * _Nullable error) { dispatch_async(dispatch_get_main_queue(), ^{ if (response) { - blockSelf.textView.text = @"added segment successfully"; + blockSelf.textView.text = @"Subscriber added to segment successfully"; } else { blockSelf.textView.text = [error debugDescription]; } @@ -98,7 +106,7 @@ - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath break; } case addDynamicSegement: { - [PushEngage addWithDynamic:@[@{@"name": @"dynamicOne" , + [PushEngage addDynamicSegments:@[@{@"name": @"dynamicOne" , @"duration": @10}, @{@"name" : @"segemt1", @"duration" : @20}, @@ -108,7 +116,7 @@ - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath dispatch_async(dispatch_get_main_queue(), ^{ if (response) { - blockSelf.textView.text = @"successfully added dynamic segment"; + blockSelf.textView.text = @"Subscriber added to the dynamic segment successfully"; } else { blockSelf.textView.text = [error debugDescription]; } @@ -119,11 +127,11 @@ - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath } case deleteAttribute: { - [PushEngage deleteAttributeWithValues:@[@"name"] + [PushEngage deleteSubscriberAttributesFor:@[@"name"] completionHandler:^(BOOL response, NSError * _Nullable error) { dispatch_async(dispatch_get_main_queue(), ^{ if (response) { - blockSelf.textView.text = @"deleted attribute successfull"; + blockSelf.textView.text = @"Attribute(s) deleted for subscriber successfully"; } else { blockSelf.textView.text = [error debugDescription]; } @@ -134,11 +142,11 @@ - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath } case removeSegment: { - [PushEngage removeWithSegments:@[@"segmentTest1"] + [PushEngage removeSegments:@[@"segmentTest1"] completionHandler:^(BOOL response, NSError * _Nullable error) { dispatch_async(dispatch_get_main_queue(), ^{ if (response) { - blockSelf.textView.text = @"Segment added successfully"; + blockSelf.textView.text = @"Subscriber removed from the segment(s)"; } else { blockSelf.textView.text = [error debugDescription]; } @@ -148,20 +156,20 @@ - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath break; } - case trigger: { - [PushEngage updateTriggerWithStatus: NO - completionHandler:^(BOOL response, NSError * _Nullable error) { - dispatch_async(dispatch_get_main_queue(), ^{ - if (response) { - blockSelf.textView.text = @"added trigger successfully"; - } else { - blockSelf.textView.text = [error debugDescription]; - } - blockSelf = nil; - }); - }]; - break; - } +// case trigger: { +// [PushEngage updateTriggerWithStatus: NO +// completionHandler:^(BOOL response, NSError * _Nullable error) { +// dispatch_async(dispatch_get_main_queue(), ^{ +// if (response) { +// blockSelf.textView.text = @"added trigger successfully"; +// } else { +// blockSelf.textView.text = [error debugDescription]; +// } +// blockSelf = nil; +// }); +// }]; +// break; +// } case addProfileId: { [PushEngage addProfileFor: @"abhishekkumarthakur@gmail.com" @@ -182,26 +190,52 @@ - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath [PushEngage getSubscriberDetailsFor: @[@"country"] completionHandler:^(SubscriberDetailsData * _Nullable response, NSError * _Nullable error) { + dispatch_async(dispatch_get_main_queue(), ^{ + if (response) { + NSString *responseString = [NSString stringWithFormat:@"device: %@, user_agent: %@, country: %@, ts_created: %@, state: %@, city: %@, host: %@, device_type: %@, timezone: %@, segments: %@", + response.device ?: @"(null)", + response.userAgent ?: @"(null)", + response.country ?: @"(null)", + response.tsCreated ?: @"(null)", + response.state ?: @"(null)", + response.city ?: @"(null)", + response.host ?: @"(null)", + response.deviceType ?: @"(null)", + response.timezone ?: @"(null)", + [response.segments componentsJoinedByString:@", "] ?: @"(null)"]; + + self.textView.text = responseString; + } else { + self.textView.text = error.localizedDescription; + } + blockSelf = nil; + }); + }]; + break; + } + + case getAttribute: { + [PushEngage getSubscriberAttributesWithCompletionHandler:^(NSDictionary * _Nullable response, + NSError * _Nullable error) { dispatch_async(dispatch_get_main_queue(), ^{ if (response) { blockSelf.textView.text = [response description]; } else { - blockSelf.textView.text = @"error to get subscription details"; + NSLog(@"error message %@", error); } blockSelf = nil; }); }]; break; } - - case getAttribute: { - [PushEngage getAttributeWithCompletionHandler:^(NSDictionary * _Nullable response, - NSError * _Nullable error) { + case setAttributes: { + [PushEngage setWithAttributes:@{@"gender" : @"male"} + completionHandler:^(BOOL response, NSError * _Nullable error) { dispatch_async(dispatch_get_main_queue(), ^{ if (response) { - blockSelf.textView.text = [response description]; + blockSelf.textView.text = @"Attribute(s) set for subscriber successfully"; } else { - NSLog(@"error message %@", error); + blockSelf.textView.text = [error debugDescription]; } blockSelf = nil; }); diff --git a/README.md b/README.md index e455a9f..dc4c985 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,10 @@

- +

### PushEngage iOS SDK --- -|pod | v0.0.1 +|pod | v0.0.2 |--- |--- | [PushEngage](https://www.pushengage.com/) now providing Mobile push notification so that your Application can interact with your Subscriber with Rich Notification (_iOS 10+_). So that your application can gain more traffic. And you can send Urgent notifications with images, badges, custom sound, deep linking , etc features along with that you can track view can click of the notifications for you anylatics from our **PushEngage** dashboard. @@ -13,12 +13,12 @@ ## Supports for Languages -Our SDK support **Swift** as well as **Objective-c** both native iOS Application Language. +Our SDK supports **Swift** as well as **Objective-C** which are both native iOS Application Languages. ## Platform -Our SDK supports from iOS 9 to above. +Our SDK supports from iOS 9 and above **Note :-** Rich Notifications are available only Supported from iOS 10+. for iOS 9 some feature will not be available. @@ -32,16 +32,16 @@ Our SDK supports from iOS 9 to above.

*** -## Installation Guide. +## Installation Guide -Please flow the instructions as mentioned in the [Installation Guide Documentation]() +Please follow the instructions as mentioned in the [Installation Guide Documentation]() ## APNS Certificate Creation for Push notification. -please flow the instructions as mentioned in the [APNS certificate creation Guide.]() +Please follow the instructions as mentioned in the [APNS certificate creation Guide.]() ## iOS SDK public APIs information link. -please flow the instructions as mentioned in the [PushEngage iOS Public APIs]() +Please follow the instructions as mentioned in the [PushEngage iOS Public APIs]()