Skip to content

Commit 7fc503a

Browse files
authored
Add notification service extension to MessagingExampleSwift.
Merge pull request #1774 from firebase/notification_service_extension
2 parents fe0b264 + f38b9fc commit 7fc503a

File tree

7 files changed

+264
-28
lines changed

7 files changed

+264
-28
lines changed

messaging/MessagingExample.xcodeproj/project.pbxproj

Lines changed: 181 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
objects = {
88

99
/* Begin PBXBuildFile section */
10+
0718C8BD2E8F256800AA7788 /* NotificationServiceExtension.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = 0718C8B62E8F256800AA7788 /* NotificationServiceExtension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
11+
0738A4882E8F2B2A00680EC4 /* NotificationService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0738A4862E8F2B2A00680EC4 /* NotificationService.swift */; };
1012
107347AB20315A3A004A66D1 /* MessagingExampleSwiftUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 107347AA20315A3A004A66D1 /* MessagingExampleSwiftUITests.swift */; };
1113
1073486120333BF5004A66D1 /* MessagingExampleUITests.m in Sources */ = {isa = PBXBuildFile; fileRef = 1073486020333BF5004A66D1 /* MessagingExampleUITests.m */; };
1214
5B334EAC56E0F5E167C81718 /* GoogleService-Info.plist in Sources */ = {isa = PBXBuildFile; fileRef = 82E79B6D15A982EAE7B0E31B /* GoogleService-Info.plist */; };
@@ -31,6 +33,13 @@
3133
/* End PBXBuildFile section */
3234

3335
/* Begin PBXContainerItemProxy section */
36+
0718C8BB2E8F256800AA7788 /* PBXContainerItemProxy */ = {
37+
isa = PBXContainerItemProxy;
38+
containerPortal = 5F5A53441ADE670C00F81DF0 /* Project object */;
39+
proxyType = 1;
40+
remoteGlobalIDString = 0718C8B52E8F256800AA7788;
41+
remoteInfo = NotificationServiceExtension;
42+
};
3443
107347AD20315A3A004A66D1 /* PBXContainerItemProxy */ = {
3544
isa = PBXContainerItemProxy;
3645
containerPortal = 5F5A53441ADE670C00F81DF0 /* Project object */;
@@ -54,7 +63,24 @@
5463
};
5564
/* End PBXContainerItemProxy section */
5665

66+
/* Begin PBXCopyFilesBuildPhase section */
67+
0718C8C22E8F256800AA7788 /* Embed Foundation Extensions */ = {
68+
isa = PBXCopyFilesBuildPhase;
69+
buildActionMask = 2147483647;
70+
dstPath = "";
71+
dstSubfolderSpec = 13;
72+
files = (
73+
0718C8BD2E8F256800AA7788 /* NotificationServiceExtension.appex in Embed Foundation Extensions */,
74+
);
75+
name = "Embed Foundation Extensions";
76+
runOnlyForDeploymentPostprocessing = 0;
77+
};
78+
/* End PBXCopyFilesBuildPhase section */
79+
5780
/* Begin PBXFileReference section */
81+
0718C8B62E8F256800AA7788 /* NotificationServiceExtension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = NotificationServiceExtension.appex; sourceTree = BUILT_PRODUCTS_DIR; };
82+
0738A4852E8F2B2A00680EC4 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
83+
0738A4862E8F2B2A00680EC4 /* NotificationService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationService.swift; sourceTree = "<group>"; };
5884
107347A820315A3A004A66D1 /* MessagingExampleSwiftUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = MessagingExampleSwiftUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
5985
107347AA20315A3A004A66D1 /* MessagingExampleSwiftUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessagingExampleSwiftUITests.swift; sourceTree = "<group>"; };
6086
107347AC20315A3A004A66D1 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
@@ -87,6 +113,13 @@
87113
/* End PBXFileReference section */
88114

