diff --git a/PpgCoreSDK.podspec b/PpgCoreSDK.podspec index c89ecf8..8e50ff4 100644 --- a/PpgCoreSDK.podspec +++ b/PpgCoreSDK.podspec @@ -16,7 +16,7 @@ Pod::Spec.new do |spec| # spec.name = "PpgCoreSDK" - spec.version = "0.0.8" + spec.version = "0.0.9" spec.summary = "PushPushGo Core SDK" # This description is used to generate tags and improve search results. diff --git a/PpgCoreSDK.xcodeproj/project.pbxproj b/PpgCoreSDK.xcodeproj/project.pbxproj index a2a9c16..80d9357 100644 --- a/PpgCoreSDK.xcodeproj/project.pbxproj +++ b/PpgCoreSDK.xcodeproj/project.pbxproj @@ -7,6 +7,8 @@ objects = { /* Begin PBXBuildFile section */ + 460B69762A38AE3800FE1D07 /* NotificationChannel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 460B69752A38AE3800FE1D07 /* NotificationChannel.swift */; }; + 460B69782A38B60000FE1D07 /* NotificationAction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 460B69772A38B60000FE1D07 /* NotificationAction.swift */; }; 464698DE2A16665700AD81FD /* PpgCoreConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = 464698DD2A16665700AD81FD /* PpgCoreConfig.swift */; }; 465FEA8D29D58A4400C85F94 /* EventService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 465FEA8B29D58A4400C85F94 /* EventService.swift */; }; 465FEA8E29D58A4400C85F94 /* PpgCoreClient.swift in Sources */ = {isa = PBXBuildFile; fileRef = 465FEA8C29D58A4400C85F94 /* PpgCoreClient.swift */; }; @@ -41,13 +43,15 @@ /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ - 464698DD2A16665700AD81FD /* PpgCoreConfig.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PpgCoreConfig.swift; sourceTree = ""; }; + 460B69752A38AE3800FE1D07 /* NotificationChannel.swift */ = {isa = PBXFileReference; indentWidth = 4; lastKnownFileType = sourcecode.swift; path = NotificationChannel.swift; sourceTree = ""; tabWidth = 4; }; + 460B69772A38B60000FE1D07 /* NotificationAction.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationAction.swift; sourceTree = ""; }; + 464698DD2A16665700AD81FD /* PpgCoreConfig.swift */ = {isa = PBXFileReference; indentWidth = 4; lastKnownFileType = sourcecode.swift; path = PpgCoreConfig.swift; sourceTree = ""; tabWidth = 4; }; 465FEA8B29D58A4400C85F94 /* EventService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EventService.swift; sourceTree = ""; }; 465FEA8C29D58A4400C85F94 /* PpgCoreClient.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PpgCoreClient.swift; sourceTree = ""; }; 465FEA9129D58A5700C85F94 /* Data.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Data.swift; sourceTree = ""; }; 465FEA9229D58A5700C85F94 /* UNNotificationAttachment.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UNNotificationAttachment.swift; sourceTree = ""; }; 465FEA9329D58A5700C85F94 /* TemporaryImage.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TemporaryImage.swift; sourceTree = ""; }; - 465FEA9729D58A6400C85F94 /* DataNotification.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DataNotification.swift; sourceTree = ""; }; + 465FEA9729D58A6400C85F94 /* DataNotification.swift */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 4; lastKnownFileType = sourcecode.swift; path = DataNotification.swift; sourceTree = ""; tabWidth = 4; }; 465FEA9829D58A6400C85F94 /* NotificationDelivered.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NotificationDelivered.swift; sourceTree = ""; }; 465FEA9929D58A6400C85F94 /* NotificationClosed.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NotificationClosed.swift; sourceTree = ""; }; 465FEA9A29D58A6400C85F94 /* NotificationClicked.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NotificationClicked.swift; sourceTree = ""; }; @@ -61,7 +65,7 @@ 46CB7CA129D322E400D1E118 /* PpgCoreSDK.docc */ = {isa = PBXFileReference; lastKnownFileType = folder.documentationcatalog; path = PpgCoreSDK.docc; sourceTree = ""; }; 46CB7CA729D322E400D1E118 /* PpgCoreSDKTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = PpgCoreSDKTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 46CB7CAC29D322E400D1E118 /* PpgCoreSDKTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PpgCoreSDKTest.swift; sourceTree = ""; }; - 46EF4EA32A15271000C5054A /* PpgCoreNotificationServiceExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PpgCoreNotificationServiceExtension.swift; sourceTree = ""; }; + 46EF4EA32A15271000C5054A /* PpgCoreNotificationServiceExtension.swift */ = {isa = PBXFileReference; indentWidth = 4; lastKnownFileType = sourcecode.swift; path = PpgCoreNotificationServiceExtension.swift; sourceTree = ""; tabWidth = 4; }; 46EF4EA52A15288E00C5054A /* NotificationFactory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationFactory.swift; sourceTree = ""; }; /* End PBXFileReference section */ @@ -115,6 +119,8 @@ 465FEA9C29D58A6400C85F94 /* Subscription.swift */, 465FEA9729D58A6400C85F94 /* DataNotification.swift */, 465FEA9B29D58A6400C85F94 /* SilentNotification.swift */, + 460B69752A38AE3800FE1D07 /* NotificationChannel.swift */, + 460B69772A38B60000FE1D07 /* NotificationAction.swift */, ); path = Models; sourceTree = ""; @@ -279,7 +285,9 @@ files = ( 465FEACA29D5939400C85F94 /* LocalNotifcationService.swift in Sources */, 465FEA9E29D58A6400C85F94 /* DataNotification.swift in Sources */, + 460B69762A38AE3800FE1D07 /* NotificationChannel.swift in Sources */, 465FEA8D29D58A4400C85F94 /* EventService.swift in Sources */, + 460B69782A38B60000FE1D07 /* NotificationAction.swift in Sources */, 465FEAA129D58A6400C85F94 /* NotificationClicked.swift in Sources */, 465FEA9429D58A5700C85F94 /* Data.swift in Sources */, 465FEAA329D58A6400C85F94 /* Subscription.swift in Sources */, diff --git a/PpgCoreSDK.xcodeproj/project.xcworkspace/xcuserdata/worotyns.xcuserdatad/UserInterfaceState.xcuserstate b/PpgCoreSDK.xcodeproj/project.xcworkspace/xcuserdata/worotyns.xcuserdatad/UserInterfaceState.xcuserstate index d253026..a787533 100644 Binary files a/PpgCoreSDK.xcodeproj/project.xcworkspace/xcuserdata/worotyns.xcuserdatad/UserInterfaceState.xcuserstate and b/PpgCoreSDK.xcodeproj/project.xcworkspace/xcuserdata/worotyns.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/PpgCoreSDK/Models/DataNotification.swift b/PpgCoreSDK/Models/DataNotification.swift index 937976e..770e577 100644 --- a/PpgCoreSDK/Models/DataNotification.swift +++ b/PpgCoreSDK/Models/DataNotification.swift @@ -8,27 +8,10 @@ import Foundation import UserNotifications -struct NotificationAction: Codable { - let icon: String - let action: String - let title: String - let url: String - - static func fromJson(json: Data) -> [NotificationAction] { - let decoder = JSONDecoder() - - guard let deserialized = try? decoder.decode([NotificationAction].self, from: json) else { - fatalError("Failed to decode notification action from JSON") - } - - return deserialized - } -} - struct DataNotification: Notification { var contextId: UUID var messageId: UUID - var sound: UNNotificationSound? + var channelName: String var foreignId: String? var actions: [NotificationAction] = [] var title: String? = nil @@ -46,7 +29,7 @@ struct DataNotification: Notification { self.title = content.title self.subtitle = content.subtitle self.body = content.body - self.sound = content.sound + self.channelName = content.userInfo["channelName"] as? String ?? "default" self.icon = content.userInfo["icon"] as? String self.image = content.userInfo["image"] as? String self.url = content.userInfo["url"] as? String @@ -98,27 +81,14 @@ struct DataNotification: Notification { if (self.body != nil) { content.body = self.body! } - - - switch(self.actions.count) { - case 1: - content.categoryIdentifier = "PPG_NOTIFICATION_WITH_ACTION" + + if (self.actions.count > 0) { content.userInfo["actions"] = self.serializeActions() - break; - case 2: - content.categoryIdentifier = "PPG_NOTIFICATION_WITH_ACTIONS" - content.userInfo["actions"] = self.serializeActions() - break; - default: - content.categoryIdentifier = "PPG_NOTIFICATION" - break - } - - if (self.sound != nil) { - content.sound = self.sound - } else { - content.sound = UNNotificationSound.default } + + let channel = PpgCoreConfig.shared.getChannel(notification: self) + content.categoryIdentifier = channel.name + content.sound = channel.sound if let image = self.image { if let attachment = try? UNNotificationAttachment(url: image) { diff --git a/PpgCoreSDK/Models/NotificationAction.swift b/PpgCoreSDK/Models/NotificationAction.swift new file mode 100644 index 0000000..3bd1ea6 --- /dev/null +++ b/PpgCoreSDK/Models/NotificationAction.swift @@ -0,0 +1,25 @@ +// +// NotificationAction.swift +// PpgCoreSDK +// +// Created by Mateusz Worotyński on 13/06/2023. +// + +import Foundation + +struct NotificationAction: Codable { + let icon: String? + let action: String + let title: String + let url: String + + static func fromJson(json: Data) -> [NotificationAction] { + let decoder = JSONDecoder() + + guard let deserialized = try? decoder.decode([NotificationAction].self, from: json) else { + fatalError("Failed to decode notification action from JSON") + } + + return deserialized + } +} diff --git a/PpgCoreSDK/Models/NotificationChannel.swift b/PpgCoreSDK/Models/NotificationChannel.swift new file mode 100644 index 0000000..1c9c02a --- /dev/null +++ b/PpgCoreSDK/Models/NotificationChannel.swift @@ -0,0 +1,22 @@ +// +// Channel.swift +// PpgCoreSDK +// +// Created by Mateusz Worotyński on 13/06/2023. +// + +import Foundation +import UserNotifications + +public enum NotificationChannelType: String { + case DEFAULT + case DEFAULT_WITH_ACTION + case DEFAULT_WITH_ACTIONS + case CUSTOM +} + +struct NotificationChannel { + var name: String + var sound: UNNotificationSound + var actions: [String] +} diff --git a/PpgCoreSDK/PpgCoreClient.swift b/PpgCoreSDK/PpgCoreClient.swift index 015ba06..41fa925 100644 --- a/PpgCoreSDK/PpgCoreClient.swift +++ b/PpgCoreSDK/PpgCoreClient.swift @@ -15,7 +15,7 @@ public enum SubscriptionActionResult { } public class PpgCoreClient: NSObject { - let eventService: EventService = EventService(config: PpgCoreConfig()) + let eventService: EventService = EventService(config: PpgCoreConfig.shared) @available(iOSApplicationExtension, unavailable) private func setBadge(num: Int) { @@ -26,46 +26,11 @@ public class PpgCoreClient: NSObject { private func getBadge() -> Int { return UIApplication.shared.applicationIconBadgeNumber } - - private func createCategoryAction(label: String, index: Int) -> UNNotificationAction { - return UNNotificationAction( - identifier: "action_\(index)", - title: label, - options: [.foreground] - ) - } - public func initialize(actionLabels: [String]) { - let firstAction = actionLabels.first ?? "Open" - let secondAction = actionLabels.last ?? "Show more" - UNUserNotificationCenter.current() - .setNotificationCategories([ - UNNotificationCategory( - identifier: "PPG_NOTIFICATION_WITH_ACTIONS", - actions: [firstAction, secondAction].enumerated().map {( index, item ) in - createCategoryAction(label: item, index: index) - }, - intentIdentifiers: [], - hiddenPreviewsBodyPlaceholder: "", - options: [.customDismissAction] - ), - UNNotificationCategory( - identifier: "PPG_NOTIFICATION_WITH_ACTION", - actions: [firstAction].enumerated().map {( index, item ) in - createCategoryAction(label: item, index: index) - }, - intentIdentifiers: [], - hiddenPreviewsBodyPlaceholder: "", - options: [.customDismissAction] - ), - UNNotificationCategory( - identifier: "PPG_NOTIFICATION", - actions: [], - intentIdentifiers: [], - hiddenPreviewsBodyPlaceholder: "", - options: [.customDismissAction] - ) - ]) + public func initialize(actionLabels: [String] = []) { + UNUserNotificationCenter + .current() + .setNotificationCategories(PpgCoreConfig.shared.getCategories(actionLabels: actionLabels)) } @available(iOSApplicationExtension, unavailable) @@ -185,7 +150,6 @@ public class PpgCoreClient: NSObject { let dataNotification = NotificationFactory.createData(content: request.content) let newContent = dataNotification.toUNNotificationMutableContent() eventService.send(delivered: dataNotification.createDeliveredEvent()) -// setActionsOnNotificationCenter(actions: dataNotification.getUNNotificationActions()) contentHandler(newContent); return newContent @@ -214,7 +178,6 @@ public class PpgCoreClient: NSObject { return; case .data: PpgCoreLogger.info("Got background message as data message omit registering event"); -// setActionsOnNotificationCenter(actions: self.getActionsFromJSON(jsonString: userInfo["actions"] as! String)) completionHandler(.newData) return; case .unknown: @@ -245,7 +208,6 @@ public class PpgCoreClient: NSObject { PpgCoreLogger.info("Got data message from local notifications"); let dataNotification = NotificationFactory.createData(content: notification.request.content) eventService.send(delivered: dataNotification.createDeliveredEvent()) -// setActionsOnNotificationCenter(actions: dataNotification.getUNNotificationActions()) break; case .silent: PpgCoreLogger.info("Got silent message from local notifications"); @@ -263,33 +225,4 @@ public class PpgCoreClient: NSObject { completionHandler([.alert, .sound]) } } - - /// Method prepared for dynamic actions, but due to iOS platform weak support not used for now - public func setActionsOnNotificationCenter(actions: [UNNotificationAction]) { - UNUserNotificationCenter - .current() - .setNotificationCategories([ - UNNotificationCategory( - identifier: "PPG_NOTIFICATION_WITH_ACTIONS", - actions: actions, - intentIdentifiers: [], - hiddenPreviewsBodyPlaceholder: "", - options: [.customDismissAction] - ), - UNNotificationCategory( - identifier: "PPG_NOTIFICATION_WITH_ACTION", - actions: actions, - intentIdentifiers: [], - hiddenPreviewsBodyPlaceholder: "", - options: [.customDismissAction] - ), - UNNotificationCategory( - identifier: "PPG_NOTIFICATION", - actions: [], - intentIdentifiers: [], - hiddenPreviewsBodyPlaceholder: "", - options: [.customDismissAction] - ) - ]) - } } diff --git a/PpgCoreSDK/PpgCoreNotificationServiceExtension.swift b/PpgCoreSDK/PpgCoreNotificationServiceExtension.swift index 6669d03..026ade5 100644 --- a/PpgCoreSDK/PpgCoreNotificationServiceExtension.swift +++ b/PpgCoreSDK/PpgCoreNotificationServiceExtension.swift @@ -10,7 +10,7 @@ import UserNotifications open class PpgCoreNotificationServiceExtension: UNNotificationServiceExtension { - let eventService: EventService = EventService(config: PpgCoreConfig()) + let eventService: EventService = EventService(config: PpgCoreConfig.shared) var contentHandler: ((UNNotificationContent) -> Void)? var bestAttemptContent: UNMutableNotificationContent? diff --git a/PpgCoreSDK/Services/PpgCoreConfig.swift b/PpgCoreSDK/Services/PpgCoreConfig.swift index 7a3aa41..6923b78 100644 --- a/PpgCoreSDK/Services/PpgCoreConfig.swift +++ b/PpgCoreSDK/Services/PpgCoreConfig.swift @@ -6,29 +6,127 @@ // import Foundation +import UserNotifications public struct PpgCoreConfig { - var endpoint: String = "https://api-core.pushpushgo.com/v1"; - init() { + static public var shared: PpgCoreConfig = PpgCoreConfig() + + var endpoint: String = "https://api-core.pushpushgo.com/v1"; - guard let plistURL = Bundle.main.url(forResource: "Info", withExtension: "plist") else { - PpgCoreLogger.error("Couldn't find Info.plist in the main bundle") - return; - } + var channels: [String: NotificationChannel] = [:] + + init() { + guard let plistURL = Bundle.main.url(forResource: "PpgCore", withExtension: "plist") else { + PpgCoreLogger.error("Couldn't find PpgCore.plist in the main bundle") + return; + } + + guard let plistData = try? Data(contentsOf: plistURL) else { + PpgCoreLogger.error("Couldn't load plist data from \(plistURL)") + return; + } - guard let plistData = try? Data(contentsOf: plistURL) else { - PpgCoreLogger.error("Couldn't load plist data from \(plistURL)") - return; + guard let plist = try? PropertyListSerialization.propertyList(from: plistData, options: [], format: nil) else { + PpgCoreLogger.error("Couldn't deserialize plist data") + return; + } + + if let overridenEndpoint = (plist as? NSDictionary)?["PpgCoreSDKEndpoint"] as? String { + self.endpoint = overridenEndpoint + } + + if let data = (plist as? NSDictionary)?["PpgCoreChannels"] as? [Any] { + for item in data { + if let channelData = item as? [String: Any], + let actions = channelData["actions"] as? [String], + let name = channelData["name"] as? String, + let sound = channelData["sound"] as? String { + + PpgCoreLogger.info("Registering \(name) channel for notifications") + + if (self.channels[name] != nil) { + PpgCoreLogger.error("Duplicated channel name check PpgCoreChannels.name declaration for duplicates in Info.plist file") + continue; + } + + let soundObject = UNNotificationSound(named: UNNotificationSoundName(rawValue: sound)) + self.channels[name] = NotificationChannel(name: name, sound: soundObject, actions: actions) + } + } + } + } + + private func createCategoryAction(label: String, index: Int) -> UNNotificationAction { + return UNNotificationAction( + identifier: "action_\(index)", + title: label, + options: [.foreground] + ) } + + private func createDefaultChannels(firstAction: String, secondAction: String) -> [String: NotificationChannel] { + return [ + NotificationChannelType.DEFAULT_WITH_ACTIONS.rawValue: NotificationChannel( + name: NotificationChannelType.DEFAULT_WITH_ACTIONS.rawValue, sound: .default, actions: [firstAction, secondAction] + ), + NotificationChannelType.DEFAULT_WITH_ACTION.rawValue: NotificationChannel( + name: NotificationChannelType.DEFAULT_WITH_ACTION.rawValue, sound: .default, actions: [firstAction] + ), + NotificationChannelType.DEFAULT.rawValue: NotificationChannel( + name: NotificationChannelType.DEFAULT.rawValue, sound: .default, actions: [] + ) + ] + } + + public func getCategories(actionLabels: [String] = []) -> Set { - guard let plist = try? PropertyListSerialization.propertyList(from: plistData, options: [], format: nil) else { - PpgCoreLogger.error("Couldn't deserialize plist data") - return; + let firstAction = actionLabels.first ?? "Open" + let secondAction = actionLabels.last ?? "Show more" + + let combinedChannels = self.channels.merging(createDefaultChannels(firstAction: firstAction, secondAction: secondAction)) { (_, new) in new } + + let categories = combinedChannels.reduce(into: Set()) { (result, channel) in + let (_, channelData) = channel + let category = UNNotificationCategory( + identifier: channelData.name, + actions: channelData.actions.enumerated().map {( index, item ) in + createCategoryAction(label: item, index: index) + }, + intentIdentifiers: [], + hiddenPreviewsBodyPlaceholder: "", + options: [.customDismissAction] + ) + result.insert(category) + } + + return categories } + + func getChannel(notification: DataNotification) -> NotificationChannel { + if (notification.channelName.isEmpty || notification.channelName == "default") { + + PpgCoreLogger.error("Channel '\(notification.channelName)' not found - fallback to default channel"); + + switch(notification.actions.count) { + case 1: + return NotificationChannel(name: NotificationChannelType.DEFAULT_WITH_ACTION.rawValue, sound: .default, actions: []) + case 2: + return NotificationChannel(name: NotificationChannelType.DEFAULT_WITH_ACTIONS.rawValue, sound: .default, actions: []) + default: + return NotificationChannel(name: NotificationChannelType.DEFAULT.rawValue, sound: .default, actions: []) + } + } - if let overridenEndpoint = (plist as? NSDictionary)?["PpgCoreSDKEndpoint"] as? String { - self.endpoint = overridenEndpoint + let channel = self.channels[notification.channelName] + + if (channel == nil) { + PpgCoreLogger.error("Channel '\(notification.channelName)' not found - fallback to default channel"); + return NotificationChannel(name: NotificationChannelType.DEFAULT.rawValue, sound: .default, actions: []) + } + + PpgCoreLogger.error("Channel '\(notification.channelName)' found"); + + return channel!; } - } } diff --git a/PpgCoreSDK/Utils/PpgCoreLogger.swift b/PpgCoreSDK/Utils/PpgCoreLogger.swift index ef4c626..822a044 100644 --- a/PpgCoreSDK/Utils/PpgCoreLogger.swift +++ b/PpgCoreSDK/Utils/PpgCoreLogger.swift @@ -9,6 +9,17 @@ import Foundation import os.log public class PpgCoreLogger { + + public static var _enabled: Bool = true; + + public static func disable() -> Void { + PpgCoreLogger._enabled = false; + } + + public static func enable() -> Void { + PpgCoreLogger._enabled = true; + } + public static func error(_ message: String, file: String = #file, function: String = #function, line: Int = #line) { log(message: message, level: .error, file: file, function: function, line: line) } @@ -18,6 +29,10 @@ public class PpgCoreLogger { } private static func log(message: String, level: OSLogType, file: String, function: String, line: Int) { + if (PpgCoreLogger._enabled == false) { + return; + } + let fileName = (file as NSString).lastPathComponent let log = OSLog(subsystem: Bundle.main.bundleIdentifier ?? "NA", category: fileName) os_log("[%{public}@:%{public}@:%d] %{public}@", log: log, type: level, fileName, function, line, message) diff --git a/README.md b/README.md index 48e40d9..a5628e0 100644 --- a/README.md +++ b/README.md @@ -68,16 +68,16 @@ Open XCode Workspace instead of Project Add to your target our library: -```swift +```sh target 'your_project_name' do use_frameworks! - pod 'PpgCoreSDK', '~> 0.0.8' + pod 'PpgCoreSDK', '~> 0.0.9' end ``` Then install pods and open xcode with workspace env -```bash +```sh $ pod install $ xed your_project_name.xcworkspace ``` @@ -96,14 +96,14 @@ $ xed your_project_name.xcworkspace 3. Finish process and on prompt about __Activate “NSE” scheme?__ click **Cancel** 4. Add to previously used name **NSE** target to `Podfile`: -``` +```sh target 'NSE' do use_frameworks! - pod 'PpgCoreSDK', '~> 0.0.8' + pod 'PpgCoreSDK', '~> 0.0.9' end ``` 5. Install pods -```bash +```sh $ pod install ``` @@ -221,10 +221,43 @@ extension AppDelegate: UNUserNotificationCenterDelegate { ``` -7. (Optional) add to Info.plist file in case if you want to override endpoint (development, self-hosted instance) add to `` +7. (optional) If you need to overwrite endpoint or prepare channels (with customized actions) create PpgCore.plist + +> Important: Select target for your **app and notification service extension**! + ```xml - PpgCoreSDKEndpoint - https://api-core.pushpushgo.com/v1 + + + + + PpgCoreSDKEndpoint + https://ppg-core.master1.qappg.co/v1 + PpgCoreChannels + + + name + testing_channel + sound + Submarine.aiff + actions + + Reply + + + + name + testing_channel_nowy + sound + sub.caf + actions + + Open + Show more + + + + + ``` # Sending notifications @@ -239,7 +272,7 @@ extension AppDelegate: UNUserNotificationCenterDelegate { ## 2. Prepare configuration 1. Wrap exported certficates with Base64 with command - ```bash + ```sh $ cat Certificate.p12 | base64 ``` 2. Prepare JSON with provider configuration diff --git a/examples/sdkdemo/NSE/Info.plist b/examples/sdkdemo/NSE/Info.plist index b48020c..57421eb 100644 --- a/examples/sdkdemo/NSE/Info.plist +++ b/examples/sdkdemo/NSE/Info.plist @@ -2,8 +2,6 @@ - PpgCoreSDKEndpoint - https://ppg-core.master1.qappg.co/v1 NSExtension NSExtensionPointIdentifier diff --git a/examples/sdkdemo/Podfile b/examples/sdkdemo/Podfile index 3ed4837..5aa9c7f 100644 --- a/examples/sdkdemo/Podfile +++ b/examples/sdkdemo/Podfile @@ -2,10 +2,10 @@ platform :ios, '14.0' target 'sdkdemo' do use_frameworks! - pod 'PpgCoreSDK', '~> 0.0.8' + pod 'PpgCoreSDK', '~> 0.0.9' end target 'NSE' do use_frameworks! - pod 'PpgCoreSDK', '~> 0.0.8' + pod 'PpgCoreSDK', '~> 0.0.9' end diff --git a/examples/sdkdemo/Podfile.lock b/examples/sdkdemo/Podfile.lock index 75aea39..c7240e8 100644 --- a/examples/sdkdemo/Podfile.lock +++ b/examples/sdkdemo/Podfile.lock @@ -1,16 +1,16 @@ PODS: - - PpgCoreSDK (0.0.8) + - PpgCoreSDK (0.0.9) DEPENDENCIES: - - PpgCoreSDK (~> 0.0.8) + - PpgCoreSDK (from `/Users/worotyns/code/ppg-core-ios-sdk`) -SPEC REPOS: - trunk: - - PpgCoreSDK +EXTERNAL SOURCES: + PpgCoreSDK: + :path: "/Users/worotyns/code/ppg-core-ios-sdk" SPEC CHECKSUMS: PpgCoreSDK: 26c4d8f23fe7b8ab9e7476f74299c69c44e12e9d -PODFILE CHECKSUM: 6239d5209967c7f2277885a6185a18240acba957 +PODFILE CHECKSUM: 024545c1607626ec99cd8a7d6b8b6e73a52f2379 COCOAPODS: 1.12.1 diff --git a/examples/sdkdemo/sdkdemo.xcodeproj/project.pbxproj b/examples/sdkdemo/sdkdemo.xcodeproj/project.pbxproj index f9818c8..790cf60 100644 --- a/examples/sdkdemo/sdkdemo.xcodeproj/project.pbxproj +++ b/examples/sdkdemo/sdkdemo.xcodeproj/project.pbxproj @@ -8,6 +8,10 @@ /* Begin PBXBuildFile section */ 35F69D93DF52ED4B6D8197CB /* Pods_sdkdemo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7531E12C10334326A2EB5EFC /* Pods_sdkdemo.framework */; }; + 460B697E2A38DCDC00FE1D07 /* PpgCore.plist in Resources */ = {isa = PBXBuildFile; fileRef = 460B697D2A38DCDC00FE1D07 /* PpgCore.plist */; }; + 460B697F2A38DCDC00FE1D07 /* PpgCore.plist in Resources */ = {isa = PBXBuildFile; fileRef = 460B697D2A38DCDC00FE1D07 /* PpgCore.plist */; }; + 460B69832A38DE3700FE1D07 /* sub.caf in Resources */ = {isa = PBXBuildFile; fileRef = 460B69822A38DE3700FE1D07 /* sub.caf */; }; + 460B69842A38DE3700FE1D07 /* sub.caf in Resources */ = {isa = PBXBuildFile; fileRef = 460B69822A38DE3700FE1D07 /* sub.caf */; }; 464698AE2A162BA800AD81FD /* sdkdemoApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 464698AD2A162BA800AD81FD /* sdkdemoApp.swift */; }; 464698B02A162BA800AD81FD /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 464698AF2A162BA800AD81FD /* ContentView.swift */; }; 464698B22A162BA900AD81FD /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 464698B12A162BA900AD81FD /* Assets.xcassets */; }; @@ -53,6 +57,8 @@ /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ + 460B697D2A38DCDC00FE1D07 /* PpgCore.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = PpgCore.plist; sourceTree = ""; }; + 460B69822A38DE3700FE1D07 /* sub.caf */ = {isa = PBXFileReference; lastKnownFileType = file; path = sub.caf; sourceTree = ""; }; 464698AA2A162BA800AD81FD /* sdkdemo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = sdkdemo.app; sourceTree = BUILT_PRODUCTS_DIR; }; 464698AD2A162BA800AD81FD /* sdkdemoApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = sdkdemoApp.swift; sourceTree = ""; }; 464698AF2A162BA800AD81FD /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = ""; }; @@ -114,6 +120,22 @@ path = Pods; sourceTree = ""; }; + 460B69802A38DE1B00FE1D07 /* Library */ = { + isa = PBXGroup; + children = ( + 460B69812A38DE2600FE1D07 /* Sound */, + ); + path = Library; + sourceTree = ""; + }; + 460B69812A38DE2600FE1D07 /* Sound */ = { + isa = PBXGroup; + children = ( + 460B69822A38DE3700FE1D07 /* sub.caf */, + ); + path = Sound; + sourceTree = ""; + }; 464698A12A162BA800AD81FD = { isa = PBXGroup; children = ( @@ -137,6 +159,7 @@ 464698AC2A162BA800AD81FD /* sdkdemo */ = { isa = PBXGroup; children = ( + 460B69802A38DE1B00FE1D07 /* Library */, 464698C12A16325200AD81FD /* Info.plist */, 464698C02A1631ED00AD81FD /* sdkdemo.entitlements */, 464698AD2A162BA800AD81FD /* sdkdemoApp.swift */, @@ -144,6 +167,7 @@ 464698B12A162BA900AD81FD /* Assets.xcassets */, 464698B32A162BA900AD81FD /* Preview Content */, 464698BE2A16306600AD81FD /* AppDelegate.swift */, + 460B697D2A38DCDC00FE1D07 /* PpgCore.plist */, ); path = sdkdemo; sourceTree = ""; @@ -251,6 +275,8 @@ buildActionMask = 2147483647; files = ( 464698B52A162BA900AD81FD /* Preview Assets.xcassets in Resources */, + 460B69832A38DE3700FE1D07 /* sub.caf in Resources */, + 460B697E2A38DCDC00FE1D07 /* PpgCore.plist in Resources */, 464698B22A162BA900AD81FD /* Assets.xcassets in Resources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -259,6 +285,8 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + 460B697F2A38DCDC00FE1D07 /* PpgCore.plist in Resources */, + 460B69842A38DE3700FE1D07 /* sub.caf in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/examples/sdkdemo/sdkdemo.xcworkspace/xcuserdata/worotyns.xcuserdatad/UserInterfaceState.xcuserstate b/examples/sdkdemo/sdkdemo.xcworkspace/xcuserdata/worotyns.xcuserdatad/UserInterfaceState.xcuserstate index 5f0d92c..c018fa5 100644 Binary files a/examples/sdkdemo/sdkdemo.xcworkspace/xcuserdata/worotyns.xcuserdatad/UserInterfaceState.xcuserstate and b/examples/sdkdemo/sdkdemo.xcworkspace/xcuserdata/worotyns.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/examples/sdkdemo/sdkdemo/Info.plist b/examples/sdkdemo/sdkdemo/Info.plist index 958ad69..634f4e4 100644 --- a/examples/sdkdemo/sdkdemo/Info.plist +++ b/examples/sdkdemo/sdkdemo/Info.plist @@ -2,8 +2,6 @@ - PpgCoreSDKEndpoint - https://ppg-core.master1.qappg.co/v1 UIBackgroundModes fetch diff --git a/examples/sdkdemo/sdkdemo/Library/Sound/sub.caf b/examples/sdkdemo/sdkdemo/Library/Sound/sub.caf new file mode 100644 index 0000000..6b7e1ab Binary files /dev/null and b/examples/sdkdemo/sdkdemo/Library/Sound/sub.caf differ diff --git a/examples/sdkdemo/sdkdemo/PpgCore.plist b/examples/sdkdemo/sdkdemo/PpgCore.plist new file mode 100644 index 0000000..f9e7042 --- /dev/null +++ b/examples/sdkdemo/sdkdemo/PpgCore.plist @@ -0,0 +1,33 @@ + + + + + PpgCoreSDKEndpoint + https://ppg-core.master1.qappg.co/v1 + PpgCoreChannels + + + name + testing_channel + sound + Submarine.aiff + actions + + CORE My1 + CORE My2 + + + + name + testing_channel_nowy + sound + sub.caf + actions + + CORE First Action Title + CORE Second Action Title + + + + +