Skip to content

Commit

Permalink
Log app open from notifications (#389)
Browse files Browse the repository at this point in the history
* save for branch switch

* skip swizzling for tests

* use different type for each kind of opening notification

* save for eod

* eod-ish save

* run only notification center checks on device and not tests

* make the callback nullable

* modularize notification delivery detetection logic and also refactor

* implement background processing and cleanup

* clean up

* version restrict background processing

* clean up

* clean up

* clean up

* move swizzle out of init

* add swift name

* change init of background jobs

* move swizzling back into init

* do not add notifications if we do not have permissions

* change name to native setup

* log all app opens for now

* add info to metadata

* change to metadata fields

* change name to conversionSource

* change casing

* only log either notification open or normal app open

* do nothing for the method notification

* formatting

* remove dead comment

* remember notification permission into radar state

* change logging level

* move the call so that it does not perform in test env

* temp adding webhook pings to bg tasks so we have a better idea on when they fire

* changes and fixes, server side working

* add more logging

* fix potential race condition

* remove clearing of pending notifications when the app foregrounds

* first pass removing deliverbility stuff

* format

* white space

* change conversion type for testing

* add more logging

* add thread dispatch

* remove logging and temp conversion name

* typo

* change name to completionhandler

* review changes

* refactor interface

* added feature gating

* clean up

* clean up

* save for eod

* temp change event name for testing

* update git ignore

* change back conversion name

* add comments as documentation

* change name and usage of useOpenedAppConversion

* address review

* version bump

* minor version bump

* default to true for useOpenedAppConversion
  • Loading branch information
KennyHuRadar authored Sep 13, 2024
1 parent 947b790 commit d2c2928
Show file tree
Hide file tree
Showing 24 changed files with 402 additions and 104 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,4 @@ docs/undocumented.json
*.xcarchive
IntegrationExamples
.build/
Example/Example.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/
10 changes: 9 additions & 1 deletion Example/Example/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,10 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UIWindowSceneDelegate, UN
self.requestLocationPermissions()

// Replace with a valid test publishable key
Radar.initialize(publishableKey: "prj_test_pk_0000000000000000000000000000000000000000")
let radarInitializeOptions = RadarInitializeOptions()
// Uncomment to enable automatic setup for notification conversions
// radarInitializeOptions.autoSetupNotificationConversion = true
Radar.initialize(publishableKey: "prj_test_pk_0000000000000000000000000000000000000000", options: radarInitializeOptions )
Radar.setUserId("testUserId")
Radar.setMetadata([ "foo": "bar" ])
Radar.setDelegate(self)
Expand Down Expand Up @@ -313,6 +316,11 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UIWindowSceneDelegate, UN
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
completionHandler([.list, .banner, .sound])
}

func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse) async {
// Uncomment for manual setup for notification conversions
// Radar.logConversion(response: response)
}