89115
/* Begin PBXFrameworksBuildPhase section */
116+
0718C8B32E8F256800AA7788 /* Frameworks */ = {
117+
isa = PBXFrameworksBuildPhase;
118+
buildActionMask = 2147483647;
119+
files = (
120+
);
121+
runOnlyForDeploymentPostprocessing = 0;
122+
};
90123
107347A520315A3A004A66D1 /* Frameworks */ = {
91124
isa = PBXFrameworksBuildPhase;
92125
buildActionMask = 2147483647;
@@ -125,6 +158,15 @@
125158
/* End PBXFrameworksBuildPhase section */
126159

127160
/* Begin PBXGroup section */
161+
0738A48A2E8F2BB900680EC4 /* NotificationServiceExtension */ = {
162+
isa = PBXGroup;
163+
children = (
164+
0738A4852E8F2B2A00680EC4 /* Info.plist */,
165+
0738A4862E8F2B2A00680EC4 /* NotificationService.swift */,
166+
);
167+
path = NotificationServiceExtension;
168+
sourceTree = "<group>";
169+
};
128170
107347A920315A3A004A66D1 /* MessagingExampleSwiftUITests */ = {
129171
isa = PBXGroup;
130172
children = (
@@ -155,6 +197,7 @@
155197
5F5A534D1ADE670C00F81DF0 /* Products */,
156198
5F9961041AE0CF4F0034F503 /* Shared */,
157199
82E79B6D15A982EAE7B0E31B /* GoogleService-Info.plist */,
200+
0738A48A2E8F2BB900680EC4 /* NotificationServiceExtension */,
158201
);
159202
sourceTree = "<group>";
160203
wrapsLines = 0;
@@ -167,6 +210,7 @@
167210
5FDE05581B0DAA090037B82F /* MessagingExampleTests.xctest */,
168211
107347A820315A3A004A66D1 /* MessagingExampleSwiftUITests.xctest */,
169212
1073485E20333BF5004A66D1 /* MessagingExampleUITests.xctest */,
213+
0718C8B62E8F256800AA7788 /* NotificationServiceExtension.appex */,
170214
);
171215
name = Products;
172216
sourceTree = "<group>";
@@ -238,6 +282,23 @@
238282
/* End PBXGroup section */
239283

240284
/* Begin PBXNativeTarget section */
285+
0718C8B52E8F256800AA7788 /* NotificationServiceExtension */ = {
286+
isa = PBXNativeTarget;
287+
buildConfigurationList = 0718C8BF2E8F256800AA7788 /* Build configuration list for PBXNativeTarget "NotificationServiceExtension" */;
288+
buildPhases = (
289+
0718C8B22E8F256800AA7788 /* Sources */,
290+
0718C8B32E8F256800AA7788 /* Frameworks */,
291+
0718C8B42E8F256800AA7788 /* Resources */,
292+
);
293+
buildRules = (
294+
);
295+
dependencies = (
296+
);
297+
name = NotificationServiceExtension;
298+
productName = NotificationServiceExtension;
299+
productReference = 0718C8B62E8F256800AA7788 /* NotificationServiceExtension.appex */;
300+
productType = "com.apple.product-type.app-extension";
301+
};
241302
107347A720315A3A004A66D1 /* MessagingExampleSwiftUITests */ = {
242303
isa = PBXNativeTarget;
243304
buildConfigurationList = 107347AF20315A3A004A66D1 /* Build configuration list for PBXNativeTarget "MessagingExampleSwiftUITests" */;
@@ -298,10 +359,12 @@
298359
5F5A53751ADE67D500F81DF0 /* Sources */,
299360
5F5A53761ADE67D500F81DF0 /* Frameworks */,
300361
5F5A53771ADE67D500F81DF0 /* Resources */,
362+
0718C8C22E8F256800AA7788 /* Embed Foundation Extensions */,
301363
);
302364
buildRules = (
303365
);
304366
dependencies = (
367+
0718C8BC2E8F256800AA7788 /* PBXTargetDependency */,
305368
);
306369
name = MessagingExampleSwift;
307370
productName = FCMSwift;
@@ -332,10 +395,14 @@
332395
5F5A53441ADE670C00F81DF0 /* Project object */ = {
333396
isa = PBXProject;
334397
attributes = {
335-
LastSwiftUpdateCheck = 0920;
398+
LastSwiftUpdateCheck = 1640;
336399
LastUpgradeCheck = 1110;
337400
ORGANIZATIONNAME = "Google Inc.";
338401
TargetAttributes = {
402+
0718C8B52E8F256800AA7788 = {
403+
CreatedOnToolsVersion = 16.4;
404+
ProvisioningStyle = Automatic;
405+
};
339406
107347A720315A3A004A66D1 = {
340407
CreatedOnToolsVersion = 9.2;
341408
LastSwiftMigration = 1110;
@@ -395,11 +462,19 @@
395462
5FDE05571B0DAA090037B82F /* MessagingExampleTests */,
396463
107347A720315A3A004A66D1 /* MessagingExampleSwiftUITests */,
397464
1073485D20333BF5004A66D1 /* MessagingExampleUITests */,
465+
0718C8B52E8F256800AA7788 /* NotificationServiceExtension */,
398466
);
399467
};
400468
/* End PBXProject section */
401469

402470
/* Begin PBXResourcesBuildPhase section */
471+
0718C8B42E8F256800AA7788 /* Resources */ = {
472+
isa = PBXResourcesBuildPhase;
473+
buildActionMask = 2147483647;
474+
files = (
475+
);
476+
runOnlyForDeploymentPostprocessing = 0;
477+
};
403478
107347A620315A3A004A66D1 /* Resources */ = {
404479
isa = PBXResourcesBuildPhase;
405480
buildActionMask = 2147483647;
@@ -444,6 +519,14 @@
444519
/* End PBXResourcesBuildPhase section */
445520

446521
/* Begin PBXSourcesBuildPhase section */
522+
0718C8B22E8F256800AA7788 /* Sources */ = {
523+
isa = PBXSourcesBuildPhase;
524+
buildActionMask = 2147483647;
525+
files = (
526+
0738A4882E8F2B2A00680EC4 /* NotificationService.swift in Sources */,
527+
);
528+
runOnlyForDeploymentPostprocessing = 0;
529+
};
447530
107347A420315A3A004A66D1 /* Sources */ = {
448531
isa = PBXSourcesBuildPhase;
449532
buildActionMask = 2147483647;
@@ -497,6 +580,11 @@
497580
/* End PBXSourcesBuildPhase section */
498581

499582
/* Begin PBXTargetDependency section */
583+
0718C8BC2E8F256800AA7788 /* PBXTargetDependency */ = {
584+
isa = PBXTargetDependency;
585+
target = 0718C8B52E8F256800AA7788 /* NotificationServiceExtension */;
586+
targetProxy = 0718C8BB2E8F256800AA7788 /* PBXContainerItemProxy */;
587+
};
500588
107347AE20315A3A004A66D1 /* PBXTargetDependency */ = {
501589
isa = PBXTargetDependency;
502590
target = 5F5A53781ADE67D500F81DF0 /* MessagingExampleSwift */;
@@ -526,6 +614,83 @@
526614
/* End PBXVariantGroup section */
527615

528616
/* Begin XCBuildConfiguration section */
617+
0718C8C02E8F256800AA7788 /* Debug */ = {
618+
isa = XCBuildConfiguration;
619+
buildSettings = {
620+
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
621+
CLANG_ANALYZER_NONNULL = YES;
622+
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
623+
CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
624+
CLANG_ENABLE_OBJC_WEAK = YES;
625+
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
626+
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
627+
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
628+
CODE_SIGN_IDENTITY = "Apple Development";
629+
CODE_SIGN_STYLE = Automatic;
630+
CURRENT_PROJECT_VERSION = 1;
631+
DEBUG_INFORMATION_FORMAT = dwarf;
632+
DEVELOPMENT_TEAM = "";
633+
ENABLE_USER_SCRIPT_SANDBOXING = YES;
634+
GCC_C_LANGUAGE_STANDARD = gnu17;
635+
GENERATE_INFOPLIST_FILE = YES;
636+
INFOPLIST_FILE = NotificationServiceExtension/Info.plist;
637+
INFOPLIST_KEY_CFBundleDisplayName = NotificationServiceExtension;
638+
INFOPLIST_KEY_NSHumanReadableCopyright = "Copyright © 2025 Google Inc. All rights reserved.";
639+
IPHONEOS_DEPLOYMENT_TARGET = 18.5;
640+
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks";
641+
LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
642+
MARKETING_VERSION = 1.0;
643+
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
644+
MTL_FAST_MATH = YES;
645+
PRODUCT_BUNDLE_IDENTIFIER = com.google.firebase.quickstart.MessagingExample.NotificationServiceExtension;
646+
PRODUCT_NAME = "$(TARGET_NAME)";
647+
PROVISIONING_PROFILE_SPECIFIER = "";
648+
SKIP_INSTALL = YES;
649+
SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)";
650+
SWIFT_EMIT_LOC_STRINGS = YES;
651+
SWIFT_VERSION = 5.0;
652+
TARGETED_DEVICE_FAMILY = "1,2";
653+
};
654+
name = Debug;
655+
};
656+
0718C8C12E8F256800AA7788 /* Release */ = {
657+
isa = XCBuildConfiguration;
658+
buildSettings = {
659+
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
660+
CLANG_ANALYZER_NONNULL = YES;
661+
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
662+
CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
663+
CLANG_ENABLE_OBJC_WEAK = YES;
664+
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
665+
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
666+
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
667+
CODE_SIGN_IDENTITY = "Apple Development";
668+
CODE_SIGN_STYLE = Automatic;
669+
COPY_PHASE_STRIP = NO;
670+
CURRENT_PROJECT_VERSION = 1;
671+
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
672+
DEVELOPMENT_TEAM = "";
673+
ENABLE_USER_SCRIPT_SANDBOXING = YES;
674+
GCC_C_LANGUAGE_STANDARD = gnu17;
675+
GENERATE_INFOPLIST_FILE = YES;
676+
INFOPLIST_FILE = NotificationServiceExtension/Info.plist;
677+
INFOPLIST_KEY_CFBundleDisplayName = NotificationServiceExtension;
678+
INFOPLIST_KEY_NSHumanReadableCopyright = "Copyright © 2025 Google Inc. All rights reserved.";
679+
IPHONEOS_DEPLOYMENT_TARGET = 18.5;
680+
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks";
681+
LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
682+
MARKETING_VERSION = 1.0;
683+
MTL_FAST_MATH = YES;
684+
PRODUCT_BUNDLE_IDENTIFIER = com.google.firebase.quickstart.MessagingExample.NotificationServiceExtension;
685+
PRODUCT_NAME = "$(TARGET_NAME)";
686+
PROVISIONING_PROFILE_SPECIFIER = "";
687+
SKIP_INSTALL = YES;
688+
SWIFT_EMIT_LOC_STRINGS = YES;
689+
SWIFT_VERSION = 5.0;
690+
TARGETED_DEVICE_FAMILY = "1,2";
691+
};
692+
name = Release;
693+
};
529694
107347B020315A3A004A66D1 /* Debug */ = {
530695
isa = XCBuildConfiguration;
531696
buildSettings = {
@@ -770,13 +935,14 @@
770935
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
771936
ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
772937
CODE_SIGN_ENTITLEMENTS = MessagingExampleSwift/MessagingExampleSwift.entitlements;
773-
CODE_SIGN_IDENTITY = "iPhone Developer";
774-
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
938+
CODE_SIGN_IDENTITY = "Apple Development";
939+
CODE_SIGN_STYLE = Automatic;
775940
DEVELOPMENT_TEAM = "";
776941
INFOPLIST_FILE = MessagingExample/Info.plist;
777942
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
778943
PRODUCT_BUNDLE_IDENTIFIER = com.google.firebase.quickstart.MessagingExample;
779944
PRODUCT_NAME = "$(TARGET_NAME)";
945+
PROVISIONING_PROFILE_SPECIFIER = "";
780946
SWIFT_SWIFT3_OBJC_INFERENCE = Off;
781947
SWIFT_VERSION = 5.0;
782948
};
@@ -788,13 +954,14 @@
788954
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
789955
ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
790956
CODE_SIGN_ENTITLEMENTS = MessagingExampleSwift/MessagingExampleSwift.entitlements;
791-
CODE_SIGN_IDENTITY = "iPhone Developer";
792-
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
957+
CODE_SIGN_IDENTITY = "Apple Development";
958+
CODE_SIGN_STYLE = Automatic;
793959
DEVELOPMENT_TEAM = "";
794960
INFOPLIST_FILE = MessagingExample/Info.plist;
795961
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
796962
PRODUCT_BUNDLE_IDENTIFIER = com.google.firebase.quickstart.MessagingExample;
797963
PRODUCT_NAME = "$(TARGET_NAME)";
964+
PROVISIONING_PROFILE_SPECIFIER = "";
798965
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
799966
SWIFT_SWIFT3_OBJC_INFERENCE = Off;
800967
SWIFT_VERSION = 5.0;
@@ -835,6 +1002,15 @@
8351002
/* End XCBuildConfiguration section */
8361003

8371004
/* Begin XCConfigurationList section */
1005+
0718C8BF2E8F256800AA7788 /* Build configuration list for PBXNativeTarget "NotificationServiceExtension" */ = {
1006+
isa = XCConfigurationList;
1007+
buildConfigurations = (
1008+
0718C8C02E8F256800AA7788 /* Debug */,
1009+
0718C8C12E8F256800AA7788 /* Release */,
1010+
);
1011+
defaultConfigurationIsVisible = 0;
1012+
defaultConfigurationName = Release;
1013+
};
8381014
107347AF20315A3A004A66D1 /* Build configuration list for PBXNativeTarget "MessagingExampleSwiftUITests" */ = {
8391015
isa = XCConfigurationList;
8401016
buildConfigurations = (

messaging/MessagingExample.xcodeproj/xcshareddata/xcschemes/MessagingExample.xcscheme

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,16 @@
7979
ReferencedContainer = "container:MessagingExample.xcodeproj">
8080
</BuildableReference>
8181
</BuildableProductRunnable>
82+
<CommandLineArguments>
83+
<CommandLineArgument
84+
argument = "-FIRDebugEnabled"
85+
isEnabled = "YES">
86+
</CommandLineArgument>
87+
<CommandLineArgument
88+
argument = "-FIRAnalyticsDebugEnabled"
89+
isEnabled = "YES">
90+
</CommandLineArgument>
91+
</CommandLineArguments>
8292
</LaunchAction>
8393
<ProfileAction
8494
buildConfiguration = "Release"

messaging/MessagingExampleSwift/AppDelegate.swift

Lines changed: 6 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -53,25 +53,8 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
5353
return true
5454
}
5555

56-
func application(_ application: UIApplication,
57-
didReceiveRemoteNotification userInfo: [AnyHashable: Any]) {
58-
// If you are receiving a notification message while your app is in the background,
59-
// this callback will not be fired till the user taps on the notification launching the application.
60-
// TODO: Handle data of notification
61-
62-
// With swizzling disabled you must let Messaging know about the message, for Analytics
63-
// Messaging.messaging().appDidReceiveMessage(userInfo)
64-
65-
// Print message ID.
66-
if let messageID = userInfo[gcmMessageIDKey] {
67-
print("Message ID: \(messageID)")
68-
}
69-
70-
// Print full message.
71-
print(userInfo)
72-
}
73-
7456
// [START receive_message]
57+
@MainActor
7558
func application(_ application: UIApplication,
7659
didReceiveRemoteNotification userInfo: [AnyHashable: Any]) async
7760
-> UIBackgroundFetchResult {
@@ -89,12 +72,12 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
8972

9073
// Print full message.
9174
print(userInfo)
92-
75+
print("Call exportDeliveryMetricsToBigQuery() from AppDelegate")
76+
Messaging.serviceExtension().exportDeliveryMetricsToBigQuery(withMessageInfo: userInfo)
9377
return UIBackgroundFetchResult.newData
9478
}
9579

9680
// [END receive_message]
97-
9881
func application(_ application: UIApplication,
9982
didFailToRegisterForRemoteNotificationsWithError error: Error) {
10083
print("Unable to register for remote notifications: \(error.localizedDescription)")
@@ -105,8 +88,9 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
10588
// the FCM registration token.
10689
func application(_ application: UIApplication,
10790
didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
108-
print("APNs token retrieved: \(deviceToken)")
109-
91+
let tokenParts = deviceToken.map { data in String(format: "%02.2hhx", data) }
92+
let token = tokenParts.joined()
93+
print("APNs token retrieved: \(token)")
11094
// With swizzling disabled you must set the APNs token here.
11195
// Messaging.messaging().apnsToken = deviceToken
11296
}

0 commit comments

Comments
 (0)