修改pods

This commit is contained in:
2025-09-20 17:13:38 +08:00
parent 7787b3ee30
commit 28ff2b0264
5251 changed files with 345029 additions and 285168 deletions

View File

@@ -14,6 +14,9 @@
* limitations under the License.
*/
#ifndef FIREBASECORE_FIRAPPINTERNAL_H
#define FIREBASECORE_FIRAPPINTERNAL_H
#import <FirebaseCore/FIRApp.h>
@class FIRComponentContainer;
@@ -40,8 +43,26 @@ extern NSString *const kFIRAppNameKey;
extern NSString *const kFIRGoogleAppIDKey;
extern NSString *const kFirebaseCoreErrorDomain;
/** The `UserDefaults` suite name for `FirebaseCore`, for those storage locations that use it. */
extern NSString *const kFirebaseCoreDefaultsSuiteName;
/**
* Keys for the strings in the plist file.
*/
extern NSString *const kFIRAPIKey;
extern NSString *const kFIRTrackingID;
extern NSString *const kFIRGoogleAppID;
extern NSString *const kFIRClientID;
extern NSString *const kFIRGCMSenderID;
extern NSString *const kFIRAndroidClientID;
extern NSString *const kFIRDatabaseURL;
extern NSString *const kFIRStorageBucket;
extern NSString *const kFIRBundleID;
extern NSString *const kFIRProjectID;
/**
* Keys for the plist file name
*/
extern NSString *const kServiceInfoFileName;
extern NSString *const kServiceInfoFileType;
/**
* The format string for the `UserDefaults` key used for storing the data collection enabled flag.
@@ -157,3 +178,5 @@ extern NSString *const FIRAuthStateDidChangeInternalNotificationUIDKey;
@end
NS_ASSUME_NONNULL_END
#endif // FIREBASECORE_FIRAPPINTERNAL_H

View File

@@ -14,6 +14,9 @@
* limitations under the License.
*/
#ifndef FIREBASECORE_FIRCOMPONENT_H
#define FIREBASECORE_FIRCOMPONENT_H
#import <Foundation/Foundation.h>
@class FIRApp;
@@ -32,8 +35,6 @@ typedef _Nullable id (^FIRComponentCreationBlock)(FIRComponentContainer *contain
BOOL *isCacheable)
NS_SWIFT_NAME(ComponentCreationBlock);
@class FIRDependency;
/// Describes the timing of instantiation. Note: new components should default to lazy unless there
/// is a strong reason to be eager.
typedef NS_ENUM(NSInteger, FIRInstantiationTiming) {
@@ -52,9 +53,6 @@ NS_SWIFT_NAME(Component)
/// The timing of instantiation.
@property(nonatomic, readonly) FIRInstantiationTiming instantiationTiming;
/// An array of dependencies for the component.
@property(nonatomic, copy, readonly) NSArray<FIRDependency *> *dependencies;
/// A block to instantiate an instance of the component with the appropriate dependencies.
@property(nonatomic, copy, readonly) FIRComponentCreationBlock creationBlock;
@@ -72,14 +70,12 @@ NS_SWIFT_NAME(init(_:creationBlock:));
/// @param protocol - The protocol describing functionality provided by the component.
/// @param instantiationTiming - When the component should be initialized. Use .lazy unless there's
/// a good reason to be instantiated earlier.
/// @param dependencies - Any dependencies the `implementingClass` has, optional or required.
/// @param creationBlock - A block to instantiate the component with a container, and if
/// @return A component that can be registered with the component container.
+ (instancetype)componentWithProtocol:(Protocol *)protocol
instantiationTiming:(FIRInstantiationTiming)instantiationTiming
dependencies:(NSArray<FIRDependency *> *)dependencies
creationBlock:(FIRComponentCreationBlock)creationBlock
NS_SWIFT_NAME(init(_:instantiationTiming:dependencies:creationBlock:));
NS_SWIFT_NAME(init(_:instantiationTiming:creationBlock:));
// clang-format on
@@ -89,3 +85,5 @@ NS_SWIFT_NAME(init(_:instantiationTiming:dependencies:creationBlock:));
@end
NS_ASSUME_NONNULL_END
#endif // FIREBASECORE_FIRCOMPONENT_H

View File

@@ -13,6 +13,10 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef FIREBASECORE_FIRCOMPONENTCONTAINER_H
#define FIREBASECORE_FIRCOMPONENTCONTAINER_H
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@@ -43,3 +47,5 @@ NS_SWIFT_NAME(FirebaseComponentContainer)
@end
NS_ASSUME_NONNULL_END
#endif // FIREBASECORE_FIRCOMPONENTCONTAINER_H

View File

@@ -14,6 +14,9 @@
* limitations under the License.
*/
#ifndef FIREBASECORE_FIRCOMPONENTTYPE_H
#define FIREBASECORE_FIRCOMPONENTTYPE_H
#import <Foundation/Foundation.h>
@class FIRComponentContainer;
@@ -33,3 +36,5 @@ NS_SWIFT_NAME(ComponentType)
@end
NS_ASSUME_NONNULL_END
#endif // FIREBASECORE_FIRCOMPONENTTYPE_H

View File

@@ -1,45 +0,0 @@
/*
* Copyright 2018 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
/// A dependency on a specific protocol's functionality.
NS_SWIFT_NAME(Dependency)
@interface FIRDependency : NSObject
/// The protocol describing functionality being depended on.
@property(nonatomic, strong, readonly) Protocol *protocol;
/// A flag to specify if the dependency is required or not.
@property(nonatomic, readonly) BOOL isRequired;
/// Initializes a dependency that is required. Calls `init(protocol:isRequired:)` with true for
/// the required parameter.
/// Creates a required dependency on the specified protocol's functionality.
+ (instancetype)dependencyWithProtocol:(Protocol *)protocol;
/// Creates a dependency on the specified protocol's functionality and specify if it's required for
/// the class's functionality.
+ (instancetype)dependencyWithProtocol:(Protocol *)protocol isRequired:(BOOL)required;
/// Use `init(withProtocol:isRequired:)` instead.
- (instancetype)init NS_UNAVAILABLE;
@end
NS_ASSUME_NONNULL_END

View File

@@ -12,6 +12,9 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef FIREBASECORE_FIRHEARTBEATLOGGER_H
#define FIREBASECORE_FIRHEARTBEATLOGGER_H
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@@ -30,19 +33,24 @@ typedef NS_ENUM(NSInteger, FIRDailyHeartbeatCode) {
FIRDailyHeartbeatCodeSome = 2,
};
NS_SWIFT_SENDABLE
@protocol FIRHeartbeatLoggerProtocol <NSObject>
/// Asynchronously logs a heartbeat.
- (void)log;
#ifndef FIREBASE_BUILD_CMAKE
/// Flushes heartbeats from storage into a structured payload of heartbeats.
- (FIRHeartbeatsPayload *)flushHeartbeatsIntoPayload;
#endif // FIREBASE_BUILD_CMAKE
/// Gets the heartbeat code for today.
- (FIRDailyHeartbeatCode)heartbeatCodeForToday;
#ifndef FIREBASE_BUILD_CMAKE
/// Returns the header value for the heartbeat logger via the given completion handler..
- (void)asyncHeaderValueWithCompletionHandler:(void (^)(NSString *_Nullable))completionHandler
API_AVAILABLE(ios(13.0), macosx(10.15), macCatalyst(13.0), tvos(13.0), watchos(6.0));
/// Return the header value for the heartbeat logger.
- (NSString *_Nullable)headerValue;
#endif // FIREBASE_BUILD_CMAKE
@end
#ifndef FIREBASE_BUILD_CMAKE
@@ -68,13 +76,23 @@ NSString *_Nullable FIRHeaderValueFromHeartbeatsPayload(FIRHeartbeatsPayload *he
- (void)log;
#ifndef FIREBASE_BUILD_CMAKE
/// Flushes heartbeats from storage into a structured payload of heartbeats.
/// Synchronously flushes heartbeats from storage into a structured payload of heartbeats.
///
/// This API is for clients using platform logging V2.
///
/// @note This API is thread-safe.
/// @return A payload of heartbeats.
- (FIRHeartbeatsPayload *)flushHeartbeatsIntoPayload;
/// Asynchronously flushes heartbeats from storage into a structured payload of heartbeats.
///
/// This API is for clients using platform logging V2.
///
/// @note This API is thread-safe.
/// @param completionHandler A completion handler to process the flushed payload of heartbeats.
- (void)flushHeartbeatsIntoPayloadWithCompletionHandler:
(void (^)(FIRHeartbeatsPayload *))completionHandler
API_AVAILABLE(ios(13.0), macosx(10.15), macCatalyst(13.0), tvos(13.0), watchos(6.0));
#endif // FIREBASE_BUILD_CMAKE
/// Gets today's corresponding heartbeat code.
@@ -88,3 +106,5 @@ NSString *_Nullable FIRHeaderValueFromHeartbeatsPayload(FIRHeartbeatsPayload *he
@end
NS_ASSUME_NONNULL_END
#endif // FIREBASECORE_FIRHEARTBEATLOGGER_H

View File

@@ -14,6 +14,9 @@
* limitations under the License.
*/
#ifndef FIREBASECORE_FIRLIBRARY_H
#define FIREBASECORE_FIRLIBRARY_H
#ifndef FIRLibrary_h
#define FIRLibrary_h
@@ -32,13 +35,10 @@ NS_SWIFT_NAME(Library)
/// FirebaseApp and participate in dependency resolution and injection.
+ (NSArray<FIRComponent *> *)componentsToRegister;
@optional
/// Implement this method if the library needs notifications for lifecycle events. This method is
/// called when the developer calls `FirebaseApp.configure()`.
+ (void)configureWithApp:(FIRApp *)app;
@end
NS_ASSUME_NONNULL_END
#endif /* FIRLibrary_h */
#endif // FIREBASECORE_FIRLIBRARY_H

View File

@@ -14,9 +14,12 @@
* limitations under the License.
*/
#ifndef FIREBASECORE_FIRLOGGER_H
#define FIREBASECORE_FIRLOGGER_H
#import <Foundation/Foundation.h>
#import <FirebaseCore/FIRLoggerLevel.h>
typedef NS_ENUM(NSInteger, FIRLoggerLevel);
NS_ASSUME_NONNULL_BEGIN
@@ -25,10 +28,10 @@ NS_ASSUME_NONNULL_BEGIN
*/
typedef NSString *const FIRLoggerService;
extern FIRLoggerService kFIRLoggerAnalytics;
extern FIRLoggerService kFIRLoggerCrash;
extern FIRLoggerService kFIRLoggerCore;
extern FIRLoggerService kFIRLoggerRemoteConfig;
extern NSString *const kFIRLoggerAnalytics;
extern NSString *const kFIRLoggerCrash;
extern NSString *const kFIRLoggerCore;
extern NSString *const kFIRLoggerRemoteConfig;
/**
* The key used to store the logger's error count.
@@ -64,6 +67,11 @@ FIRLoggerLevel FIRGetLoggerLevel(void);
*/
void FIRSetLoggerLevel(FIRLoggerLevel loggerLevel);
void FIRSetLoggerLevelNotice(void);
void FIRSetLoggerLevelWarning(void);
void FIRSetLoggerLevelError(void);
void FIRSetLoggerLevelDebug(void);
/**
* Checks if the specified logger level is loggable given the current settings.
* (required) log level (one of the FirebaseLoggerLevel enum values).
@@ -71,6 +79,11 @@ void FIRSetLoggerLevel(FIRLoggerLevel loggerLevel);
*/
BOOL FIRIsLoggableLevel(FIRLoggerLevel loggerLevel, BOOL analyticsComponent);
BOOL FIRIsLoggableLevelNotice(void);
BOOL FIRIsLoggableLevelWarning(void);
BOOL FIRIsLoggableLevelError(void);
BOOL FIRIsLoggableLevelDebug(void);
/**
* Logs a message to the Xcode console and the device log. If running from AppStore, will
* not log any messages with a level higher than FirebaseLoggerLevelNotice to avoid log spamming.
@@ -85,7 +98,7 @@ BOOL FIRIsLoggableLevel(FIRLoggerLevel loggerLevel, BOOL analyticsComponent);
* string.
*/
extern void FIRLogBasic(FIRLoggerLevel level,
FIRLoggerService service,
NSString *category,
NSString *messageCode,
NSString *message,
// On 64-bit simulators, va_list is not a pointer, so cannot be marked nullable
@@ -110,43 +123,51 @@ extern void FIRLogBasic(FIRLoggerLevel level,
* Example usage:
* FirebaseLogError(kFirebaseLoggerCore, @"I-COR000001", @"Configuration of %@ failed.", app.name);
*/
extern void FIRLogError(FIRLoggerService service, NSString *messageCode, NSString *message, ...)
extern void FIRLogError(NSString *category, NSString *messageCode, NSString *message, ...)
NS_FORMAT_FUNCTION(3, 4);
extern void FIRLogWarning(FIRLoggerService service, NSString *messageCode, NSString *message, ...)
extern void FIRLogWarning(NSString *category, NSString *messageCode, NSString *message, ...)
NS_FORMAT_FUNCTION(3, 4);
extern void FIRLogNotice(FIRLoggerService service, NSString *messageCode, NSString *message, ...)
extern void FIRLogNotice(NSString *category, NSString *messageCode, NSString *message, ...)
NS_FORMAT_FUNCTION(3, 4);
extern void FIRLogInfo(FIRLoggerService service, NSString *messageCode, NSString *message, ...)
extern void FIRLogInfo(NSString *category, NSString *messageCode, NSString *message, ...)
NS_FORMAT_FUNCTION(3, 4);
extern void FIRLogDebug(FIRLoggerService service, NSString *messageCode, NSString *message, ...)
extern void FIRLogDebug(NSString *category, NSString *messageCode, NSString *message, ...)
NS_FORMAT_FUNCTION(3, 4);
// TODO: Come up with a better logging scheme for Swift.
/**
* Logs a debug message to the Xcode console and the device log. If running from AppStore, will
* not log any messages with a level higher than FirebaseLoggerLevelNotice to avoid log spamming.
* This function is intended to be used by Swift clients that do not support variadic parameters.
* This function is similar to the one above, except it takes a `va_list` instead of the listed
* variables.
*
* @param service The service name of type `FirebaseLoggerService`.
* @param messageCode The mesage code. starting with "I-" which means iOS, followed by a capitalized
* three-character service identifier and a six digit integer message ID that is unique within the
* service. An example of the message code is @"I-COR000001".
* @param message The message string.
*/
extern void FIRLogDebugSwift(FIRLoggerService service, NSString *messageCode, NSString *message);
/**
* Logs a warning message to the Xcode console and the device log. If running from AppStore, will
* not log any messages with a level higher than FirebaseLoggerLevelNotice to avoid log spamming.
* This function is intended to be used by Swift clients that do not support variadic parameters.
* The following functions accept the following parameters in order: (required) service
* name of type FirebaseLoggerService.
*
* @param service The service name of type `FirebaseLoggerService`.
* @param messageCode The mesage code. starting with "I-" which means iOS, followed by a capitalized
* three-character service identifier and a six digit integer message ID that is unique within the
* service. An example of the message code is @"I-COR000001".
* @param message The message string.
* (required) message code starting from "I-" which means iOS,
* followed by a capitalized three-character service identifier and a six digit integer message
* ID that is unique within the service. An example of the message code is @"I-COR000001".
* See go/firebase-log-proposal for details.
* (required) message string which can be a format string.
* (optional) A va_list
*/
extern void FIRLogWarningSwift(FIRLoggerService service, NSString *messageCode, NSString *message);
extern void FIRLogBasicError(NSString *category,
NSString *messageCode,
NSString *message,
va_list args_ptr);
extern void FIRLogBasicWarning(NSString *category,
NSString *messageCode,
NSString *message,
va_list args_ptr);
extern void FIRLogBasicNotice(NSString *category,
NSString *messageCode,
NSString *message,
va_list args_ptr);
extern void FIRLogBasicInfo(NSString *category,
NSString *messageCode,
NSString *message,
va_list args_ptr);
extern void FIRLogBasicDebug(NSString *category,
NSString *messageCode,
NSString *message,
va_list args_ptr);
#ifdef __cplusplus
} // extern "C"
@@ -155,35 +176,17 @@ extern void FIRLogWarningSwift(FIRLoggerService service, NSString *messageCode,
NS_SWIFT_NAME(FirebaseLogger)
@interface FIRLoggerWrapper : NSObject
/// Logs a given message at a given log level. This API is effectively a wrapper for the
/// `FIRLogBasic` C API.
///
/// - Parameters:
/// - level: The log level to use (defined by `FirebaseLoggerLevel` enum values).
/// - service: The service name of type `FirebaseLoggerService`.
/// - code: The mesage code. Starting with "I-" which means iOS, followed by a capitalized
/// three-character service identifier and a six digit integer message ID that is unique within
/// the service. An example of the message code is @"I-COR000001".
/// - message: Formatted string to be used as the log's message.
/// - args: Arguments list obtained from calling `va_start`, used when message is a format string.
+ (void)logWithLevel:(FIRLoggerLevel)level
withService:(FIRLoggerService)service
withCode:(NSString *)messageCode
withMessage:(NSString *)message
withArgs:(va_list)args;
/// Logs a given message at a given log level.
///
/// - Parameters:
/// - level: The log level to use (defined by `FirebaseLoggerLevel` enum values).
/// - service: The service name of type `FirebaseLoggerService`.
/// - code: The mesage code. Starting with "I-" which means iOS, followed by a capitalized
/// - category: The service name of type `FirebaseLoggerService`.
/// - code: The message code. Starting with "I-" which means iOS, followed by a capitalized
/// three-character service identifier and a six digit integer message ID that is unique within
/// the service. An example of the message code is @"I-COR000001".
/// - message: Formatted string to be used as the log's message.
/// - args: Arguments list obtained from calling `va_start`, used when message is a format string.
+ (void)logWithLevel:(FIRLoggerLevel)level
service:(FIRLoggerService)service
service:(NSString *)category
code:(NSString *)code
message:(NSString *)message
__attribute__((__swift_name__("log(level:service:code:message:)")));
@@ -191,3 +194,5 @@ NS_SWIFT_NAME(FirebaseLogger)
@end
NS_ASSUME_NONNULL_END
#endif // FIREBASECORE_FIRLOGGER_H

View File

@@ -1,106 +0,0 @@
/*
* Copyright 2017 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import <FirebaseCore/FIROptions.h>
/**
* Keys for the strings in the plist file.
*/
extern NSString *const kFIRAPIKey;
extern NSString *const kFIRTrackingID;
extern NSString *const kFIRGoogleAppID;
extern NSString *const kFIRClientID;
extern NSString *const kFIRGCMSenderID;
extern NSString *const kFIRAndroidClientID;
extern NSString *const kFIRDatabaseURL;
extern NSString *const kFIRStorageBucket;
extern NSString *const kFIRBundleID;
extern NSString *const kFIRProjectID;
/**
* Keys for the plist file name
*/
extern NSString *const kServiceInfoFileName;
extern NSString *const kServiceInfoFileType;
/**
* This header file exposes the initialization of FirebaseOptions to internal use.
*/
@interface FIROptions ()
/**
* `resetDefaultOptions` and `initInternalWithOptionsDictionary` are exposed only for unit tests.
*/
+ (void)resetDefaultOptions;
/**
* Initializes the options with dictionary. The above strings are the keys of the dictionary.
* This is the designated initializer.
*/
- (instancetype)initInternalWithOptionsDictionary:(NSDictionary *)serviceInfoDictionary
NS_DESIGNATED_INITIALIZER;
/**
* `defaultOptions` and `defaultOptionsDictionary` are exposed in order to be used in FirebaseApp
* and other first party services.
*/
+ (FIROptions *)defaultOptions;
+ (NSDictionary *)defaultOptionsDictionary;
/**
* Indicates whether or not Analytics collection was explicitly enabled via a plist flag or at
* runtime.
*/
@property(nonatomic, readonly) BOOL isAnalyticsCollectionExplicitlySet;
/**
* Whether or not Analytics Collection was enabled. Analytics Collection is enabled unless
* explicitly disabled in GoogleService-Info.plist.
*/
@property(nonatomic, readonly) BOOL isAnalyticsCollectionEnabled;
/**
* Whether or not Analytics Collection was completely disabled. If true, then
* isAnalyticsCollectionEnabled will be false.
*/
@property(nonatomic, readonly) BOOL isAnalyticsCollectionDeactivated;
/**
* The version ID of the client library, e.g. @"1100000".
*/
@property(nonatomic, readonly, copy) NSString *libraryVersionID;
/**
* The flag indicating whether this object was constructed with the values in the default plist
* file.
*/
@property(nonatomic) BOOL usingOptionsFromDefaultPlist;
/**
* Whether or not Measurement was enabled. Measurement is enabled unless explicitly disabled in
* GoogleService-Info.plist.
*/
@property(nonatomic, readonly) BOOL isMeasurementEnabled;
/**
* Whether or not editing is locked. This should occur after `FirebaseOptions` has been set on a
* `FirebaseApp`.
*/
@property(nonatomic, getter=isEditingLocked) BOOL editingLocked;
@end

View File

@@ -12,14 +12,17 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef FIREBASECORE_FIREBASECOREINTERNAL_H
#define FIREBASECORE_FIREBASECOREINTERNAL_H
@import FirebaseCore;
#import "FIRAppInternal.h"
#import "FIRComponent.h"
#import "FIRComponentContainer.h"
#import "FIRComponentType.h"
#import "FIRDependency.h"
#import "FIRHeartbeatLogger.h"
#import "FIRLibrary.h"
#import "FIRLogger.h"
#import "FIROptionsInternal.h"
#endif // FIREBASECORE_FIREBASECOREINTERNAL_H

View File

@@ -0,0 +1,39 @@
/*
* Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import "FirebaseMessaging/Sources/Public/FirebaseMessaging/FIRMessaging+ExtensionHelper.h"
#import "FirebaseMessaging/Sources/Public/FirebaseMessaging/FIRMessaging.h"
#import "FirebaseMessaging/Sources/Public/FirebaseMessaging/FIRMessagingExtensionHelper.h"
@implementation FIRMessaging (ExtensionHelper)
+ (FIRMessagingExtensionHelper *)extensionHelper {
static dispatch_once_t once;
static FIRMessagingExtensionHelper *extensionHelper;
dispatch_once(&once, ^{
extensionHelper = [[FIRMessagingExtensionHelper alloc] init];
});
return extensionHelper;
}
#if SWIFT_PACKAGE || COCOAPODS || FIREBASE_BUILD_CARTHAGE || FIREBASE_BUILD_ZIP_FILE
/// Stub used to force the linker to include the categories in this file.
void FIRInclude_FIRMessaging_ExtensionHelper_Category(void) {
}
#endif // SWIFT_PACKAGE || COCOAPODS || FIREBASE_BUILD_CARTHAGE || FIREBASE_BUILD_ZIP_FILE
@end

View File

@@ -40,7 +40,6 @@
#import "FirebaseMessaging/Sources/FIRMessagingUtilities.h"
#import "FirebaseMessaging/Sources/FIRMessaging_Private.h"
#import "FirebaseMessaging/Sources/NSError+FIRMessaging.h"
#import "FirebaseMessaging/Sources/Public/FirebaseMessaging/FIRMessagingExtensionHelper.h"
#import "FirebaseMessaging/Sources/Token/FIRMessagingAuthService.h"
#import "FirebaseMessaging/Sources/Token/FIRMessagingTokenInfo.h"
#import "FirebaseMessaging/Sources/Token/FIRMessagingTokenManager.h"
@@ -49,13 +48,8 @@
static NSString *const kFIRMessagingMessageViaAPNSRootKey = @"aps";
static NSString *const kFIRMessagingReachabilityHostname = @"www.google.com";
#if defined(__IPHONE_10_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0
const NSNotificationName FIRMessagingRegistrationTokenRefreshedNotification =
@"com.firebase.messaging.notif.fcm-token-refreshed";
#else
NSString *const FIRMessagingRegistrationTokenRefreshedNotification =
@"com.firebase.messaging.notif.fcm-token-refreshed";
#endif // defined(__IPHONE_10_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0
NSString *const kFIRMessagingUserDefaultsKeyAutoInitEnabled =
@"com.firebase.messaging.auto-init.enabled"; // Auto Init Enabled key stored in NSUserDefaults
@@ -65,7 +59,7 @@ NSString *const kFIRMessagingPlistAutoInitEnabled =
NSString *const FIRMessagingErrorDomain = @"com.google.fcm";
const BOOL FIRMessagingIsAPNSSyncMessage(NSDictionary *message) {
BOOL FIRMessagingIsAPNSSyncMessage(NSDictionary *message) {
if ([message[kFIRMessagingMessageViaAPNSRootKey] isKindOfClass:[NSDictionary class]]) {
NSDictionary *aps = message[kFIRMessagingMessageViaAPNSRootKey];
if (aps && [aps isKindOfClass:[NSDictionary class]]) {
@@ -136,20 +130,9 @@ BOOL FIRMessagingIsContextManagerMessage(NSDictionary *message) {
return (FIRMessaging *)instance;
}
+ (FIRMessagingExtensionHelper *)extensionHelper {
static dispatch_once_t once;
static FIRMessagingExtensionHelper *extensionHelper;
dispatch_once(&once, ^{
extensionHelper = [[FIRMessagingExtensionHelper alloc] init];
});
return extensionHelper;
}
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
- (instancetype)initWithAnalytics:(nullable id<FIRAnalyticsInterop>)analytics
userDefaults:(GULUserDefaults *)defaults
heartbeatLogger:(FIRHeartbeatLogger *)heartbeatLogger {
#pragma clang diagnostic pop
self = [super init];
if (self != nil) {
_loggedMessageIDs = [NSMutableSet set];
@@ -173,8 +156,6 @@ BOOL FIRMessagingIsContextManagerMessage(NSDictionary *message) {
}
+ (nonnull NSArray<FIRComponent *> *)componentsToRegister {
FIRDependency *analyticsDep = [FIRDependency dependencyWithProtocol:@protocol(FIRAnalyticsInterop)
isRequired:NO];
FIRComponentCreationBlock creationBlock =
^id _Nullable(FIRComponentContainer *container, BOOL *isCacheable) {
if (!container.app.isDefaultApp) {
@@ -187,13 +168,10 @@ BOOL FIRMessagingIsContextManagerMessage(NSDictionary *message) {
// Ensure it's cached so it returns the same instance every time messaging is called.
*isCacheable = YES;
id<FIRAnalyticsInterop> analytics = FIR_COMPONENT(FIRAnalyticsInterop, container);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
FIRMessaging *messaging =
[[FIRMessaging alloc] initWithAnalytics:analytics
userDefaults:[GULUserDefaults standardUserDefaults]
heartbeatLogger:container.app.heartbeatLogger];
#pragma clang diagnostic pop
[messaging start];
[messaging configureMessagingWithOptions:container.app.options];
@@ -203,7 +181,6 @@ BOOL FIRMessagingIsContextManagerMessage(NSDictionary *message) {
FIRComponent *messagingProvider =
[FIRComponent componentWithProtocol:@protocol(FIRMessagingInterop)
instantiationTiming:FIRInstantiationTimingEagerInDefaultApp
dependencies:@[ analyticsDep ]
creationBlock:creationBlock];
return @[ messagingProvider ];
@@ -226,11 +203,11 @@ BOOL FIRMessagingIsContextManagerMessage(NSDictionary *message) {
// This is not needed for app extension except for watch.
#if TARGET_OS_WATCH
[self didCompleteConfigure];
#else
#else // TARGET_OS_WATCH
if (![GULAppEnvironmentUtil isAppExtension]) {
[self didCompleteConfigure];
}
#endif
#endif // TARGET_OS_WATCH
}
- (void)didCompleteConfigure {
@@ -398,7 +375,7 @@ BOOL FIRMessagingIsContextManagerMessage(NSDictionary *message) {
}
- (void)handleIncomingLinkIfNeededFromMessage:(NSDictionary *)message {
#if TARGET_OS_IOS || TARGET_OS_TV
#if TARGET_OS_IOS || TARGET_OS_TV || TARGET_OS_VISION
NSURL *url = [self linkURLFromMessage:message];
if (url == nil) {
return;
@@ -417,14 +394,6 @@ BOOL FIRMessagingIsContextManagerMessage(NSDictionary *message) {
SEL continueUserActivitySelector = @selector(application:
continueUserActivity:restorationHandler:);
SEL openURLWithOptionsSelector = @selector(application:openURL:options:);
SEL openURLWithSourceApplicationSelector = @selector(application:
openURL:sourceApplication:annotation:);
// TODO(Xcode 15): When Xcode 15 is the minimum supported Xcode version, it will be unnecessary to
// check if `TARGET_OS_VISION` is defined.
#if TARGET_OS_IOS && (!defined(TARGET_OS_VISION) || !TARGET_OS_VISION)
SEL handleOpenURLSelector = @selector(application:handleOpenURL:);
#endif // TARGET_OS_IOS && (!defined(TARGET_OS_VISION) || !TARGET_OS_VISION)
// Due to FIRAAppDelegateProxy swizzling, this selector will most likely get chosen, whether or
// not the actual application has implemented
// |application:continueUserActivity:restorationHandler:|. A warning will be displayed to the user
@@ -439,30 +408,8 @@ BOOL FIRMessagingIsContextManagerMessage(NSDictionary *message) {
restorationHandler:^(NSArray *_Nullable restorableObjects){
// Do nothing, as we don't support the app calling this block
}];
} else if ([appDelegate respondsToSelector:openURLWithOptionsSelector]) {
[appDelegate application:application openURL:url options:@{}];
// Similarly, |application:openURL:sourceApplication:annotation:| will also always be called,
// due to the default swizzling done by FIRAAppDelegateProxy in Firebase Analytics
} else if ([appDelegate respondsToSelector:openURLWithSourceApplicationSelector]) {
// TODO(Xcode 15): When Xcode 15 is the minimum supported Xcode version, it will be unnecessary to
// check if `TARGET_OS_VISION` is defined.
#if TARGET_OS_IOS && (!defined(TARGET_OS_VISION) || !TARGET_OS_VISION)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
[appDelegate application:application
openURL:url
sourceApplication:FIRMessagingAppIdentifier()
annotation:@{}];
#pragma clang diagnostic pop
} else if ([appDelegate respondsToSelector:handleOpenURLSelector]) {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
[appDelegate application:application handleOpenURL:url];
#pragma clang diagnostic pop
#endif // TARGET_OS_IOS && (!defined(TARGET_OS_VISION) || !TARGET_OS_VISION)
}
#endif // TARGET_OS_IOS || TARGET_OS_TV
#endif // TARGET_OS_IOS || TARGET_OS_TV || TARGET_OS_VISION
}
- (NSURL *)linkURLFromMessage:(NSDictionary *)message {
@@ -540,14 +487,13 @@ BOOL FIRMessagingIsContextManagerMessage(NSDictionary *message) {
BOOL isFCMAutoInitEnabled = [self isAutoInitEnabled];
[_messagingUserDefaults setBool:autoInitEnabled
forKey:kFIRMessagingUserDefaultsKeyAutoInitEnabled];
[_messagingUserDefaults synchronize];
if (!isFCMAutoInitEnabled && autoInitEnabled) {
[self.tokenManager tokenAndRequestIfNotExist];
}
}
- (NSString *)FCMToken {
// Gets the current default token, and requets a new one if it doesn't exist.
// Gets the current default token, and requests a new one if it doesn't exist.
NSString *token = [self.tokenManager tokenAndRequestIfNotExist];
return token;
}
@@ -1073,4 +1019,22 @@ BOOL FIRMessagingIsContextManagerMessage(NSDictionary *message) {
return [self currentLocale];
}
#pragma mark - Force Category Linking
#if SWIFT_PACKAGE || COCOAPODS || FIREBASE_BUILD_CARTHAGE || FIREBASE_BUILD_ZIP_FILE
extern void FIRInclude_FIRMessaging_ExtensionHelper_Category(void);
#endif // SWIFT_PACKAGE || COCOAPODS || FIREBASE_BUILD_CARTHAGE || FIREBASE_BUILD_ZIP_FILE
extern void FIRInclude_NSDictionary_FIRMessaging_Category(void);
extern void FIRInclude_NSError_FIRMessaging_Category(void);
/// Does nothing when called, and not meant to be called.
///
/// This method forces the linker to include categories even if
/// users do not include the '-ObjC' linker flag in their project.
+ (void)noop {
#if SWIFT_PACKAGE || COCOAPODS || FIREBASE_BUILD_CARTHAGE || FIREBASE_BUILD_ZIP_FILE
FIRInclude_FIRMessaging_ExtensionHelper_Category();
#endif // SWIFT_PACKAGE || COCOAPODS || FIREBASE_BUILD_CARTHAGE || FIREBASE_BUILD_ZIP_FILE
FIRInclude_NSDictionary_FIRMessaging_Category();
FIRInclude_NSError_FIRMessaging_Category();
}
@end

View File

@@ -13,11 +13,8 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0 || \
__MAC_OS_X_VERSION_MAX_ALLOWED >= __MAC_10_14 || __TV_OS_VERSION_MAX_ALLOWED >= __TV_10_0 || \
__WATCH_OS_VERSION_MAX_ALLOWED >= __WATCHOS_3_0 || TARGET_OS_MACCATALYST
#import <UserNotifications/UserNotifications.h>
#endif
#import "FirebaseMessaging/Sources/FIRMessagingContextManagerService.h"
@@ -176,7 +173,7 @@ typedef NS_ENUM(NSUInteger, FIRMessagingContextManagerMessageType) {
if (apsDictionary[kFIRMessagingContextManagerBadgeKey]) {
content.badge = apsDictionary[kFIRMessagingContextManagerBadgeKey];
}
#if TARGET_OS_IOS || TARGET_OS_OSX || TARGET_OS_WATCH
#if !TARGET_OS_TV
// The following fields are not available on tvOS
if ([apsDictionary[kFIRMessagingContextManagerBodyKey] length]) {
content.body = apsDictionary[kFIRMessagingContextManagerBodyKey];
@@ -204,7 +201,7 @@ typedef NS_ENUM(NSUInteger, FIRMessagingContextManagerMessageType) {
if (userInfo.count) {
content.userInfo = userInfo;
}
#endif // TARGET_OS_IOS || TARGET_OS_OSX || TARGET_OS_WATCH
#endif // !TARGET_OS_TV
return content;
}

View File

@@ -111,7 +111,7 @@ pb_bytes_array_t *FIRMessagingEncodeString(NSString *string) {
self.bestAttemptContent = content;
// The `userInfo` property isn't available on newer versions of tvOS.
#if TARGET_OS_IOS || TARGET_OS_OSX || TARGET_OS_WATCH
#if !TARGET_OS_TV
NSObject *currentImageURL = content.userInfo[kPayloadOptionsName][kPayloadOptionsImageURLName];
if (!currentImageURL || currentImageURL == [NSNull null]) {
[self deliverNotification];
@@ -131,12 +131,12 @@ pb_bytes_array_t *FIRMessagingEncodeString(NSString *string) {
@"The Image URL provided is invalid %@.", currentImageURL);
[self deliverNotification];
}
#else
#else // !TARGET_OS_TV
[self deliverNotification];
#endif
#endif // !TARGET_OS_TV
}
#if TARGET_OS_IOS || TARGET_OS_OSX || TARGET_OS_WATCH
#if !TARGET_OS_TV
- (NSString *)fileExtensionForResponse:(NSURLResponse *)response {
NSString *suggestedPathExtension = [response.suggestedFilename pathExtension];
if (suggestedPathExtension.length > 0) {
@@ -194,7 +194,7 @@ pb_bytes_array_t *FIRMessagingEncodeString(NSString *string) {
completionHandler(attachment);
}] resume];
}
#endif
#endif // !TARGET_OS_TV
- (void)deliverNotification {
if (self.contentHandler) {

View File

@@ -16,7 +16,6 @@
#import "FirebaseMessaging/Sources/FIRMessagingPubSub.h"
#import <GoogleUtilities/GULSecureCoding.h>
#import <GoogleUtilities/GULUserDefaults.h>
#import "FirebaseMessaging/Sources/FIRMessagingDefines.h"
#import "FirebaseMessaging/Sources/FIRMessagingLogger.h"
@@ -226,14 +225,15 @@ static NSString *const kPendingSubscriptionsListKey =
- (void)archivePendingTopicsList:(FIRMessagingPendingTopicsList *)topicsList {
GULUserDefaults *defaults = [GULUserDefaults standardUserDefaults];
NSError *error;
NSData *pendingData = [GULSecureCoding archivedDataWithRootObject:topicsList error:&error];
NSData *pendingData = [NSKeyedArchiver archivedDataWithRootObject:topicsList
requiringSecureCoding:YES
error:&error];
if (error) {
FIRMessagingLoggerError(kFIRMessagingMessageCodePubSubArchiveError,
@"Failed to archive topic list data %@", error);
return;
}
[defaults setObject:pendingData forKey:kPendingSubscriptionsListKey];
[defaults synchronize];
}
- (void)restorePendingTopicsList {
@@ -242,7 +242,7 @@ static NSString *const kPendingSubscriptionsListKey =
FIRMessagingPendingTopicsList *subscriptions;
if (pendingData) {
NSError *error;
subscriptions = [GULSecureCoding
subscriptions = [NSKeyedUnarchiver
unarchivedObjectOfClasses:[NSSet setWithObjects:FIRMessagingPendingTopicsList.class, nil]
fromData:pendingData
error:&error];
@@ -310,7 +310,7 @@ static NSString *const kTopicRegexPattern = @"/topics/([a-zA-Z0-9-_.~%]+)";
}
/**
* Gets the class describing occurences of topic names and sender IDs in the sender.
* Gets the class describing occurrences of topic names and sender IDs in the sender.
*
* @param topic The topic expression used to generate a pubsub topic
*

View File

@@ -300,10 +300,10 @@ static NSString *kUserNotificationDidReceiveResponseSelectorString =
IMP originalMethodImplementation =
method_setImplementation(originalMethod, swizzledImplementation);
IMP nonexistantMethodImplementation = [self nonExistantMethodImplementationForClass:klass];
IMP nonexistentMethodImplementation = [self nonExistentMethodImplementationForClass:klass];
if (originalMethodImplementation &&
originalMethodImplementation != nonexistantMethodImplementation &&
originalMethodImplementation != nonexistentMethodImplementation &&
originalMethodImplementation != swizzledImplementation) {
[self saveOriginalImplementation:originalMethodImplementation forSelector:originalSelector];
}
@@ -344,8 +344,8 @@ static NSString *kUserNotificationDidReceiveResponseSelectorString =
// behavior as if the method was not implemented.
// See: http://stackoverflow.com/a/8276527/9849
IMP nonExistantMethodImplementation = [self nonExistantMethodImplementationForClass:klass];
method_setImplementation(swizzledMethod, nonExistantMethodImplementation);
IMP nonExistentMethodImplementation = [self nonExistentMethodImplementationForClass:klass];
method_setImplementation(swizzledMethod, nonExistentMethodImplementation);
}
}
@@ -353,11 +353,11 @@ static NSString *kUserNotificationDidReceiveResponseSelectorString =
// This is useful to generate from a stable, "known missing" selector, as the IMP can be compared
// in case we are setting an implementation for a class that was previously "unswizzled" into a
// non-existant implementation.
- (IMP)nonExistantMethodImplementationForClass:(Class)klass {
SEL nonExistantSelector = NSSelectorFromString(@"aNonExistantMethod");
IMP nonExistantMethodImplementation = class_getMethodImplementation(klass, nonExistantSelector);
return nonExistantMethodImplementation;
// non-existent implementation.
- (IMP)nonExistentMethodImplementationForClass:(Class)klass {
SEL nonExistentSelector = NSSelectorFromString(@"aNonExistentMethod");
IMP nonExistentMethodImplementation = class_getMethodImplementation(klass, nonExistentSelector);
return nonExistentMethodImplementation;
}
// A safe, non-leaky way return a property object by its name
@@ -384,15 +384,8 @@ id FIRMessagingPropertyNameFromObject(id object, NSString *propertyName, Class k
}
#pragma mark - GULApplicationDelegate
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-implementations"
- (void)application:(GULApplication *)application
didReceiveRemoteNotification:(NSDictionary *)userInfo {
[[FIRMessaging messaging] appDidReceiveMessage:userInfo];
}
#pragma clang diagnostic pop
#if TARGET_OS_IOS || TARGET_OS_TV
#if TARGET_OS_IOS || TARGET_OS_TV || TARGET_OS_VISION
- (void)application:(UIApplication *)application
didReceiveRemoteNotification:(NSDictionary *)userInfo
fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
@@ -408,7 +401,7 @@ id FIRMessagingPropertyNameFromObject(id object, NSString *propertyName, Class k
@"application:didFailToRegisterForRemoteNotificationsWithError: %@",
error.localizedDescription);
}
#endif
#endif // TARGET_OS_IOS || TARGET_OS_TV || TARGET_OS_VISION
- (void)application:(GULApplication *)application
didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {

View File

@@ -56,7 +56,7 @@
- (FIRMessagingPersistentSyncMessage *)querySyncMessageWithRmqID:(NSString *)rmqID;
/**
* Delete the expired sync messages from persisten store. Also deletes messages that have been
* Delete the expired sync messages from persistent store. Also deletes messages that have been
* delivered both via APNS and MCS.
*/
- (void)deleteExpiredOrFinishedSyncMessages;

View File

@@ -277,14 +277,14 @@ NSString *_Nonnull FIRMessagingStringFromSQLiteResult(int result) {
- (FIRMessagingPersistentSyncMessage *)querySyncMessageWithRmqID:(NSString *)rmqID {
__block FIRMessagingPersistentSyncMessage *persistentMessage;
dispatch_sync(_databaseOperationQueue, ^{
NSString *queryFormat = @"SELECT %@ FROM %@ WHERE %@ = '%@'";
NSString *queryFormat = @"SELECT %@ FROM %@ WHERE %@ = ?";
NSString *query =
[NSString stringWithFormat:queryFormat,
kSyncMessagesColumns, // SELECT (rmq_id, expiration_ts,
// apns_recv, mcs_recv)
kTableSyncMessages, // FROM sync_rmq
kRmqIdColumn, // WHERE rmq_id
rmqID];
kRmqIdColumn // WHERE rmq_id
];
sqlite3_stmt *stmt;
if (sqlite3_prepare_v2(self->_database, [query UTF8String], -1, &stmt, NULL) != SQLITE_OK) {
@@ -293,6 +293,13 @@ NSString *_Nonnull FIRMessagingStringFromSQLiteResult(int result) {
return;
}
if (sqlite3_bind_text(stmt, 1, [rmqID UTF8String], (int)[rmqID length], SQLITE_STATIC) !=
SQLITE_OK) {
[self logError];
sqlite3_finalize(stmt);
return;
}
const int rmqIDColumn = 0;
const int expirationTimestampColumn = 1;
const int apnsReceivedColumn = 2;
@@ -489,10 +496,12 @@ NSString *_Nonnull FIRMessagingStringFromSQLiteResult(int result) {
BOOL didOpenDatabase = YES;
if (![fileManager fileExistsAtPath:path]) {
// We've to separate between different versions here because of backwards compatbility issues.
int result = sqlite3_open_v2(
[path UTF8String], &self -> _database,
SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_FILEPROTECTION_NONE, NULL);
// We've to separate between different versions here because of backward compatibility issues.
int flags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE;
#ifdef SQLITE_OPEN_FILEPROTECTION_NONE
flags |= SQLITE_OPEN_FILEPROTECTION_NONE;
#endif
int result = sqlite3_open_v2([path UTF8String], &self -> _database, flags, NULL);
if (result != SQLITE_OK) {
NSString *errorString = FIRMessagingStringFromSQLiteResult(result);
NSString *errorMessage = [NSString
@@ -509,9 +518,11 @@ NSString *_Nonnull FIRMessagingStringFromSQLiteResult(int result) {
[self createTableWithName:kTableS2DRmqIds command:kCreateTableS2DRmqIds];
} else {
// Calling sqlite3_open should create the database, since the file doesn't exist.
int result = sqlite3_open_v2(
[path UTF8String], &self -> _database,
SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_FILEPROTECTION_NONE, NULL);
int flags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE;
#ifdef SQLITE_OPEN_FILEPROTECTION_NONE
flags |= SQLITE_OPEN_FILEPROTECTION_NONE;
#endif
int result = sqlite3_open_v2([path UTF8String], &self -> _database, flags, NULL);
if (result != SQLITE_OK) {
NSString *errorString = FIRMessagingStringFromSQLiteResult(result);
NSString *errorMessage =

View File

@@ -39,7 +39,7 @@
- (void)removeExpiredSyncMessages;
/**
* App did recive a sync message via APNS.
* App did receive a sync message via APNS.
*
* @param message The sync message received.
*

View File

@@ -28,12 +28,16 @@ static NSString *const kFIRMessagingAPNSProdPrefix = @"p_";
static NSString *const kFIRMessagingWatchKitExtensionPoint = @"com.apple.watchkit";
#if TARGET_OS_IOS || TARGET_OS_TV || TARGET_OS_WATCH
static NSString *const kEntitlementsAPSEnvironmentKey = @"Entitlements.aps-environment";
#else
#if TARGET_OS_OSX
// macOS uses a different entitlement key than the rest of Apple's platforms:
// https://developer.apple.com/documentation/bundleresources/entitlements/com_apple_developer_aps-environment
static NSString *const kEntitlementsAPSEnvironmentKey =
@"Entitlements.com.apple.developer.aps-environment";
#endif
#else
// Entitlement key for all non-macOS platforms:
// https://developer.apple.com/documentation/bundleresources/entitlements/aps-environment
static NSString *const kEntitlementsAPSEnvironmentKey = @"Entitlements.aps-environment";
#endif // TARGET_OS_OSX
static NSString *const kAPSEnvironmentDevelopmentValue = @"development";
#pragma mark - URL Helpers
@@ -85,9 +89,9 @@ NSString *FIRMessagingAppIdentifier(void) {
} else {
return bundleID;
}
#else
#else // TARGET_OS_WATCH
return bundleID;
#endif
#endif // TARGET_OS_WATCH
}
NSString *FIRMessagingFirebaseAppID(void) {
@@ -108,17 +112,17 @@ BOOL FIRMessagingIsWatchKitExtension(void) {
} else {
return NO;
}
#else
#else // TARGET_OS_WATCH
return NO;
#endif
#endif // TARGET_OS_WATCH
}
NSSearchPathDirectory FIRMessagingSupportedDirectory(void) {
#if TARGET_OS_TV
return NSCachesDirectory;
#else
#else // TARGET_OS_TV
return NSApplicationSupportDirectory;
#endif
#endif // TARGET_OS_TV
}
#pragma mark - Locales
@@ -311,11 +315,10 @@ BOOL FIRMessagingIsProductionApp(void) {
#if TARGET_OS_OSX || TARGET_OS_MACCATALYST
NSString *path = [[[[NSBundle mainBundle] resourcePath] stringByDeletingLastPathComponent]
stringByAppendingPathComponent:@"embedded.provisionprofile"];
#elif TARGET_OS_IOS || TARGET_OS_TV || TARGET_OS_WATCH || \
(defined(TARGET_OS_VISION) && TARGET_OS_VISION)
#else // TARGET_OS_OSX || TARGET_OS_MACCATALYST
NSString *path = [[[NSBundle mainBundle] bundlePath]
stringByAppendingPathComponent:@"embedded.mobileprovision"];
#endif
#endif // TARGET_OS_OSX || TARGET_OS_MACCATALYST
if ([GULAppEnvironmentUtil isAppStoreReceiptSandbox] && !path.length) {
// Distributed via TestFlight

View File

@@ -56,3 +56,7 @@
}
@end
/// Stub used to force the linker to include the categories in this file.
void FIRInclude_NSDictionary_FIRMessaging_Category(void) {
}

View File

@@ -27,3 +27,7 @@
}
@end
/// Stub used to force the linker to include the categories in this file.
void FIRInclude_NSError_FIRMessaging_Category(void) {
}

View File

@@ -0,0 +1,39 @@
/*
* Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import <Foundation/Foundation.h>
#import "FIRMessaging.h"
NS_ASSUME_NONNULL_BEGIN
@class FIRMessagingExtensionHelper;
@interface FIRMessaging (ExtensionHelper)
/**
* Use the MessagingExtensionHelper to populate rich UI content for your notifications.
* For example, if an image URL is set in your notification payload or on the console,
* you can use the MessagingExtensionHelper instance returned from this method to render
* the image in your notification.
*
* @return An instance of MessagingExtensionHelper that handles the extensions API.
*/
+ (FIRMessagingExtensionHelper *)extensionHelper NS_SWIFT_NAME(serviceExtension());
@end
NS_ASSUME_NONNULL_END

View File

@@ -136,7 +136,6 @@ NS_SWIFT_NAME(MessagingMessageInfo)
@end
@class FIRMessaging;
@class FIRMessagingExtensionHelper;
/**
* A protocol to handle token update or data message delivery from FCM.
@@ -159,7 +158,7 @@ NS_SWIFT_NAME(MessagingDelegate)
@end
/**
* Firebase Messaging lets you reliably deliver messages at no cost.
* Firebase Messaging lets you reliably deliver messages.
*
* To send or receive messages, the app must get a
* registration token. This token authorizes an
@@ -184,17 +183,6 @@ NS_SWIFT_NAME(Messaging)
*/
+ (instancetype)messaging NS_SWIFT_NAME(messaging());
/**
* Use the MessagingExtensionHelper to populate rich UI content for your notifications.
* For example, if an image URL is set in your notification payload or on the console,
* you can use the MessagingExtensionHelper instance returned from this method to render
* the image in your notification.
*
* @return An instance of MessagingExtensionHelper that handles the extensions API.
*/
+ (FIRMessagingExtensionHelper *)extensionHelper NS_SWIFT_NAME(serviceExtension())
NS_AVAILABLE(10.14, 10.0);
/**
* Unavailable. Use +messaging instead.
*/

View File

@@ -16,6 +16,8 @@
#import <Foundation/Foundation.h>
#import "FIRMessaging+ExtensionHelper.h"
@class UNMutableNotificationContent, UNNotificationContent;
#if __has_include(<UserNotifications/UserNotifications.h>)

View File

@@ -14,5 +14,6 @@
* limitations under the License.
*/
#import "FIRMessaging+ExtensionHelper.h"
#import "FIRMessaging.h"
#import "FIRMessagingExtensionHelper.h"

View File

@@ -68,17 +68,19 @@ static NSString *const kFIRInstanceIDAPNSInfoSandboxKey = @"sandbox";
return clone;
}
#pragma mark - NSCoding
#pragma mark - NSSecureCoding
+ (BOOL)supportsSecureCoding {
return YES;
}
- (nullable instancetype)initWithCoder:(NSCoder *)aDecoder {
id deviceToken = [aDecoder decodeObjectForKey:kFIRInstanceIDAPNSInfoTokenKey];
if (![deviceToken isKindOfClass:[NSData class]]) {
NSData *deviceToken = [aDecoder decodeObjectOfClass:[NSData class]
forKey:kFIRInstanceIDAPNSInfoTokenKey];
if (!deviceToken) {
return nil;
}
BOOL isSandbox = [aDecoder decodeBoolForKey:kFIRInstanceIDAPNSInfoSandboxKey];
return [self initWithDeviceToken:(NSData *)deviceToken isSandbox:isSandbox];
}

View File

@@ -92,17 +92,17 @@ NSString *const kFIRMessagingKeychainWildcardIdentifier = @"*";
NSMutableDictionary *keychainQuery = [self keychainQueryForService:service account:account];
NSMutableArray<NSData *> *results;
keychainQuery[(__bridge id)kSecReturnData] = (__bridge id)kCFBooleanTrue;
#if TARGET_OS_IOS || TARGET_OS_TV || (defined(TARGET_OS_VISION) && TARGET_OS_VISION)
#if TARGET_OS_OSX || TARGET_OS_WATCH
keychainQuery[(__bridge id)kSecMatchLimit] = (__bridge id)kSecMatchLimitOne;
NSData *passwordInfos =
CFBridgingRelease([[FIRMessagingKeychain sharedInstance] itemWithQuery:keychainQuery]);
#else // TARGET_OS_OSX || TARGET_OS_WATCH
keychainQuery[(__bridge id)kSecReturnAttributes] = (__bridge id)kCFBooleanTrue;
keychainQuery[(__bridge id)kSecMatchLimit] = (__bridge id)kSecMatchLimitAll;
// FIRMessagingKeychain should only take a query and return a result, will handle the query here.
NSArray *passwordInfos =
CFBridgingRelease([[FIRMessagingKeychain sharedInstance] itemWithQuery:keychainQuery]);
#elif TARGET_OS_OSX || TARGET_OS_WATCH
keychainQuery[(__bridge id)kSecMatchLimit] = (__bridge id)kSecMatchLimitOne;
NSData *passwordInfos =
CFBridgingRelease([[FIRMessagingKeychain sharedInstance] itemWithQuery:keychainQuery]);
#endif
#endif // TARGET_OS_OSX || TARGET_OS_WATCH
if (!passwordInfos) {
// Nothing was found, simply return from this sync block.
@@ -119,7 +119,9 @@ NSString *const kFIRMessagingKeychainWildcardIdentifier = @"*";
return @[];
}
results = [[NSMutableArray alloc] init];
#if TARGET_OS_IOS || TARGET_OS_TV
#if TARGET_OS_OSX || TARGET_OS_WATCH
[results addObject:passwordInfos];
#else // TARGET_OS_OSX || TARGET_OS_WATCH
NSInteger numPasswords = passwordInfos.count;
for (NSUInteger i = 0; i < numPasswords; i++) {
NSDictionary *passwordInfo = [passwordInfos objectAtIndex:i];
@@ -127,9 +129,7 @@ NSString *const kFIRMessagingKeychainWildcardIdentifier = @"*";
[results addObject:passwordInfo[(__bridge id)kSecValueData]];
}
}
#elif TARGET_OS_OSX || TARGET_OS_WATCH
[results addObject:passwordInfos];
#endif
#endif // TARGET_OS_OSX || TARGET_OS_WATCH
// We query the keychain because it didn't exist in cache, now query is done, update the result in
// the cache.
if ([service isEqualToString:kFIRMessagingKeychainWildcardIdentifier] ||

View File

@@ -39,7 +39,7 @@
*
* @return Helper which allows to read write data to a backup excluded plist.
*/
- (instancetype)initWithFileName:(NSString *)fileName subDirectory:(NSString *)subDirectory;
- (instancetype)initWithPlistFile:(NSString *)fileName subDirectory:(NSString *)subDirectory;
/**
* Write dictionary data to the backup excluded plist file. If the file does not exist

View File

@@ -28,7 +28,7 @@
@implementation FIRMessagingBackupExcludedPlist
- (instancetype)initWithFileName:(NSString *)fileName subDirectory:(NSString *)subDirectory {
- (instancetype)initWithPlistFile:(NSString *)fileName subDirectory:(NSString *)subDirectory {
self = [super init];
if (self) {
_fileName = [fileName copy];

View File

@@ -44,7 +44,7 @@ FOUNDATION_EXPORT NSString *const kFIRMessagingDeviceDataVersionKey;
* gService data.
*
* @param existingCheckin An existing checkin preference object, if available.
* @param completion Completion hander called on success or failure of device checkin.
* @param completion Completion handler called on success or failure of device checkin.
*/
- (void)checkinWithExistingCheckin:(nullable FIRMessagingCheckinPreferences *)existingCheckin
completion:

View File

@@ -48,8 +48,8 @@ NSString *const kFIRMessagingCheckinKeychainService = @"com.google.iid.checkin";
self = [super init];
if (self) {
_plist = [[FIRMessagingBackupExcludedPlist alloc]
initWithFileName:kCheckinFileName
subDirectory:kFIRMessagingInstanceIDSubDirectoryName];
initWithPlistFile:kCheckinFileName
subDirectory:kFIRMessagingInstanceIDSubDirectoryName];
_keychain =
[[FIRMessagingAuthKeychain alloc] initWithIdentifier:kFIRMessagingCheckinKeychainGeneric];
}

View File

@@ -77,7 +77,7 @@
[self handleResponseWithData:data response:response error:error];
};
NSURLSessionConfiguration *config = NSURLSessionConfiguration.defaultSessionConfiguration;
NSURLSessionConfiguration *config = NSURLSessionConfiguration.ephemeralSessionConfiguration;
config.timeoutIntervalForResource = 60.0f; // 1 minute
NSURLSession *session = [NSURLSession sessionWithConfiguration:config];
self.dataTask = [session dataTaskWithRequest:request completionHandler:requestHandler];

View File

@@ -108,7 +108,7 @@ NSString *const kFIRMessagingFirebaseHeartbeatKey = @"X-firebase-client-log-type
FIRMessaging_STRONGIFY(self);
[self handleResponseWithData:data response:response error:error];
};
NSURLSessionConfiguration *config = NSURLSessionConfiguration.defaultSessionConfiguration;
NSURLSessionConfiguration *config = NSURLSessionConfiguration.ephemeralSessionConfiguration;
config.timeoutIntervalForResource = 60.0f; // 1 minute
NSURLSession *session = [NSURLSession sessionWithConfiguration:config];
self.dataTask = [session dataTaskWithRequest:request completionHandler:requestHandler];
@@ -172,6 +172,11 @@ NSString *const kFIRMessagingFirebaseHeartbeatKey = @"X-firebase-client-log-type
FIRMessagingLoggerDebug(kFIRMessagingMessageCodeInternal001, @"%@", failureReason);
responseError = [NSError messagingErrorWithCode:kFIRMessagingErrorCodeInvalidIdentity
failureReason:failureReason];
} else {
FIRMessagingLoggerDebug(kFIRMessagingMessageCodeTokenFetchOperationRequestError,
@"Token fetch got an error from server: %@", errorValue);
responseError = [NSError messagingErrorWithCode:kFIRMessagingErrorCodeUnknown
failureReason:errorValue];
}
}
if (!responseError) {

View File

@@ -26,7 +26,7 @@
* created from a dictionary. The same keys are used
* when decoding/encoding an archive.
*/
/// Specifies a dictonary key whose value represents the authorized entity, or
/// Specifies a dictionary key whose value represents the authorized entity, or
/// Sender ID for the token.
static NSString *const kFIRInstanceIDAuthorizedEntityKey = @"authorized_entity";
/// Specifies a dictionary key whose value represents the scope of the token,
@@ -143,32 +143,29 @@ static const NSTimeInterval kDefaultFetchTokenInterval = 7 * 24 * 60 * 60; // 7
BOOL needsMigration = NO;
// These value cannot be nil
id authorizedEntity = [aDecoder decodeObjectForKey:kFIRInstanceIDAuthorizedEntityKey];
if (![authorizedEntity isKindOfClass:[NSString class]]) {
NSString *authorizedEntity = [aDecoder decodeObjectOfClass:[NSString class]
forKey:kFIRInstanceIDAuthorizedEntityKey];
if (!authorizedEntity) {
return nil;
}
id scope = [aDecoder decodeObjectForKey:kFIRInstanceIDScopeKey];
if (![scope isKindOfClass:[NSString class]]) {
NSString *scope = [aDecoder decodeObjectOfClass:[NSString class] forKey:kFIRInstanceIDScopeKey];
if (!scope) {
return nil;
}
id token = [aDecoder decodeObjectForKey:kFIRInstanceIDTokenKey];
if (![token isKindOfClass:[NSString class]]) {
NSString *token = [aDecoder decodeObjectOfClass:[NSString class] forKey:kFIRInstanceIDTokenKey];
if (!token) {
return nil;
}
// These values are nullable, so only fail the decode if the type does not match
// These values are nullable, so don't fail on nil.
id appVersion = [aDecoder decodeObjectForKey:kFIRInstanceIDAppVersionKey];
if (appVersion && ![appVersion isKindOfClass:[NSString class]]) {
return nil;
}
NSString *appVersion = [aDecoder decodeObjectOfClass:[NSString class]
forKey:kFIRInstanceIDAppVersionKey];
NSString *firebaseAppID = [aDecoder decodeObjectOfClass:[NSString class]
forKey:kFIRInstanceIDFirebaseAppIDKey];
id firebaseAppID = [aDecoder decodeObjectForKey:kFIRInstanceIDFirebaseAppIDKey];
if (firebaseAppID && ![firebaseAppID isKindOfClass:[NSString class]]) {
return nil;
}
NSSet *classes = [[NSSet alloc] initWithArray:@[ FIRMessagingAPNSInfo.class ]];
FIRMessagingAPNSInfo *rawAPNSInfo = [aDecoder decodeObjectOfClasses:classes
forKey:kFIRInstanceIDAPNSInfoKey];
@@ -179,13 +176,13 @@ static const NSTimeInterval kDefaultFetchTokenInterval = 7 * 24 * 60 * 60; // 7
// users have upgraded to at least 10.19.0. Perhaps, after privacy manifests have been required
// for awhile?
@try {
[NSKeyedUnarchiver setClass:[FIRMessagingAPNSInfo class]
forClassName:@"FIRInstanceIDAPNSInfo"];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
rawAPNSInfo = [NSKeyedUnarchiver unarchiveObjectWithData:(NSData *)rawAPNSInfo];
NSKeyedUnarchiver *unarchiver =
[[NSKeyedUnarchiver alloc] initForReadingFromData:(NSData *)rawAPNSInfo error:nil];
unarchiver.requiresSecureCoding = NO;
[unarchiver setClass:[FIRMessagingAPNSInfo class] forClassName:@"FIRInstanceIDAPNSInfo"];
rawAPNSInfo = [unarchiver decodeObjectForKey:NSKeyedArchiveRootObjectKey];
[unarchiver finishDecoding];
needsMigration = YES;
#pragma clang diagnostic pop
} @catch (NSException *exception) {
FIRMessagingLoggerInfo(kFIRMessagingMessageCodeTokenInfoBadAPNSInfo,
@"Could not parse raw APNS Info while parsing archived token info.");
@@ -194,10 +191,8 @@ static const NSTimeInterval kDefaultFetchTokenInterval = 7 * 24 * 60 * 60; // 7
}
}
id cacheTime = [aDecoder decodeObjectForKey:kFIRInstanceIDCacheTimeKey];
if (cacheTime && ![cacheTime isKindOfClass:[NSDate class]]) {
return nil;
}
NSDate *cacheTime = [aDecoder decodeObjectOfClass:[NSDate class]
forKey:kFIRInstanceIDCacheTimeKey];
self = [super init];
if (self) {

View File

@@ -194,13 +194,13 @@
return;
}
#if TARGET_OS_SIMULATOR && TARGET_OS_IOS
#if TARGET_OS_SIMULATOR
if (tokenOptions[kFIRMessagingTokenOptionsAPNSKey] != nil) {
// If APNS token is available on iOS Simulator, we must use the sandbox profile
// https://developer.apple.com/documentation/xcode-release-notes/xcode-14-release-notes
tokenOptions[kFIRMessagingTokenOptionsAPNSIsSandboxKey] = @(YES);
}
#endif
#endif // TARGET_OS_SIMULATOR
if (tokenOptions[kFIRMessagingTokenOptionsAPNSKey] != nil &&
tokenOptions[kFIRMessagingTokenOptionsAPNSIsSandboxKey] == nil) {
@@ -333,7 +333,7 @@
handler:^(NSError *error) {
if (!error) {
// Do not send the token back in case the save was unsuccessful. Since with
// the new asychronous fetch mechanism this can lead to infinite loops, for
// the new asynchronous fetch mechanism this can lead to infinite loops, for
// example, we will return a valid token even though we weren't able to store
// it in our cache. The first token will lead to a onTokenRefresh callback
// wherein the user again calls `getToken` but since we weren't able to save
@@ -689,17 +689,17 @@
return;
}
// Use this token type for when we have to automatically fetch tokens in the future
#if TARGET_OS_SIMULATOR && TARGET_OS_IOS
#if TARGET_OS_SIMULATOR
// If APNS token is available on iOS Simulator, we must use the sandbox profile
// https://developer.apple.com/documentation/xcode-release-notes/xcode-14-release-notes
BOOL isSandboxApp = YES;
#else
#else // TARGET_OS_SIMULATOR
NSInteger type = [userInfo[kFIRMessagingAPNSTokenType] integerValue];
BOOL isSandboxApp = (type == FIRMessagingAPNSTokenTypeSandbox);
if (type == FIRMessagingAPNSTokenTypeUnknown) {
isSandboxApp = FIRMessagingIsSandboxApp();
}
#endif
#endif // TARGET_OS_SIMULATOR
// Pro-actively invalidate the default token, if the APNs change makes it
// invalid. Previously, we invalidated just before fetching the token.
@@ -744,7 +744,7 @@
handler:^(NSString *_Nullable token,
NSError *_Nullable error){
// Do nothing as callback is not needed and the
// sub-funciton already handle errors.
// sub-function already handle errors.
}];
}
if ([self->_tokenStore cachedTokenInfos].count == 0) {
@@ -752,7 +752,7 @@
scope:kFIRMessagingDefaultTokenScope
options:tokenOptions
handler:^(NSString *_Nullable FCMToken, NSError *_Nullable error){
// Do nothing as callback is not needed and the sub-funciton
// Do nothing as callback is not needed and the sub-function
// already handle errors.
}];
}

View File

@@ -99,19 +99,14 @@ static NSString *const kFIRMessagingTokenKeychainId = @"com.google.iid-tokens";
+ (nullable FIRMessagingTokenInfo *)tokenInfoFromKeychainItem:(NSData *)item {
// Check if it is saved as an archived FIRMessagingTokenInfo, otherwise return nil.
FIRMessagingTokenInfo *tokenInfo = nil;
// NOTE: Passing in nil to unarchiveObjectWithData will result in an iOS error logged
// in the console on iOS 10 and below. Avoid by checking item.data's existence.
if (item) {
// TODO(chliangGoogle: Use the new API and secureCoding protocol.
@try {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
[NSKeyedUnarchiver setClass:[FIRMessagingTokenInfo class]
forClassName:@"FIRInstanceIDTokenInfo"];
tokenInfo = [NSKeyedUnarchiver unarchiveObjectWithData:item];
#pragma clang diagnostic pop
NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingFromData:item
error:nil];
unarchiver.requiresSecureCoding = NO;
[unarchiver setClass:[FIRMessagingTokenInfo class] forClassName:@"FIRInstanceIDTokenInfo"];
tokenInfo = [unarchiver decodeObjectForKey:NSKeyedArchiveRootObjectKey];
[unarchiver finishDecoding];
} @catch (NSException *exception) {
FIRMessagingLoggerDebug(kFIRMessagingMessageCodeTokenStoreExceptionUnarchivingTokenInfo,
@"Unable to parse token info from Keychain item; item was in an "

View File

@@ -86,7 +86,7 @@ For details on using Firebase from a Framework or a library, refer to [firebase_
To develop Firebase software in this repository, ensure that you have at least
the following software:
* Xcode 14.1 (or later)
* Xcode 16.2 (or later)
CocoaPods is still the canonical way to develop, but much of the repo now supports
development with Swift Package Manager.
@@ -137,7 +137,7 @@ Alternatively, disable signing in each target:
### Adding a New Firebase Pod
Refer to [AddNewPod](AddNewPod.md) Markdown file for details.
Refer to [AddNewPod](docs/AddNewPod.md) Markdown file for details.
### Managing Headers and Imports
@@ -153,7 +153,7 @@ GitHub Actions will verify that any code changes are done in a style-compliant
way. Install `clang-format` and `mint`:
```console
brew install clang-format@18
brew install clang-format@20
brew install mint
```
@@ -235,6 +235,11 @@ at **Project Settings > Cloud Messaging > [Your Firebase App]**.
The iOS Simulator cannot register for remote notifications and will not receive push notifications.
To receive push notifications, follow the steps above and run the app on a physical device.
### Vertex AI for Firebase
See the [Vertex AI for Firebase README](FirebaseVertexAI#development) for
instructions about building and testing the SDK.
## Building with Firebase on Apple platforms
Firebase provides official beta support for macOS, Catalyst, and tvOS. visionOS and watchOS