Skip to content

Commit

Permalink
Merge branch 'release/v1.2.1'
Browse files Browse the repository at this point in the history
  • Loading branch information
Catalin Demian committed Oct 12, 2021
2 parents eb89038 + f3f62e2 commit 11f85d3
Show file tree
Hide file tree
Showing 14 changed files with 326 additions and 72 deletions.
24 changes: 15 additions & 9 deletions Ometria Sample/OmetriaSample/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -88,16 +88,22 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD

// MARK: - OmetriaNotificationInteractionDelegate

// This method will be called each time the user interacts with a notification from Ometria
// which contains a deepLinkURL. Write your own custom code in order to
// properly redirect the app to the screen that should be displayed.
// If you do not implement this method at all, the default behaviour is to open the browser and log a DeepLinkOpened Event as you can see below.
// Note, this is now deprecated and will be removed in a future version. Use 'handleOmetriaNotificationInteraction' instead.
func handleDeepLinkInteraction(_ deepLink: URL) {
if UIApplication.shared.canOpenURL(deepLink) == true {
UIApplication.shared.open(deepLink)
Ometria.sharedInstance().trackDeepLinkOpenedEvent(link: deepLink.absoluteString, screenName: "Safari")
} else {
print("The provided deeplink URL (\(deepLink.absoluteString) cannot be processed.")
}

// This method will be called each time the user interacts with a notification from Ometria.
// Write your own custom code in order to
// properly redirect the app to the screen that should be displayed.
// If you do not implement this interface at all, the default behaviour is to open the browser and log a DeepLinkOpened Event as you can see below.
func handleOmetriaNotificationInteraction(_ notification: OmetriaNotification) {
if let urlString = notification.deepLinkActionUrl, let url = URL(string: urlString) {
if UIApplication.shared.canOpenURL(url) == true {
UIApplication.shared.open(url)
Ometria.sharedInstance().trackDeepLinkOpenedEvent(link: urlString, screenName: "Safari")
} else {
print("The provided deeplink URL (\(urlString) cannot be processed.")
}
}
}

Expand Down
1 change: 0 additions & 1 deletion Ometria Sample/Podfile
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,3 @@ post_install do |installer|
end
end
end

86 changes: 86 additions & 0 deletions Ometria Sample/Podfile.lock
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
PODS:
- FirebaseCore (8.8.0):
- FirebaseCoreDiagnostics (~> 8.0)
- GoogleUtilities/Environment (~> 7.4)
- GoogleUtilities/Logger (~> 7.4)
- FirebaseCoreDiagnostics (8.8.0):
- GoogleDataTransport (~> 9.0)
- GoogleUtilities/Environment (~> 7.4)
- GoogleUtilities/Logger (~> 7.4)
- nanopb (~> 2.30908.0)
- FirebaseInstallations (8.8.0):
- FirebaseCore (~> 8.0)
- GoogleUtilities/Environment (~> 7.4)
- GoogleUtilities/UserDefaults (~> 7.4)
- PromisesObjC (< 3.0, >= 1.2)
- FirebaseMessaging (8.8.0):
- FirebaseCore (~> 8.0)
- FirebaseInstallations (~> 8.0)
- GoogleDataTransport (~> 9.0)
- GoogleUtilities/AppDelegateSwizzler (~> 7.4)
- GoogleUtilities/Environment (~> 7.4)
- GoogleUtilities/Reachability (~> 7.4)
- GoogleUtilities/UserDefaults (~> 7.4)
- nanopb (~> 2.30908.0)
- GoogleDataTransport (9.1.0):
- GoogleUtilities/Environment (~> 7.2)
- nanopb (~> 2.30908.0)
- PromisesObjC (< 3.0, >= 1.2)
- GoogleUtilities/AppDelegateSwizzler (7.5.2):
- GoogleUtilities/Environment
- GoogleUtilities/Logger
- GoogleUtilities/Network
- GoogleUtilities/Environment (7.5.2):
- PromisesObjC (< 3.0, >= 1.2)
- GoogleUtilities/Logger (7.5.2):
- GoogleUtilities/Environment
- GoogleUtilities/Network (7.5.2):
- GoogleUtilities/Logger
- "GoogleUtilities/NSData+zlib"
- GoogleUtilities/Reachability
- "GoogleUtilities/NSData+zlib (7.5.2)"
- GoogleUtilities/Reachability (7.5.2):
- GoogleUtilities/Logger
- GoogleUtilities/UserDefaults (7.5.2):
- GoogleUtilities/Logger
- nanopb (2.30908.0):
- nanopb/decode (= 2.30908.0)
- nanopb/encode (= 2.30908.0)
- nanopb/decode (2.30908.0)
- nanopb/encode (2.30908.0)
- Ometria (1.2.0):
- FirebaseMessaging
- PromisesObjC (2.0.0)

DEPENDENCIES:
- Ometria (from `../`)

SPEC REPOS:
trunk:
- FirebaseCore
- FirebaseCoreDiagnostics
- FirebaseInstallations
- FirebaseMessaging
- GoogleDataTransport
- GoogleUtilities
- nanopb
- PromisesObjC

EXTERNAL SOURCES:
Ometria:
:path: "../"

SPEC CHECKSUMS:
FirebaseCore: 98b29e3828f0a53651c363937a7f7d92a19f1ba2
FirebaseCoreDiagnostics: fe77f42da6329d6d83d21fd9d621a6b704413bfc
FirebaseInstallations: 2563cb18a723ef9c6ef18318a49519b75dce613c
FirebaseMessaging: 419b5c9d84f294a753c6501d8cfb9ced1ce37304
GoogleDataTransport: 85fd18ff3019bb85d3f2c551d04c481dedf71fc9
GoogleUtilities: 8de2a97a17e15b6b98e38e8770e2d129a57c0040
nanopb: a0ba3315591a9ae0a16a309ee504766e90db0c96
Ometria: 6477d0bcaefbdba4effbdaff0e76707dd472ec5b
PromisesObjC: 68159ce6952d93e17b2dfe273b8c40907db5ba58

PODFILE CHECKSUM: 971be00875f337bfd598cb9bcd32e1c6b5cbc944

COCOAPODS: 1.10.1
12 changes: 8 additions & 4 deletions Ometria.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
4E8961FA250FB1C200EEC9F6 /* Ometria.podspec in Resources */ = {isa = PBXBuildFile; fileRef = 4E8961F9250FB1C200EEC9F6 /* Ometria.podspec */; };
4E96478524E3F90B00274FC3 /* OmetriaBasketItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E96478324E3F90B00274FC3 /* OmetriaBasketItem.swift */; };
4E96478624E3F90B00274FC3 /* OmetriaBasket.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E96478424E3F90B00274FC3 /* OmetriaBasket.swift */; };
4E96AB4824D30ADB00623FA6 /* AutomaticScreenViewsTracker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E96AB4724D30ADB00623FA6 /* AutomaticScreenViewsTracker.swift */; };
4E96AB4F24D4927900623FA6 /* NotificationHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E96AB4E24D4927900623FA6 /* NotificationHandler.swift */; };
4EA10CE524ED5A97007FF49D /* JSONDecoder+KeyPath.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4EA10CE424ED5A97007FF49D /* JSONDecoder+KeyPath.swift */; };
4EA10CE724ED70AB007FF49D /* ParamEncoder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4EA10CE624ED70AB007FF49D /* ParamEncoder.swift */; };
Expand All @@ -39,6 +38,8 @@
4EFF18B624EA55690020389A /* JSONCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4EFF18B524EA55690020389A /* JSONCache.swift */; };
4EFF18B824EA559A0020389A /* CodableCaching.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4EFF18B724EA559A0020389A /* CodableCaching.swift */; };
4EFF18BB24EA63230020389A /* EventHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4EFF18BA24EA63230020389A /* EventHandler.swift */; };
EC56B60127048E17009D808A /* Decodable.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC56B60027048E17009D808A /* Decodable.swift */; };
EC56B60327048E23009D808A /* OmetriaNotification.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC56B60227048E23009D808A /* OmetriaNotification.swift */; };
/* End PBXBuildFile section */

