Skip to content

Commit d8cb608

Browse files
committed
feat: enhance AppDelegate
1 parent 0470f8e commit d8cb608

2 files changed

Lines changed: 123 additions & 36 deletions

File tree

example/ios/ReactNativeSdkExample.xcodeproj/project.pbxproj

Lines changed: 31 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@
99
/* Begin PBXBuildFile section */
1010
00E356F31AD99517003FC87E /* ReactNativeSdkExampleTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 00E356F21AD99517003FC87E /* ReactNativeSdkExampleTests.m */; };
1111
13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; };
12+
1A990D0CDC805E6B277A757F /* libPods-ReactNativeSdkExample.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5D0C0ACFEE5C77CF4A675B73 /* libPods-ReactNativeSdkExample.a */; };
1213
779227342DFA3FB500D69EC0 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 779227332DFA3FB500D69EC0 /* AppDelegate.swift */; };
13-
7A78ECB858FF7B7F2B3C15FD /* libPods-ReactNativeSdkExample.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 0E6013A3CAD2CEA39589EB48 /* libPods-ReactNativeSdkExample.a */; };
1414
81AB9BB82411601600AC10FF /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */; };
1515
A3A40C20801B8F02005FA4C0 /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = 1FC6B09E65A7BD9F6864C5D8 /* PrivacyInfo.xcprivacy */; };
1616
/* End PBXBuildFile section */
@@ -29,19 +29,19 @@
2929
00E356EE1AD99517003FC87E /* ReactNativeSdkExampleTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = ReactNativeSdkExampleTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
3030
00E356F11AD99517003FC87E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
3131
00E356F21AD99517003FC87E /* ReactNativeSdkExampleTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ReactNativeSdkExampleTests.m; sourceTree = "<group>"; };
32-
0E6013A3CAD2CEA39589EB48 /* libPods-ReactNativeSdkExample.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-ReactNativeSdkExample.a"; sourceTree = BUILT_PRODUCTS_DIR; };
3332
13B07F961A680F5B00A75B9A /* ReactNativeSdkExample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = ReactNativeSdkExample.app; sourceTree = BUILT_PRODUCTS_DIR; };
3433
13B07FB51A68108700A75B9A /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = ReactNativeSdkExample/Images.xcassets; sourceTree = "<group>"; };
3534
13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = ReactNativeSdkExample/Info.plist; sourceTree = "<group>"; };
3635
13B07FB81A68108700A75B9A /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = PrivacyInfo.xcprivacy; path = ReactNativeSdkExample/PrivacyInfo.xcprivacy; sourceTree = "<group>"; };
3736
1FC6B09E65A7BD9F6864C5D8 /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xml; name = PrivacyInfo.xcprivacy; path = ReactNativeSdkExample/PrivacyInfo.xcprivacy; sourceTree = "<group>"; };
37+
5D0C0ACFEE5C77CF4A675B73 /* libPods-ReactNativeSdkExample.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-ReactNativeSdkExample.a"; sourceTree = BUILT_PRODUCTS_DIR; };
38+
6E3EFD52D0FD52FBD6EEE4FD /* Pods-ReactNativeSdkExample.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ReactNativeSdkExample.release.xcconfig"; path = "Target Support Files/Pods-ReactNativeSdkExample/Pods-ReactNativeSdkExample.release.xcconfig"; sourceTree = "<group>"; };
3839
779227312DFA3FB500D69EC0 /* ReactNativeSdkExample-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "ReactNativeSdkExample-Bridging-Header.h"; sourceTree = "<group>"; };
3940
779227322DFA3FB500D69EC0 /* ReactNativeSdkExampleTests-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "ReactNativeSdkExampleTests-Bridging-Header.h"; sourceTree = "<group>"; };
4041
779227332DFA3FB500D69EC0 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = AppDelegate.swift; path = ReactNativeSdkExample/AppDelegate.swift; sourceTree = "<group>"; };
41-
7C953C8BB795CAD77F34D8D7 /* Pods-ReactNativeSdkExample.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ReactNativeSdkExample.release.xcconfig"; path = "Target Support Files/Pods-ReactNativeSdkExample/Pods-ReactNativeSdkExample.release.xcconfig"; sourceTree = "<group>"; };
42+
7E618CBD06C168ADAA45A7D6 /* Pods-ReactNativeSdkExample.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ReactNativeSdkExample.debug.xcconfig"; path = "Target Support Files/Pods-ReactNativeSdkExample/Pods-ReactNativeSdkExample.debug.xcconfig"; sourceTree = "<group>"; };
4243
81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; name = LaunchScreen.storyboard; path = ReactNativeSdkExample/LaunchScreen.storyboard; sourceTree = "<group>"; };
4344
ED297162215061F000B7C4FE /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = System/Library/Frameworks/JavaScriptCore.framework; sourceTree = SDKROOT; };
44-
FC1667EC7B1616549D9E12AD /* Pods-ReactNativeSdkExample.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ReactNativeSdkExample.debug.xcconfig"; path = "Target Support Files/Pods-ReactNativeSdkExample/Pods-ReactNativeSdkExample.debug.xcconfig"; sourceTree = "<group>"; };
4545
/* End PBXFileReference section */
4646