func notify(_ body: String) {
UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound]) { (granted, error) in
Expand Down
49 changes: 25 additions & 24 deletions Example/Example/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,30 @@
<string>1</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<false/>
<key>NSPinnedDomains</key>
<dict>
<key>api-verified.radar.io</key>
<dict>
<key>NSIncludesSubdomains</key>
<true/>
<key>NSPinnedLeafIdentities</key>
<array>
<dict>
<key>SPKI-SHA256-BASE64</key>
<string>15ktYXSSU2llpy7YyCgeqUKDBkjcimK/weUcec960sI=</string>
</dict>
<dict>
<key>SPKI-SHA256-BASE64</key>
<string>15ktYXSSU2llpy7YyCgeqUKDBkjcimK/weUcec960sI=</string>
</dict>
</array>
</dict>
</dict>
</dict>
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>Your background location usage description goes here.</string>
<key>NSLocationWhenInUseUsageDescription</key>
Expand All @@ -45,6 +69,7 @@
</dict>
<key>UIBackgroundModes</key>
<array>
<string>fetch</string>
<string>location</string>
</array>
<key>UILaunchStoryboardName</key>
Expand All @@ -68,29 +93,5 @@
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<false/>
<key>NSPinnedDomains</key>
<dict>
<key>api-verified.radar.io</key>
<dict>
<key>NSIncludesSubdomains</key>
<true/>
<key>NSPinnedLeafIdentities</key>
<array>
<dict>
<key>SPKI-SHA256-BASE64</key>
<string>15ktYXSSU2llpy7YyCgeqUKDBkjcimK/weUcec960sI=</string>
</dict>
<dict>
<key>SPKI-SHA256-BASE64</key>
<string>15ktYXSSU2llpy7YyCgeqUKDBkjcimK/weUcec960sI=</string>
</dict>
</array>
</dict>
</dict>
</dict>
</dict>
</plist>
2 changes: 1 addition & 1 deletion RadarSDK.podspec
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = 'RadarSDK'
s.version = '3.17.0'
s.version = '3.18.0'
s.summary = 'iOS SDK for Radar, the leading geofencing and location tracking platform'
s.homepage = 'https://radar.com'
s.author = { 'Radar Labs, Inc.' => '[email protected]' }
Expand Down
14 changes: 12 additions & 2 deletions RadarSDK.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,9 @@
DD8E2F7D24018C54002D51AB /* CLVisitMock.m in Sources */ = {isa = PBXBuildFile; fileRef = DD8E2F7C24018C54002D51AB /* CLVisitMock.m */; };
DE1E7644239724FD006F34A1 /* search_geofences.json in Resources */ = {isa = PBXBuildFile; fileRef = DE1E7643239724FD006F34A1 /* search_geofences.json */; };
E698B6502C6112FA00084371 /* RadarMotionProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = E698B64F2C6112FA00084371 /* RadarMotionProtocol.h */; settings = {ATTRIBUTES = (Public, ); }; };
E6B93B722C90E2B8003CB858 /* RadarInitializeOptions.h in Headers */ = {isa = PBXBuildFile; fileRef = E6B93B712C90E2B8003CB858 /* RadarInitializeOptions.h */; settings = {ATTRIBUTES = (Public, ); }; };
E6B93B742C90E5B8003CB858 /* RadarInitializeOptions.m in Sources */ = {isa = PBXBuildFile; fileRef = E6B93B732C90E5B8003CB858 /* RadarInitializeOptions.m */; };
E6B93B752C90E5B8003CB858 /* RadarInitializeOptions.m in Sources */ = {isa = PBXBuildFile; fileRef = E6B93B732C90E5B8003CB858 /* RadarInitializeOptions.m */; };
E6EEC56E2B20F41A00DD096B /* RadarFileStorage.h in Headers */ = {isa = PBXBuildFile; fileRef = E6EEC56D2B20F41A00DD096B /* RadarFileStorage.h */; };
E6EEC5702B20F45D00DD096B /* RadarFileStorage.m in Sources */ = {isa = PBXBuildFile; fileRef = E6EEC56F2B20F45D00DD096B /* RadarFileStorage.m */; };
F65AF72C2C10B242002BA009 /* get_config_response.json in Resources */ = {isa = PBXBuildFile; fileRef = F65AF72B2C10B242002BA009 /* get_config_response.json */; };
Expand Down Expand Up @@ -337,6 +340,8 @@
DDF1157C2524E18100D575C4 /* RadarTrip.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RadarTrip.m; sourceTree = "<group>"; };
DE1E7643239724FD006F34A1 /* search_geofences.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = search_geofences.json; sourceTree = "<group>"; };
E698B64F2C6112FA00084371 /* RadarMotionProtocol.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RadarMotionProtocol.h; sourceTree = "<group>"; };
E6B93B712C90E2B8003CB858 /* RadarInitializeOptions.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RadarInitializeOptions.h; sourceTree = "<group>"; };
E6B93B732C90E5B8003CB858 /* RadarInitializeOptions.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RadarInitializeOptions.m; sourceTree = "<group>"; };
E6EEC56D2B20F41A00DD096B /* RadarFileStorage.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RadarFileStorage.h; sourceTree = "<group>"; };
E6EEC56F2B20F45D00DD096B /* RadarFileStorage.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RadarFileStorage.m; sourceTree = "<group>"; };
F65AF72B2C10B242002BA009 /* get_config_response.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = get_config_response.json; sourceTree = "<group>"; };
Expand Down Expand Up @@ -390,6 +395,7 @@
96A5A0DA27AD9F7F007B960B /* RadarEvent.h */,
96A5A0E927AD9F7F007B960B /* RadarFraud.h */,
96A5A0E627AD9F7F007B960B /* RadarGeofence.h */,
E6B93B712C90E2B8003CB858 /* RadarInitializeOptions.h */,
96A5A0E227AD9F7F007B960B /* RadarGeofenceGeometry.h */,
96A5A0F327AD9F7F007B960B /* RadarPlace.h */,
96A5A0F027AD9F7F007B960B /* RadarPolygonGeometry.h */,
Expand Down Expand Up @@ -474,6 +480,7 @@
532FC303277A783900989279 /* Radar+Internal.h */,
DD236C9923087F9200EB88F9 /* RadarAPIClient.m */,
DD633EC1237C5B800026C91A /* RadarAPIHelper.h */,
E6B93B732C90E5B8003CB858 /* RadarInitializeOptions.m */,
DD633EC2237C5B800026C91A /* RadarAPIHelper.m */,
DD6F4F662573174400AFA38B /* RadarBeaconManager.h */,
DD64416E25B398A7003C3E63 /* RadarBeaconManager.m */,
Expand Down Expand Up @@ -642,6 +649,7 @@
019514362BD078D90031ABA2 /* RadarVerifiedLocationToken.h in Headers */,
96A5A10B27AD9F7F007B960B /* RadarTripOptions.h in Headers */,
E698B6502C6112FA00084371 /* RadarMotionProtocol.h in Headers */,
E6B93B722C90E2B8003CB858 /* RadarInitializeOptions.h in Headers */,
82F7FAEE2A65FE030055AA4B /* RadarVerificationManager.h in Headers */,
96A5A0C727AD9F41007B960B /* RadarChain+Internal.h in Headers */,
96A5A0C827AD9F41007B960B /* RadarBeacon+Internal.h in Headers */,
Expand Down Expand Up @@ -853,6 +861,7 @@
E6EEC5702B20F45D00DD096B /* RadarFileStorage.m in Sources */,
0107AB29262201F4008AB52F /* RadarTrackingOptions.m in Sources */,
0107AB2F262201FB008AB52F /* RadarUtils.m in Sources */,
E6B93B752C90E5B8003CB858 /* RadarInitializeOptions.m in Sources */,
0107AA8926220140008AB52F /* RadarChain.m in Sources */,
F667F8272BFBF3C8001F2F67 /* RadarSdkConfiguration.m in Sources */,
F667F8272BFBF3C8001F2F67 /* RadarSdkConfiguration.m in Sources */,
Expand Down Expand Up @@ -896,6 +905,7 @@
DD8E2F7424018C17002D51AB /* RadarPermissionsHelperMock.m in Sources */,
DD8E2F7724018C25002D51AB /* RadarAPIHelperMock.m in Sources */,
96B465BC27D6732500D7119B /* CLLocation+RadarTests.m in Sources */,
E6B93B742C90E5B8003CB858 /* RadarInitializeOptions.m in Sources */,
DD103211237E0C47003DD408 /* RadarSDKTests.m in Sources */,
DD8E2F7124018BF9002D51AB /* RadarTestUtils.m in Sources */,
DD8E2F7D24018C54002D51AB /* CLVisitMock.m in Sources */,
Expand Down Expand Up @@ -1038,7 +1048,7 @@
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 10.0;
MARKETING_VERSION = "3.17.0";
MARKETING_VERSION = 3.18.0;
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES;
ONLY_ACTIVE_ARCH = YES;
Expand Down Expand Up @@ -1096,7 +1106,7 @@
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 10.0;
MARKETING_VERSION = "3.17.0";
MARKETING_VERSION = 3.18.0;
MTL_ENABLE_DEBUG_INFO = NO;
MTL_FAST_MATH = YES;
OTHER_CFLAGS = "-fembed-bitcode";
Expand Down
35 changes: 32 additions & 3 deletions RadarSDK/Include/Radar.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#import "RadarTrackingOptions.h"
#import "RadarVerifiedLocationToken.h"
#import "RadarUser.h"
#import "RadarInitializeOptions.h"