/* Begin PBXFileReference section */
Expand All @@ -51,7 +52,6 @@
4E8961F9250FB1C200EEC9F6 /* Ometria.podspec */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Ometria.podspec; sourceTree = "<group>"; };
4E96478324E3F90B00274FC3 /* OmetriaBasketItem.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OmetriaBasketItem.swift; sourceTree = "<group>"; };
4E96478424E3F90B00274FC3 /* OmetriaBasket.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OmetriaBasket.swift; sourceTree = "<group>"; };
4E96AB4724D30ADB00623FA6 /* AutomaticScreenViewsTracker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AutomaticScreenViewsTracker.swift; sourceTree = "<group>"; };
4E96AB4E24D4927900623FA6 /* NotificationHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationHandler.swift; sourceTree = "<group>"; };
4EA10CE424ED5A97007FF49D /* JSONDecoder+KeyPath.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "JSONDecoder+KeyPath.swift"; sourceTree = "<group>"; };
4EA10CE624ED70AB007FF49D /* ParamEncoder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ParamEncoder.swift; sourceTree = "<group>"; };
Expand All @@ -77,6 +77,8 @@
4EFF18B724EA559A0020389A /* CodableCaching.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CodableCaching.swift; sourceTree = "<group>"; };
4EFF18BA24EA63230020389A /* EventHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EventHandler.swift; sourceTree = "<group>"; };
7F5D7686F934DEAE653B4617 /* Pods_Ometria.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Ometria.framework; sourceTree = BUILT_PRODUCTS_DIR; };
EC56B60027048E17009D808A /* Decodable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Decodable.swift; sourceTree = "<group>"; };
EC56B60227048E23009D808A /* OmetriaNotification.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OmetriaNotification.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */

/* Begin PBXFrameworksBuildPhase section */
Expand All @@ -96,6 +98,7 @@
children = (
4EA10CE424ED5A97007FF49D /* JSONDecoder+KeyPath.swift */,
4E47423724EE6590005F1F68 /* JSONEncoder+Ometria.swift */,
EC56B60027048E17009D808A /* Decodable.swift */,
4EE7A8C924C81BDD00B316A7 /* ApplicationUtils.swift */,
4EF3710924F39C4B00450B52 /* Array+Chunks.swift */,
4EF3710C24F56D0E00450B52 /* Constants.swift */,
Expand Down Expand Up @@ -155,6 +158,7 @@
children = (
4E96478424E3F90B00274FC3 /* OmetriaBasket.swift */,
4E96478324E3F90B00274FC3 /* OmetriaBasketItem.swift */,
EC56B60227048E23009D808A /* OmetriaNotification.swift */,
4EE7A8D224C88F0500B316A7 /* OmetriaEvent.swift */,
4EF3711124F7912C00450B52 /* OmetriaNotificationBody.swift */,
);
Expand Down Expand Up @@ -184,7 +188,6 @@
4E567CC9250F7B4900D68DEB /* Screen Views */ = {
isa = PBXGroup;
children = (
4E96AB4724D30ADB00623FA6 /* AutomaticScreenViewsTracker.swift */,
);
name = "Screen Views";
sourceTree = "<group>";
Expand Down Expand Up @@ -354,7 +357,9 @@
4EE7A8D024C8483600B316A7 /* ReadWriteLock.swift in Sources */,
4E88929424ED9A07002593FD /* EventsAPI.swift in Sources */,
4E96AB4F24D4927900623FA6 /* NotificationHandler.swift in Sources */,
EC56B60127048E17009D808A /* Decodable.swift in Sources */,
4E0DB1ED24CABE9200EA2859 /* OmetriaDefaults.swift in Sources */,
EC56B60327048E23009D808A /* OmetriaNotification.swift in Sources */,
4EE7A8D324C88F0500B316A7 /* OmetriaEvent.swift in Sources */,
4E5B2E2824ED4B470063FA50 /* NetworkService.swift in Sources */,
4EC94EDE24B8BCFB00B8591C /* OmetriaConfig.swift in Sources */,
Expand All @@ -369,7 +374,6 @@
4E5B2E2A24ED4C320063FA50 /* Result.swift in Sources */,
4EF3710A24F39C4B00450B52 /* Array+Chunks.swift in Sources */,
4E96478524E3F90B00274FC3 /* OmetriaBasketItem.swift in Sources */,
4E96AB4824D30ADB00623FA6 /* AutomaticScreenViewsTracker.swift in Sources */,
4EE7A8CA24C81BDD00B316A7 /* ApplicationUtils.swift in Sources */,
4EBDBF8D24C1906600AB8DCE /* Swizzler.swift in Sources */,
4EFF18BB24EA63230020389A /* EventHandler.swift in Sources */,
Expand Down
Binary file not shown.
34 changes: 26 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -403,17 +403,16 @@ The Ometria SDK will automatically source all the required tokens and provide th

This way your app will start receiving notifications from Ometria. Handling those notifications while the app is running in the foreground is up to you.

### Handling interaction with notifications that contain URLs
### Handling interaction with notifications

Ometria allows you to send URLs alongside your push notifications and allows you to handle them on the device.
Ometria allows you to send URLs and tracking info alongside your push notifications and allows you to handle them on the device.

By default, the Ometria SDK automatically handles any interaction with push notifications that contain URLs by opening them in a browser.

However, it enables developers to handle those URLs as they see fit (e.g. take the user to a specific screen in the app).

To get access to those interactions and the URLs, implement the `OmetriaNotificationInteractionDelegate`.

There is only one method that is required, and it will be triggered every time the user taps on a notification that has a deepLink action URL.

This is what it would look like in code:

```swift
Expand All @@ -430,10 +429,29 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD
}

// This method will be called each time the user interacts with a notification from Ometria
// which contains a deepLinkURL. Write your own custom code in order to
// properly redirect the app to the screen that should be displayed.
func handleDeepLinkInteraction(_ deepLink: URL) {
print("url: \(deepLink)")
// Write your own custom code in order to properly redirect the app to the screen that should be displayed.
func handleOmetriaNotificationInteraction(_ notification: OmetriaNotification) {
print(notification.deepLinkActionUrl)
}
}
```

The `OmetriaNotification` object also provides access to other fields in the notification payload, including custom tracking properties that you choose to send.

One can access all of these fields in the above-mentioned method.

If for some reason developers need access to the `OmetriaNotification` object in a context other than the OmetriaNotificationInteractionDelegate, Ometria SDK provides a method called `parseNotification(_ content:UNNotificationContent)` for this purpose:

```swift
import UserNotifications

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate, OmetriaNotificationInteractionDelegate {

func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
let notificationContent = notification.request.content
let ometriaNotification = Ometria.sharedInstance().parseNotification(notificationContent)
completionHandler([.alert, .sound])
}
}
```
Expand Down
3 changes: 2 additions & 1 deletion Sources/Ometria/ApplicationUtils.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ extension Ometria {
}
return sharedApplication
}


@available(iOSApplicationExtension, unavailable)
static func doesAppUseScenes() -> Bool {
let delegateClass: AnyClass! = object_getClass(UIApplication.shared.delegate)

Expand Down
3 changes: 2 additions & 1 deletion Sources/Ometria/AutomaticLifecycleTracker.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ import UIKit
open class AutomaticLifecycleTracker {

var isRunning = false


@available(iOSApplicationExtension, unavailable)
func startTracking() {
guard !isRunning else {
return
Expand Down
24 changes: 16 additions & 8 deletions Sources/Ometria/AutomaticPushTracker.swift
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ open class AutomaticPushTracker: NSObject {

open var isRunning = false
open var isDelegateObserverAdded = false


@available(iOSApplicationExtension, unavailable)
open func startTracking() {
guard !isRunning else {
return
Expand All @@ -43,7 +44,8 @@ open class AutomaticPushTracker: NSObject {

NotificationCenter.default.addObserver(self, selector: #selector(firebaseTokenDidRefresh(notification:)), name: Notification.Name.MessagingRegistrationTokenRefreshed, object: nil)
}


@available(iOSApplicationExtension, unavailable)
open func stopTracking() {
guard isRunning else {
return
Expand All @@ -63,7 +65,8 @@ open class AutomaticPushTracker: NSObject {
UNUserNotificationCenter.current().removeDelegateObserver(observer: self)
}
}


@available(iOSApplicationExtension, unavailable)
private func swizzleDidRegisterForRemoteNotificationsWithDeviceToken() {
Logger.verbose(message: "Swizzle did register for remote notifications")
let newSelector = #selector(UIResponder.om_application(_:didRegisterForRemoteNotificationsWithDeviceToken:))
Expand All @@ -77,13 +80,15 @@ open class AutomaticPushTracker: NSObject {
Logger.verbose(message: "Application did register for remote notifications")
}
}


@available(iOSApplicationExtension, unavailable)
private func unswizzleDidRegisterForRemoteNotificationsWithDeviceToken() {
let delegateClass: AnyClass! = object_getClass(UIApplication.shared.delegate)
let originalSelector = #selector(UIApplicationDelegate.application(_:didRegisterForRemoteNotificationsWithDeviceToken:))
Swizzler.unswizzleSelector(originalSelector, aClass: delegateClass)
}


@available(iOSApplicationExtension, unavailable)
private func swizzleDidFailToRegisterForRemoteNotificationsWithError() {
Logger.verbose(message: "Swizzle did fail to register for remote notifications")
let newSelector = #selector(UIResponder.om_application(_:didFailToRegisterForRemoteNotificationsWithError:))
Expand All @@ -97,14 +102,16 @@ open class AutomaticPushTracker: NSObject {
Logger.verbose(message: "Application did fail to register for remote notifications")
}
}


@available(iOSApplicationExtension, unavailable)
private func unswizzleDidFailToRegisterForRemoteNotificationsWithError() {
let delegateClass: AnyClass! = object_getClass(UIApplication.shared.delegate)
let originalSelector = #selector(UIApplicationDelegate.application(_:didFailToRegisterForRemoteNotificationsWithError:))

Swizzler.unswizzleSelector(originalSelector, aClass: delegateClass)
}


@available(iOSApplicationExtension, unavailable)
private func swizzleDidReceiveSilentNotification() {
Logger.verbose(message: "Swizzle application:didReceiveRemoteNotification:fetchCompletionHandler:")
let newSelector = #selector(UIResponder.om_application(_:didReceiveRemoteNotification:fetchCompletionHandler:))
Expand All @@ -118,7 +125,8 @@ open class AutomaticPushTracker: NSObject {
Logger.debug(message: "Application didReceiveSilentNotification")
}
}


@available(iOSApplicationExtension, unavailable)
private func unswizzleDidReceiveSilentNotification() {
let delegateClass: AnyClass! = object_getClass(UIApplication.shared.delegate)
let originalSelector = #selector(UIApplicationDelegate.application(_:didReceiveRemoteNotification:fetchCompletionHandler:))
Expand Down
17 changes: 17 additions & 0 deletions Sources/Ometria/Decodable+Serialization.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
//
// Decodable+Serialization.swift
// Ometria
//
// Created by Sergiu Corbu on 29.09.2021.
// Copyright © 2021 Cata. All rights reserved.
//

import Foundation

extension Decodable {

init(from: [String: Any]) throws {
let data = try JSONSerialization.data(withJSONObject: from, options: .prettyPrinted)
self = try JSONDecoder().decode(Self.self, from: data)
}
}
Loading

0 comments on commit 11f85d3

Please sign in to comment.