4747
/* Begin PBXFrameworksBuildPhase section */
@@ -56,7 +56,7 @@
5656
isa = PBXFrameworksBuildPhase;
5757
buildActionMask = 2147483647;
5858
files = (
59-
7A78ECB858FF7B7F2B3C15FD /* libPods-ReactNativeSdkExample.a in Frameworks */,
59+
1A990D0CDC805E6B277A757F /* libPods-ReactNativeSdkExample.a in Frameworks */,
6060
);
6161
runOnlyForDeploymentPostprocessing = 0;
6262
};
@@ -99,7 +99,7 @@
9999
isa = PBXGroup;
100100
children = (
101101
ED297162215061F000B7C4FE /* JavaScriptCore.framework */,
102-
0E6013A3CAD2CEA39589EB48 /* libPods-ReactNativeSdkExample.a */,
102+
5D0C0ACFEE5C77CF4A675B73 /* libPods-ReactNativeSdkExample.a */,
103103
);
104104
name = Frameworks;
105105
sourceTree = "<group>";
@@ -138,8 +138,8 @@
138138
BBD78D7AC51CEA395F1C20DB /* Pods */ = {
139139
isa = PBXGroup;
140140
children = (
141-
FC1667EC7B1616549D9E12AD /* Pods-ReactNativeSdkExample.debug.xcconfig */,
142-
7C953C8BB795CAD77F34D8D7 /* Pods-ReactNativeSdkExample.release.xcconfig */,
141+
7E618CBD06C168ADAA45A7D6 /* Pods-ReactNativeSdkExample.debug.xcconfig */,
142+
6E3EFD52D0FD52FBD6EEE4FD /* Pods-ReactNativeSdkExample.release.xcconfig */,
143143
);
144144
path = Pods;
145145
sourceTree = "<group>";
@@ -169,13 +169,13 @@
169169
isa = PBXNativeTarget;
170170
buildConfigurationList = 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "ReactNativeSdkExample" */;
171171
buildPhases = (
172-
84FB78A43318D70EFC6E5885 /* [CP] Check Pods Manifest.lock */,
172+
B3B30202110DC49F0E0CA2D9 /* [CP] Check Pods Manifest.lock */,
173173
13B07F871A680F5B00A75B9A /* Sources */,
174174
13B07F8C1A680F5B00A75B9A /* Frameworks */,
175175
13B07F8E1A680F5B00A75B9A /* Resources */,
176176
00DD1BFF1BD5951E006B06BC /* Bundle React Native code and images */,
177-
76DD352201970F7652206F40 /* [CP] Embed Pods Frameworks */,
178-
92B70AE4A9F5E887121D0B73 /* [CP] Copy Pods Resources */,
177+
1E8C258AE112C7B549689AE9 /* [CP] Embed Pods Frameworks */,
178+
8677EE75FBA28E8975AEBDB8 /* [CP] Copy Pods Resources */,
179179
);
180180
buildRules = (
181181
);
@@ -260,7 +260,7 @@
260260
shellPath = /bin/sh;
261261
shellScript = "set -e\n\nWITH_ENVIRONMENT=\"$REACT_NATIVE_PATH/scripts/xcode/with-environment.sh\"\nREACT_NATIVE_XCODE=\"$REACT_NATIVE_PATH/scripts/react-native-xcode.sh\"\n\n/bin/sh -c \"$WITH_ENVIRONMENT $REACT_NATIVE_XCODE\"\n";
262262
};
263-
76DD352201970F7652206F40 /* [CP] Embed Pods Frameworks */ = {
263+
1E8C258AE112C7B549689AE9 /* [CP] Embed Pods Frameworks */ = {
264264
isa = PBXShellScriptBuildPhase;
265265
buildActionMask = 2147483647;
266266
files = (
@@ -277,43 +277,43 @@
277277
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-ReactNativeSdkExample/Pods-ReactNativeSdkExample-frameworks.sh\"\n";
278278
showEnvVarsInLog = 0;
279279
};
280-
84FB78A43318D70EFC6E5885 /* [CP] Check Pods Manifest.lock */ = {
280+
8677EE75FBA28E8975AEBDB8 /* [CP] Copy Pods Resources */ = {
281281
isa = PBXShellScriptBuildPhase;
282282
buildActionMask = 2147483647;
283283
files = (
284284
);
285285
inputFileListPaths = (
286+
"${PODS_ROOT}/Target Support Files/Pods-ReactNativeSdkExample/Pods-ReactNativeSdkExample-resources-${CONFIGURATION}-input-files.xcfilelist",
286287
);
287-
inputPaths = (
288-
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
289-
"${PODS_ROOT}/Manifest.lock",
290-
);
291-
name = "[CP] Check Pods Manifest.lock";
288+
name = "[CP] Copy Pods Resources";
292289
outputFileListPaths = (
293-
);
294-
outputPaths = (
295-
"$(DERIVED_FILE_DIR)/Pods-ReactNativeSdkExample-checkManifestLockResult.txt",
290+
"${PODS_ROOT}/Target Support Files/Pods-ReactNativeSdkExample/Pods-ReactNativeSdkExample-resources-${CONFIGURATION}-output-files.xcfilelist",
296291
);
297292
runOnlyForDeploymentPostprocessing = 0;
298293
shellPath = /bin/sh;
299-
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";
294+
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-ReactNativeSdkExample/Pods-ReactNativeSdkExample-resources.sh\"\n";
300295
showEnvVarsInLog = 0;
301296
};
302-
92B70AE4A9F5E887121D0B73 /* [CP] Copy Pods Resources */ = {
297+
B3B30202110DC49F0E0CA2D9 /* [CP] Check Pods Manifest.lock */ = {
303298
isa = PBXShellScriptBuildPhase;
304299
buildActionMask = 2147483647;
305300
files = (
306301
);
307302
inputFileListPaths = (
308-
"${PODS_ROOT}/Target Support Files/Pods-ReactNativeSdkExample/Pods-ReactNativeSdkExample-resources-${CONFIGURATION}-input-files.xcfilelist",
309303
);
310-
name = "[CP] Copy Pods Resources";
304+
inputPaths = (
305+
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
306+
"${PODS_ROOT}/Manifest.lock",
307+
);
308+
name = "[CP] Check Pods Manifest.lock";
311309
outputFileListPaths = (
312-
"${PODS_ROOT}/Target Support Files/Pods-ReactNativeSdkExample/Pods-ReactNativeSdkExample-resources-${CONFIGURATION}-output-files.xcfilelist",
310+
);
311+
outputPaths = (
312+
"$(DERIVED_FILE_DIR)/Pods-ReactNativeSdkExample-checkManifestLockResult.txt",
313313
);
314314
runOnlyForDeploymentPostprocessing = 0;
315315
shellPath = /bin/sh;
316-
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-ReactNativeSdkExample/Pods-ReactNativeSdkExample-resources.sh\"\n";
316+
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";
317317
showEnvVarsInLog = 0;
318318
};
319319
/* End PBXShellScriptBuildPhase section */
@@ -406,11 +406,12 @@
406406
};
407407
13B07F941A680F5B00A75B9A /* Debug */ = {
408408
isa = XCBuildConfiguration;
409-
baseConfigurationReference = FC1667EC7B1616549D9E12AD /* Pods-ReactNativeSdkExample.debug.xcconfig */;
409+
baseConfigurationReference = 7E618CBD06C168ADAA45A7D6 /* Pods-ReactNativeSdkExample.debug.xcconfig */;
410410
buildSettings = {
411411
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
412412
CLANG_ENABLE_MODULES = YES;
413413
CURRENT_PROJECT_VERSION = 1;
414+
"DEBUG_INFORMATION_FORMAT[sdk=iphonesimulator*]" = dwarf;
414415
DEVELOPMENT_TEAM = BP98Z28R86;
415416
ENABLE_BITCODE = NO;
416417
INFOPLIST_FILE = ReactNativeSdkExample/Info.plist;
@@ -436,11 +437,12 @@
436437
};
437438
13B07F951A680F5B00A75B9A /* Release */ = {
438439
isa = XCBuildConfiguration;
439-
baseConfigurationReference = 7C953C8BB795CAD77F34D8D7 /* Pods-ReactNativeSdkExample.release.xcconfig */;
440+
baseConfigurationReference = 6E3EFD52D0FD52FBD6EEE4FD /* Pods-ReactNativeSdkExample.release.xcconfig */;
440441
buildSettings = {
441442
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
442443
CLANG_ENABLE_MODULES = YES;
443444
CURRENT_PROJECT_VERSION = 1;
445+
"DEBUG_INFORMATION_FORMAT[sdk=iphonesimulator*]" = dwarf;
444446
DEVELOPMENT_TEAM = BP98Z28R86;
445447
INFOPLIST_FILE = ReactNativeSdkExample/Info.plist;
446448
IPHONEOS_DEPLOYMENT_TARGET = 15.1;

example/ios/ReactNativeSdkExample/AppDelegate.swift

Lines changed: 92 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,13 @@
55
// Created by Loren Posen on 6/11/25.
66
//
77

8+
import UIKit
89
import React
9-
import ReactAppDependencyProvider
1010
import React_RCTAppDelegate
11-
import UIKit
11+
import ReactAppDependencyProvider
12+
import UserNotifications
13+
14+
import IterableSDK
1215

1316
@main
1417
class AppDelegate: UIResponder, UIApplicationDelegate {
@@ -21,6 +24,9 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
2124
_ application: UIApplication,
2225
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil
2326
) -> Bool {
27+
NSLog("FINISHED LAUNCHING WITH OPTIONS")
28+
ITBInfo()
29+
2430
let delegate = ReactNativeDelegate()
2531
let factory = RCTReactNativeFactory(delegate: delegate)
2632
delegate.dependencyProvider = RCTAppDependencyProvider()
@@ -36,8 +42,73 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
3642
launchOptions: launchOptions
3743
)
3844

45+
setupUserNotificationCenter()
46+
3947
return true
4048
}
49+
50+
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
51+
NSLog("REGISTERED FOR REMOTE NOTIFICATIONS")
52+
ITBInfo()
53+
IterableAPI.register(token: deviceToken)
54+
}
55+
56+
func application(_ application: UIApplication,
57+
didFailToRegisterForRemoteNotificationsWithError
58+
error: Error) {
59+
NSLog("FAILED TO REGISTER FOR REMOTE NOTIFICATIONS")
60+
ITBInfo("error: \(error)")
61+
}
62+
63+
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
64+
NSLog("RECEIVED REMOTE NOTIFICATIONS")
65+
ITBInfo()
66+
IterableAppIntegration.application(application, didReceiveRemoteNotification: userInfo, fetchCompletionHandler: completionHandler)
67+
}
68+
69+
func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool {
70+
NSLog("RECEIVED UNIVERSAL LINK")
71+
NSLog("userActivity: \(userActivity)")
72+
ITBInfo()
73+
guard let url = userActivity.webpageURL else {
74+
return false
75+
}
76+
77+
return IterableAPI.handle(universalLink: url)
78+
}
79+
80+
func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
81+
NSLog("OPEN URL")
82+
NSLog("url: \(url)")
83+
NSLog("options: \(options)")
84+
ITBInfo()
85+
return RCTLinkingManager.application(app, open: url, options: options)
86+
}
87+
88+
private func setupUserNotificationCenter() {
89+
UNUserNotificationCenter.current().delegate = self
90+
UNUserNotificationCenter.current().getNotificationSettings { settings in
91+
if settings.authorizationStatus != .authorized {
92+
ITBInfo("Not authorized")
93+
// not authorized, ask for permission
94+
UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .badge, .sound]) { success, _ in
95+
ITBInfo("auth: \(success)")
96+
if success {
97+
DispatchQueue.main.async {
98+
UIApplication.shared.registerForRemoteNotifications()
99+
}
100+
}
101+
// TODO: Handle error etc.
102+
}
103+
} else {
104+
// already authorized
105+
ITBInfo("Already authorized")
106+
DispatchQueue.main.async {
107+
UIApplication.shared.registerForRemoteNotifications()
108+
}
109+
}
110+
}
111+
}
41112
}
42113