NS_ASSUME_NONNULL_BEGIN

Expand Down Expand Up @@ -302,7 +303,7 @@ typedef void (^_Nonnull RadarRouteMatrixCompletionHandler)(RadarStatus status, R
@see https://radar.com/documentation/api#send-a-custom-event
*/
typedef void (^_Nonnull RadarLogConversionCompletionHandler)(RadarStatus status, RadarEvent *_Nullable event);
typedef void (^_Nullable RadarLogConversionCompletionHandler)(RadarStatus status, RadarEvent *_Nullable event);

/**
The main class used to interact with the Radar SDK.
Expand All @@ -324,6 +325,18 @@ typedef void (^_Nonnull RadarLogConversionCompletionHandler)(RadarStatus status,
*/
+ (void)initializeWithPublishableKey:(NSString *_Nonnull)publishableKey NS_SWIFT_NAME(initialize(publishableKey:));

/**
Initializes the Radar SDK.
@warning Call this method from the main thread in your `AppDelegate` class before calling any other Radar methods.
@param publishableKey Your publishable API key.
@param options Radar SDK initialization options.
@see https://radar.com/documentation/sdk/ios#initialize-sdk
*/

+ (void)initializeWithPublishableKey:(NSString *)publishableKey options:(RadarInitializeOptions *)options NS_SWIFT_NAME(initialize(publishableKey:options:));
#pragma mark - Properties

/**
Expand Down Expand Up @@ -634,7 +647,7 @@ typedef void (^_Nonnull RadarLogConversionCompletionHandler)(RadarStatus status,
completionHandler:(RadarLogConversionCompletionHandler)completionHandler NS_SWIFT_NAME(logConversion(name:metadata:completionHandler:));

/**
Logs a conversion with revenue
Logs a conversion with revenue.
@param name The name of the conversion.
@param revenue The revenue generated by the conversion.
Expand All @@ -649,13 +662,22 @@ typedef void (^_Nonnull RadarLogConversionCompletionHandler)(RadarStatus status,
completionHandler:(RadarLogConversionCompletionHandler)completionHandler NS_SWIFT_NAME(logConversion(name:revenue:metadata:completionHandler:));

/**
logConversionWithNotification
Logs a conversion with a notification.
@param request The request associated with the notification
@see https://radar.com/documentation/api#send-a-custom-event
*/
+ (void)logConversionWithNotification:(UNNotificationRequest *_Nullable)request NS_SWIFT_NAME(logConversion(request:));

/**
Logs a conversion with a notification. This should only be used to manually setup logging of notification conversions.
@param response The response associated with user interaction with the notification.
@see https://radar.com/documentation/api#send-a-custom-event
*/

+ (void)logConversionWithNotificationResponse:(UNNotificationResponse *)response NS_SWIFT_NAME(logConversion(response:));

#pragma mark - Trips

/**
Expand Down Expand Up @@ -1203,6 +1225,13 @@ logConversionWithNotification
*/
+ (NSDictionary *)dictionaryForLocation:(CLLocation *)location NS_SWIFT_NAME(dictionaryForLocation(_:));


/**
Performs optional setup for Radar SDK within the AppDelegate. This method only needs to be called if Radar is initalized in cross-platform code.
*/
+ (void)nativeSetup NS_SWIFT_NAME(nativeSetup());

@end

NS_ASSUME_NONNULL_END
17 changes: 17 additions & 0 deletions RadarSDK/Include/RadarInitializeOptions.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
//
// RadarInitializeOptions.h
// RadarSDK
//
// Created by Kenny Hu on 9/10/24.
// Copyright © 2024 Radar Labs, Inc. All rights reserved.
//


#import <Foundation/Foundation.h>

@interface RadarInitializeOptions : NSObject

@property (assign, nonatomic) BOOL autoLogNotificationConversions;

@end

8 changes: 8 additions & 0 deletions RadarSDK/Radar+Internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,12 @@

+ (void)logOpenedAppConversion;

+ (void)logConversionWithNotification:(UNNotificationRequest *_Nonnull)request
eventName:(NSString *_Nonnull)eventName
conversionSource:(NSString *_Nullable)conversionSource
deliveredAfter:(NSDate *_Nullable)deliveredAfter;

+ (void)logOpenedAppConversionWithNotification:(UNNotificationRequest *_Nonnull)request
conversionSource:(NSString *_Nullable)conversionSource;

@end
Loading

0 comments on commit d2c2928

Please sign in to comment.