43114
class ReactNativeDelegate: RCTDefaultReactNativeFactoryDelegate {
@@ -46,10 +117,24 @@ class ReactNativeDelegate: RCTDefaultReactNativeFactoryDelegate {
46117
}
47118

48119
override func bundleURL() -> URL? {
49-
#if DEBUG
50-
RCTBundleURLProvider.sharedSettings().jsBundleURL(forBundleRoot: "index")
51-
#else
52-
Bundle.main.url(forResource: "main", withExtension: "jsbundle")
53-
#endif
120+
#if DEBUG
121+
RCTBundleURLProvider.sharedSettings().jsBundleURL(forBundleRoot: "index")
122+
#else
123+
Bundle.main.url(forResource: "main", withExtension: "jsbundle")
124+
#endif
125+
}
126+
}
127+
128+
extension AppDelegate: UNUserNotificationCenterDelegate {
129+
// App is running in the foreground
130+
public func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
131+
NSLog("WILL PRESENT NOTIFICATION")
132+
completionHandler([.alert, .badge, .sound])
133+
}
134+
135+
// The method will be called on the delegate when the user responded to the notification by opening the application, dismissing the notification or choosing a UNNotificationAction. The delegate must be set before the application returns from applicationDidFinishLaunching:.
136+
public func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
137+
NSLog("DID RECEIVE NOTIFICATION RESPONSE")
138+
IterableAppIntegration.userNotificationCenter(center, didReceive: response, withCompletionHandler: completionHandler)
54139
}
55140
}

0 commit comments

Comments
 (0)