Archived
Configured colours and added additional images to ready app for iOS 13 dark mode
This commit is contained in:
Generated
+4
-5
@@ -85,7 +85,7 @@ In order to keep Alamofire focused specifically on core networking implementatio
|
||||
$ gem install cocoapods
|
||||
```
|
||||
|
||||
> CocoaPods 1.1+ is required to build Alamofire 4.0+.
|
||||
> CocoaPods 1.7+ is required to build Alamofire 4.9+.
|
||||
|
||||
To integrate Alamofire into your Xcode project using CocoaPods, specify it in your `Podfile`:
|
||||
|
||||
@@ -95,7 +95,7 @@ platform :ios, '10.0'
|
||||
use_frameworks!
|
||||
|
||||
target '<Your Target Name>' do
|
||||
pod 'Alamofire', '~> 4.7'
|
||||
pod 'Alamofire', '~> 4.9'
|
||||
end
|
||||
```
|
||||
|
||||
@@ -112,14 +112,13 @@ $ pod install
|
||||
You can install Carthage with [Homebrew](https://brew.sh/) using the following command:
|
||||
|
||||
```bash
|
||||
$ brew update
|
||||
$ brew install carthage
|
||||
```
|
||||
|
||||
To integrate Alamofire into your Xcode project using Carthage, specify it in your `Cartfile`:
|
||||
|
||||
```ogdl
|
||||
github "Alamofire/Alamofire" ~> 4.7
|
||||
github "Alamofire/Alamofire" ~> 4.9
|
||||
```
|
||||
|
||||
Run `carthage update` to build the framework and drag the built `Alamofire.framework` into your Xcode project.
|
||||
@@ -142,7 +141,7 @@ dependencies: [
|
||||
|
||||
```swift
|
||||
dependencies: [
|
||||
.package(url: "https://github.com/Alamofire/Alamofire.git", from: "4.0.0")
|
||||
.package(url: "https://github.com/Alamofire/Alamofire.git", from: "4.9.0")
|
||||
]
|
||||
```
|
||||
|
||||
|
||||
@@ -159,7 +159,10 @@ open class NetworkReachabilityManager {
|
||||
let queueEnabled = SCNetworkReachabilitySetDispatchQueue(reachability, listenerQueue)
|
||||
|
||||
listenerQueue.async {
|
||||
self.previousFlags = SCNetworkReachabilityFlags(rawValue: 1 << 30)
|
||||
|
||||
guard let flags = self.flags else { return }
|
||||
|
||||
self.notifyListener(flags)
|
||||
}
|
||||
|
||||
|
||||
Generated
+13
-2
@@ -497,8 +497,19 @@ open class DownloadRequest: Request {
|
||||
// MARK: State
|
||||
|
||||
/// Cancels the request.
|
||||
open override func cancel() {
|
||||
downloadDelegate.downloadTask.cancel { self.downloadDelegate.resumeData = $0 }
|
||||
override open func cancel() {
|
||||
cancel(createResumeData: true)
|
||||
}
|
||||
|
||||
/// Cancels the request.
|
||||
///
|
||||
/// - parameter createResumeData: Determines whether resume data is created via the underlying download task or not.
|
||||
open func cancel(createResumeData: Bool) {
|
||||
if createResumeData {
|
||||
downloadDelegate.downloadTask.cancel { self.downloadDelegate.resumeData = $0 }
|
||||
} else {
|
||||
downloadDelegate.downloadTask.cancel()
|
||||
}
|
||||
|
||||
NotificationCenter.default.post(
|
||||
name: Notification.Name.Task.DidCancel,
|
||||
|
||||
Generated
+8
-2
@@ -219,7 +219,10 @@ extension DataRequest {
|
||||
/// - returns: The request.
|
||||
@discardableResult
|
||||
public func validate() -> Self {
|
||||
return validate(statusCode: self.acceptableStatusCodes).validate(contentType: self.acceptableContentTypes)
|
||||
let contentTypes = { [unowned self] in
|
||||
self.acceptableContentTypes
|
||||
}
|
||||
return validate(statusCode: acceptableStatusCodes).validate(contentType: contentTypes())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -310,6 +313,9 @@ extension DownloadRequest {
|
||||
/// - returns: The request.
|
||||
@discardableResult
|
||||
public func validate() -> Self {
|
||||
return validate(statusCode: self.acceptableStatusCodes).validate(contentType: self.acceptableContentTypes)
|
||||
let contentTypes = { [unowned self] in
|
||||
self.acceptableContentTypes
|
||||
}
|
||||
return validate(statusCode: acceptableStatusCodes).validate(contentType: contentTypes())
|
||||
}
|
||||
}
|
||||
|
||||
BIN
Binary file not shown.
BIN
Binary file not shown.
@@ -20,6 +20,9 @@
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
/// Block typedef callback parameter to getUserPropertiesWithCallback:.
|
||||
typedef void (^FIRAInteropUserPropertiesCallback)(NSDictionary<NSString *, id> *userProperties);
|
||||
|
||||
/// Connector for bridging communication between Firebase SDKs and FirebaseAnalytics API.
|
||||
@protocol FIRAnalyticsInterop
|
||||
|
||||
@@ -40,6 +43,9 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
/// Returns the maximum number of user properties.
|
||||
- (NSInteger)maxUserProperties:(NSString *)origin;
|
||||
|
||||
/// Returns the user properties to a callback function.
|
||||
- (void)getUserPropertiesWithCallback:(FIRAInteropUserPropertiesCallback)callback;
|
||||
|
||||
/// Logs events.
|
||||
- (void)logEventWithOrigin:(NSString *)origin
|
||||
name:(NSString *)name
|
||||
|
||||
Generated
+7
-6
@@ -1,8 +1,8 @@
|
||||
# Firebase iOS Open Source Development [](https://travis-ci.org/firebase/firebase-ios-sdk)
|
||||
|
||||
This repository contains a subset of the Firebase iOS SDK source. It currently
|
||||
includes FirebaseCore, FirebaseAuth, FirebaseDatabase, FirebaseFirestore,
|
||||
FirebaseFunctions, FirebaseInstanceID, FirebaseInAppMessaging,
|
||||
includes FirebaseCore, FirebaseABTesting, FirebaseAuth, FirebaseDatabase,
|
||||
FirebaseFirestore, FirebaseFunctions, FirebaseInstanceID, FirebaseInAppMessaging,
|
||||
FirebaseInAppMessagingDisplay, FirebaseMessaging and FirebaseStorage.
|
||||
|
||||
The repository also includes GoogleUtilities source. The
|
||||
@@ -80,9 +80,8 @@ For the pod that you want to develop:
|
||||
|
||||
`pod gen Firebase{name here}.podspec --local-sources=./ --auto-open`
|
||||
|
||||
Firestore and Functions have self contained Xcode projects. See
|
||||
[Firestore/README.md](Firestore/README.md) and
|
||||
[Functions/README.md](Functions/README.md).
|
||||
Firestore has a self contained Xcode project. See
|
||||
[Firestore/README.md](Firestore/README.md).
|
||||
|
||||
### Adding a New Firebase Pod
|
||||
|
||||
@@ -179,7 +178,8 @@ very grateful! We'd like to empower as many developers as we can to be able to
|
||||
participate in the Firebase community.
|
||||
|
||||
### macOS and tvOS
|
||||
Thanks to contributions from the community, FirebaseAuth, FirebaseCore, FirebaseDatabase, FirebaseMessaging,
|
||||
Thanks to contributions from the community, FirebaseABTesting, FirebaseAuth, FirebaseCore,
|
||||
FirebaseDatabase, FirebaseMessaging,
|
||||
FirebaseFirestore, FirebaseFunctions and FirebaseStorage now compile, run unit tests, and work on
|
||||
macOS and tvOS.
|
||||
|
||||
@@ -195,6 +195,7 @@ Note that the Firebase pod is not available for macOS and tvOS.
|
||||
To install, add a subset of the following to the Podfile:
|
||||
|
||||
```
|
||||
pod 'FirebaseABTesting'
|
||||
pod 'FirebaseAuth'
|
||||
pod 'FirebaseCore'
|
||||
pod 'FirebaseDatabase'
|
||||
|
||||
Generated
+1
-1
@@ -352,7 +352,7 @@ static NSMutableDictionary *sLibraryVersions;
|
||||
}
|
||||
|
||||
// Check if the Analytics flag is explicitly set. If so, no further actions are necessary.
|
||||
if ([self.options isAnalyticsCollectionExpicitlySet]) {
|
||||
if ([self.options isAnalyticsCollectionExplicitlySet]) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
+31
-6
@@ -23,7 +23,9 @@
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface FIRComponentContainer ()
|
||||
@interface FIRComponentContainer () {
|
||||
dispatch_queue_t _containerQueue;
|
||||
}
|
||||
|
||||
/// The dictionary of components that are registered for a particular app. The key is an NSString
|
||||
/// of the protocol.
|
||||
@@ -67,6 +69,8 @@ static NSMutableSet<Class> *sFIRComponentRegistrants;
|
||||
_app = app;
|
||||
_cachedInstances = [NSMutableDictionary<NSString *, id> dictionary];
|
||||
_components = [NSMutableDictionary<NSString *, FIRComponentCreationBlock> dictionary];
|
||||
_containerQueue =
|
||||
dispatch_queue_create("com.google.FirebaseComponentContainer", DISPATCH_QUEUE_SERIAL);
|
||||
|
||||
[self populateComponentsFromRegisteredClasses:allRegistrants forApp:app];
|
||||
}
|
||||
@@ -92,7 +96,7 @@ static NSMutableSet<Class> *sFIRComponentRegistrants;
|
||||
// Store the creation block for later usage.
|
||||
self.components[protocolName] = component.creationBlock;
|
||||
|
||||
// Instantiate the
|
||||
// Instantiate the instance if it has requested to be instantiated.
|
||||
BOOL shouldInstantiateEager =
|
||||
(component.instantiationTiming == FIRInstantiationTimingAlwaysEager);
|
||||
BOOL shouldInstantiateDefaultEager =
|
||||
@@ -136,7 +140,9 @@ static NSMutableSet<Class> *sFIRComponentRegistrants;
|
||||
|
||||
// The instance is ready to be returned, but check if it should be cached first before returning.
|
||||
if (shouldCache) {
|
||||
self.cachedInstances[protocolName] = instance;
|
||||
dispatch_sync(_containerQueue, ^{
|
||||
self.cachedInstances[protocolName] = instance;
|
||||
});
|
||||
}
|
||||
|
||||
return instance;
|
||||
@@ -147,7 +153,11 @@ static NSMutableSet<Class> *sFIRComponentRegistrants;
|
||||
- (nullable id)instanceForProtocol:(Protocol *)protocol {
|
||||
// Check if there is a cached instance, and return it if so.
|
||||
NSString *protocolName = NSStringFromProtocol(protocol);
|
||||
id cachedInstance = self.cachedInstances[protocolName];
|
||||
__block id cachedInstance;
|
||||
dispatch_sync(_containerQueue, ^{
|
||||
cachedInstance = self.cachedInstances[protocolName];
|
||||
});
|
||||
|
||||
if (cachedInstance) {
|
||||
return cachedInstance;
|
||||
}
|
||||
@@ -161,14 +171,29 @@ static NSMutableSet<Class> *sFIRComponentRegistrants;
|
||||
|
||||
- (void)removeAllCachedInstances {
|
||||
// Loop through the cache and notify each instance that is a maintainer to clean up after itself.
|
||||
for (id instance in self.cachedInstances.allValues) {
|
||||
// Design note: we're getting a copy here, unlocking the cached instances, iterating over the
|
||||
// copy, then locking and removing all cached instances. A race condition *could* exist where a
|
||||
// new cached instance is created between the copy and the removal, but the chances are slim and
|
||||
// side-effects are significantly smaller than including the entire loop in the `dispatch_sync`
|
||||
// block (access to the cache from inside the block would deadlock and crash).
|
||||
__block NSDictionary<NSString *, id> *instancesCopy;
|
||||
dispatch_sync(_containerQueue, ^{
|
||||
instancesCopy = [self.cachedInstances copy];
|
||||
});
|
||||
|
||||
for (id instance in instancesCopy.allValues) {
|
||||
if ([instance conformsToProtocol:@protocol(FIRComponentLifecycleMaintainer)] &&
|
||||
[instance respondsToSelector:@selector(appWillBeDeleted:)]) {
|
||||
[instance appWillBeDeleted:self.app];
|
||||
}
|
||||
}
|
||||
|
||||
[self.cachedInstances removeAllObjects];
|
||||
instancesCopy = nil;
|
||||
|
||||
// Empty the cache.
|
||||
dispatch_sync(_containerQueue, ^{
|
||||
[self.cachedInstances removeAllObjects];
|
||||
});
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
+1
-1
@@ -399,7 +399,7 @@ static NSDictionary *sDefaultOptionsDictionary = nil;
|
||||
return [value boolValue];
|
||||
}
|
||||
|
||||
- (BOOL)isAnalyticsCollectionExpicitlySet {
|
||||
- (BOOL)isAnalyticsCollectionExplicitlySet {
|
||||
// If it's de-activated, it classifies as explicity set. If not, it's not a good enough indication
|
||||
// that the developer wants FirebaseAnalytics enabled so continue checking.
|
||||
if (self.isAnalyticsCollectionDeactivated) {
|
||||
|
||||
@@ -65,7 +65,7 @@ extern NSString *const kServiceInfoFileType;
|
||||
* Indicates whether or not Analytics collection was explicitly enabled via a plist flag or at
|
||||
* runtime.
|
||||
*/
|
||||
@property(nonatomic, readonly) BOOL isAnalyticsCollectionExpicitlySet;
|
||||
@property(nonatomic, readonly) BOOL isAnalyticsCollectionExplicitlySet;
|
||||
|
||||
/**
|
||||
* Whether or not Analytics Collection was enabled. Analytics Collection is enabled unless
|
||||
|
||||
Generated
+17
-10
@@ -1,9 +1,10 @@
|
||||
# Firebase iOS Open Source Development [](https://travis-ci.org/firebase/firebase-ios-sdk)
|
||||
|
||||
This repository contains a subset of the Firebase iOS SDK source. It currently
|
||||
includes FirebaseCore, FirebaseAuth, FirebaseDatabase, FirebaseFirestore,
|
||||
FirebaseFunctions, FirebaseInstanceID, FirebaseInAppMessaging,
|
||||
FirebaseInAppMessagingDisplay, FirebaseMessaging and FirebaseStorage.
|
||||
includes FirebaseCore, FirebaseABTesting, FirebaseAuth, FirebaseDatabase,
|
||||
FirebaseFirestore, FirebaseFunctions, FirebaseInstanceID, FirebaseInAppMessaging,
|
||||
FirebaseInAppMessagingDisplay, FirebaseMessaging, FirebaseRemoteConfig, and
|
||||
FirebaseStorage.
|
||||
|
||||
The repository also includes GoogleUtilities source. The
|
||||
[GoogleUtilities](GoogleUtilities/README.md) pod is
|
||||
@@ -80,9 +81,8 @@ For the pod that you want to develop:
|
||||
|
||||
`pod gen Firebase{name here}.podspec --local-sources=./ --auto-open`
|
||||
|
||||
Firestore and Functions have self contained Xcode projects. See
|
||||
[Firestore/README.md](Firestore/README.md) and
|
||||
[Functions/README.md](Functions/README.md).
|
||||
Firestore has a self contained Xcode project. See
|
||||
[Firestore/README.md](Firestore/README.md).
|
||||
|
||||
### Adding a New Firebase Pod
|
||||
|
||||
@@ -99,13 +99,17 @@ Travis will verify that any code changes are done in a style compliant way. Inst
|
||||
These commands will get the right versions:
|
||||
|
||||
```
|
||||
brew install https://raw.githubusercontent.com/Homebrew/homebrew-core/773cb75d360b58f32048f5964038d09825a507c8/Formula/clang-format.rb
|
||||
brew install https://raw.githubusercontent.com/Homebrew/homebrew-core/3dfea1004e0736754bbf49673cca8aaed8a94089/Formula/swiftformat.rb
|
||||
brew upgrade https://raw.githubusercontent.com/Homebrew/homebrew-core/e3496d9/Formula/clang-format.rb
|
||||
brew upgrade https://raw.githubusercontent.com/Homebrew/homebrew-core/7963c3d/Formula/swiftformat.rb
|
||||
```
|
||||
|
||||
Note: if you already have a newer version of these installed you may need to
|
||||
`brew switch` to this version.
|
||||
|
||||
To update this section, find the versions of clang-format and swiftformat.rb to
|
||||
match the versions in the CI failure logs
|
||||
[here](https://github.com/Homebrew/homebrew-core/tree/master/Formula).
|
||||
|
||||
### Running Unit Tests
|
||||
|
||||
Select a scheme and press Command-u to build a component and run its unit tests.
|
||||
@@ -179,8 +183,9 @@ very grateful! We'd like to empower as many developers as we can to be able to
|
||||
participate in the Firebase community.
|
||||
|
||||
### macOS and tvOS
|
||||
Thanks to contributions from the community, FirebaseAuth, FirebaseCore, FirebaseDatabase, FirebaseMessaging,
|
||||
FirebaseFirestore, FirebaseFunctions and FirebaseStorage now compile, run unit tests, and work on
|
||||
Thanks to contributions from the community, FirebaseABTesting, FirebaseAuth, FirebaseCore,
|
||||
FirebaseDatabase, FirebaseMessaging, FirebaseFirestore,
|
||||
FirebaseFunctions, FirebaseRemoteConfig, and FirebaseStorage now compile, run unit tests, and work on
|
||||
macOS and tvOS.
|
||||
|
||||
For tvOS, checkout the [Sample](Example/tvOSSample).
|
||||
@@ -195,12 +200,14 @@ Note that the Firebase pod is not available for macOS and tvOS.
|
||||
To install, add a subset of the following to the Podfile:
|
||||
|
||||
```
|
||||
pod 'FirebaseABTesting'
|
||||
pod 'FirebaseAuth'
|
||||
pod 'FirebaseCore'
|
||||
pod 'FirebaseDatabase'
|
||||
pod 'FirebaseFirestore'
|
||||
pod 'FirebaseFunctions'
|
||||
pod 'FirebaseMessaging'
|
||||
pod 'FirebaseRemoteConfig'
|
||||
pod 'FirebaseStorage'
|
||||
```
|
||||
|
||||
|
||||
+21
-19
@@ -17,10 +17,10 @@
|
||||
#import <objc/runtime.h>
|
||||
#include <sys/utsname.h>
|
||||
|
||||
#import <GoogleDataTransport/GDTConsoleLogger.h>
|
||||
#import <GoogleDataTransport/GDTEvent.h>
|
||||
#import <GoogleDataTransport/GDTTargets.h>
|
||||
#import <GoogleDataTransport/GDTTransport.h>
|
||||
#import <GoogleDataTransport/GDTCORConsoleLogger.h>
|
||||
#import <GoogleDataTransport/GDTCOREvent.h>
|
||||
#import <GoogleDataTransport/GDTCORTargets.h>
|
||||
#import <GoogleDataTransport/GDTCORTransport.h>
|
||||
|
||||
#import <GoogleUtilities/GULAppEnvironmentUtil.h>
|
||||
#import <GoogleUtilities/GULLogger.h>
|
||||
@@ -92,7 +92,8 @@ static NSString *const kFIRAppDiagnosticsSDKVersionKey = @"FIRAppDiagnosticsSDKV
|
||||
NSString *const kFIRCoreDiagnosticsHeartbeatDateFileName = @"FIREBASE_DIAGNOSTICS_HEARTBEAT_DATE";
|
||||
|
||||
/**
|
||||
* @note This should implement the GDTEventDataObject protocol, but can't because of weak-linking.
|
||||
* @note This should implement the GDTCOREventDataObject protocol, but can't because of
|
||||
* weak-linking.
|
||||
*/
|
||||
@interface FIRCoreDiagnosticsLog : NSObject
|
||||
|
||||
@@ -111,14 +112,14 @@ NSString *const kFIRCoreDiagnosticsHeartbeatDateFileName = @"FIREBASE_DIAGNOSTIC
|
||||
return self;
|
||||
}
|
||||
|
||||
// Provided and required by the GDTEventDataObject protocol.
|
||||
// Provided and required by the GDTCOREventDataObject protocol.
|
||||
- (NSData *)transportBytes {
|
||||
pb_ostream_t sizestream = PB_OSTREAM_SIZING;
|
||||
|
||||
// Encode 1 time to determine the size.
|
||||
if (!pb_encode(&sizestream, logs_proto_mobilesdk_ios_ICoreConfiguration_fields, &_config)) {
|
||||
GDTLogError(GDTMCETransportBytesError, @"Error in nanopb encoding for size: %s",
|
||||
PB_GET_ERROR(&sizestream));
|
||||
GDTCORLogError(GDTCORMCETransportBytesError, @"Error in nanopb encoding for size: %s",
|
||||
PB_GET_ERROR(&sizestream));
|
||||
}
|
||||
|
||||
// Encode a 2nd time to actually get the bytes from it.
|
||||
@@ -126,8 +127,8 @@ NSString *const kFIRCoreDiagnosticsHeartbeatDateFileName = @"FIREBASE_DIAGNOSTIC
|
||||
CFMutableDataRef dataRef = CFDataCreateMutable(CFAllocatorGetDefault(), bufferSize);
|
||||
pb_ostream_t ostream = pb_ostream_from_buffer((void *)CFDataGetBytePtr(dataRef), bufferSize);
|
||||
if (!pb_encode(&ostream, logs_proto_mobilesdk_ios_ICoreConfiguration_fields, &_config)) {
|
||||
GDTLogError(GDTMCETransportBytesError, @"Error in nanopb encoding for bytes: %s",
|
||||
PB_GET_ERROR(&ostream));
|
||||
GDTCORLogError(GDTCORMCETransportBytesError, @"Error in nanopb encoding for bytes: %s",
|
||||
PB_GET_ERROR(&ostream));
|
||||
}
|
||||
CFDataSetLength(dataRef, ostream.bytes_written);
|
||||
|
||||
@@ -149,7 +150,7 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
@property(nonatomic, readonly) dispatch_queue_t diagnosticsQueue;
|
||||
|
||||
/** The transport object used to send data. */
|
||||
@property(nonatomic, readonly) GDTTransport *transport;
|
||||
@property(nonatomic, readonly) GDTCORTransport *transport;
|
||||
|
||||
/** The storage to store the date of the last sent heartbeat. */
|
||||
@property(nonatomic, readonly) FIRCoreDiagnosticsDateFileStorage *heartbeatDateStorage;
|
||||
@@ -170,9 +171,9 @@ NS_ASSUME_NONNULL_END
|
||||
}
|
||||
|
||||
- (instancetype)init {
|
||||
GDTTransport *transport = [[GDTTransport alloc] initWithMappingID:@"137"
|
||||
transformers:nil
|
||||
target:kGDTTargetCCT];
|
||||
GDTCORTransport *transport = [[GDTCORTransport alloc] initWithMappingID:@"137"
|
||||
transformers:nil
|
||||
target:kGDTCORTargetCCT];
|
||||
|
||||
FIRCoreDiagnosticsDateFileStorage *dateStorage = [[FIRCoreDiagnosticsDateFileStorage alloc]
|
||||
initWithFileURL:[[self class] filePathURLWithName:kFIRCoreDiagnosticsHeartbeatDateFileName]];
|
||||
@@ -182,11 +183,11 @@ NS_ASSUME_NONNULL_END
|
||||
|
||||
/** Initializer for unit tests.
|
||||
*
|
||||
* @param transport A `GDTTransport` instance which that be used to send event.
|
||||
* @param transport A `GDTCORTransport` instance which that be used to send event.
|
||||
* @param heartbeatDateStorage An instanse of date storage to track heartbeat sending.
|
||||
* @return Returns the initialized `FIRCoreDiagnostics` instance.
|
||||
*/
|
||||
- (instancetype)initWithTransport:(GDTTransport *)transport
|
||||
- (instancetype)initWithTransport:(GDTCORTransport *)transport
|
||||
heartbeatDateStorage:(FIRCoreDiagnosticsDateFileStorage *)heartbeatDateStorage {
|
||||
self = [super init];
|
||||
if (self) {
|
||||
@@ -374,7 +375,8 @@ void FIRPopulateProtoWithCommonInfoFromApp(logs_proto_mobilesdk_ios_ICoreConfigu
|
||||
config->has_pod_name = 1;
|
||||
|
||||
if (!diagnosticObjects[kFIRCDllAppsCountKey]) {
|
||||
GDTLogError(GDTMCEGeneralError, @"%@", @"App count is a required value in the data dict.");
|
||||
GDTCORLogError(GDTCORMCEGeneralError, @"%@",
|
||||
@"App count is a required value in the data dict.");
|
||||
}
|
||||
config->app_count = (int32_t)[diagnosticObjects[kFIRCDllAppsCountKey] integerValue];
|
||||
config->has_app_count = 1;
|
||||
@@ -635,8 +637,8 @@ void FIRPopulateProtoWithInfoPlistValues(logs_proto_mobilesdk_ios_ICoreConfigura
|
||||
FIRCoreDiagnosticsLog *log = [[FIRCoreDiagnosticsLog alloc] initWithConfig:icore_config];
|
||||
|
||||
// Send the log as a telemetry event.
|
||||
GDTEvent *event = [self.transport eventForTransport];
|
||||
event.dataObject = (id<GDTEventDataObject>)log;
|
||||
GDTCOREvent *event = [self.transport eventForTransport];
|
||||
event.dataObject = (id<GDTCOREventDataObject>)log;
|
||||
[self.transport sendTelemetryEvent:event];
|
||||
});
|
||||
}
|
||||
|
||||
+7
-19
@@ -26,28 +26,19 @@
|
||||
|
||||
|
||||
|
||||
const pb_field_t logs_proto_mobilesdk_ios_ICoreConfiguration_fields[34] = {
|
||||
const pb_field_t logs_proto_mobilesdk_ios_ICoreConfiguration_fields[22] = {
|
||||
PB_FIELD( 1, UENUM , OPTIONAL, STATIC , FIRST, logs_proto_mobilesdk_ios_ICoreConfiguration, configuration_type, configuration_type, 0),
|
||||
PB_FIELD( 2, BYTES , OPTIONAL, POINTER , OTHER, logs_proto_mobilesdk_ios_ICoreConfiguration, version_name, configuration_type, 0),
|
||||
PB_FIELD( 3, INT64 , OPTIONAL, STATIC , OTHER, logs_proto_mobilesdk_ios_ICoreConfiguration, build_number, version_name, 0),
|
||||
PB_FIELD( 4, UENUM , OPTIONAL, STATIC , OTHER, logs_proto_mobilesdk_ios_ICoreConfiguration, build_type, build_number, 0),
|
||||
PB_FIELD( 5, BYTES , OPTIONAL, POINTER , OTHER, logs_proto_mobilesdk_ios_ICoreConfiguration, plist_version, build_type, 0),
|
||||
PB_FIELD( 6, UENUM , REPEATED, POINTER , OTHER, logs_proto_mobilesdk_ios_ICoreConfiguration, sdk_service_enabled, plist_version, 0),
|
||||
PB_FIELD( 7, UENUM , REPEATED, POINTER , OTHER, logs_proto_mobilesdk_ios_ICoreConfiguration, sdk_service_installed, sdk_service_enabled, 0),
|
||||
PB_FIELD( 7, UENUM , REPEATED, POINTER , OTHER, logs_proto_mobilesdk_ios_ICoreConfiguration, sdk_service_installed, configuration_type, 0),
|
||||
PB_FIELD( 9, BYTES , OPTIONAL, POINTER , OTHER, logs_proto_mobilesdk_ios_ICoreConfiguration, device_model, sdk_service_installed, 0),
|
||||
PB_FIELD( 10, BYTES , OPTIONAL, POINTER , OTHER, logs_proto_mobilesdk_ios_ICoreConfiguration, app_id, device_model, 0),
|
||||
PB_FIELD( 11, INT64 , OPTIONAL, STATIC , OTHER, logs_proto_mobilesdk_ios_ICoreConfiguration, project_number, app_id, 0),
|
||||
PB_FIELD( 12, BYTES , OPTIONAL, POINTER , OTHER, logs_proto_mobilesdk_ios_ICoreConfiguration, bundle_id, project_number, 0),
|
||||
PB_FIELD( 13, BYTES , OPTIONAL, POINTER , OTHER, logs_proto_mobilesdk_ios_ICoreConfiguration, client_id, bundle_id, 0),
|
||||
PB_FIELD( 14, BYTES , OPTIONAL, POINTER , OTHER, logs_proto_mobilesdk_ios_ICoreConfiguration, install, client_id, 0),
|
||||
PB_FIELD( 16, UENUM , OPTIONAL, STATIC , OTHER, logs_proto_mobilesdk_ios_ICoreConfiguration, pod_name, install, 0),
|
||||
PB_FIELD( 12, BYTES , OPTIONAL, POINTER , OTHER, logs_proto_mobilesdk_ios_ICoreConfiguration, bundle_id, app_id, 0),
|
||||
PB_FIELD( 16, UENUM , OPTIONAL, STATIC , OTHER, logs_proto_mobilesdk_ios_ICoreConfiguration, pod_name, bundle_id, 0),
|
||||
PB_FIELD( 18, BYTES , OPTIONAL, POINTER , OTHER, logs_proto_mobilesdk_ios_ICoreConfiguration, icore_version, pod_name, 0),
|
||||
PB_FIELD( 19, BYTES , OPTIONAL, POINTER , OTHER, logs_proto_mobilesdk_ios_ICoreConfiguration, sdk_version, icore_version, 0),
|
||||
PB_FIELD( 20, UENUM , OPTIONAL, STATIC , OTHER, logs_proto_mobilesdk_ios_ICoreConfiguration, sdk_name, sdk_version, 0),
|
||||
PB_FIELD( 21, INT32 , OPTIONAL, STATIC , OTHER, logs_proto_mobilesdk_ios_ICoreConfiguration, app_count, sdk_name, 0),
|
||||
PB_FIELD( 22, BYTES , OPTIONAL, POINTER , OTHER, logs_proto_mobilesdk_ios_ICoreConfiguration, os_version, app_count, 0),
|
||||
PB_FIELD( 23, BYTES , OPTIONAL, POINTER , OTHER, logs_proto_mobilesdk_ios_ICoreConfiguration, itunes_id, os_version, 0),
|
||||
PB_FIELD( 24, BYTES , OPTIONAL, POINTER , OTHER, logs_proto_mobilesdk_ios_ICoreConfiguration, min_supported_ios_version, itunes_id, 0),
|
||||
PB_FIELD( 24, BYTES , OPTIONAL, POINTER , OTHER, logs_proto_mobilesdk_ios_ICoreConfiguration, min_supported_ios_version, os_version, 0),
|
||||
PB_FIELD( 25, BOOL , OPTIONAL, STATIC , OTHER, logs_proto_mobilesdk_ios_ICoreConfiguration, use_default_app, min_supported_ios_version, 0),
|
||||
PB_FIELD( 26, BOOL , OPTIONAL, STATIC , OTHER, logs_proto_mobilesdk_ios_ICoreConfiguration, deployed_in_app_store, use_default_app, 0),
|
||||
PB_FIELD( 27, INT32 , OPTIONAL, STATIC , OTHER, logs_proto_mobilesdk_ios_ICoreConfiguration, dynamic_framework_count, deployed_in_app_store, 0),
|
||||
@@ -55,11 +46,8 @@ const pb_field_t logs_proto_mobilesdk_ios_ICoreConfiguration_fields[34] = {
|
||||
PB_FIELD( 29, BOOL , OPTIONAL, STATIC , OTHER, logs_proto_mobilesdk_ios_ICoreConfiguration, using_zip_file, apple_framework_version, 0),
|
||||
PB_FIELD( 30, UENUM , OPTIONAL, STATIC , OTHER, logs_proto_mobilesdk_ios_ICoreConfiguration, deployment_type, using_zip_file, 0),
|
||||
PB_FIELD( 31, BYTES , OPTIONAL, POINTER , OTHER, logs_proto_mobilesdk_ios_ICoreConfiguration, platform_info, deployment_type, 0),
|
||||
PB_FIELD( 32, INT64 , OPTIONAL, STATIC , OTHER, logs_proto_mobilesdk_ios_ICoreConfiguration, app_extensions, platform_info, 0),
|
||||
PB_FIELD( 33, BOOL , OPTIONAL, STATIC , OTHER, logs_proto_mobilesdk_ios_ICoreConfiguration, swizzling_enabled, app_extensions, 0),
|
||||
PB_FIELD( 34, INT32 , OPTIONAL, STATIC , OTHER, logs_proto_mobilesdk_ios_ICoreConfiguration, log_error_count, swizzling_enabled, 0),
|
||||
PB_FIELD( 35, INT32 , OPTIONAL, STATIC , OTHER, logs_proto_mobilesdk_ios_ICoreConfiguration, log_warning_count, log_error_count, 0),
|
||||
PB_FIELD( 36, BOOL , OPTIONAL, STATIC , OTHER, logs_proto_mobilesdk_ios_ICoreConfiguration, using_gdt, log_warning_count, 0),
|
||||
PB_FIELD( 33, BOOL , OPTIONAL, STATIC , OTHER, logs_proto_mobilesdk_ios_ICoreConfiguration, swizzling_enabled, platform_info, 0),
|
||||
PB_FIELD( 36, BOOL , OPTIONAL, STATIC , OTHER, logs_proto_mobilesdk_ios_ICoreConfiguration, using_gdt, swizzling_enabled, 0),
|
||||
PB_LAST_FIELD
|
||||
};
|
||||
|
||||
|
||||
+3
-34
@@ -111,23 +111,11 @@ typedef enum _logs_proto_mobilesdk_ios_ICoreConfiguration_DeploymentType {
|
||||
typedef struct _logs_proto_mobilesdk_ios_ICoreConfiguration {
|
||||
bool has_configuration_type;
|
||||
logs_proto_mobilesdk_ios_ICoreConfiguration_ConfigurationType configuration_type;
|
||||
pb_bytes_array_t *version_name;
|
||||
bool has_build_number;
|
||||
int64_t build_number;
|
||||
bool has_build_type;
|
||||
logs_proto_mobilesdk_ios_ICoreConfiguration_BuildType build_type;
|
||||
pb_bytes_array_t *plist_version;
|
||||
pb_size_t sdk_service_enabled_count;
|
||||
logs_proto_mobilesdk_ios_ICoreConfiguration_ServiceType *sdk_service_enabled;
|
||||
pb_size_t sdk_service_installed_count;
|
||||
logs_proto_mobilesdk_ios_ICoreConfiguration_ServiceType *sdk_service_installed;
|
||||
pb_bytes_array_t *device_model;
|
||||
pb_bytes_array_t *app_id;
|
||||
bool has_project_number;
|
||||
int64_t project_number;
|
||||
pb_bytes_array_t *bundle_id;
|
||||
pb_bytes_array_t *client_id;
|
||||
pb_bytes_array_t *install;
|
||||
bool has_pod_name;
|
||||
logs_proto_mobilesdk_ios_ICoreConfiguration_PodName pod_name;
|
||||
pb_bytes_array_t *icore_version;
|
||||
@@ -137,7 +125,6 @@ typedef struct _logs_proto_mobilesdk_ios_ICoreConfiguration {
|
||||
bool has_app_count;
|
||||
int32_t app_count;
|
||||
pb_bytes_array_t *os_version;
|
||||
pb_bytes_array_t *itunes_id;
|
||||
pb_bytes_array_t *min_supported_ios_version;
|
||||
bool has_use_default_app;
|
||||
bool use_default_app;
|
||||
@@ -151,14 +138,8 @@ typedef struct _logs_proto_mobilesdk_ios_ICoreConfiguration {
|
||||
bool has_deployment_type;
|
||||
logs_proto_mobilesdk_ios_ICoreConfiguration_DeploymentType deployment_type;
|
||||
pb_bytes_array_t *platform_info;
|
||||
bool has_app_extensions;
|
||||
int64_t app_extensions;
|
||||
bool has_swizzling_enabled;
|
||||
bool swizzling_enabled;
|
||||
bool has_log_error_count;
|
||||
int32_t log_error_count;
|
||||
bool has_log_warning_count;
|
||||
int32_t log_warning_count;
|
||||
bool has_using_gdt;
|
||||
bool using_gdt;
|
||||
/* @@protoc_insertion_point(struct:logs_proto_mobilesdk_ios_ICoreConfiguration) */
|
||||
@@ -167,30 +148,21 @@ typedef struct _logs_proto_mobilesdk_ios_ICoreConfiguration {
|
||||
/* Default values for struct fields */
|
||||
|
||||
/* Initializer values for message structs */
|
||||
#define logs_proto_mobilesdk_ios_ICoreConfiguration_init_default {false, _logs_proto_mobilesdk_ios_ICoreConfiguration_ConfigurationType_MIN, NULL, false, 0, false, _logs_proto_mobilesdk_ios_ICoreConfiguration_BuildType_MIN, NULL, 0, NULL, 0, NULL, NULL, NULL, false, 0, NULL, NULL, NULL, false, _logs_proto_mobilesdk_ios_ICoreConfiguration_PodName_MIN, NULL, NULL, false, _logs_proto_mobilesdk_ios_ICoreConfiguration_ServiceType_MIN, false, 0, NULL, NULL, NULL, false, 0, false, 0, false, 0, NULL, false, 0, false, _logs_proto_mobilesdk_ios_ICoreConfiguration_DeploymentType_MIN, NULL, false, 0, false, 0, false, 0, false, 0, false, 0}
|
||||
#define logs_proto_mobilesdk_ios_ICoreConfiguration_init_zero {false, _logs_proto_mobilesdk_ios_ICoreConfiguration_ConfigurationType_MIN, NULL, false, 0, false, _logs_proto_mobilesdk_ios_ICoreConfiguration_BuildType_MIN, NULL, 0, NULL, 0, NULL, NULL, NULL, false, 0, NULL, NULL, NULL, false, _logs_proto_mobilesdk_ios_ICoreConfiguration_PodName_MIN, NULL, NULL, false, _logs_proto_mobilesdk_ios_ICoreConfiguration_ServiceType_MIN, false, 0, NULL, NULL, NULL, false, 0, false, 0, false, 0, NULL, false, 0, false, _logs_proto_mobilesdk_ios_ICoreConfiguration_DeploymentType_MIN, NULL, false, 0, false, 0, false, 0, false, 0, false, 0}
|
||||
#define logs_proto_mobilesdk_ios_ICoreConfiguration_init_default {false, _logs_proto_mobilesdk_ios_ICoreConfiguration_ConfigurationType_MIN, 0, NULL, NULL, NULL, NULL, false, _logs_proto_mobilesdk_ios_ICoreConfiguration_PodName_MIN, NULL, NULL, false, _logs_proto_mobilesdk_ios_ICoreConfiguration_ServiceType_MIN, false, 0, NULL, NULL, false, 0, false, 0, false, 0, NULL, false, 0, false, _logs_proto_mobilesdk_ios_ICoreConfiguration_DeploymentType_MIN, NULL, false, 0, false, 0}
|
||||
#define logs_proto_mobilesdk_ios_ICoreConfiguration_init_zero {false, _logs_proto_mobilesdk_ios_ICoreConfiguration_ConfigurationType_MIN, 0, NULL, NULL, NULL, NULL, false, _logs_proto_mobilesdk_ios_ICoreConfiguration_PodName_MIN, NULL, NULL, false, _logs_proto_mobilesdk_ios_ICoreConfiguration_ServiceType_MIN, false, 0, NULL, NULL, false, 0, false, 0, false, 0, NULL, false, 0, false, _logs_proto_mobilesdk_ios_ICoreConfiguration_DeploymentType_MIN, NULL, false, 0, false, 0}
|
||||
|
||||
/* Field tags (for use in manual encoding/decoding) */
|
||||
#define logs_proto_mobilesdk_ios_ICoreConfiguration_pod_name_tag 16
|
||||
#define logs_proto_mobilesdk_ios_ICoreConfiguration_configuration_type_tag 1
|
||||
#define logs_proto_mobilesdk_ios_ICoreConfiguration_version_name_tag 2
|
||||
#define logs_proto_mobilesdk_ios_ICoreConfiguration_icore_version_tag 18
|
||||
#define logs_proto_mobilesdk_ios_ICoreConfiguration_sdk_version_tag 19
|
||||
#define logs_proto_mobilesdk_ios_ICoreConfiguration_build_number_tag 3
|
||||
#define logs_proto_mobilesdk_ios_ICoreConfiguration_build_type_tag 4
|
||||
#define logs_proto_mobilesdk_ios_ICoreConfiguration_plist_version_tag 5
|
||||
#define logs_proto_mobilesdk_ios_ICoreConfiguration_sdk_service_enabled_tag 6
|
||||
#define logs_proto_mobilesdk_ios_ICoreConfiguration_sdk_service_installed_tag 7
|
||||
#define logs_proto_mobilesdk_ios_ICoreConfiguration_sdk_name_tag 20
|
||||
#define logs_proto_mobilesdk_ios_ICoreConfiguration_device_model_tag 9
|
||||
#define logs_proto_mobilesdk_ios_ICoreConfiguration_os_version_tag 22
|
||||
#define logs_proto_mobilesdk_ios_ICoreConfiguration_app_id_tag 10
|
||||
#define logs_proto_mobilesdk_ios_ICoreConfiguration_project_number_tag 11
|
||||
#define logs_proto_mobilesdk_ios_ICoreConfiguration_bundle_id_tag 12
|
||||
#define logs_proto_mobilesdk_ios_ICoreConfiguration_client_id_tag 13
|
||||
#define logs_proto_mobilesdk_ios_ICoreConfiguration_itunes_id_tag 23
|
||||
#define logs_proto_mobilesdk_ios_ICoreConfiguration_min_supported_ios_version_tag 24
|
||||
#define logs_proto_mobilesdk_ios_ICoreConfiguration_install_tag 14
|
||||
#define logs_proto_mobilesdk_ios_ICoreConfiguration_use_default_app_tag 25
|
||||
#define logs_proto_mobilesdk_ios_ICoreConfiguration_app_count_tag 21
|
||||
#define logs_proto_mobilesdk_ios_ICoreConfiguration_deployed_in_app_store_tag 26
|
||||
@@ -199,14 +171,11 @@ typedef struct _logs_proto_mobilesdk_ios_ICoreConfiguration {
|
||||
#define logs_proto_mobilesdk_ios_ICoreConfiguration_using_zip_file_tag 29
|
||||
#define logs_proto_mobilesdk_ios_ICoreConfiguration_deployment_type_tag 30
|
||||
#define logs_proto_mobilesdk_ios_ICoreConfiguration_platform_info_tag 31
|
||||
#define logs_proto_mobilesdk_ios_ICoreConfiguration_app_extensions_tag 32
|
||||
#define logs_proto_mobilesdk_ios_ICoreConfiguration_swizzling_enabled_tag 33
|
||||
#define logs_proto_mobilesdk_ios_ICoreConfiguration_log_error_count_tag 34
|
||||
#define logs_proto_mobilesdk_ios_ICoreConfiguration_log_warning_count_tag 35
|
||||
#define logs_proto_mobilesdk_ios_ICoreConfiguration_using_gdt_tag 36
|
||||
|
||||
/* Struct field encoding specification for nanopb */
|
||||
extern const pb_field_t logs_proto_mobilesdk_ios_ICoreConfiguration_fields[34];
|
||||
extern const pb_field_t logs_proto_mobilesdk_ios_ICoreConfiguration_fields[22];
|
||||
|
||||
/* Maximum encoded size of messages (where known) */
|
||||
/* logs_proto_mobilesdk_ios_ICoreConfiguration_size depends on runtime parameters */
|
||||
|
||||
Generated
+17
-10
@@ -1,9 +1,10 @@
|
||||
# Firebase iOS Open Source Development [](https://travis-ci.org/firebase/firebase-ios-sdk)
|
||||
|
||||
This repository contains a subset of the Firebase iOS SDK source. It currently
|
||||
includes FirebaseCore, FirebaseAuth, FirebaseDatabase, FirebaseFirestore,
|
||||
FirebaseFunctions, FirebaseInstanceID, FirebaseInAppMessaging,
|
||||
FirebaseInAppMessagingDisplay, FirebaseMessaging and FirebaseStorage.
|
||||
includes FirebaseCore, FirebaseABTesting, FirebaseAuth, FirebaseDatabase,
|
||||
FirebaseFirestore, FirebaseFunctions, FirebaseInstanceID, FirebaseInAppMessaging,
|
||||
FirebaseInAppMessagingDisplay, FirebaseMessaging, FirebaseRemoteConfig, and
|
||||
FirebaseStorage.
|
||||
|
||||
The repository also includes GoogleUtilities source. The
|
||||
[GoogleUtilities](GoogleUtilities/README.md) pod is
|
||||
@@ -80,9 +81,8 @@ For the pod that you want to develop:
|
||||
|
||||
`pod gen Firebase{name here}.podspec --local-sources=./ --auto-open`
|
||||
|
||||
Firestore and Functions have self contained Xcode projects. See
|
||||
[Firestore/README.md](Firestore/README.md) and
|
||||
[Functions/README.md](Functions/README.md).
|
||||
Firestore has a self contained Xcode project. See
|
||||
[Firestore/README.md](Firestore/README.md).
|
||||
|
||||
### Adding a New Firebase Pod
|
||||
|
||||
@@ -99,13 +99,17 @@ Travis will verify that any code changes are done in a style compliant way. Inst
|
||||
These commands will get the right versions:
|
||||
|
||||
```
|
||||
brew install https://raw.githubusercontent.com/Homebrew/homebrew-core/773cb75d360b58f32048f5964038d09825a507c8/Formula/clang-format.rb
|
||||
brew install https://raw.githubusercontent.com/Homebrew/homebrew-core/3dfea1004e0736754bbf49673cca8aaed8a94089/Formula/swiftformat.rb
|
||||
brew upgrade https://raw.githubusercontent.com/Homebrew/homebrew-core/e3496d9/Formula/clang-format.rb
|
||||
brew upgrade https://raw.githubusercontent.com/Homebrew/homebrew-core/7963c3d/Formula/swiftformat.rb
|
||||
```
|
||||
|
||||
Note: if you already have a newer version of these installed you may need to
|
||||
`brew switch` to this version.
|
||||
|
||||
To update this section, find the versions of clang-format and swiftformat.rb to
|
||||
match the versions in the CI failure logs
|
||||
[here](https://github.com/Homebrew/homebrew-core/tree/master/Formula).
|
||||
|
||||
### Running Unit Tests
|
||||
|
||||
Select a scheme and press Command-u to build a component and run its unit tests.
|
||||
@@ -179,8 +183,9 @@ very grateful! We'd like to empower as many developers as we can to be able to
|
||||
participate in the Firebase community.
|
||||
|
||||
### macOS and tvOS
|
||||
Thanks to contributions from the community, FirebaseAuth, FirebaseCore, FirebaseDatabase, FirebaseMessaging,
|
||||
FirebaseFirestore, FirebaseFunctions and FirebaseStorage now compile, run unit tests, and work on
|
||||
Thanks to contributions from the community, FirebaseABTesting, FirebaseAuth, FirebaseCore,
|
||||
FirebaseDatabase, FirebaseMessaging, FirebaseFirestore,
|
||||
FirebaseFunctions, FirebaseRemoteConfig, and FirebaseStorage now compile, run unit tests, and work on
|
||||
macOS and tvOS.
|
||||
|
||||
For tvOS, checkout the [Sample](Example/tvOSSample).
|
||||
@@ -195,12 +200,14 @@ Note that the Firebase pod is not available for macOS and tvOS.
|
||||
To install, add a subset of the following to the Podfile:
|
||||
|
||||
```
|
||||
pod 'FirebaseABTesting'
|
||||
pod 'FirebaseAuth'
|
||||
pod 'FirebaseCore'
|
||||
pod 'FirebaseDatabase'
|
||||
pod 'FirebaseFirestore'
|
||||
pod 'FirebaseFunctions'
|
||||
pod 'FirebaseMessaging'
|
||||
pod 'FirebaseRemoteConfig'
|
||||
pod 'FirebaseStorage'
|
||||
```
|
||||
|
||||
|
||||
+1
-1
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#import "FIRInstanceIDCheckinPreferences.h"
|
||||
#import <FirebaseInstanceID/FIRInstanceIDCheckinPreferences.h>
|
||||
|
||||
@interface FIRInstanceIDCheckinPreferences (Internal)
|
||||
|
||||
|
||||
+1
-1
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#import "FIRInstanceIDCheckinPreferences.h"
|
||||
#import <FirebaseInstanceID/FIRInstanceIDCheckinPreferences.h>
|
||||
|
||||
/** Checkin refresh interval. **/
|
||||
FOUNDATION_EXPORT const NSTimeInterval kFIRInstanceIDDefaultCheckinInterval;
|
||||
|
||||
+1
-14
@@ -16,6 +16,7 @@
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#import <FirebaseInstanceID/FIRInstanceID+Private.h>
|
||||
#import "FIRInstanceIDUtilities.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
@@ -31,20 +32,6 @@ FOUNDATION_EXPORT NSString *const kFIRInstanceIDDeviceDataVersionKey;
|
||||
|
||||
@class FIRInstanceIDCheckinPreferences;
|
||||
|
||||
/**
|
||||
* @related FIRInstanceIDCheckinService
|
||||
*
|
||||
* The completion handler invoked once the fetch from Checkin server finishes.
|
||||
* For successful fetches we returned checkin information by the checkin service
|
||||
* and `nil` error, else we return the appropriate error object as reported by the
|
||||
* Checkin Service.
|
||||
*
|
||||
* @param checkinPreferences The checkin preferences as fetched from the server.
|
||||
* @param error The error object which fetching GServices data.
|
||||
*/
|
||||
typedef void (^FIRInstanceIDDeviceCheckinCompletion)(
|
||||
FIRInstanceIDCheckinPreferences *_Nullable checkinPreferences, NSError *_Nullable error);
|
||||
|
||||
/**
|
||||
* Register the device with Checkin Service and get back the `authID`, `secret
|
||||
* token` etc. for the client. Checkin results are cached in the
|
||||
|
||||
+17
-5
@@ -14,14 +14,26 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#import "FIRInstanceID.h"
|
||||
|
||||
#import "FIRInstanceIDCheckinService.h"
|
||||
#import <FirebaseInstanceID/FIRInstanceID.h>
|
||||
#import <FirebaseInstanceID/FIRInstanceIDCheckinPreferences.h>
|
||||
|
||||
/**
|
||||
* Internal API used by Firebase SDK teams by calling in reflection or internal teams.
|
||||
* @related FIRInstanceIDCheckinService
|
||||
*
|
||||
* The completion handler invoked once the fetch from Checkin server finishes.
|
||||
* For successful fetches we returned checkin information by the checkin service
|
||||
* and `nil` error, else we return the appropriate error object as reported by the
|
||||
* Checkin Service.
|
||||
*
|
||||
* @param checkinPreferences The checkin preferences as fetched from the server.
|
||||
* @param error The error object which fetching GServices data.
|
||||
*/
|
||||
typedef void (^FIRInstanceIDDeviceCheckinCompletion)(
|
||||
FIRInstanceIDCheckinPreferences *_Nullable checkinPreferences, NSError *_Nullable error);
|
||||
|
||||
/**
|
||||
* Private API used by Firebase SDK teams by calling in reflection or internal teams.
|
||||
*/
|
||||
// TODO(chliangGoogle) Rename this to Internal.
|
||||
@interface FIRInstanceID (Private)
|
||||
|
||||
/**
|
||||
Generated
+7
-6
@@ -1,8 +1,8 @@
|
||||
# Firebase iOS Open Source Development [](https://travis-ci.org/firebase/firebase-ios-sdk)
|
||||
|
||||
This repository contains a subset of the Firebase iOS SDK source. It currently
|
||||
includes FirebaseCore, FirebaseAuth, FirebaseDatabase, FirebaseFirestore,
|
||||
FirebaseFunctions, FirebaseInstanceID, FirebaseInAppMessaging,
|
||||
includes FirebaseCore, FirebaseABTesting, FirebaseAuth, FirebaseDatabase,
|
||||
FirebaseFirestore, FirebaseFunctions, FirebaseInstanceID, FirebaseInAppMessaging,
|
||||
FirebaseInAppMessagingDisplay, FirebaseMessaging and FirebaseStorage.
|
||||
|
||||
The repository also includes GoogleUtilities source. The
|
||||
@@ -80,9 +80,8 @@ For the pod that you want to develop:
|
||||
|
||||
`pod gen Firebase{name here}.podspec --local-sources=./ --auto-open`
|
||||
|
||||
Firestore and Functions have self contained Xcode projects. See
|
||||
[Firestore/README.md](Firestore/README.md) and
|
||||
[Functions/README.md](Functions/README.md).
|
||||
Firestore has a self contained Xcode project. See
|
||||
[Firestore/README.md](Firestore/README.md).
|
||||
|
||||
### Adding a New Firebase Pod
|
||||
|
||||
@@ -179,7 +178,8 @@ very grateful! We'd like to empower as many developers as we can to be able to
|
||||
participate in the Firebase community.
|
||||
|
||||
### macOS and tvOS
|
||||
Thanks to contributions from the community, FirebaseAuth, FirebaseCore, FirebaseDatabase, FirebaseMessaging,
|
||||
Thanks to contributions from the community, FirebaseABTesting, FirebaseAuth, FirebaseCore,
|
||||
FirebaseDatabase, FirebaseMessaging,
|
||||
FirebaseFirestore, FirebaseFunctions and FirebaseStorage now compile, run unit tests, and work on
|
||||
macOS and tvOS.
|
||||
|
||||
@@ -195,6 +195,7 @@ Note that the Firebase pod is not available for macOS and tvOS.
|
||||
To install, add a subset of the following to the Podfile:
|
||||
|
||||
```
|
||||
pod 'FirebaseABTesting'
|
||||
pod 'FirebaseAuth'
|
||||
pod 'FirebaseCore'
|
||||
pod 'FirebaseDatabase'
|
||||
|
||||
@@ -47,6 +47,7 @@ typedef NS_ENUM(NSInteger, FIRMessagingMessageCode) {
|
||||
kFIRMessagingMessageCodeTokenDelegateMethodsNotImplemented = 2023, // I-FCM002023
|
||||
kFIRMessagingMessageCodeTopicFormatIsDeprecated = 2024,
|
||||
kFIRMessagingMessageCodeDirectChannelConnectionFailed = 2025,
|
||||
kFIRMessagingMessageCodeInvalidClient = 2026,
|
||||
// FIRMessagingClient.m
|
||||
kFIRMessagingMessageCodeClient000 = 4000, // I-FCM004000
|
||||
kFIRMessagingMessageCodeClient001 = 4001, // I-FCM004001
|
||||
@@ -60,6 +61,9 @@ typedef NS_ENUM(NSInteger, FIRMessagingMessageCode) {
|
||||
kFIRMessagingMessageCodeClient009 = 4009, // I-FCM004009
|
||||
kFIRMessagingMessageCodeClient010 = 4010, // I-FCM004010
|
||||
kFIRMessagingMessageCodeClient011 = 4011, // I-FCM004011
|
||||
kFIRMessagingMessageCodeClientInvalidState = 4012,
|
||||
kFIRMessagingMessageCodeClientInvalidStateTimeout = 4013,
|
||||
|
||||
// FIRMessagingConnection.m
|
||||
kFIRMessagingMessageCodeConnection000 = 5000, // I-FCM005000
|
||||
kFIRMessagingMessageCodeConnection001 = 5001, // I-FCM005001
|
||||
@@ -106,6 +110,8 @@ typedef NS_ENUM(NSInteger, FIRMessagingMessageCode) {
|
||||
kFIRMessagingMessageCodeDataMessageManager010 = 7010, // I-FCM007010
|
||||
kFIRMessagingMessageCodeDataMessageManager011 = 7011, // I-FCM007011
|
||||
kFIRMessagingMessageCodeDataMessageManager012 = 7012, // I-FCM007012
|
||||
kFIRMessagingMessageCodeDataMessageManager013 = 7013,
|
||||
|
||||
// FIRMessagingPendingTopicsList.m
|
||||
kFIRMessagingMessageCodePendingTopicsList000 = 8000, // I-FCM008000
|
||||
// FIRMessagingPubSub.m
|
||||
@@ -196,4 +202,7 @@ typedef NS_ENUM(NSInteger, FIRMessagingMessageCode) {
|
||||
kFIRMessagingServiceExtensionLocalFileNotCreated = 20002,
|
||||
kFIRMessagingServiceExtensionImageNotAttached = 20003,
|
||||
|
||||
// FIRMessagingCodedInputStream.m
|
||||
kFIRMessagingCodeInputStreamInvalidParameters = 21000,
|
||||
|
||||
};
|
||||
|
||||
+60
-58
@@ -18,26 +18,6 @@
|
||||
#error FIRMessagingLib should be compiled with ARC.
|
||||
#endif
|
||||
|
||||
#import "FIRMessaging.h"
|
||||
#import "FIRMessaging_Private.h"
|
||||
|
||||
#import "FIRMessagingAnalytics.h"
|
||||
#import "FIRMessagingClient.h"
|
||||
#import "FIRMessagingConstants.h"
|
||||
#import "FIRMessagingContextManagerService.h"
|
||||
#import "FIRMessagingDataMessageManager.h"
|
||||
#import "FIRMessagingDefines.h"
|
||||
#import "FIRMessagingExtensionHelper.h"
|
||||
#import "FIRMessagingLogger.h"
|
||||
#import "FIRMessagingPubSub.h"
|
||||
#import "FIRMessagingReceiver.h"
|
||||
#import "FIRMessagingRemoteNotificationsProxy.h"
|
||||
#import "FIRMessagingRmqManager.h"
|
||||
#import "FIRMessagingSyncMessageManager.h"
|
||||
#import "FIRMessagingUtilities.h"
|
||||
#import "FIRMessagingVersionUtilities.h"
|
||||
#import "FIRMessaging_Private.h"
|
||||
|
||||
#import <FirebaseAnalyticsInterop/FIRAnalyticsInterop.h>
|
||||
#import <FirebaseCore/FIRAppInternal.h>
|
||||
#import <FirebaseCore/FIRComponent.h>
|
||||
@@ -46,11 +26,28 @@
|
||||
#import <FirebaseCore/FIRLibrary.h>
|
||||
#import <FirebaseInstanceID/FirebaseInstanceID.h>
|
||||
#import <FirebaseInstanceID/FIRInstanceID_Private.h>
|
||||
#import <FirebaseMessaging/FIRMessaging.h>
|
||||
#import <FirebaseMessaging/FIRMessagingExtensionHelper.h>
|
||||
#import <GoogleUtilities/GULReachabilityChecker.h>
|
||||
#import <GoogleUtilities/GULUserDefaults.h>
|
||||
#import <GoogleUtilities/GULAppDelegateSwizzler.h>
|
||||
|
||||
#import "NSError+FIRMessaging.h"
|
||||
#import "Firebase/Messaging/FIRMessagingAnalytics.h"
|
||||
#import "Firebase/Messaging/FIRMessagingClient.h"
|
||||
#import "Firebase/Messaging/FIRMessagingConstants.h"
|
||||
#import "Firebase/Messaging/FIRMessagingContextManagerService.h"
|
||||
#import "Firebase/Messaging/FIRMessagingDataMessageManager.h"
|
||||
#import "Firebase/Messaging/FIRMessagingDefines.h"
|
||||
#import "Firebase/Messaging/FIRMessagingLogger.h"
|
||||
#import "Firebase/Messaging/FIRMessagingPubSub.h"
|
||||
#import "Firebase/Messaging/FIRMessagingReceiver.h"
|
||||
#import "Firebase/Messaging/FIRMessagingRemoteNotificationsProxy.h"
|
||||
#import "Firebase/Messaging/FIRMessagingRmqManager.h"
|
||||
#import "Firebase/Messaging/FIRMessagingSyncMessageManager.h"
|
||||
#import "Firebase/Messaging/FIRMessagingUtilities.h"
|
||||
#import "Firebase/Messaging/FIRMessagingVersionUtilities.h"
|
||||
#import "Firebase/Messaging/FIRMessaging_Private.h"
|
||||
#import "Firebase/Messaging/NSError+FIRMessaging.h"
|
||||
|
||||
static NSString *const kFIRMessagingMessageViaAPNSRootKey = @"aps";
|
||||
static NSString *const kFIRMessagingReachabilityHostname = @"www.google.com";
|
||||
@@ -89,6 +86,20 @@ NSString *const kFIRMessagingAPNSTokenType = @"APNSTokenType"; // APNS Token typ
|
||||
NSString *const kFIRMessagingPlistAutoInitEnabled =
|
||||
@"FirebaseMessagingAutoInitEnabled"; // Auto Init Enabled key stored in Info.plist
|
||||
|
||||
const BOOL FIRMessagingIsAPNSSyncMessage(NSDictionary *message) {
|
||||
if ([message[kFIRMessagingMessageViaAPNSRootKey] isKindOfClass:[NSDictionary class]]) {
|
||||
NSDictionary *aps = message[kFIRMessagingMessageViaAPNSRootKey];
|
||||
if (aps && [aps isKindOfClass:[NSDictionary class]]) {
|
||||
return [aps[kFIRMessagingMessageAPNSContentAvailableKey] boolValue];
|
||||
}
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
|
||||
BOOL FIRMessagingIsContextManagerMessage(NSDictionary *message) {
|
||||
return [FIRMessagingContextManagerService isContextManagerMessage:message];
|
||||
}
|
||||
|
||||
@interface FIRMessagingMessageInfo ()
|
||||
|
||||
@property(nonatomic, readwrite, assign) FIRMessagingMessageStatus status;
|
||||
@@ -170,13 +181,7 @@ NSString *const kFIRMessagingPlistAutoInitEnabled =
|
||||
FIR_COMPONENT(FIRMessagingInstanceProvider, defaultApp.container);
|
||||
|
||||
// We know the instance coming from the container is a FIRMessaging instance, cast it and move on.
|
||||
FIRMessaging *messaging = (FIRMessaging *)instance;
|
||||
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
[messaging start];
|
||||
});
|
||||
return messaging;
|
||||
return (FIRMessaging *)instance;
|
||||
}
|
||||
|
||||
+ (FIRMessagingExtensionHelper *)extensionHelper {
|
||||
@@ -223,9 +228,12 @@ NSString *const kFIRMessagingPlistAutoInitEnabled =
|
||||
// Ensure it's cached so it returns the same instance every time messaging is called.
|
||||
*isCacheable = YES;
|
||||
id<FIRAnalyticsInterop> analytics = FIR_COMPONENT(FIRAnalyticsInterop, container);
|
||||
return [[FIRMessaging alloc] initWithAnalytics:analytics
|
||||
withInstanceID:[FIRInstanceID instanceID]
|
||||
withUserDefaults:[GULUserDefaults standardUserDefaults]];
|
||||
FIRMessaging *messaging =
|
||||
[[FIRMessaging alloc] initWithAnalytics:analytics
|
||||
withInstanceID:[FIRInstanceID instanceID]
|
||||
withUserDefaults:[GULUserDefaults standardUserDefaults]];
|
||||
[messaging start];
|
||||
return messaging;
|
||||
};
|
||||
FIRComponent *messagingProvider =
|
||||
[FIRComponent componentWithProtocol:@protocol(FIRMessagingInstanceProvider)
|
||||
@@ -348,7 +356,9 @@ NSString *const kFIRMessagingPlistAutoInitEnabled =
|
||||
}
|
||||
|
||||
- (void)setupTopics {
|
||||
_FIRMessagingDevAssert(self.client, @"Invalid nil client before init pubsub.");
|
||||
if (!self.client) {
|
||||
FIRMessagingLoggerWarn(kFIRMessagingMessageCodeInvalidClient, @"Invalid nil client before init pubsub.");
|
||||
}
|
||||
self.pubsub = [[FIRMessagingPubSub alloc] initWithClient:self.client];
|
||||
}
|
||||
|
||||
@@ -367,8 +377,6 @@ NSString *const kFIRMessagingPlistAutoInitEnabled =
|
||||
}
|
||||
|
||||
- (void)teardown {
|
||||
_FIRMessagingDevAssert([NSThread isMainThread],
|
||||
@"FIRMessaging should be called from main thread only.");
|
||||
[self.client teardown];
|
||||
self.pubsub = nil;
|
||||
self.syncMessageManager = nil;
|
||||
@@ -390,21 +398,25 @@ NSString *const kFIRMessagingPlistAutoInitEnabled =
|
||||
// the message to the device.
|
||||
BOOL isOldMessage = NO;
|
||||
NSString *messageID = message[kFIRMessagingMessageIDKey];
|
||||
if ([messageID length]) {
|
||||
if (messageID.length) {
|
||||
[self.rmq2Manager saveS2dMessageWithRmqId:messageID];
|
||||
|
||||
BOOL isSyncMessage = [[self class] isAPNSSyncMessage:message];
|
||||
BOOL isSyncMessage = FIRMessagingIsAPNSSyncMessage(message);
|
||||
if (isSyncMessage) {
|
||||
isOldMessage = [self.syncMessageManager didReceiveAPNSSyncMessage:message];
|
||||
}
|
||||
}
|
||||
// Prevent duplicates by keeping a cache of all the logged messages during each session.
|
||||
// The duplicates only happen when the 3P app calls `appDidReceiveMessage:` along with
|
||||
// us swizzling their implementation to call the same method implicitly.
|
||||
if (!isOldMessage && messageID.length) {
|
||||
isOldMessage = [self.loggedMessageIDs containsObject:messageID];
|
||||
if (!isOldMessage) {
|
||||
[self.loggedMessageIDs addObject:messageID];
|
||||
|
||||
// Prevent duplicates by keeping a cache of all the logged messages during each session.
|
||||
// The duplicates only happen when the 3P app calls `appDidReceiveMessage:` along with
|
||||
// us swizzling their implementation to call the same method implicitly.
|
||||
// We need to rule out the contextual message because it shares the same message ID
|
||||
// as the local notification it will schedule. And because it is also a APNSSync message
|
||||
// its duplication is already checked previously.
|
||||
if (!isOldMessage && !FIRMessagingIsContextManagerMessage(message)) {
|
||||
isOldMessage = [self.loggedMessageIDs containsObject:messageID];
|
||||
if (!isOldMessage) {
|
||||
[self.loggedMessageIDs addObject:messageID];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -417,20 +429,12 @@ NSString *const kFIRMessagingPlistAutoInitEnabled =
|
||||
}
|
||||
|
||||
- (BOOL)handleContextManagerMessage:(NSDictionary *)message {
|
||||
if ([FIRMessagingContextManagerService isContextManagerMessage:message]) {
|
||||
if (FIRMessagingIsContextManagerMessage(message)) {
|
||||
return [FIRMessagingContextManagerService handleContextManagerMessage:message];
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
|
||||
+ (BOOL)isAPNSSyncMessage:(NSDictionary *)message {
|
||||
if ([message[kFIRMessagingMessageViaAPNSRootKey] isKindOfClass:[NSDictionary class]]) {
|
||||
NSDictionary *aps = message[kFIRMessagingMessageViaAPNSRootKey];
|
||||
return [aps[kFIRMessagingMessageAPNSContentAvailableKey] boolValue];
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (void)handleIncomingLinkIfNeededFromMessage:(NSDictionary *)message {
|
||||
#if TARGET_OS_IOS || TARGET_OS_TV
|
||||
NSURL *url = [self linkURLFromMessage:message];
|
||||
@@ -826,15 +830,13 @@ NSString *const kFIRMessagingPlistAutoInitEnabled =
|
||||
to:(NSString *)to
|
||||
withMessageID:(NSString *)messageID
|
||||
timeToLive:(int64_t)ttl {
|
||||
_FIRMessagingDevAssert([to length] != 0, @"Invalid receiver id for FIRMessaging-message");
|
||||
|
||||
NSMutableDictionary *fcmMessage = [[self class] createFIRMessagingMessageWithMessage:message
|
||||
to:to
|
||||
withID:messageID
|
||||
timeToLive:ttl
|
||||
delay:0];
|
||||
FIRMessagingLoggerInfo(kFIRMessagingMessageCodeMessaging013, @"Sending message: %@ with id: %@",
|
||||
message, messageID);
|
||||
FIRMessagingLoggerInfo(kFIRMessagingMessageCodeMessaging013, @"Sending message: %@ with id: %@ to %@.",
|
||||
message, messageID, to);
|
||||
[self.dataMessageManager sendDataMessageStanza:fcmMessage];
|
||||
}
|
||||
|
||||
@@ -872,7 +874,7 @@ NSString *const kFIRMessagingPlistAutoInitEnabled =
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wunguarded-availability"
|
||||
[self.delegate messaging:self didReceiveMessage:remoteMessage];
|
||||
#pragma pop
|
||||
#pragma clang diagnostic pop
|
||||
} else {
|
||||
// Delegate methods weren't implemented, so messages are being dropped, log a warning
|
||||
FIRMessagingLoggerWarn(kFIRMessagingMessageCodeRemoteMessageDelegateMethodNotImplemented,
|
||||
|
||||
@@ -14,14 +14,16 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#import "FIRMessagingAnalytics.h"
|
||||
#import "FIRMessagingLogger.h"
|
||||
#import "Firebase/Messaging/FIRMessagingAnalytics.h"
|
||||
|
||||
#import <FirebaseAnalyticsInterop/FIRInteropEventNames.h>
|
||||
#import <FirebaseAnalyticsInterop/FIRInteropParameterNames.h>
|
||||
#import <GoogleUtilities/GULAppEnvironmentUtil.h>
|
||||
#import <GoogleUtilities/GULAppDelegateSwizzler.h>
|
||||
|
||||
#import "Firebase/Messaging/FIRMessagingLogger.h"
|
||||
|
||||
|
||||
static NSString *const kLogTag = @"FIRMessagingAnalytics";
|
||||
|
||||
// aps Key
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#import "FIRMessaging.h"
|
||||
#import <FirebaseMessaging/FIRMessaging.h>
|
||||
|
||||
@class GULReachabilityChecker;
|
||||
@class GPBMessage;
|
||||
|
||||
+32
-33
@@ -14,22 +14,22 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#import "FIRMessagingClient.h"
|
||||
#import "Firebase/Messaging/FIRMessagingClient.h"
|
||||
|
||||
#import <FirebaseInstanceID/FIRInstanceID_Private.h>
|
||||
#import <FirebaseMessaging/FIRMessaging.h>
|
||||
#import <GoogleUtilities/GULReachabilityChecker.h>
|
||||
|
||||
#import "FIRMessaging.h"
|
||||
#import "FIRMessagingConnection.h"
|
||||
#import "FIRMessagingConstants.h"
|
||||
#import "FIRMessagingDataMessageManager.h"
|
||||
#import "FIRMessagingDefines.h"
|
||||
#import "FIRMessagingLogger.h"
|
||||
#import "FIRMessagingRmqManager.h"
|
||||
#import "FIRMessagingTopicsCommon.h"
|
||||
#import "FIRMessagingUtilities.h"
|
||||
#import "NSError+FIRMessaging.h"
|
||||
#import "FIRMessagingPubSubRegistrar.h"
|
||||
#import "Firebase/Messaging/FIRMessagingConnection.h"
|
||||
#import "Firebase/Messaging/FIRMessagingConstants.h"
|
||||
#import "Firebase/Messaging/FIRMessagingDataMessageManager.h"
|
||||
#import "Firebase/Messaging/FIRMessagingDefines.h"
|
||||
#import "Firebase/Messaging/FIRMessagingLogger.h"
|
||||
#import "Firebase/Messaging/FIRMessagingRmqManager.h"
|
||||
#import "Firebase/Messaging/FIRMessagingTopicsCommon.h"
|
||||
#import "Firebase/Messaging/FIRMessagingUtilities.h"
|
||||
#import "Firebase/Messaging/NSError+FIRMessaging.h"
|
||||
#import "Firebase/Messaging/FIRMessagingPubSubRegistrar.h"
|
||||
|
||||
static const NSTimeInterval kConnectTimeoutInterval = 40.0;
|
||||
static const NSTimeInterval kReconnectDelayInSeconds = 2 * 60; // 2 minutes
|
||||
@@ -131,7 +131,9 @@ static NSUInteger FIRMessagingServerPort() {
|
||||
}
|
||||
|
||||
- (void)teardown {
|
||||
FIRMessagingLoggerDebug(kFIRMessagingMessageCodeClient000, @"");
|
||||
if (![NSThread isMainThread]) {
|
||||
FIRMessagingLoggerDebug(kFIRMessagingMessageCodeClient000, @"FIRMessagingClient should be called from main thread only.");
|
||||
}
|
||||
self.stayConnected = NO;
|
||||
|
||||
// Clear all the handlers
|
||||
@@ -140,9 +142,8 @@ static NSUInteger FIRMessagingServerPort() {
|
||||
[self.connection teardown];
|
||||
|
||||
// Stop all subscription requests
|
||||
[self.registrar stopAllSubscriptionRequests];
|
||||
[self.registrar stopAllSubscriptionRequests];
|
||||
|
||||
_FIRMessagingDevAssert(self.connection.state == kFIRMessagingConnectionNotConnected, @"Did not disconnect");
|
||||
[NSObject cancelPreviousPerformRequestsWithTarget:self];
|
||||
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
||||
@@ -166,10 +167,7 @@ static NSUInteger FIRMessagingServerPort() {
|
||||
options:(NSDictionary *)options
|
||||
shouldDelete:(BOOL)shouldDelete
|
||||
handler:(FIRMessagingTopicOperationCompletion)handler {
|
||||
|
||||
_FIRMessagingDevAssert(handler != nil, @"Invalid handler to FIRMessaging subscribe");
|
||||
|
||||
FIRMessagingTopicOperationCompletion completion = ^void(NSError *error) {
|
||||
FIRMessagingTopicOperationCompletion completion = ^void(NSError *error) {
|
||||
if (error) {
|
||||
FIRMessagingLoggerError(kFIRMessagingMessageCodeClient001, @"Failed to subscribe to topic %@",
|
||||
error);
|
||||
@@ -182,7 +180,9 @@ static NSUInteger FIRMessagingServerPort() {
|
||||
@"Successfully subscribed to topic %@", topic);
|
||||
}
|
||||
}
|
||||
handler(error);
|
||||
if (handler) {
|
||||
handler(error);
|
||||
}
|
||||
};
|
||||
|
||||
if ([[FIRInstanceID instanceID] tryToLoadValidCheckinInfo]) {
|
||||
@@ -316,8 +316,6 @@ static NSUInteger FIRMessagingServerPort() {
|
||||
|
||||
self.stayConnected = tryToConnectLater;
|
||||
[self.connection signOut];
|
||||
_FIRMessagingDevAssert(self.connection.state == kFIRMessagingConnectionNotConnected,
|
||||
@"FIRMessaging connection did not disconnect");
|
||||
|
||||
// since we can disconnect while still trying to establish the connection it's required to
|
||||
// cancel all performSelectors else the object might be retained
|
||||
@@ -421,8 +419,6 @@ static NSUInteger FIRMessagingServerPort() {
|
||||
- (void)setupConnection {
|
||||
NSString *host = FIRMessagingServerHost();
|
||||
NSUInteger port = FIRMessagingServerPort();
|
||||
_FIRMessagingDevAssert([host length] > 0 && port != 0, @"Invalid port or host");
|
||||
|
||||
if (self.connection != nil) {
|
||||
// if there is an old connection, explicitly sign it off.
|
||||
[self.connection signOut];
|
||||
@@ -447,17 +443,20 @@ static NSUInteger FIRMessagingServerPort() {
|
||||
[NSObject cancelPreviousPerformRequestsWithTarget:self
|
||||
selector:@selector(tryToConnect)
|
||||
object:nil];
|
||||
|
||||
NSString *deviceAuthID = [FIRInstanceID instanceID].deviceAuthID;
|
||||
NSString *secretToken = [FIRInstanceID instanceID].secretToken;
|
||||
if (deviceAuthID.length == 0 || secretToken.length == 0 ||
|
||||
!self.connection) {
|
||||
FIRMessagingLoggerWarn(kFIRMessagingMessageCodeClientInvalidState,
|
||||
@"Invalid state to connect, deviceAuthID: %@, secretToken: %@, connection state: %ld",
|
||||
deviceAuthID, secretToken, (long)self.connection.state);
|
||||
return;
|
||||
}
|
||||
// Do not re-sign in if there is already a connection in progress.
|
||||
if (self.connection.state != kFIRMessagingConnectionNotConnected) {
|
||||
return;
|
||||
}
|
||||
|
||||
_FIRMessagingDevAssert([FIRInstanceID instanceID].deviceAuthID.length > 0 &&
|
||||
[FIRInstanceID instanceID].secretToken.length > 0 &&
|
||||
self.connection != nil,
|
||||
@"Invalid state cannot connect");
|
||||
|
||||
self.connectRetryCount = MIN(kMaxRetryExponent, self.connectRetryCount + 1);
|
||||
[self performSelector:@selector(didConnectTimeout)
|
||||
withObject:nil
|
||||
@@ -466,9 +465,9 @@ static NSUInteger FIRMessagingServerPort() {
|
||||
}
|
||||
|
||||
- (void)didConnectTimeout {
|
||||
_FIRMessagingDevAssert(self.connection.state != kFIRMessagingConnectionSignedIn,
|
||||
@"Invalid state for MCS connection");
|
||||
|
||||
if (self.connection.state == kFIRMessagingConnectionSignedIn) {
|
||||
FIRMessagingLoggerWarn(kFIRMessagingMessageCodeClientInvalidStateTimeout, @"Invalid state for connection timeout.");
|
||||
}
|
||||
if (self.stayConnected) {
|
||||
[self.connection signOut];
|
||||
[self scheduleConnectRetry];
|
||||
|
||||
@@ -14,8 +14,10 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#import "FIRMessagingCodedInputStream.h"
|
||||
#import "FIRMessagingDefines.h"
|
||||
#import "Firebase/Messaging/FIRMessagingCodedInputStream.h"
|
||||
|
||||
#import "Firebase/Messaging/FIRMMessageCode.h"
|
||||
#import "Firebase/Messaging/FIRMessagingLogger.h"
|
||||
|
||||
typedef struct {
|
||||
const void *bytes;
|
||||
@@ -32,9 +34,10 @@ static BOOL CheckSize(BufferState *state, size_t size) {
|
||||
}
|
||||
|
||||
static BOOL ReadRawByte(BufferState *state, int8_t *output) {
|
||||
_FIRMessagingDevAssert(output != NULL && state != NULL, @"Invalid parameters");
|
||||
|
||||
if (CheckSize(state, sizeof(int8_t))) {
|
||||
if (state == NULL || output == NULL) {
|
||||
FIRMessagingLoggerDebug(kFIRMessagingCodeInputStreamInvalidParameters, @"Invalid parameters.");
|
||||
}
|
||||
if (output != nil && CheckSize(state, sizeof(int8_t))) {
|
||||
*output = ((int8_t *)state->bytes)[state->bufferPos++];
|
||||
return YES;
|
||||
}
|
||||
@@ -42,8 +45,10 @@ static BOOL ReadRawByte(BufferState *state, int8_t *output) {
|
||||
}
|
||||
|
||||
static BOOL ReadRawVarInt32(BufferState *state, int32_t *output) {
|
||||
_FIRMessagingDevAssert(output != NULL && state != NULL, @"Invalid parameters");
|
||||
|
||||
if (state == NULL || output == NULL) {
|
||||
FIRMessagingLoggerDebug(kFIRMessagingCodeInputStreamInvalidParameters, @"Invalid parameters.");
|
||||
return NO;
|
||||
}
|
||||
int8_t tmp = 0;
|
||||
if (!ReadRawByte(state, &tmp)) {
|
||||
return NO;
|
||||
|
||||
+14
-23
@@ -14,20 +14,21 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#import "FIRMessagingConnection.h"
|
||||
#import "Firebase/Messaging/FIRMessagingConnection.h"
|
||||
|
||||
#import "Protos/GtalkCore.pbobjc.h"
|
||||
#import "Protos/GtalkExtensions.pbobjc.h"
|
||||
#import <FirebaseMessaging/FIRMessaging.h>
|
||||
|
||||
#import "FIRMessaging.h"
|
||||
#import "FIRMessagingDataMessageManager.h"
|
||||
#import "FIRMessagingDefines.h"
|
||||
#import "FIRMessagingLogger.h"
|
||||
#import "FIRMessagingRmqManager.h"
|
||||
#import "FIRMessagingSecureSocket.h"
|
||||
#import "FIRMessagingUtilities.h"
|
||||
#import "FIRMessagingVersionUtilities.h"
|
||||
#import "FIRMessaging_Private.h"
|
||||
#import "Firebase/Messaging/Protos/GtalkCore.pbobjc.h"
|
||||
#import "Firebase/Messaging/Protos/GtalkExtensions.pbobjc.h"
|
||||
|
||||
#import "Firebase/Messaging/FIRMessagingDataMessageManager.h"
|
||||
#import "Firebase/Messaging/FIRMessagingDefines.h"
|
||||
#import "Firebase/Messaging/FIRMessagingLogger.h"
|
||||
#import "Firebase/Messaging/FIRMessagingRmqManager.h"
|
||||
#import "Firebase/Messaging/FIRMessagingSecureSocket.h"
|
||||
#import "Firebase/Messaging/FIRMessagingUtilities.h"
|
||||
#import "Firebase/Messaging/FIRMessagingVersionUtilities.h"
|
||||
#import "Firebase/Messaging/FIRMessaging_Private.h"
|
||||
|
||||
static NSInteger const kIqSelectiveAck = 12;
|
||||
static NSInteger const kIqStreamAck = 13;
|
||||
@@ -144,7 +145,6 @@ static NSString *const kRemoteFromAddress = @"from";
|
||||
}
|
||||
|
||||
- (void)signIn {
|
||||
_FIRMessagingDevAssert(self.state == kFIRMessagingConnectionNotConnected, @"Invalid connection state.");
|
||||
if (self.state != kFIRMessagingConnectionNotConnected) {
|
||||
return;
|
||||
}
|
||||
@@ -200,11 +200,8 @@ static NSString *const kRemoteFromAddress = @"from";
|
||||
}
|
||||
|
||||
- (void)didDisconnectWithSecureSocket:(FIRMessagingSecureSocket *)socket {
|
||||
_FIRMessagingDevAssert(self.socket == socket, @"Invalid socket");
|
||||
_FIRMessagingDevAssert(self.socket.state == kFIRMessagingSecureSocketClosed, @"Socket already closed");
|
||||
|
||||
FIRMessagingLoggerDebug(kFIRMessagingMessageCodeConnection002,
|
||||
@"Secure socket disconnected from FIRMessaging service.");
|
||||
@"Secure socket disconnected from FIRMessaging service. %ld", (long)self.socket.state);
|
||||
[self disconnect];
|
||||
[self.delegate connection:self didCloseForReason:kFIRMessagingConnectionCloseReasonSocketDisconnected];
|
||||
}
|
||||
@@ -294,7 +291,6 @@ static NSString *const kRemoteFromAddress = @"from";
|
||||
return;
|
||||
}
|
||||
|
||||
_FIRMessagingDevAssert(self.socket != nil, @"Socket shouldn't be nil");
|
||||
if (self.socket == nil) {
|
||||
return;
|
||||
}
|
||||
@@ -438,10 +434,6 @@ static NSString *const kRemoteFromAddress = @"from";
|
||||
return;
|
||||
}
|
||||
FIRMessagingLoggerDebug(kFIRMessagingMessageCodeConnection012, @"Logged onto MCS service.");
|
||||
// We sent the persisted list of unack'd messages with login so we can assume they have been ack'd
|
||||
// by the server.
|
||||
_FIRMessagingDevAssert(self.unackedS2dIds.count == 0, @"No ids present");
|
||||
_FIRMessagingDevAssert(self.outStreamId == 1, @"Login should be the first stream id");
|
||||
|
||||
self.state = kFIRMessagingConnectionSignedIn;
|
||||
self.lastLoginServerTimestamp = loginResponse.serverTimestamp;
|
||||
@@ -659,7 +651,6 @@ static NSString *const kRemoteFromAddress = @"from";
|
||||
}
|
||||
|
||||
- (void)disconnect {
|
||||
_FIRMessagingDevAssert(self.state != kFIRMessagingConnectionNotConnected, @"Connection already not connected");
|
||||
// cancel pending timeout tasks.
|
||||
[self cancelConnectionTimeoutTask];
|
||||
// cancel pending heartbeat.
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#import "FIRMessagingConstants.h"
|
||||
#import "Firebase/Messaging/FIRMessagingConstants.h"
|
||||
|
||||
NSString *const kFIRMessagingRawDataKey = @"rawData";
|
||||
NSString *const kFIRMessagingCollapseKey = @"collapse_key";
|
||||
|
||||
+20
-16
@@ -14,11 +14,11 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#import "FIRMessagingContextManagerService.h"
|
||||
#import "Firebase/Messaging/FIRMessagingContextManagerService.h"
|
||||
|
||||
#import "FIRMessagingDefines.h"
|
||||
#import "FIRMessagingLogger.h"
|
||||
#import "FIRMessagingUtilities.h"
|
||||
#import "Firebase/Messaging/FIRMessagingDefines.h"
|
||||
#import "Firebase/Messaging/FIRMessagingLogger.h"
|
||||
#import "Firebase/Messaging/FIRMessagingUtilities.h"
|
||||
|
||||
#import <GoogleUtilities/GULAppDelegateSwizzler.h>
|
||||
|
||||
@@ -44,6 +44,7 @@ NSString *const kFIRMessagingContextManagerCategoryKey =
|
||||
NSString *const kFIRMessagingContextManagerSoundKey = kFIRMessagingContextManagerNotificationKeyPrefix @"sound";
|
||||
NSString *const kFIRMessagingContextManagerContentAvailableKey =
|
||||
kFIRMessagingContextManagerNotificationKeyPrefix @"content-available";
|
||||
static NSString *const kFIRMessagingAPNSPayloadKey = @"aps";
|
||||
|
||||
typedef NS_ENUM(NSUInteger, FIRMessagingContextManagerMessageType) {
|
||||
FIRMessagingContextManagerMessageTypeNone,
|
||||
@@ -77,19 +78,16 @@ typedef NS_ENUM(NSUInteger, FIRMessagingContextManagerMessageType) {
|
||||
|
||||
+ (BOOL)handleContextManagerLocalTimeMessage:(NSDictionary *)message {
|
||||
NSString *startTimeString = message[kFIRMessagingContextManagerLocalTimeStart];
|
||||
if (!startTimeString) {
|
||||
FIRMessagingLoggerError(kFIRMessagingMessageCodeContextManagerService002,
|
||||
@"Invalid local start date format %@. Message dropped",
|
||||
startTimeString);
|
||||
return NO;
|
||||
}
|
||||
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
|
||||
dateFormatter.locale = [NSLocale localeWithLocaleIdentifier:@"en_US_POSIX"];
|
||||
[dateFormatter setDateFormat:kLocalTimeFormatString];
|
||||
NSDate *startDate = [dateFormatter dateFromString:startTimeString];
|
||||
|
||||
_FIRMessagingDevAssert(startDate, @"Invalid local start date format %@", startTimeString);
|
||||
if (!startTimeString) {
|
||||
FIRMessagingLoggerError(kFIRMessagingMessageCodeContextManagerService002,
|
||||
@"Invalid local start date format %@. Message dropped",
|
||||
startTimeString);
|
||||
return NO;
|
||||
}
|
||||
|
||||
NSDate *currentDate = [NSDate date];
|
||||
|
||||
if ([currentDate compare:startDate] == NSOrderedAscending) {
|
||||
@@ -106,8 +104,6 @@ typedef NS_ENUM(NSUInteger, FIRMessagingContextManagerMessageType) {
|
||||
}
|
||||
|
||||
NSDate *endDate = [dateFormatter dateFromString:endTimeString];
|
||||
|
||||
_FIRMessagingDevAssert(endDate, @"Invalid local end date format %@", endTimeString);
|
||||
if (!endTimeString) {
|
||||
FIRMessagingLoggerError(kFIRMessagingMessageCodeContextManagerService004,
|
||||
@"Invalid local end date format %@. Message dropped", endTimeString);
|
||||
@@ -153,7 +149,7 @@ typedef NS_ENUM(NSUInteger, FIRMessagingContextManagerMessageType) {
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wunguarded-availability"
|
||||
notification.alertTitle = apsDictionary[kFIRMessagingContextManagerTitleKey];
|
||||
#pragma pop
|
||||
#pragma clang diagnostic pop
|
||||
}
|
||||
}
|
||||
|
||||
@@ -179,7 +175,10 @@ typedef NS_ENUM(NSUInteger, FIRMessagingContextManagerMessageType) {
|
||||
if (!application) {
|
||||
return;
|
||||
}
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
|
||||
[application scheduleLocalNotification:notification];
|
||||
#pragma clang diagnostic pop
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -192,6 +191,11 @@ typedef NS_ENUM(NSUInteger, FIRMessagingContextManagerMessageType) {
|
||||
continue;
|
||||
} else if ([keyString hasPrefix:kContextManagerPrefixKey]) {
|
||||
continue;
|
||||
} else if ([keyString isEqualToString:kFIRMessagingAPNSPayloadKey]) {
|
||||
// Local timezone message is scheduled with FCM payload. APNS payload with
|
||||
// content_available should be ignored and not passed to the scheduled
|
||||
// messages.
|
||||
continue;
|
||||
}
|
||||
}
|
||||
data[[key copy]] = message[key];
|
||||
|
||||
+21
-23
@@ -14,22 +14,22 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#import "FIRMessagingDataMessageManager.h"
|
||||
#import "Firebase/Messaging/FIRMessagingDataMessageManager.h"
|
||||
|
||||
#import "Protos/GtalkCore.pbobjc.h"
|
||||
#import "Firebase/Messaging/Protos/GtalkCore.pbobjc.h"
|
||||
|
||||
#import "FIRMessagingClient.h"
|
||||
#import "FIRMessagingConnection.h"
|
||||
#import "FIRMessagingConstants.h"
|
||||
#import "FIRMessagingDefines.h"
|
||||
#import "FIRMessagingDelayedMessageQueue.h"
|
||||
#import "FIRMessagingLogger.h"
|
||||
#import "FIRMessagingReceiver.h"
|
||||
#import "FIRMessagingRmqManager.h"
|
||||
#import "FIRMessaging_Private.h"
|
||||
#import "FIRMessagingSyncMessageManager.h"
|
||||
#import "FIRMessagingUtilities.h"
|
||||
#import "NSError+FIRMessaging.h"
|
||||
#import "Firebase/Messaging/FIRMessagingClient.h"
|
||||
#import "Firebase/Messaging/FIRMessagingConnection.h"
|
||||
#import "Firebase/Messaging/FIRMessagingConstants.h"
|
||||
#import "Firebase/Messaging/FIRMessagingDefines.h"
|
||||
#import "Firebase/Messaging/FIRMessagingDelayedMessageQueue.h"
|
||||
#import "Firebase/Messaging/FIRMessagingLogger.h"
|
||||
#import "Firebase/Messaging/FIRMessagingReceiver.h"
|
||||
#import "Firebase/Messaging/FIRMessagingRmqManager.h"
|
||||
#import "Firebase/Messaging/FIRMessaging_Private.h"
|
||||
#import "Firebase/Messaging/FIRMessagingSyncMessageManager.h"
|
||||
#import "Firebase/Messaging/FIRMessagingUtilities.h"
|
||||
#import "Firebase/Messaging/NSError+FIRMessaging.h"
|
||||
|
||||
static const int kMaxAppDataSizeDefault = 4 * 1024; // 4k
|
||||
static const int kMinDelaySeconds = 1; // 1 second
|
||||
@@ -96,8 +96,9 @@ typedef NS_ENUM(int8_t, UpstreamForceReconnect) {
|
||||
}
|
||||
|
||||
- (void)setDeviceAuthID:(NSString *)deviceAuthID secretToken:(NSString *)secretToken {
|
||||
_FIRMessagingDevAssert([deviceAuthID length] && [secretToken length],
|
||||
@"Invalid credentials for FIRMessaging");
|
||||
if (deviceAuthID.length == 0 || secretToken.length == 0) {
|
||||
FIRMessagingLoggerWarn(kFIRMessagingMessageCodeDataMessageManager013, @"Invalid credentials: deviceAuthID: %@, secrectToken: %@", deviceAuthID, secretToken);
|
||||
}
|
||||
self.deviceAuthID = deviceAuthID;
|
||||
self.secretToken = secretToken;
|
||||
}
|
||||
@@ -135,31 +136,29 @@ typedef NS_ENUM(int8_t, UpstreamForceReconnect) {
|
||||
- (NSDictionary *)parseDataMessage:(GtalkDataMessageStanza *)dataMessage {
|
||||
NSMutableDictionary *message = [NSMutableDictionary dictionary];
|
||||
NSString *from = [dataMessage from];
|
||||
if ([from length]) {
|
||||
if (from.length) {
|
||||
message[kFIRMessagingFromKey] = from;
|
||||
}
|
||||
|
||||
// raw data
|
||||
NSData *rawData = [dataMessage rawData];
|
||||
if ([rawData length]) {
|
||||
if (rawData.length) {
|
||||
message[kFIRMessagingRawDataKey] = rawData;
|
||||
}
|
||||
|
||||
NSString *token = [dataMessage token];
|
||||
if ([token length]) {
|
||||
if (token.length) {
|
||||
message[kFIRMessagingCollapseKey] = token;
|
||||
}
|
||||
|
||||
// Add the persistent_id. This would be removed later before sending the message to the device.
|
||||
NSString *persistentID = [dataMessage persistentId];
|
||||
_FIRMessagingDevAssert([persistentID length], @"Invalid MCS message without persistentID");
|
||||
if ([persistentID length]) {
|
||||
if (persistentID.length) {
|
||||
message[kFIRMessagingMessageIDKey] = persistentID;
|
||||
}
|
||||
|
||||
// third-party data
|
||||
for (GtalkAppData *item in dataMessage.appDataArray) {
|
||||
_FIRMessagingDevAssert(item.hasKey && item.hasValue, @"Invalid AppData");
|
||||
|
||||
// do not process the "from" key -- is not useful
|
||||
if ([kFIRMessagingFromKey isEqualToString:item.key]) {
|
||||
@@ -175,7 +174,6 @@ typedef NS_ENUM(int8_t, UpstreamForceReconnect) {
|
||||
}
|
||||
message[kDataMessageNotificationKey][key] = item.value;
|
||||
} else {
|
||||
_FIRMessagingDevAssert([key length], @"Invalid key in MCS message: %@", key);
|
||||
FIRMessagingLoggerError(kFIRMessagingMessageCodeDataMessageManager001,
|
||||
@"Invalid key in MCS message: %@", key);
|
||||
}
|
||||
|
||||
+1
-38
@@ -17,16 +17,6 @@
|
||||
#ifndef FIRMessaging_xcodeproj_FIRMessagingDefines_h
|
||||
#define FIRMessaging_xcodeproj_FIRMessagingDefines_h
|
||||
|
||||
#define _FIRMessaging_VERBOSE_LOGGING 1
|
||||
|
||||
// Verbose Logging
|
||||
#if (_FIRMessaging_VERBOSE_LOGGING)
|
||||
#define FIRMessaging_DEV_VERBOSE_LOG(...) NSLog(__VA_ARGS__)
|
||||
#else
|
||||
#define FIRMessaging_DEV_VERBOSE_LOG(...) do { } while (0)
|
||||
#endif // FIRMessaging_VERBOSE_LOGGING
|
||||
|
||||
|
||||
// WEAKIFY & STRONGIFY
|
||||
// Helper macro.
|
||||
#define _FIRMessaging_WEAKNAME(VAR) VAR ## _weak_
|
||||
@@ -40,45 +30,18 @@ __strong __typeof__(VAR) VAR = _FIRMessaging_WEAKNAME(VAR); \
|
||||
_Pragma("clang diagnostic pop")
|
||||
|
||||
|
||||
// Type Conversions (used for NSInteger etc)
|
||||
#ifndef _FIRMessaging_L
|
||||
#define _FIRMessaging_L(v) (long)(v)
|
||||
#endif
|
||||
|
||||
#ifndef _FIRMessaging_UL
|
||||
#define _FIRMessaging_UL(v) (unsigned long)(v)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
// Debug Assert
|
||||
#ifndef _FIRMessagingDevAssert
|
||||
// we directly invoke the NSAssert handler so we can pass on the varargs
|
||||
// (NSAssert doesn't have a macro we can use that takes varargs)
|
||||
#ifdef DEBUG
|
||||
#define _FIRMessagingDevAssert(condition, ...) \
|
||||
do { \
|
||||
if (!(condition)) { \
|
||||
[[NSAssertionHandler currentHandler] \
|
||||
handleFailureInFunction:(NSString *) \
|
||||
[NSString stringWithUTF8String:__PRETTY_FUNCTION__] \
|
||||
file:(NSString *)[NSString stringWithUTF8String:__FILE__] \
|
||||
lineNumber:__LINE__ \
|
||||
description:__VA_ARGS__]; \
|
||||
} \
|
||||
} while(0)
|
||||
#else // !defined(DEBUG)
|
||||
#define _FIRMessagingDevAssert(condition, ...) do { } while (0)
|
||||
#endif // !defined(DEBUG)
|
||||
|
||||
#endif // _FIRMessagingDevAssert
|
||||
|
||||
// Invalidates the initializer from which it's called.
|
||||
#ifndef FIRMessagingInvalidateInitializer
|
||||
#define FIRMessagingInvalidateInitializer() \
|
||||
do { \
|
||||
[self class]; /* Avoid warning of dead store to |self|. */ \
|
||||
_FIRMessagingDevAssert(NO, @"Invalid initializer."); \
|
||||
NSAssert(NO, @"Invalid initializer."); \
|
||||
return nil; \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
+5
-6
@@ -14,13 +14,13 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#import "FIRMessagingDelayedMessageQueue.h"
|
||||
#import "Firebase/Messaging/FIRMessagingDelayedMessageQueue.h"
|
||||
|
||||
#import "Protos/GtalkCore.pbobjc.h"
|
||||
#import "Firebase/Messaging/Protos/GtalkCore.pbobjc.h"
|
||||
|
||||
#import "FIRMessagingDefines.h"
|
||||
#import "FIRMessagingRmqManager.h"
|
||||
#import "FIRMessagingUtilities.h"
|
||||
#import "Firebase/Messaging/FIRMessagingDefines.h"
|
||||
#import "Firebase/Messaging/FIRMessagingRmqManager.h"
|
||||
#import "Firebase/Messaging/FIRMessagingUtilities.h"
|
||||
|
||||
static const int kMaxQueuedMessageCount = 10;
|
||||
|
||||
@@ -49,7 +49,6 @@ static const int kMaxQueuedMessageCount = 10;
|
||||
|
||||
- (instancetype)initWithRmqScanner:(id<FIRMessagingRmqScanner>)rmqScanner
|
||||
sendDelayedMessagesHandler:(FIRMessagingSendDelayedMessagesHandler)sendDelayedMessagesHandler {
|
||||
_FIRMessagingDevAssert(sendDelayedMessagesHandler, @"Invalid nil callback for delayed messages");
|
||||
self = [super init];
|
||||
if (self) {
|
||||
_rmqScanner = rmqScanner;
|
||||
|
||||
@@ -14,10 +14,10 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#import "FIRMessagingExtensionHelper.h"
|
||||
#import <FirebaseMessaging/FIRMessagingExtensionHelper.h>
|
||||
|
||||
#import "FIRMMessageCode.h"
|
||||
#import "FIRMessagingLogger.h"
|
||||
#import "Firebase/Messaging/FIRMMessageCode.h"
|
||||
#import "Firebase/Messaging/FIRMessagingLogger.h"
|
||||
|
||||
static NSString *const kPayloadOptionsName = @"fcm_options";
|
||||
static NSString *const kPayloadOptionsImageURLName = @"image";
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#import "FIRMessagingLogger.h"
|
||||
#import "Firebase/Messaging/FIRMessagingLogger.h"
|
||||
|
||||
#import <FirebaseCore/FIRLogger.h>
|
||||
|
||||
|
||||
@@ -14,9 +14,9 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#import "FIRMessagingPacketQueue.h"
|
||||
#import "Firebase/Messaging/FIRMessagingPacketQueue.h"
|
||||
|
||||
#import "FIRMessagingDefines.h"
|
||||
#import "Firebase/Messaging/FIRMessagingDefines.h"
|
||||
|
||||
@interface FIRMessagingPacket ()
|
||||
|
||||
|
||||
@@ -16,8 +16,9 @@
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#import "FIRMessaging.h"
|
||||
#import "FIRMessagingTopicsCommon.h"
|
||||
#import <FirebaseMessaging/FIRMessaging.h>
|
||||
|
||||
#import "Firebase/Messaging/FIRMessagingTopicsCommon.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
|
||||
@@ -14,13 +14,13 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#import "FIRMessagingPendingTopicsList.h"
|
||||
#import "Firebase/Messaging/FIRMessagingPendingTopicsList.h"
|
||||
|
||||
#import "FIRMessaging_Private.h"
|
||||
#import "FIRMessagingLogger.h"
|
||||
#import "FIRMessagingPubSub.h"
|
||||
#import "Firebase/Messaging/FIRMessaging_Private.h"
|
||||
#import "Firebase/Messaging/FIRMessagingLogger.h"
|
||||
#import "Firebase/Messaging/FIRMessagingPubSub.h"
|
||||
|
||||
#import "FIRMessagingDefines.h"
|
||||
#import "Firebase/Messaging/FIRMessagingDefines.h"
|
||||
|
||||
NSString *const kPendingTopicBatchActionKey = @"action";
|
||||
NSString *const kPendingTopicBatchTopicsKey = @"topics";
|
||||
|
||||
+2
-2
@@ -14,9 +14,9 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#import "FIRMessagingPersistentSyncMessage.h"
|
||||
#import "Firebase/Messaging/FIRMessagingPersistentSyncMessage.h"
|
||||
|
||||
#import "FIRMessagingDefines.h"
|
||||
#import "Firebase/Messaging/FIRMessagingDefines.h"
|
||||
|
||||
@interface FIRMessagingPersistentSyncMessage ()
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#import "FIRMessaging.h"
|
||||
#import <FirebaseMessaging/FIRMessaging.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
|
||||
+10
-16
@@ -14,19 +14,19 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#import "FIRMessagingPubSub.h"
|
||||
#import "Firebase/Messaging/FIRMessagingPubSub.h"
|
||||
|
||||
#import <GoogleUtilities/GULUserDefaults.h>
|
||||
#import <FirebaseMessaging/FIRMessaging.h>
|
||||
|
||||
#import "FIRMessaging.h"
|
||||
#import "FIRMessagingClient.h"
|
||||
#import "FIRMessagingDefines.h"
|
||||
#import "FIRMessagingLogger.h"
|
||||
#import "FIRMessagingPendingTopicsList.h"
|
||||
#import "FIRMessagingUtilities.h"
|
||||
#import "FIRMessaging_Private.h"
|
||||
#import "NSDictionary+FIRMessaging.h"
|
||||
#import "NSError+FIRMessaging.h"
|
||||
#import "Firebase/Messaging/FIRMessagingClient.h"
|
||||
#import "Firebase/Messaging/FIRMessagingDefines.h"
|
||||
#import "Firebase/Messaging/FIRMessagingLogger.h"
|
||||
#import "Firebase/Messaging/FIRMessagingPendingTopicsList.h"
|
||||
#import "Firebase/Messaging/FIRMessagingUtilities.h"
|
||||
#import "Firebase/Messaging/FIRMessaging_Private.h"
|
||||
#import "Firebase/Messaging/NSDictionary+FIRMessaging.h"
|
||||
#import "Firebase/Messaging/NSError+FIRMessaging.h"
|
||||
|
||||
static NSString *const kPendingSubscriptionsListKey =
|
||||
@"com.firebase.messaging.pending-subscriptions";
|
||||
@@ -59,8 +59,6 @@ static NSString *const kPendingSubscriptionsListKey =
|
||||
topic:(NSString *)topic
|
||||
options:(NSDictionary *)options
|
||||
handler:(FIRMessagingTopicOperationCompletion)handler {
|
||||
_FIRMessagingDevAssert([token length], @"FIRMessaging error no token specified");
|
||||
_FIRMessagingDevAssert([topic length], @"FIRMessaging error Invalid empty topic specified");
|
||||
if (!self.client) {
|
||||
handler([NSError errorWithFCMErrorCode:kFIRMessagingErrorCodePubSubFIRMessagingNotSetup]);
|
||||
return;
|
||||
@@ -102,14 +100,10 @@ static NSString *const kPendingSubscriptionsListKey =
|
||||
topic:(NSString *)topic
|
||||
options:(NSDictionary *)options
|
||||
handler:(FIRMessagingTopicOperationCompletion)handler {
|
||||
_FIRMessagingDevAssert([token length], @"FIRMessaging error no token specified");
|
||||
_FIRMessagingDevAssert([topic length], @"FIRMessaging error Invalid empty topic specified");
|
||||
|
||||
if (!self.client) {
|
||||
handler([NSError errorWithFCMErrorCode:kFIRMessagingErrorCodePubSubFIRMessagingNotSetup]);
|
||||
return;
|
||||
}
|
||||
|
||||
token = [token copy];
|
||||
topic = [topic copy];
|
||||
if (![options count]) {
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#import "FIRMessagingTopicOperation.h"
|
||||
#import "Firebase/Messaging/FIRMessagingTopicOperation.h"
|
||||
|
||||
@interface FIRMessagingPubSubRegistrar : NSObject
|
||||
|
||||
|
||||
@@ -14,12 +14,12 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#import "FIRMessagingPubSubRegistrar.h"
|
||||
#import "Firebase/Messaging/FIRMessagingPubSubRegistrar.h"
|
||||
|
||||
#import "FIRMessagingDefines.h"
|
||||
#import "FIRMessagingPubSubRegistrar.h"
|
||||
#import "FIRMessagingTopicsCommon.h"
|
||||
#import "NSError+FIRMessaging.h"
|
||||
#import "Firebase/Messaging/FIRMessagingDefines.h"
|
||||
#import "Firebase/Messaging/FIRMessagingPubSubRegistrar.h"
|
||||
#import "Firebase/Messaging/FIRMessagingTopicsCommon.h"
|
||||
#import "Firebase/Messaging/NSError+FIRMessaging.h"
|
||||
|
||||
@interface FIRMessagingPubSubRegistrar ()
|
||||
|
||||
|
||||
@@ -14,8 +14,8 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#import "FIRMessagingDataMessageManager.h"
|
||||
#import "FIRMessaging.h"
|
||||
#import <FirebaseMessaging/FIRMessaging.h>
|
||||
#import "Firebase/Messaging/FIRMessagingDataMessageManager.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
|
||||
@@ -14,12 +14,13 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#import "FIRMessagingReceiver.h"
|
||||
#import "Firebase/Messaging/FIRMessagingReceiver.h"
|
||||
|
||||
#import "FIRMessaging.h"
|
||||
#import "FIRMessagingLogger.h"
|
||||
#import "FIRMessagingUtilities.h"
|
||||
#import "FIRMessaging_Private.h"
|
||||
#import <FirebaseMessaging/FIRMessaging.h>
|
||||
|
||||
#import "Firebase/Messaging/FIRMessagingLogger.h"
|
||||
#import "Firebase/Messaging/FIRMessagingUtilities.h"
|
||||
#import "Firebase/Messaging/FIRMessaging_Private.h"
|
||||
|
||||
static NSString *const kUpstreamMessageIDUserInfoKey = @"messageID";
|
||||
static NSString *const kUpstreamErrorUserInfoKey = @"error";
|
||||
|
||||
+49
-49
@@ -14,14 +14,14 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#import "FIRMessagingRemoteNotificationsProxy.h"
|
||||
#import "Firebase/Messaging/FIRMessagingRemoteNotificationsProxy.h"
|
||||
|
||||
#import <objc/runtime.h>
|
||||
|
||||
#import "FIRMessagingConstants.h"
|
||||
#import "FIRMessagingLogger.h"
|
||||
#import "FIRMessagingUtilities.h"
|
||||
#import "FIRMessaging_Private.h"
|
||||
#import "Firebase/Messaging/FIRMessagingConstants.h"
|
||||
#import "Firebase/Messaging/FIRMessagingLogger.h"
|
||||
#import "Firebase/Messaging/FIRMessagingUtilities.h"
|
||||
#import "Firebase/Messaging/FIRMessaging_Private.h"
|
||||
#import <GoogleUtilities/GULAppDelegateSwizzler.h>
|
||||
|
||||
static void * UserNotificationObserverContext = &UserNotificationObserverContext;
|
||||
@@ -93,9 +93,9 @@ static NSString *kUserNotificationDidReceiveResponseSelectorString =
|
||||
Class notificationCenterClass = NSClassFromString(@"UNUserNotificationCenter");
|
||||
if (notificationCenterClass) {
|
||||
// We are linked against iOS 10 SDK or above
|
||||
id notificationCenter = getNamedPropertyFromObject(notificationCenterClass,
|
||||
@"currentNotificationCenter",
|
||||
notificationCenterClass);
|
||||
id notificationCenter = FIRMessagingPropertyNameFromObject(notificationCenterClass,
|
||||
@"currentNotificationCenter",
|
||||
notificationCenterClass);
|
||||
if (notificationCenter) {
|
||||
[self listenForDelegateChangesInUserNotificationCenter:notificationCenter];
|
||||
}
|
||||
@@ -125,7 +125,7 @@ static NSString *kUserNotificationDidReceiveResponseSelectorString =
|
||||
if (![notificationCenter isKindOfClass:notificationCenterClass]) {
|
||||
return;
|
||||
}
|
||||
id delegate = getNamedPropertyFromObject(notificationCenter, @"delegate", nil);
|
||||
id delegate = FIRMessagingPropertyNameFromObject(notificationCenter, @"delegate", nil);
|
||||
Protocol *delegateProtocol = NSProtocolFromString(@"UNUserNotificationCenterDelegate");
|
||||
if ([delegate conformsToProtocol:delegateProtocol]) {
|
||||
// Swizzle this object now, if available
|
||||
@@ -156,7 +156,7 @@ static NSString *kUserNotificationDidReceiveResponseSelectorString =
|
||||
if ([delegate respondsToSelector:willPresentNotificationSelector]) {
|
||||
[self swizzleSelector:willPresentNotificationSelector
|
||||
inClass:[delegate class]
|
||||
withImplementation:(IMP)FCM_swizzle_willPresentNotificationWithHandler
|
||||
withImplementation:(IMP)FCMSwizzleWillPresentNotificationWithHandler
|
||||
inProtocol:userNotificationCenterProtocol];
|
||||
}
|
||||
SEL didReceiveNotificationResponseSelector =
|
||||
@@ -164,7 +164,7 @@ static NSString *kUserNotificationDidReceiveResponseSelectorString =
|
||||
if ([delegate respondsToSelector:didReceiveNotificationResponseSelector]) {
|
||||
[self swizzleSelector:didReceiveNotificationResponseSelector
|
||||
inClass:[delegate class]
|
||||
withImplementation:(IMP)FCM_swizzle_didReceiveNotificationResponseWithHandler
|
||||
withImplementation:(IMP)FCMSwizzleDidReceiveNotificationResponseWithHandler
|
||||
inProtocol:userNotificationCenterProtocol];
|
||||
}
|
||||
self.currentUserNotificationCenterDelegate = delegate;
|
||||
@@ -263,13 +263,13 @@ static NSString *kUserNotificationDidReceiveResponseSelectorString =
|
||||
|
||||
- (IMP)originalImplementationForSelector:(SEL)selector {
|
||||
NSString *selectorString = NSStringFromSelector(selector);
|
||||
NSValue *implementation_value = self.originalAppDelegateImps[selectorString];
|
||||
if (!implementation_value) {
|
||||
NSValue *implementationValue = self.originalAppDelegateImps[selectorString];
|
||||
if (!implementationValue) {
|
||||
return nil;
|
||||
}
|
||||
|
||||
IMP imp;
|
||||
[implementation_value getValue:&imp];
|
||||
[implementationValue getValue:&imp];
|
||||
return imp;
|
||||
}
|
||||
|
||||
@@ -300,27 +300,27 @@ static NSString *kUserNotificationDidReceiveResponseSelectorString =
|
||||
// This class implements this method, so replace the original implementation
|
||||
// with our new implementation and save the old implementation.
|
||||
|
||||
IMP __original_method_implementation =
|
||||
IMP originalMethodImplementation =
|
||||
method_setImplementation(originalMethod, swizzledImplementation);
|
||||
|
||||
IMP __nonexistant_method_implementation = [self nonExistantMethodImplementationForClass:klass];
|
||||
IMP nonexistantMethodImplementation = [self nonExistantMethodImplementationForClass:klass];
|
||||
|
||||
if (__original_method_implementation &&
|
||||
__original_method_implementation != __nonexistant_method_implementation &&
|
||||
__original_method_implementation != swizzledImplementation) {
|
||||
[self saveOriginalImplementation:__original_method_implementation
|
||||
if (originalMethodImplementation &&
|
||||
originalMethodImplementation != nonexistantMethodImplementation &&
|
||||
originalMethodImplementation != swizzledImplementation) {
|
||||
[self saveOriginalImplementation:originalMethodImplementation
|
||||
forSelector:originalSelector];
|
||||
}
|
||||
} else {
|
||||
// The class doesn't have this method, so add our swizzled implementation as the
|
||||
// original implementation of the original method.
|
||||
struct objc_method_description method_description =
|
||||
struct objc_method_description methodDescription =
|
||||
protocol_getMethodDescription(protocol, originalSelector, NO, YES);
|
||||
|
||||
BOOL methodAdded = class_addMethod(klass,
|
||||
originalSelector,
|
||||
swizzledImplementation,
|
||||
method_description.types);
|
||||
methodDescription.types);
|
||||
if (!methodAdded) {
|
||||
FIRMessagingLoggerError(kFIRMessagingMessageCodeRemoteNotificationsProxyMethodNotAdded,
|
||||
@"Could not add method for %@ to class %@",
|
||||
@@ -339,10 +339,10 @@ static NSString *kUserNotificationDidReceiveResponseSelectorString =
|
||||
return;
|
||||
}
|
||||
|
||||
IMP original_imp = [self originalImplementationForSelector:selector];
|
||||
if (original_imp) {
|
||||
IMP originalImp = [self originalImplementationForSelector:selector];
|
||||
if (originalImp) {
|
||||
// Restore the original implementation as the current implementation
|
||||
method_setImplementation(swizzledMethod, original_imp);
|
||||
method_setImplementation(swizzledMethod, originalImp);
|
||||
[self removeImplementationForSelector:selector];
|
||||
} else {
|
||||
// This class originally did not have an implementation for this selector.
|
||||
@@ -369,7 +369,7 @@ static NSString *kUserNotificationDidReceiveResponseSelectorString =
|
||||
}
|
||||
|
||||
// A safe, non-leaky way return a property object by its name
|
||||
id getNamedPropertyFromObject(id object, NSString *propertyName, Class klass) {
|
||||
id FIRMessagingPropertyNameFromObject(id object, NSString *propertyName, Class klass) {
|
||||
SEL selector = NSSelectorFromString(propertyName);
|
||||
if (![object respondsToSelector:selector]) {
|
||||
return nil;
|
||||
@@ -433,16 +433,16 @@ didFailToRegisterForRemoteNotificationsWithError:(NSError *)error {
|
||||
* In order to make FCM SDK compile and compatible with iOS SDKs before iOS 10, hide the
|
||||
* parameter types from the swizzling implementation.
|
||||
*/
|
||||
void FCM_swizzle_willPresentNotificationWithHandler(
|
||||
id self, SEL _cmd, id center, id notification, void (^handler)(NSUInteger)) {
|
||||
static void FCMSwizzleWillPresentNotificationWithHandler(
|
||||
id self, SEL cmd, id center, id notification, void (^handler)(NSUInteger)) {
|
||||
|
||||
FIRMessagingRemoteNotificationsProxy *proxy = [FIRMessagingRemoteNotificationsProxy sharedProxy];
|
||||
IMP original_imp = [proxy originalImplementationForSelector:_cmd];
|
||||
IMP originalImp = [proxy originalImplementationForSelector:cmd];
|
||||
|
||||
void (^callOriginalMethodIfAvailable)(void) = ^{
|
||||
if (original_imp) {
|
||||
((void (*)(id, SEL, id, id, void (^)(NSUInteger)))original_imp)(
|
||||
self, _cmd, center, notification, handler);
|
||||
if (originalImp) {
|
||||
((void (*)(id, SEL, id, id, void (^)(NSUInteger)))originalImp)(
|
||||
self, cmd, center, notification, handler);
|
||||
}
|
||||
return;
|
||||
};
|
||||
@@ -476,7 +476,7 @@ void FCM_swizzle_willPresentNotificationWithHandler(
|
||||
}
|
||||
|
||||
// Attempt to access the user info
|
||||
id notificationUserInfo = userInfoFromNotification(notification);
|
||||
id notificationUserInfo = FIRMessagingUserInfoFromNotification(notification);
|
||||
|
||||
if (!notificationUserInfo) {
|
||||
// Could not access notification.request.content.userInfo.
|
||||
@@ -498,16 +498,16 @@ void FCM_swizzle_willPresentNotificationWithHandler(
|
||||
* In order to make FCM SDK compile and compatible with iOS SDKs before iOS 10, hide the
|
||||
* parameter types from the swizzling implementation.
|
||||
*/
|
||||
void FCM_swizzle_didReceiveNotificationResponseWithHandler(
|
||||
id self, SEL _cmd, id center, id response, void (^handler)(void)) {
|
||||
static void FCMSwizzleDidReceiveNotificationResponseWithHandler(
|
||||
id self, SEL cmd, id center, id response, void (^handler)(void)) {
|
||||
|
||||
FIRMessagingRemoteNotificationsProxy *proxy = [FIRMessagingRemoteNotificationsProxy sharedProxy];
|
||||
IMP original_imp = [proxy originalImplementationForSelector:_cmd];
|
||||
IMP originalImp = [proxy originalImplementationForSelector:cmd];
|
||||
|
||||
void (^callOriginalMethodIfAvailable)(void) = ^{
|
||||
if (original_imp) {
|
||||
((void (*)(id, SEL, id, id, void (^)(void)))original_imp)(
|
||||
self, _cmd, center, response, handler);
|
||||
if (originalImp) {
|
||||
((void (*)(id, SEL, id, id, void (^)(void)))originalImp)(
|
||||
self, cmd, center, response, handler);
|
||||
}
|
||||
return;
|
||||
};
|
||||
@@ -543,11 +543,11 @@ void FCM_swizzle_didReceiveNotificationResponseWithHandler(
|
||||
return;
|
||||
}
|
||||
id notificationClass = NSClassFromString(@"UNNotification");
|
||||
id notification = getNamedPropertyFromObject(response, @"notification", notificationClass);
|
||||
id notification = FIRMessagingPropertyNameFromObject(response, @"notification", notificationClass);
|
||||
|
||||
// With a notification object, use the common code to reach deep into notification
|
||||
// (notification.request.content.userInfo)
|
||||
id notificationUserInfo = userInfoFromNotification(notification);
|
||||
id notificationUserInfo = FIRMessagingUserInfoFromNotification(notification);
|
||||
if (!notificationUserInfo) {
|
||||
// Could not access notification.request.content.userInfo.
|
||||
callOriginalMethodIfAvailable();
|
||||
@@ -559,7 +559,7 @@ void FCM_swizzle_didReceiveNotificationResponseWithHandler(
|
||||
callOriginalMethodIfAvailable();
|
||||
}
|
||||
|
||||
id userInfoFromNotification(id notification) {
|
||||
static id FIRMessagingUserInfoFromNotification(id notification) {
|
||||
|
||||
// Select the userInfo field from UNNotification.request.content.userInfo.
|
||||
SEL requestSelector = NSSelectorFromString(@"request");
|
||||
@@ -568,7 +568,7 @@ id userInfoFromNotification(id notification) {
|
||||
return nil;
|
||||
}
|
||||
Class requestClass = NSClassFromString(@"UNNotificationRequest");
|
||||
id notificationRequest = getNamedPropertyFromObject(notification, @"request", requestClass);
|
||||
id notificationRequest = FIRMessagingPropertyNameFromObject(notification, @"request", requestClass);
|
||||
|
||||
SEL notificationContentSelector = NSSelectorFromString(@"content");
|
||||
if (!notificationRequest
|
||||
@@ -577,9 +577,9 @@ id userInfoFromNotification(id notification) {
|
||||
return nil;
|
||||
}
|
||||
Class contentClass = NSClassFromString(@"UNNotificationContent");
|
||||
id notificationContent = getNamedPropertyFromObject(notificationRequest,
|
||||
@"content",
|
||||
contentClass);
|
||||
id notificationContent = FIRMessagingPropertyNameFromObject(notificationRequest,
|
||||
@"content",
|
||||
contentClass);
|
||||
|
||||
SEL notificationUserInfoSelector = NSSelectorFromString(@"userInfo");
|
||||
if (!notificationContent
|
||||
@@ -587,9 +587,9 @@ id userInfoFromNotification(id notification) {
|
||||
// Cannot access the userInfo property.
|
||||
return nil;
|
||||
}
|
||||
id notificationUserInfo = getNamedPropertyFromObject(notificationContent,
|
||||
@"userInfo",
|
||||
[NSDictionary class]);
|
||||
id notificationUserInfo = FIRMessagingPropertyNameFromObject(notificationContent,
|
||||
@"userInfo",
|
||||
[NSDictionary class]);
|
||||
|
||||
if (!notificationUserInfo) {
|
||||
// This is not the expected notification handler.
|
||||
|
||||
+10
-27
@@ -14,17 +14,17 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#import "FIRMessagingRmq2PersistentStore.h"
|
||||
#import "Firebase/Messaging/FIRMessagingRmq2PersistentStore.h"
|
||||
|
||||
#import <sqlite3.h>
|
||||
|
||||
#import "FIRMessagingConstants.h"
|
||||
#import "FIRMessagingDefines.h"
|
||||
#import "FIRMessagingLogger.h"
|
||||
#import "FIRMessagingPersistentSyncMessage.h"
|
||||
#import "FIRMessagingUtilities.h"
|
||||
#import "NSError+FIRMessaging.h"
|
||||
#import "Protos/GtalkCore.pbobjc.h"
|
||||
#import "Firebase/Messaging/FIRMessagingConstants.h"
|
||||
#import "Firebase/Messaging/FIRMessagingDefines.h"
|
||||
#import "Firebase/Messaging/FIRMessagingLogger.h"
|
||||
#import "Firebase/Messaging/FIRMessagingPersistentSyncMessage.h"
|
||||
#import "Firebase/Messaging/FIRMessagingUtilities.h"
|
||||
#import "Firebase/Messaging/NSError+FIRMessaging.h"
|
||||
#import "Firebase/Messaging/Protos/GtalkCore.pbobjc.h"
|
||||
|
||||
#ifndef _FIRMessagingRmqLogAndExit
|
||||
#define _FIRMessagingRmqLogAndExit(stmt, return_value) \
|
||||
@@ -106,7 +106,7 @@ NSString * _Nonnull FIRMessagingStringFromSQLiteResult(int result) {
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wunguarded-availability"
|
||||
const char *errorStr = sqlite3_errstr(result);
|
||||
#pragma pop
|
||||
#pragma clang diagnostic pop
|
||||
NSString *errorString = [NSString stringWithFormat:@"%d - %s", result, errorStr];
|
||||
return errorString;
|
||||
}
|
||||
@@ -395,12 +395,6 @@ NSString * _Nonnull FIRMessagingStringFromSQLiteResult(int result) {
|
||||
|
||||
- (int)deleteMessagesFromTable:(NSString *)tableName
|
||||
withRmqIds:(NSArray *)rmqIds {
|
||||
_FIRMessagingDevAssert([tableName isEqualToString:kTableOutgoingRmqMessages] ||
|
||||
[tableName isEqualToString:kTableLastRmqId] ||
|
||||
[tableName isEqualToString:kTableS2DRmqIds] ||
|
||||
[tableName isEqualToString:kTableSyncMessages],
|
||||
@"%@: Invalid Table Name %@", kFCMRmqStoreTag, tableName);
|
||||
|
||||
BOOL isRmqIDString = NO;
|
||||
// RmqID is a string only for outgoing messages
|
||||
if ([tableName isEqualToString:kTableS2DRmqIds] ||
|
||||
@@ -592,9 +586,7 @@ NSString * _Nonnull FIRMessagingStringFromSQLiteResult(int result) {
|
||||
int8_t type = sqlite3_column_int(statement, typeColumnNumber);
|
||||
const void *bytes = sqlite3_column_blob(statement, dataColumnNumber);
|
||||
int length = sqlite3_column_bytes(statement, dataColumnNumber);
|
||||
_FIRMessagingDevAssert(bytes != NULL,
|
||||
@"%@ Message with no data being stored in Rmq",
|
||||
kFCMRmqStoreTag);
|
||||
|
||||
NSData *data = [NSData dataWithBytes:bytes length:length];
|
||||
handler(rmqId, type, data);
|
||||
}
|
||||
@@ -604,8 +596,6 @@ NSString * _Nonnull FIRMessagingStringFromSQLiteResult(int result) {
|
||||
#pragma mark - Sync Messages
|
||||
|
||||
- (FIRMessagingPersistentSyncMessage *)querySyncMessageWithRmqID:(NSString *)rmqID {
|
||||
_FIRMessagingDevAssert([rmqID length], @"Invalid rmqID key %@ to search in SYNC_RMQ", rmqID);
|
||||
|
||||
NSString *queryFormat = @"SELECT %@ FROM %@ WHERE %@ = '%@'";
|
||||
NSString *query = [NSString stringWithFormat:queryFormat,
|
||||
kSyncMessagesColumns, // SELECT (rmq_id, expiration_ts, apns_recv, mcs_recv)
|
||||
@@ -645,12 +635,10 @@ NSString * _Nonnull FIRMessagingStringFromSQLiteResult(int result) {
|
||||
}
|
||||
sqlite3_finalize(stmt);
|
||||
|
||||
_FIRMessagingDevAssert(count <= 1, @"Found multiple messages in %@ with same RMQ ID", kTableSyncMessages);
|
||||
return persistentMessage;
|
||||
}
|
||||
|
||||
- (BOOL)deleteSyncMessageWithRmqID:(NSString *)rmqID {
|
||||
_FIRMessagingDevAssert([rmqID length], @"Invalid rmqID key %@ to delete in SYNC_RMQ", rmqID);
|
||||
return [self deleteMessagesFromTable:kTableSyncMessages withRmqIds:@[rmqID]] > 0;
|
||||
}
|
||||
|
||||
@@ -695,8 +683,6 @@ NSString * _Nonnull FIRMessagingStringFromSQLiteResult(int result) {
|
||||
apnsReceived:(BOOL)apnsReceived
|
||||
mcsReceived:(BOOL)mcsReceived
|
||||
error:(NSError **)error {
|
||||
_FIRMessagingDevAssert([rmqID length], @"Invalid nil message to persist to SYNC_RMQ");
|
||||
|
||||
NSString *insertFormat = @"INSERT INTO %@ (%@, %@, %@, %@) VALUES (?, ?, ?, ?)";
|
||||
NSString *insertSQL = [NSString stringWithFormat:insertFormat,
|
||||
kTableSyncMessages, // Table name
|
||||
@@ -759,9 +745,6 @@ NSString * _Nonnull FIRMessagingStringFromSQLiteResult(int result) {
|
||||
column:(NSString *)column
|
||||
value:(BOOL)value
|
||||
error:(NSError **)error {
|
||||
_FIRMessagingDevAssert([column isEqualToString:kSyncMessageAPNSReceivedColumn] ||
|
||||
[column isEqualToString:kSyncMessageMCSReceivedColumn],
|
||||
@"Invalid column name %@ for SYNC_RMQ", column);
|
||||
NSString *queryFormat = @"UPDATE %@ " // Table name
|
||||
@"SET %@ = %d " // column=value
|
||||
@"WHERE %@ = ?"; // condition
|
||||
|
||||
@@ -14,15 +14,15 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#import "FIRMessagingRmqManager.h"
|
||||
#import "Firebase/Messaging/FIRMessagingRmqManager.h"
|
||||
|
||||
#import <sqlite3.h>
|
||||
|
||||
#import "FIRMessagingDefines.h"
|
||||
#import "FIRMessagingLogger.h"
|
||||
#import "FIRMessagingRmq2PersistentStore.h"
|
||||
#import "FIRMessagingUtilities.h"
|
||||
#import "Protos/GtalkCore.pbobjc.h"
|
||||
#import "Firebase/Messaging/FIRMessagingDefines.h"
|
||||
#import "Firebase/Messaging/FIRMessagingLogger.h"
|
||||
#import "Firebase/Messaging/FIRMessagingRmq2PersistentStore.h"
|
||||
#import "Firebase/Messaging/FIRMessagingUtilities.h"
|
||||
#import "Firebase/Messaging/Protos/GtalkCore.pbobjc.h"
|
||||
|
||||
#ifndef _FIRMessagingRmqLogAndExit
|
||||
#define _FIRMessagingRmqLogAndExit(stmt, return_value) \
|
||||
@@ -51,7 +51,6 @@ static NSString *const kFCMRmqTag = @"FIRMessagingRmq:";
|
||||
- (instancetype)initWithDatabaseName:(NSString *)databaseName {
|
||||
self = [super init];
|
||||
if (self) {
|
||||
_FIRMessagingDevAssert([databaseName length] > 0, @"RMQ: Invalid rmq db name");
|
||||
_rmq2Store = [[FIRMessagingRmq2PersistentStore alloc] initWithDatabaseName:databaseName];
|
||||
_outstandingMessages = [NSMutableDictionary dictionaryWithCapacity:2];
|
||||
_rmqId = -1;
|
||||
|
||||
@@ -14,16 +14,16 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#import "FIRMessagingSecureSocket.h"
|
||||
#import "Firebase/Messaging/FIRMessagingSecureSocket.h"
|
||||
|
||||
#import <Protobuf/GPBMessage.h>
|
||||
#import <Protobuf/GPBCodedOutputStream.h>
|
||||
#import <Protobuf/GPBUtilities.h>
|
||||
|
||||
#import "FIRMessagingCodedInputStream.h"
|
||||
#import "FIRMessagingDefines.h"
|
||||
#import "FIRMessagingLogger.h"
|
||||
#import "FIRMessagingPacketQueue.h"
|
||||
#import "Firebase/Messaging/FIRMessagingCodedInputStream.h"
|
||||
#import "Firebase/Messaging/FIRMessagingDefines.h"
|
||||
#import "Firebase/Messaging/FIRMessagingLogger.h"
|
||||
#import "Firebase/Messaging/FIRMessagingPacketQueue.h"
|
||||
|
||||
static const NSUInteger kMaxBufferLength = 1024 * 1024; // 1M
|
||||
static const NSUInteger kBufferLengthIncrement = 16 * 1024; // 16k
|
||||
@@ -97,10 +97,6 @@ static NSUInteger SerializedSize(int32_t value) {
|
||||
- (void)connectToHost:(NSString *)host
|
||||
port:(NSUInteger)port
|
||||
onRunLoop:(NSRunLoop *)runLoop {
|
||||
_FIRMessagingDevAssert(host != nil, @"Invalid host");
|
||||
_FIRMessagingDevAssert(runLoop != nil, @"Invalid runloop");
|
||||
_FIRMessagingDevAssert(self.state == kFIRMessagingSecureSocketNotOpen, @"Socket is already connected");
|
||||
|
||||
if (!host || self.state != kFIRMessagingSecureSocketNotOpen) {
|
||||
return;
|
||||
}
|
||||
@@ -140,8 +136,6 @@ static NSUInteger SerializedSize(int32_t value) {
|
||||
if (!self.inStream && !self.outStream) {
|
||||
FIRMessagingLoggerDebug(kFIRMessagingMessageCodeSecureSocket002,
|
||||
@"The socket is not open or already closed.");
|
||||
_FIRMessagingDevAssert(self.state == kFIRMessagingSecureSocketClosed || self.state == kFIRMessagingSecureSocketNotOpen,
|
||||
@"Socket is already disconnected.");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -175,7 +169,6 @@ static NSUInteger SerializedSize(int32_t value) {
|
||||
@"Try to read from socket that is not opened");
|
||||
return;
|
||||
}
|
||||
_FIRMessagingDevAssert(stream == self.inStream, @"Incorrect stream");
|
||||
if (![self performRead]) {
|
||||
FIRMessagingLoggerDebug(kFIRMessagingMessageCodeSecureSocket004,
|
||||
@"Error occurred when reading incoming stream");
|
||||
@@ -218,7 +211,6 @@ static NSUInteger SerializedSize(int32_t value) {
|
||||
@"Try to write to socket that is not opened");
|
||||
return;
|
||||
}
|
||||
_FIRMessagingDevAssert(stream == self.outStream, @"Incorrect stream");
|
||||
[self performWrite];
|
||||
break;
|
||||
default:
|
||||
@@ -229,11 +221,7 @@ static NSUInteger SerializedSize(int32_t value) {
|
||||
#pragma mark - Private
|
||||
|
||||
- (void)openStream:(NSStream *)stream isVOIPStream:(BOOL)isVOIPStream {
|
||||
_FIRMessagingDevAssert(stream != nil, @"Invalid stream");
|
||||
_FIRMessagingDevAssert(self.runLoop != nil, @"Invalid runloop");
|
||||
|
||||
if (stream) {
|
||||
_FIRMessagingDevAssert([stream streamStatus] == NSStreamStatusNotOpen, @"Stream already open");
|
||||
if ([stream streamStatus] != NSStreamStatusNotOpen) {
|
||||
FIRMessagingLoggerDebug(kFIRMessagingMessageCodeSecureSocket009,
|
||||
@"stream should not be open.");
|
||||
@@ -252,9 +240,6 @@ static NSUInteger SerializedSize(int32_t value) {
|
||||
}
|
||||
|
||||
- (void)closeStream:(NSStream *)stream {
|
||||
_FIRMessagingDevAssert(stream != nil, @"Invalid stream");
|
||||
_FIRMessagingDevAssert(self.runLoop != nil, @"Invalid runloop");
|
||||
|
||||
if (stream) {
|
||||
[stream close];
|
||||
[stream removeFromRunLoop:self.runLoop forMode:NSDefaultRunLoopMode];
|
||||
@@ -263,8 +248,6 @@ static NSUInteger SerializedSize(int32_t value) {
|
||||
}
|
||||
|
||||
- (BOOL)performRead {
|
||||
_FIRMessagingDevAssert(self.state == kFIRMessagingSecureSocketOpen, @"Socket should be open");
|
||||
|
||||
if (!self.isVersionReceived) {
|
||||
self.isVersionReceived = YES;
|
||||
uint8_t versionByte = 0;
|
||||
@@ -279,11 +262,6 @@ static NSUInteger SerializedSize(int32_t value) {
|
||||
|
||||
while (YES) {
|
||||
BOOL isInputBufferValid = [self.inputBuffer length] > 0;
|
||||
_FIRMessagingDevAssert(isInputBufferValid,
|
||||
@"Invalid input buffer size %lu. Used bytes length %lu, buffer content: %@",
|
||||
_FIRMessaging_UL([self.inputBuffer length]),
|
||||
_FIRMessaging_UL(self.inputBufferLength),
|
||||
self.inputBuffer);
|
||||
if (!isInputBufferValid) {
|
||||
FIRMessagingLoggerDebug(kFIRMessagingMessageCodeSecureSocket011,
|
||||
@"Input buffer is not valid.");
|
||||
@@ -323,12 +301,9 @@ static NSUInteger SerializedSize(int32_t value) {
|
||||
_FIRMessaging_UL(self.inputBufferLength),
|
||||
_FIRMessaging_UL([self.inputBuffer length]));
|
||||
[self.inputBuffer increaseLengthBy:kBufferLengthIncrement];
|
||||
_FIRMessagingDevAssert([self.inputBuffer length] > self.inputBufferLength, @"Invalid buffer size");
|
||||
}
|
||||
|
||||
while (self.inputBufferLength > 0 && [self.inputBuffer length] > 0) {
|
||||
_FIRMessagingDevAssert([self.inputBuffer length] >= self.inputBufferLength,
|
||||
@"Buffer longer than length");
|
||||
NSRange inputRange = NSMakeRange(0, self.inputBufferLength);
|
||||
size_t protoBytes = 0;
|
||||
// read the actual proto data coming in
|
||||
@@ -342,7 +317,6 @@ static NSUInteger SerializedSize(int32_t value) {
|
||||
} else if (readResult == kFIRMessagingSecureSocketReadResultIncomplete) {
|
||||
break;
|
||||
}
|
||||
_FIRMessagingDevAssert(self.inputBufferLength >= protoBytes, @"More bytes than buffer can handle");
|
||||
// we have read (0, protoBytes) of data in the inputBuffer
|
||||
if (protoBytes == self.inputBufferLength) {
|
||||
// did completely read the buffer data can be reset for further processing
|
||||
@@ -354,12 +328,6 @@ static NSUInteger SerializedSize(int32_t value) {
|
||||
[self.inputBuffer replaceBytesInRange:NSMakeRange(0, protoBytes) withBytes:NULL length:0];
|
||||
// reallocate more data
|
||||
[self.inputBuffer increaseLengthBy:protoBytes];
|
||||
_FIRMessagingDevAssert([self.inputBuffer length] == prevLength,
|
||||
@"Invalid input buffer size %lu. Used bytes length %lu, "
|
||||
@"buffer content: %@",
|
||||
_FIRMessaging_UL([self.inputBuffer length]),
|
||||
_FIRMessaging_UL(self.inputBufferLength),
|
||||
self.inputBuffer);
|
||||
self.inputBufferLength -= protoBytes;
|
||||
}
|
||||
}
|
||||
@@ -381,7 +349,6 @@ static NSUInteger SerializedSize(int32_t value) {
|
||||
return kFIRMessagingSecureSocketReadResultIncomplete;
|
||||
}
|
||||
// NOTE tag can be zero for |HeartbeatPing|, and length can be zero for |Close| proto
|
||||
_FIRMessagingDevAssert(rawTag >= 0 && length >= 0, @"Invalid tag or length");
|
||||
if (rawTag < 0 || length < 0) {
|
||||
FIRMessagingLoggerDebug(kFIRMessagingMessageCodeSecureSocket015, @"Buffer data corrupted.");
|
||||
return kFIRMessagingSecureSocketReadResultCorrupt;
|
||||
@@ -399,8 +366,6 @@ static NSUInteger SerializedSize(int32_t value) {
|
||||
}
|
||||
|
||||
- (void)performWrite {
|
||||
_FIRMessagingDevAssert(self.state == kFIRMessagingSecureSocketOpen, @"Invalid socket state");
|
||||
|
||||
if (!self.isVersionSent) {
|
||||
self.isVersionSent = YES;
|
||||
uint8_t versionByte = kVersion;
|
||||
|
||||
+7
-9
@@ -14,14 +14,14 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#import "FIRMessagingSyncMessageManager.h"
|
||||
#import "Firebase/Messaging/FIRMessagingSyncMessageManager.h"
|
||||
|
||||
#import "FIRMessagingConstants.h"
|
||||
#import "FIRMessagingDefines.h"
|
||||
#import "FIRMessagingLogger.h"
|
||||
#import "FIRMessagingPersistentSyncMessage.h"
|
||||
#import "FIRMessagingRmqManager.h"
|
||||
#import "FIRMessagingUtilities.h"
|
||||
#import "Firebase/Messaging/FIRMessagingConstants.h"
|
||||
#import "Firebase/Messaging/FIRMessagingDefines.h"
|
||||
#import "Firebase/Messaging/FIRMessagingLogger.h"
|
||||
#import "Firebase/Messaging/FIRMessagingPersistentSyncMessage.h"
|
||||
#import "Firebase/Messaging/FIRMessagingRmqManager.h"
|
||||
#import "Firebase/Messaging/FIRMessagingUtilities.h"
|
||||
|
||||
static const int64_t kDefaultSyncMessageTTL = 4 * 7 * 24 * 60 * 60; // 4 weeks
|
||||
// 4 MB of free space is required to persist Sync messages
|
||||
@@ -40,7 +40,6 @@ static const uint64_t kMinFreeDiskSpaceInMB = 1;
|
||||
}
|
||||
|
||||
- (instancetype)initWithRmqManager:(FIRMessagingRmqManager *)rmqManager {
|
||||
_FIRMessagingDevAssert(rmqManager, @"Invalid nil rmq manager while initalizing sync message manager");
|
||||
self = [super init];
|
||||
if (self) {
|
||||
_rmqManager = rmqManager;
|
||||
@@ -72,7 +71,6 @@ static const uint64_t kMinFreeDiskSpaceInMB = 1;
|
||||
viaAPNS:(BOOL)viaAPNS
|
||||
viaMCS:(BOOL)viaMCS {
|
||||
NSString *rmqID = message[kFIRMessagingMessageIDKey];
|
||||
_FIRMessagingDevAssert([rmqID length], @"Invalid nil rmqID for message");
|
||||
if (![rmqID length]) {
|
||||
FIRMessagingLoggerError(kFIRMessagingMessageCodeSyncMessageManager002,
|
||||
@"Invalid nil rmqID for sync message.");
|
||||
|
||||
@@ -16,8 +16,9 @@
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#import "FIRMessaging.h"
|
||||
#import "FIRMessagingTopicsCommon.h"
|
||||
#import <FirebaseMessaging/FIRMessaging.h>
|
||||
|
||||
#import "Firebase/Messaging/FIRMessagingTopicsCommon.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
|
||||
@@ -14,14 +14,14 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#import "FIRMessagingTopicOperation.h"
|
||||
#import "Firebase/Messaging/FIRMessagingTopicOperation.h"
|
||||
|
||||
#import <FirebaseInstanceID/FIRInstanceID_Private.h>
|
||||
|
||||
#import "FIRMessagingDefines.h"
|
||||
#import "FIRMessagingLogger.h"
|
||||
#import "FIRMessagingUtilities.h"
|
||||
#import "NSError+FIRMessaging.h"
|
||||
#import "Firebase/Messaging/FIRMessagingDefines.h"
|
||||
#import "Firebase/Messaging/FIRMessagingLogger.h"
|
||||
#import "Firebase/Messaging/FIRMessagingUtilities.h"
|
||||
#import "Firebase/Messaging/NSError+FIRMessaging.h"
|
||||
|
||||
#define DEBUG_LOG_SUBSCRIPTION_OPERATION_DURATIONS 0
|
||||
|
||||
@@ -217,7 +217,7 @@ NSString *FIRMessagingSubscriptionsServer() {
|
||||
}
|
||||
FIRMessagingLoggerDebug(kFIRMessagingMessageCodeTopicOption001,
|
||||
@"Device registration HTTP fetch error. Error Code: %ld",
|
||||
_FIRMessaging_L(error.code));
|
||||
(long)error.code);
|
||||
[self finishWithError:error];
|
||||
return;
|
||||
}
|
||||
@@ -229,7 +229,6 @@ NSString *FIRMessagingSubscriptionsServer() {
|
||||
return;
|
||||
}
|
||||
NSArray *parts = [response componentsSeparatedByString:@"="];
|
||||
_FIRMessagingDevAssert(parts.count, @"Invalid registration response");
|
||||
if (![parts[0] isEqualToString:@"token"] || parts.count <= 1) {
|
||||
FIRMessagingLoggerDebug(kFIRMessagingMessageCodeTopicOption002,
|
||||
@"Invalid registration response %@", response);
|
||||
|
||||
@@ -14,11 +14,11 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#import "FIRMessagingUtilities.h"
|
||||
#import "Firebase/Messaging/FIRMessagingUtilities.h"
|
||||
|
||||
#import "Protos/GtalkCore.pbobjc.h"
|
||||
#import "Firebase/Messaging/Protos/GtalkCore.pbobjc.h"
|
||||
|
||||
#import "FIRMessagingLogger.h"
|
||||
#import "Firebase/Messaging/FIRMessagingLogger.h"
|
||||
|
||||
#import <GoogleUtilities/GULAppEnvironmentUtil.h>
|
||||
|
||||
|
||||
@@ -14,9 +14,9 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#import "FIRMessagingVersionUtilities.h"
|
||||
#import "Firebase/Messaging/FIRMessagingVersionUtilities.h"
|
||||
|
||||
#import "FIRMessagingDefines.h"
|
||||
#import "Firebase/Messaging/FIRMessagingDefines.h"
|
||||
|
||||
// Convert the macro to a string
|
||||
#define STR_EXPAND(x) #x
|
||||
@@ -39,7 +39,6 @@ void FIRMessagingParseCurrentLibraryVersion(void) {
|
||||
// Parse versions
|
||||
// major, minor, patch[-beta#]
|
||||
allVersions = [daylightVersion componentsSeparatedByString:kSemanticVersioningSeparator];
|
||||
_FIRMessagingDevAssert(allVersions.count == 3, @"Invalid versioning of FIRMessaging library");
|
||||
if (allVersions.count == 3) {
|
||||
majorVersion = [allVersions[0] intValue];
|
||||
minorVersion = [allVersions[1] intValue];
|
||||
@@ -47,7 +46,6 @@ void FIRMessagingParseCurrentLibraryVersion(void) {
|
||||
// Parse patch and beta versions
|
||||
NSArray *patchAndBetaVersion =
|
||||
[allVersions[2] componentsSeparatedByString:kBetaVersionPrefix];
|
||||
_FIRMessagingDevAssert(patchAndBetaVersion.count <= 2, @"Invalid versioning of FIRMessaging library");
|
||||
if (patchAndBetaVersion.count == 2) {
|
||||
patchVersion = [patchAndBetaVersion[0] intValue];
|
||||
betaVersion = [patchAndBetaVersion[1] intValue];
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#import "FIRMessaging.h"
|
||||
#import <FirebaseMessaging/FIRMessaging.h>
|
||||
|
||||
@class FIRMessagingClient;
|
||||
@class FIRMessagingPubSub;
|
||||
|
||||
@@ -14,4 +14,4 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#import "FIRMessaging.h"
|
||||
#import <FirebaseMessaging/FIRMessaging.h>
|
||||
|
||||
-30
@@ -1,30 +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.
|
||||
*/
|
||||
|
||||
/// @file FIRMessagingInternalUtilities.h
|
||||
///
|
||||
/// Internal Class Names and Methods that other libs can query at runtime.
|
||||
|
||||
/// FIRMessaging Class that responds to the FIRMessaging SDK version selector.
|
||||
/// Verify at runtime if the class exists and implements the
|
||||
/// required method.
|
||||
static NSString *const kFIRMessagingSDKClassString = @"FIRMessaging";
|
||||
|
||||
/// FIRMessaging selector that returns the current FIRMessaging library version.
|
||||
static NSString *const kFIRMessagingSDKVersionSelectorString = @"FIRMessagingSDKVersion";
|
||||
|
||||
/// FIRMessaging selector that returns the current device locale.
|
||||
static NSString *const kFIRMessagingSDKLocaleSelectorString = @"FIRMessagingSDKCurrentLocale";
|
||||
+4
@@ -21,6 +21,10 @@
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
/// This class is used to automatically populate a notification with an image if it is
|
||||
/// specified in the notification body via the `image` parameter. Images and other
|
||||
/// rich content can be populated manually without the use of this class. See the
|
||||
/// `UNNotificationServiceExtension` type for more details.
|
||||
__IOS_AVAILABLE(10.0) __OSX_AVAILABLE(10.14)
|
||||
@interface FIRMessagingExtensionHelper : NSObject
|
||||
|
||||
|
||||
@@ -14,5 +14,5 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#import "FIRMessaging.h"
|
||||
#import "FIRMessagingExtensionHelper.h"
|
||||
#import <FirebaseMessaging/FIRMessaging.h>
|
||||
#import <FirebaseMessaging/FIRMessagingExtensionHelper.h>
|
||||
|
||||
Generated
+17
-10
@@ -1,9 +1,10 @@
|
||||
# Firebase iOS Open Source Development [](https://travis-ci.org/firebase/firebase-ios-sdk)
|
||||
|
||||
This repository contains a subset of the Firebase iOS SDK source. It currently
|
||||
includes FirebaseCore, FirebaseAuth, FirebaseDatabase, FirebaseFirestore,
|
||||
FirebaseFunctions, FirebaseInstanceID, FirebaseInAppMessaging,
|
||||
FirebaseInAppMessagingDisplay, FirebaseMessaging and FirebaseStorage.
|
||||
includes FirebaseCore, FirebaseABTesting, FirebaseAuth, FirebaseDatabase,
|
||||
FirebaseFirestore, FirebaseFunctions, FirebaseInstanceID, FirebaseInAppMessaging,
|
||||
FirebaseInAppMessagingDisplay, FirebaseMessaging, FirebaseRemoteConfig, and
|
||||
FirebaseStorage.
|
||||
|
||||
The repository also includes GoogleUtilities source. The
|
||||
[GoogleUtilities](GoogleUtilities/README.md) pod is
|
||||
@@ -80,9 +81,8 @@ For the pod that you want to develop:
|
||||
|
||||
`pod gen Firebase{name here}.podspec --local-sources=./ --auto-open`
|
||||
|
||||
Firestore and Functions have self contained Xcode projects. See
|
||||
[Firestore/README.md](Firestore/README.md) and
|
||||
[Functions/README.md](Functions/README.md).
|
||||
Firestore has a self contained Xcode project. See
|
||||
[Firestore/README.md](Firestore/README.md).
|
||||
|
||||
### Adding a New Firebase Pod
|
||||
|
||||
@@ -99,13 +99,17 @@ Travis will verify that any code changes are done in a style compliant way. Inst
|
||||
These commands will get the right versions:
|
||||
|
||||
```
|
||||
brew install https://raw.githubusercontent.com/Homebrew/homebrew-core/773cb75d360b58f32048f5964038d09825a507c8/Formula/clang-format.rb
|
||||
brew install https://raw.githubusercontent.com/Homebrew/homebrew-core/3dfea1004e0736754bbf49673cca8aaed8a94089/Formula/swiftformat.rb
|
||||
brew upgrade https://raw.githubusercontent.com/Homebrew/homebrew-core/e3496d9/Formula/clang-format.rb
|
||||
brew upgrade https://raw.githubusercontent.com/Homebrew/homebrew-core/7963c3d/Formula/swiftformat.rb
|
||||
```
|
||||
|
||||
Note: if you already have a newer version of these installed you may need to
|
||||
`brew switch` to this version.
|
||||
|
||||
To update this section, find the versions of clang-format and swiftformat.rb to
|
||||
match the versions in the CI failure logs
|
||||
[here](https://github.com/Homebrew/homebrew-core/tree/master/Formula).
|
||||
|
||||
### Running Unit Tests
|
||||
|
||||
Select a scheme and press Command-u to build a component and run its unit tests.
|
||||
@@ -179,8 +183,9 @@ very grateful! We'd like to empower as many developers as we can to be able to
|
||||
participate in the Firebase community.
|
||||
|
||||
### macOS and tvOS
|
||||
Thanks to contributions from the community, FirebaseAuth, FirebaseCore, FirebaseDatabase, FirebaseMessaging,
|
||||
FirebaseFirestore, FirebaseFunctions and FirebaseStorage now compile, run unit tests, and work on
|
||||
Thanks to contributions from the community, FirebaseABTesting, FirebaseAuth, FirebaseCore,
|
||||
FirebaseDatabase, FirebaseMessaging, FirebaseFirestore,
|
||||
FirebaseFunctions, FirebaseRemoteConfig, and FirebaseStorage now compile, run unit tests, and work on
|
||||
macOS and tvOS.
|
||||
|
||||
For tvOS, checkout the [Sample](Example/tvOSSample).
|
||||
@@ -195,12 +200,14 @@ Note that the Firebase pod is not available for macOS and tvOS.
|
||||
To install, add a subset of the following to the Podfile:
|
||||
|
||||
```
|
||||
pod 'FirebaseABTesting'
|
||||
pod 'FirebaseAuth'
|
||||
pod 'FirebaseCore'
|
||||
pod 'FirebaseDatabase'
|
||||
pod 'FirebaseFirestore'
|
||||
pod 'FirebaseFunctions'
|
||||
pod 'FirebaseMessaging'
|
||||
pod 'FirebaseRemoteConfig'
|
||||
pod 'FirebaseStorage'
|
||||
```
|
||||
|
||||
|
||||
BIN
Binary file not shown.
+7
-7
@@ -14,18 +14,18 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#import "GDTLibrary/Private/GDTAssert.h"
|
||||
#import "GDTCORLibrary/Public/GDTCORAssert.h"
|
||||
|
||||
GDTAssertionBlock GDTAssertionBlockToRunInsteadOfNSAssert(void) {
|
||||
GDTCORAssertionBlock GDTCORAssertionBlockToRunInstead(void) {
|
||||
// This class is only compiled in by unit tests, and this should fail quickly in optimized builds.
|
||||
Class GDTAssertClass = NSClassFromString(@"GDTAssertHelper");
|
||||
if (__builtin_expect(!!GDTAssertClass, 0)) {
|
||||
Class GDTCORAssertClass = NSClassFromString(@"GDTCORAssertHelper");
|
||||
if (__builtin_expect(!!GDTCORAssertClass, 0)) {
|
||||
SEL assertionBlockSEL = NSSelectorFromString(@"assertionBlock");
|
||||
if (assertionBlockSEL) {
|
||||
IMP assertionBlockIMP = [GDTAssertClass methodForSelector:assertionBlockSEL];
|
||||
IMP assertionBlockIMP = [GDTCORAssertClass methodForSelector:assertionBlockSEL];
|
||||
if (assertionBlockIMP) {
|
||||
GDTAssertionBlock assertionBlock =
|
||||
((GDTAssertionBlock(*)(id, SEL))assertionBlockIMP)(GDTAssertClass, assertionBlockSEL);
|
||||
GDTCORAssertionBlock assertionBlock = ((GDTCORAssertionBlock(*)(id, SEL))assertionBlockIMP)(
|
||||
GDTCORAssertClass, assertionBlockSEL);
|
||||
if (assertionBlock) {
|
||||
return assertionBlock;
|
||||
}
|
||||
+18
-18
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#import "GDTLibrary/Public/GDTClock.h"
|
||||
#import "GDTCORLibrary/Public/GDTCORClock.h"
|
||||
|
||||
#import <sys/sysctl.h>
|
||||
|
||||
@@ -74,7 +74,7 @@ static int64_t UptimeInNanoseconds() {
|
||||
}
|
||||
|
||||
// TODO: Consider adding a 'trustedTime' property that can be populated by the response from a BE.
|
||||
@implementation GDTClock
|
||||
@implementation GDTCORClock
|
||||
|
||||
- (instancetype)init {
|
||||
self = [super init];
|
||||
@@ -90,17 +90,17 @@ static int64_t UptimeInNanoseconds() {
|
||||
return self;
|
||||
}
|
||||
|
||||
+ (GDTClock *)snapshot {
|
||||
return [[GDTClock alloc] init];
|
||||
+ (GDTCORClock *)snapshot {
|
||||
return [[GDTCORClock alloc] init];
|
||||
}
|
||||
|
||||
+ (instancetype)clockSnapshotInTheFuture:(uint64_t)millisInTheFuture {
|
||||
GDTClock *snapshot = [self snapshot];
|
||||
GDTCORClock *snapshot = [self snapshot];
|
||||
snapshot->_timeMillis += millisInTheFuture;
|
||||
return snapshot;
|
||||
}
|
||||
|
||||
- (BOOL)isAfter:(GDTClock *)otherClock {
|
||||
- (BOOL)isAfter:(GDTCORClock *)otherClock {
|
||||
// These clocks are trivially comparable when they share a kernel boot time.
|
||||
if (_kernelBootTime == otherClock->_kernelBootTime) {
|
||||
int64_t timeDiff = (_timeMillis + _timezoneOffsetSeconds) -
|
||||
@@ -126,16 +126,16 @@ static int64_t UptimeInNanoseconds() {
|
||||
#pragma mark - NSSecureCoding
|
||||
|
||||
/** NSKeyedCoder key for timeMillis property. */
|
||||
static NSString *const kGDTClockTimeMillisKey = @"GDTClockTimeMillis";
|
||||
static NSString *const kGDTCORClockTimeMillisKey = @"GDTCORClockTimeMillis";
|
||||
|
||||
/** NSKeyedCoder key for timezoneOffsetMillis property. */
|
||||
static NSString *const kGDTClockTimezoneOffsetSeconds = @"GDTClockTimezoneOffsetSeconds";
|
||||
static NSString *const kGDTCORClockTimezoneOffsetSeconds = @"GDTCORClockTimezoneOffsetSeconds";
|
||||
|
||||
/** NSKeyedCoder key for _kernelBootTime ivar. */
|
||||
static NSString *const kGDTClockKernelBootTime = @"GDTClockKernelBootTime";
|
||||
static NSString *const kGDTCORClockKernelBootTime = @"GDTCORClockKernelBootTime";
|
||||
|
||||
/** NSKeyedCoder key for _uptime ivar. */
|
||||
static NSString *const kGDTClockUptime = @"GDTClockUptime";
|
||||
static NSString *const kGDTCORClockUptime = @"GDTCORClockUptime";
|
||||
|
||||
+ (BOOL)supportsSecureCoding {
|
||||
return YES;
|
||||
@@ -146,19 +146,19 @@ static NSString *const kGDTClockUptime = @"GDTClockUptime";
|
||||
if (self) {
|
||||
// TODO: If the kernelBootTime is more recent, we need to change the kernel boot time and
|
||||
// uptimeMillis ivars
|
||||
_timeMillis = [aDecoder decodeInt64ForKey:kGDTClockTimeMillisKey];
|
||||
_timezoneOffsetSeconds = [aDecoder decodeInt64ForKey:kGDTClockTimezoneOffsetSeconds];
|
||||
_kernelBootTime = [aDecoder decodeInt64ForKey:kGDTClockKernelBootTime];
|
||||
_uptime = [aDecoder decodeInt64ForKey:kGDTClockUptime];
|
||||
_timeMillis = [aDecoder decodeInt64ForKey:kGDTCORClockTimeMillisKey];
|
||||
_timezoneOffsetSeconds = [aDecoder decodeInt64ForKey:kGDTCORClockTimezoneOffsetSeconds];
|
||||
_kernelBootTime = [aDecoder decodeInt64ForKey:kGDTCORClockKernelBootTime];
|
||||
_uptime = [aDecoder decodeInt64ForKey:kGDTCORClockUptime];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)encodeWithCoder:(NSCoder *)aCoder {
|
||||
[aCoder encodeInt64:_timeMillis forKey:kGDTClockTimeMillisKey];
|
||||
[aCoder encodeInt64:_timezoneOffsetSeconds forKey:kGDTClockTimezoneOffsetSeconds];
|
||||
[aCoder encodeInt64:_kernelBootTime forKey:kGDTClockKernelBootTime];
|
||||
[aCoder encodeInt64:_uptime forKey:kGDTClockUptime];
|
||||
[aCoder encodeInt64:_timeMillis forKey:kGDTCORClockTimeMillisKey];
|
||||
[aCoder encodeInt64:_timezoneOffsetSeconds forKey:kGDTCORClockTimezoneOffsetSeconds];
|
||||
[aCoder encodeInt64:_kernelBootTime forKey:kGDTCORClockKernelBootTime];
|
||||
[aCoder encodeInt64:_uptime forKey:kGDTCORClockUptime];
|
||||
}
|
||||
|
||||
@end
|
||||
+7
-7
@@ -14,20 +14,20 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#import "GDTLibrary/Public/GDTConsoleLogger.h"
|
||||
#import "GDTCORLibrary/Public/GDTCORConsoleLogger.h"
|
||||
|
||||
/** The console logger prefix. */
|
||||
static NSString *kGDTConsoleLogger = @"[GoogleDataTransport]";
|
||||
static NSString *kGDTCORConsoleLogger = @"[GoogleDataTransport]";
|
||||
|
||||
NSString *GDTMessageCodeEnumToString(GDTMessageCode code) {
|
||||
return [[NSString alloc] initWithFormat:@"I-GDT%06ld", (long)code];
|
||||
NSString *GDTCORMessageCodeEnumToString(GDTCORMessageCode code) {
|
||||
return [[NSString alloc] initWithFormat:@"I-GDTCOR%06ld", (long)code];
|
||||
}
|
||||
|
||||
void GDTLog(GDTMessageCode code, NSString *format, ...) {
|
||||
void GDTCORLog(GDTCORMessageCode code, NSString *format, ...) {
|
||||
// Don't log anything in not debug builds.
|
||||
#ifndef NDEBUG
|
||||
NSString *logFormat = [NSString
|
||||
stringWithFormat:@"%@[%@] %@", kGDTConsoleLogger, GDTMessageCodeEnumToString(code), format];
|
||||
NSString *logFormat = [NSString stringWithFormat:@"%@[%@] %@", kGDTCORConsoleLogger,
|
||||
GDTCORMessageCodeEnumToString(code), format];
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
NSLogv(logFormat, args);
|
||||
+8
-8
@@ -14,9 +14,9 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#import <GoogleDataTransport/GDTDataFuture.h>
|
||||
#import <GoogleDataTransport/GDTCORDataFuture.h>
|
||||
|
||||
@implementation GDTDataFuture
|
||||
@implementation GDTCORDataFuture
|
||||
|
||||
- (instancetype)initWithFileURL:(NSURL *)fileURL {
|
||||
self = [super init];
|
||||
@@ -38,25 +38,25 @@
|
||||
#pragma mark - NSSecureCoding
|
||||
|
||||
/** Coding key for _fileURL ivar. */
|
||||
static NSString *kGDTDataFutureFileURLKey = @"GDTDataFutureFileURLKey";
|
||||
static NSString *kGDTCORDataFutureFileURLKey = @"GDTCORDataFutureFileURLKey";
|
||||
|
||||
/** Coding key for _data ivar. */
|
||||
static NSString *kGDTDataFutureDataKey = @"GDTDataFutureDataKey";
|
||||
static NSString *kGDTCORDataFutureDataKey = @"GDTCORDataFutureDataKey";
|
||||
|
||||
+ (BOOL)supportsSecureCoding {
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (void)encodeWithCoder:(nonnull NSCoder *)aCoder {
|
||||
[aCoder encodeObject:_fileURL forKey:kGDTDataFutureFileURLKey];
|
||||
[aCoder encodeObject:_originalData forKey:kGDTDataFutureDataKey];
|
||||
[aCoder encodeObject:_fileURL forKey:kGDTCORDataFutureFileURLKey];
|
||||
[aCoder encodeObject:_originalData forKey:kGDTCORDataFutureDataKey];
|
||||
}
|
||||
|
||||
- (nullable instancetype)initWithCoder:(nonnull NSCoder *)aDecoder {
|
||||
self = [self init];
|
||||
if (self) {
|
||||
_fileURL = [aDecoder decodeObjectOfClass:[NSURL class] forKey:kGDTDataFutureFileURLKey];
|
||||
_originalData = [aDecoder decodeObjectOfClass:[NSData class] forKey:kGDTDataFutureDataKey];
|
||||
_fileURL = [aDecoder decodeObjectOfClass:[NSURL class] forKey:kGDTCORDataFutureFileURLKey];
|
||||
_originalData = [aDecoder decodeObjectOfClass:[NSData class] forKey:kGDTCORDataFutureDataKey];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
+16
-13
@@ -14,29 +14,32 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#import <GoogleDataTransport/GDTEvent.h>
|
||||
#import <GoogleDataTransport/GDTCOREvent.h>
|
||||
|
||||
#import <GoogleDataTransport/GDTStoredEvent.h>
|
||||
#import <GoogleDataTransport/GDTCORAssert.h>
|
||||
#import <GoogleDataTransport/GDTCORStoredEvent.h>
|
||||
|
||||
#import "GDTLibrary/Private/GDTAssert.h"
|
||||
#import "GDTLibrary/Private/GDTEvent_Private.h"
|
||||
#import "GDTCORLibrary/Private/GDTCOREvent_Private.h"
|
||||
|
||||
@implementation GDTEvent
|
||||
@implementation GDTCOREvent
|
||||
|
||||
- (instancetype)initWithMappingID:(NSString *)mappingID target:(NSInteger)target {
|
||||
GDTAssert(mappingID.length > 0, @"Please give a valid mapping ID");
|
||||
GDTAssert(target > 0, @"A target cannot be negative or 0");
|
||||
GDTCORAssert(mappingID.length > 0, @"Please give a valid mapping ID");
|
||||
GDTCORAssert(target > 0, @"A target cannot be negative or 0");
|
||||
if (mappingID == nil || mappingID.length == 0 || target <= 0) {
|
||||
return nil;
|
||||
}
|
||||
self = [super init];
|
||||
if (self) {
|
||||
_mappingID = mappingID;
|
||||
_target = target;
|
||||
_qosTier = GDTEventQosDefault;
|
||||
_qosTier = GDTCOREventQosDefault;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (instancetype)copy {
|
||||
GDTEvent *copy = [[GDTEvent alloc] initWithMappingID:_mappingID target:_target];
|
||||
GDTCOREvent *copy = [[GDTCOREvent alloc] initWithMappingID:_mappingID target:_target];
|
||||
copy.dataObject = _dataObject;
|
||||
copy.dataObjectTransportBytes = _dataObjectTransportBytes;
|
||||
copy.qosTier = _qosTier;
|
||||
@@ -57,7 +60,7 @@
|
||||
return [self hash] == [object hash];
|
||||
}
|
||||
|
||||
- (void)setDataObject:(id<GDTEventDataObject>)dataObject {
|
||||
- (void)setDataObject:(id<GDTCOREventDataObject>)dataObject {
|
||||
// If you're looking here because of a performance issue in -transportBytes slowing the assignment
|
||||
// of -dataObject, one way to address this is to add a queue to this class,
|
||||
// dispatch_(barrier_ if concurrent)async here, and implement the getter with a dispatch_sync.
|
||||
@@ -67,8 +70,8 @@
|
||||
}
|
||||
}
|
||||
|
||||
- (GDTStoredEvent *)storedEventWithDataFuture:(GDTDataFuture *)dataFuture {
|
||||
return [[GDTStoredEvent alloc] initWithEvent:self dataFuture:dataFuture];
|
||||
- (GDTCORStoredEvent *)storedEventWithDataFuture:(GDTCORDataFuture *)dataFuture {
|
||||
return [[GDTCORStoredEvent alloc] initWithEvent:self dataFuture:dataFuture];
|
||||
}
|
||||
|
||||
#pragma mark - NSSecureCoding and NSCoding Protocols
|
||||
@@ -100,7 +103,7 @@ static NSString *clockSnapshotKey = @"_clockSnapshot";
|
||||
_dataObjectTransportBytes = [aDecoder decodeObjectOfClass:[NSData class]
|
||||
forKey:dataObjectTransportBytesKey];
|
||||
_qosTier = [aDecoder decodeIntegerForKey:qosTierKey];
|
||||
_clockSnapshot = [aDecoder decodeObjectOfClass:[GDTClock class] forKey:clockSnapshotKey];
|
||||
_clockSnapshot = [aDecoder decodeObjectOfClass:[GDTCORClock class] forKey:clockSnapshotKey];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
+119
@@ -0,0 +1,119 @@
|
||||
/*
|
||||
* Copyright 2019 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 "GDTCORLibrary/Public/GDTCORLifecycle.h"
|
||||
|
||||
#import <GoogleDataTransport/GDTCOREvent.h>
|
||||
|
||||
#import "GDTCORLibrary/Private/GDTCORRegistrar_Private.h"
|
||||
#import "GDTCORLibrary/Private/GDTCORStorage_Private.h"
|
||||
#import "GDTCORLibrary/Private/GDTCORTransformer_Private.h"
|
||||
#import "GDTCORLibrary/Private/GDTCORUploadCoordinator.h"
|
||||
|
||||
@implementation GDTCORLifecycle
|
||||
|
||||
+ (void)load {
|
||||
[self sharedInstance];
|
||||
}
|
||||
|
||||
/** Creates/returns the singleton instance of this class.
|
||||
*
|
||||
* @return The singleton instance of this class.
|
||||
*/
|
||||
+ (instancetype)sharedInstance {
|
||||
static GDTCORLifecycle *sharedInstance;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
sharedInstance = [[GDTCORLifecycle alloc] init];
|
||||
});
|
||||
return sharedInstance;
|
||||
}
|
||||
|
||||
- (instancetype)init {
|
||||
self = [super init];
|
||||
if (self) {
|
||||
NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
|
||||
[notificationCenter addObserver:self
|
||||
selector:@selector(applicationDidEnterBackground:)
|
||||
name:kGDTCORApplicationDidEnterBackgroundNotification
|
||||
object:nil];
|
||||
[notificationCenter addObserver:self
|
||||
selector:@selector(applicationWillEnterForeground:)
|
||||
name:kGDTCORApplicationWillEnterForegroundNotification
|
||||
object:nil];
|
||||
|
||||
NSString *name = kGDTCORApplicationWillTerminateNotification;
|
||||
[notificationCenter addObserver:self
|
||||
selector:@selector(applicationWillTerminate:)
|
||||
name:name
|
||||
object:nil];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)dealloc {
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
||||
}
|
||||
|
||||
- (void)applicationDidEnterBackground:(NSNotification *)notification {
|
||||
GDTCORApplication *application = [GDTCORApplication sharedApplication];
|
||||
if ([[GDTCORTransformer sharedInstance] respondsToSelector:@selector(appWillBackground:)]) {
|
||||
[[GDTCORTransformer sharedInstance] appWillBackground:application];
|
||||
}
|
||||
if ([[GDTCORStorage sharedInstance] respondsToSelector:@selector(appWillBackground:)]) {
|
||||
[[GDTCORStorage sharedInstance] appWillBackground:application];
|
||||
}
|
||||
if ([[GDTCORUploadCoordinator sharedInstance] respondsToSelector:@selector(appWillBackground:)]) {
|
||||
[[GDTCORUploadCoordinator sharedInstance] appWillBackground:application];
|
||||
}
|
||||
if ([[GDTCORRegistrar sharedInstance] respondsToSelector:@selector(appWillBackground:)]) {
|
||||
[[GDTCORRegistrar sharedInstance] appWillBackground:application];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)applicationWillEnterForeground:(NSNotification *)notification {
|
||||
GDTCORApplication *application = [GDTCORApplication sharedApplication];
|
||||
if ([[GDTCORTransformer sharedInstance] respondsToSelector:@selector(appWillForeground:)]) {
|
||||
[[GDTCORTransformer sharedInstance] appWillForeground:application];
|
||||
}
|
||||
if ([[GDTCORStorage sharedInstance] respondsToSelector:@selector(appWillForeground:)]) {
|
||||
[[GDTCORStorage sharedInstance] appWillForeground:application];
|
||||
}
|
||||
if ([[GDTCORUploadCoordinator sharedInstance] respondsToSelector:@selector(appWillForeground:)]) {
|
||||
[[GDTCORUploadCoordinator sharedInstance] appWillForeground:application];
|
||||
}
|
||||
if ([[GDTCORRegistrar sharedInstance] respondsToSelector:@selector(appWillForeground:)]) {
|
||||
[[GDTCORRegistrar sharedInstance] appWillForeground:application];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)applicationWillTerminate:(NSNotification *)notification {
|
||||
GDTCORApplication *application = [GDTCORApplication sharedApplication];
|
||||
if ([[GDTCORTransformer sharedInstance] respondsToSelector:@selector(appWillTerminate:)]) {
|
||||
[[GDTCORTransformer sharedInstance] appWillTerminate:application];
|
||||
}
|
||||
if ([[GDTCORStorage sharedInstance] respondsToSelector:@selector(appWillTerminate:)]) {
|
||||
[[GDTCORStorage sharedInstance] appWillTerminate:application];
|
||||
}
|
||||
if ([[GDTCORUploadCoordinator sharedInstance] respondsToSelector:@selector(appWillTerminate:)]) {
|
||||
[[GDTCORUploadCoordinator sharedInstance] appWillTerminate:application];
|
||||
}
|
||||
if ([[GDTCORRegistrar sharedInstance] respondsToSelector:@selector(appWillTerminate:)]) {
|
||||
[[GDTCORRegistrar sharedInstance] appWillTerminate:application];
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
+41
-22
@@ -14,20 +14,22 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#import <GoogleDataTransport/GDTPlatform.h>
|
||||
#import <GoogleDataTransport/GDTCORPlatform.h>
|
||||
|
||||
const GDTBackgroundIdentifier GDTBackgroundIdentifierInvalid = 0;
|
||||
#import <GoogleDataTransport/GDTCORAssert.h>
|
||||
|
||||
NSString *const kGDTApplicationDidEnterBackgroundNotification =
|
||||
@"GDTApplicationDidEnterBackgroundNotification";
|
||||
const GDTCORBackgroundIdentifier GDTCORBackgroundIdentifierInvalid = 0;
|
||||
|
||||
NSString *const kGDTApplicationWillEnterForegroundNotification =
|
||||
@"GDTApplicationWillEnterForegroundNotification";
|
||||
NSString *const kGDTCORApplicationDidEnterBackgroundNotification =
|
||||
@"GDTCORApplicationDidEnterBackgroundNotification";
|
||||
|
||||
NSString *const kGDTApplicationWillTerminateNotification =
|
||||
@"GDTApplicationWillTerminateNotification";
|
||||
NSString *const kGDTCORApplicationWillEnterForegroundNotification =
|
||||
@"GDTCORApplicationWillEnterForegroundNotification";
|
||||
|
||||
BOOL GDTReachabilityFlagsContainWWAN(SCNetworkReachabilityFlags flags) {
|
||||
NSString *const kGDTCORApplicationWillTerminateNotification =
|
||||
@"GDTCORApplicationWillTerminateNotification";
|
||||
|
||||
BOOL GDTCORReachabilityFlagsContainWWAN(SCNetworkReachabilityFlags flags) {
|
||||
#if TARGET_OS_IOS
|
||||
return (flags & kSCNetworkReachabilityFlagsIsWWAN) == kSCNetworkReachabilityFlagsIsWWAN;
|
||||
#else
|
||||
@@ -35,22 +37,23 @@ BOOL GDTReachabilityFlagsContainWWAN(SCNetworkReachabilityFlags flags) {
|
||||
#endif // TARGET_OS_IOS
|
||||
}
|
||||
|
||||
@implementation GDTApplication
|
||||
@implementation GDTCORApplication
|
||||
|
||||
+ (void)load {
|
||||
#if TARGET_OS_IOS || TARGET_OS_TV
|
||||
// If this asserts, please file a bug at https://github.com/firebase/firebase-ios-sdk/issues.
|
||||
NSAssert(GDTBackgroundIdentifierInvalid == UIBackgroundTaskInvalid,
|
||||
@"GDTBackgroundIdentifierInvalid and UIBackgroundTaskInvalid should be the same.");
|
||||
GDTCORFatalAssert(
|
||||
GDTCORBackgroundIdentifierInvalid == UIBackgroundTaskInvalid,
|
||||
@"GDTCORBackgroundIdentifierInvalid and UIBackgroundTaskInvalid should be the same.");
|
||||
#endif
|
||||
[self sharedApplication];
|
||||
}
|
||||
|
||||
+ (nullable GDTApplication *)sharedApplication {
|
||||
static GDTApplication *application;
|
||||
+ (nullable GDTCORApplication *)sharedApplication {
|
||||
static GDTCORApplication *application;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
application = [[GDTApplication alloc] init];
|
||||
application = [[GDTCORApplication alloc] init];
|
||||
});
|
||||
return application;
|
||||
}
|
||||
@@ -74,6 +77,20 @@ BOOL GDTReachabilityFlagsContainWWAN(SCNetworkReachabilityFlags flags) {
|
||||
selector:@selector(iOSApplicationWillTerminate:)
|
||||
name:name
|
||||
object:nil];
|
||||
|
||||
#if defined(__IPHONE_13_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 130000
|
||||
if (@available(iOS 13, tvOS 13.0, *)) {
|
||||
[notificationCenter addObserver:self
|
||||
selector:@selector(iOSApplicationWillEnterForeground:)
|
||||
name:UISceneWillEnterForegroundNotification
|
||||
object:nil];
|
||||
[notificationCenter addObserver:self
|
||||
selector:@selector(iOSApplicationDidEnterBackground:)
|
||||
name:UISceneWillDeactivateNotification
|
||||
object:nil];
|
||||
}
|
||||
#endif // defined(__IPHONE_13_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 130000
|
||||
|
||||
#elif TARGET_OS_OSX
|
||||
NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
|
||||
[notificationCenter addObserver:self
|
||||
@@ -85,13 +102,15 @@ BOOL GDTReachabilityFlagsContainWWAN(SCNetworkReachabilityFlags flags) {
|
||||
return self;
|
||||
}
|
||||
|
||||
- (GDTBackgroundIdentifier)beginBackgroundTaskWithExpirationHandler:(void (^)(void))handler {
|
||||
- (GDTCORBackgroundIdentifier)beginBackgroundTaskWithExpirationHandler:(void (^)(void))handler {
|
||||
return
|
||||
[[self sharedApplicationForBackgroundTask] beginBackgroundTaskWithExpirationHandler:handler];
|
||||
}
|
||||
|
||||
- (void)endBackgroundTask:(GDTBackgroundIdentifier)bgID {
|
||||
[[self sharedApplicationForBackgroundTask] endBackgroundTask:bgID];
|
||||
- (void)endBackgroundTask:(GDTCORBackgroundIdentifier)bgID {
|
||||
if (bgID != GDTCORBackgroundIdentifierInvalid) {
|
||||
[[self sharedApplicationForBackgroundTask] endBackgroundTask:bgID];
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - App environment helpers
|
||||
@@ -131,17 +150,17 @@ BOOL GDTReachabilityFlagsContainWWAN(SCNetworkReachabilityFlags flags) {
|
||||
#if TARGET_OS_IOS || TARGET_OS_TV
|
||||
- (void)iOSApplicationDidEnterBackground:(NSNotification *)notif {
|
||||
NSNotificationCenter *notifCenter = [NSNotificationCenter defaultCenter];
|
||||
[notifCenter postNotificationName:kGDTApplicationDidEnterBackgroundNotification object:nil];
|
||||
[notifCenter postNotificationName:kGDTCORApplicationDidEnterBackgroundNotification object:nil];
|
||||
}
|
||||
|
||||
- (void)iOSApplicationWillEnterForeground:(NSNotification *)notif {
|
||||
NSNotificationCenter *notifCenter = [NSNotificationCenter defaultCenter];
|
||||
[notifCenter postNotificationName:kGDTApplicationWillEnterForegroundNotification object:nil];
|
||||
[notifCenter postNotificationName:kGDTCORApplicationWillEnterForegroundNotification object:nil];
|
||||
}
|
||||
|
||||
- (void)iOSApplicationWillTerminate:(NSNotification *)notif {
|
||||
NSNotificationCenter *notifCenter = [NSNotificationCenter defaultCenter];
|
||||
[notifCenter postNotificationName:kGDTApplicationWillTerminateNotification object:nil];
|
||||
[notifCenter postNotificationName:kGDTCORApplicationWillTerminateNotification object:nil];
|
||||
}
|
||||
#endif // TARGET_OS_IOS || TARGET_OS_TV
|
||||
|
||||
@@ -150,7 +169,7 @@ BOOL GDTReachabilityFlagsContainWWAN(SCNetworkReachabilityFlags flags) {
|
||||
#if TARGET_OS_OSX
|
||||
- (void)macOSApplicationWillTerminate:(NSNotification *)notif {
|
||||
NSNotificationCenter *notifCenter = [NSNotificationCenter defaultCenter];
|
||||
[notifCenter postNotificationName:kGDTApplicationWillTerminateNotification object:nil];
|
||||
[notifCenter postNotificationName:kGDTCORApplicationWillTerminateNotification object:nil];
|
||||
}
|
||||
#endif // TARGET_OS_OSX
|
||||
|
||||
+21
-19
@@ -14,10 +14,10 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#import "GDTLibrary/Private/GDTReachability.h"
|
||||
#import "GDTLibrary/Private/GDTReachability_Private.h"
|
||||
#import "GDTCORLibrary/Private/GDTCORReachability.h"
|
||||
#import "GDTCORLibrary/Private/GDTCORReachability_Private.h"
|
||||
|
||||
#import <GoogleDataTransport/GDTConsoleLogger.h>
|
||||
#import <GoogleDataTransport/GDTCORConsoleLogger.h>
|
||||
|
||||
#import <netinet/in.h>
|
||||
|
||||
@@ -27,11 +27,11 @@
|
||||
* @param flags The new flag values.
|
||||
* @param info Any data that might be passed in by the callback.
|
||||
*/
|
||||
static void GDTReachabilityCallback(SCNetworkReachabilityRef reachability,
|
||||
SCNetworkReachabilityFlags flags,
|
||||
void *info);
|
||||
static void GDTCORReachabilityCallback(SCNetworkReachabilityRef reachability,
|
||||
SCNetworkReachabilityFlags flags,
|
||||
void *info);
|
||||
|
||||
@implementation GDTReachability {
|
||||
@implementation GDTCORReachability {
|
||||
/** The reachability object. */
|
||||
SCNetworkReachabilityRef _reachabilityRef;
|
||||
|
||||
@@ -47,18 +47,18 @@ static void GDTReachabilityCallback(SCNetworkReachabilityRef reachability,
|
||||
}
|
||||
|
||||
+ (instancetype)sharedInstance {
|
||||
static GDTReachability *sharedInstance;
|
||||
static GDTCORReachability *sharedInstance;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
sharedInstance = [[GDTReachability alloc] init];
|
||||
sharedInstance = [[GDTCORReachability alloc] init];
|
||||
});
|
||||
return sharedInstance;
|
||||
}
|
||||
|
||||
+ (SCNetworkReachabilityFlags)currentFlags {
|
||||
__block SCNetworkReachabilityFlags currentFlags;
|
||||
dispatch_sync([GDTReachability sharedInstance] -> _reachabilityQueue, ^{
|
||||
GDTReachability *reachability = [GDTReachability sharedInstance];
|
||||
dispatch_sync([GDTCORReachability sharedInstance] -> _reachabilityQueue, ^{
|
||||
GDTCORReachability *reachability = [GDTCORReachability sharedInstance];
|
||||
currentFlags = reachability->_flags ? reachability->_flags : reachability->_callbackFlags;
|
||||
});
|
||||
return currentFlags;
|
||||
@@ -72,16 +72,18 @@ static void GDTReachabilityCallback(SCNetworkReachabilityRef reachability,
|
||||
zeroAddress.sin_len = sizeof(zeroAddress);
|
||||
zeroAddress.sin_family = AF_INET;
|
||||
|
||||
_reachabilityQueue = dispatch_queue_create("com.google.GDTReachability", DISPATCH_QUEUE_SERIAL);
|
||||
_reachabilityQueue =
|
||||
dispatch_queue_create("com.google.GDTCORReachability", DISPATCH_QUEUE_SERIAL);
|
||||
_reachabilityRef = SCNetworkReachabilityCreateWithAddress(
|
||||
kCFAllocatorDefault, (const struct sockaddr *)&zeroAddress);
|
||||
Boolean success = SCNetworkReachabilitySetDispatchQueue(_reachabilityRef, _reachabilityQueue);
|
||||
if (!success) {
|
||||
GDTLogWarning(GDTMCWReachabilityFailed, @"%@", @"The reachability queue wasn't set.");
|
||||
GDTCORLogWarning(GDTCORMCWReachabilityFailed, @"%@", @"The reachability queue wasn't set.");
|
||||
}
|
||||
success = SCNetworkReachabilitySetCallback(_reachabilityRef, GDTReachabilityCallback, NULL);
|
||||
success = SCNetworkReachabilitySetCallback(_reachabilityRef, GDTCORReachabilityCallback, NULL);
|
||||
if (!success) {
|
||||
GDTLogWarning(GDTMCWReachabilityFailed, @"%@", @"The reachability callback wasn't set.");
|
||||
GDTCORLogWarning(GDTCORMCWReachabilityFailed, @"%@",
|
||||
@"The reachability callback wasn't set.");
|
||||
}
|
||||
|
||||
// Get the initial set of flags.
|
||||
@@ -103,8 +105,8 @@ static void GDTReachabilityCallback(SCNetworkReachabilityRef reachability,
|
||||
|
||||
@end
|
||||
|
||||
static void GDTReachabilityCallback(SCNetworkReachabilityRef reachability,
|
||||
SCNetworkReachabilityFlags flags,
|
||||
void *info) {
|
||||
[[GDTReachability sharedInstance] setCallbackFlags:flags];
|
||||
static void GDTCORReachabilityCallback(SCNetworkReachabilityRef reachability,
|
||||
SCNetworkReachabilityFlags flags,
|
||||
void *info) {
|
||||
[[GDTCORReachability sharedInstance] setCallbackFlags:flags];
|
||||
}
|
||||
+33
-32
@@ -14,23 +14,23 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#import "GDTLibrary/Public/GDTRegistrar.h"
|
||||
#import "GDTCORLibrary/Public/GDTCORRegistrar.h"
|
||||
|
||||
#import "GDTLibrary/Private/GDTRegistrar_Private.h"
|
||||
#import "GDTCORLibrary/Private/GDTCORRegistrar_Private.h"
|
||||
|
||||
@implementation GDTRegistrar {
|
||||
@implementation GDTCORRegistrar {
|
||||
/** Backing ivar for targetToUploader property. */
|
||||
NSMutableDictionary<NSNumber *, id<GDTUploader>> *_targetToUploader;
|
||||
NSMutableDictionary<NSNumber *, id<GDTCORUploader>> *_targetToUploader;
|
||||
|
||||
/** Backing ivar for targetToPrioritizer property. */
|
||||
NSMutableDictionary<NSNumber *, id<GDTPrioritizer>> *_targetToPrioritizer;
|
||||
NSMutableDictionary<NSNumber *, id<GDTCORPrioritizer>> *_targetToPrioritizer;
|
||||
}
|
||||
|
||||
+ (instancetype)sharedInstance {
|
||||
static GDTRegistrar *sharedInstance;
|
||||
static GDTCORRegistrar *sharedInstance;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
sharedInstance = [[GDTRegistrar alloc] init];
|
||||
sharedInstance = [[GDTCORRegistrar alloc] init];
|
||||
});
|
||||
return sharedInstance;
|
||||
}
|
||||
@@ -38,38 +38,39 @@
|
||||
- (instancetype)init {
|
||||
self = [super init];
|
||||
if (self) {
|
||||
_registrarQueue = dispatch_queue_create("com.google.GDTRegistrar", DISPATCH_QUEUE_CONCURRENT);
|
||||
_registrarQueue =
|
||||
dispatch_queue_create("com.google.GDTCORRegistrar", DISPATCH_QUEUE_CONCURRENT);
|
||||
_targetToPrioritizer = [[NSMutableDictionary alloc] init];
|
||||
_targetToUploader = [[NSMutableDictionary alloc] init];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)registerUploader:(id<GDTUploader>)backend target:(GDTTarget)target {
|
||||
__weak GDTRegistrar *weakSelf = self;
|
||||
- (void)registerUploader:(id<GDTCORUploader>)backend target:(GDTCORTarget)target {
|
||||
__weak GDTCORRegistrar *weakSelf = self;
|
||||
dispatch_barrier_async(_registrarQueue, ^{
|
||||
GDTRegistrar *strongSelf = weakSelf;
|
||||
GDTCORRegistrar *strongSelf = weakSelf;
|
||||
if (strongSelf) {
|
||||
strongSelf->_targetToUploader[@(target)] = backend;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
- (void)registerPrioritizer:(id<GDTPrioritizer>)prioritizer target:(GDTTarget)target {
|
||||
__weak GDTRegistrar *weakSelf = self;
|
||||
- (void)registerPrioritizer:(id<GDTCORPrioritizer>)prioritizer target:(GDTCORTarget)target {
|
||||
__weak GDTCORRegistrar *weakSelf = self;
|
||||
dispatch_barrier_async(_registrarQueue, ^{
|
||||
GDTRegistrar *strongSelf = weakSelf;
|
||||
GDTCORRegistrar *strongSelf = weakSelf;
|
||||
if (strongSelf) {
|
||||
strongSelf->_targetToPrioritizer[@(target)] = prioritizer;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
- (NSMutableDictionary<NSNumber *, id<GDTUploader>> *)targetToUploader {
|
||||
__block NSMutableDictionary<NSNumber *, id<GDTUploader>> *targetToUploader;
|
||||
__weak GDTRegistrar *weakSelf = self;
|
||||
- (NSMutableDictionary<NSNumber *, id<GDTCORUploader>> *)targetToUploader {
|
||||
__block NSMutableDictionary<NSNumber *, id<GDTCORUploader>> *targetToUploader;
|
||||
__weak GDTCORRegistrar *weakSelf = self;
|
||||
dispatch_sync(_registrarQueue, ^{
|
||||
GDTRegistrar *strongSelf = weakSelf;
|
||||
GDTCORRegistrar *strongSelf = weakSelf;
|
||||
if (strongSelf) {
|
||||
targetToUploader = strongSelf->_targetToUploader;
|
||||
}
|
||||
@@ -77,11 +78,11 @@
|
||||
return targetToUploader;
|
||||
}
|
||||
|
||||
- (NSMutableDictionary<NSNumber *, id<GDTPrioritizer>> *)targetToPrioritizer {
|
||||
__block NSMutableDictionary<NSNumber *, id<GDTPrioritizer>> *targetToPrioritizer;
|
||||
__weak GDTRegistrar *weakSelf = self;
|
||||
- (NSMutableDictionary<NSNumber *, id<GDTCORPrioritizer>> *)targetToPrioritizer {
|
||||
__block NSMutableDictionary<NSNumber *, id<GDTCORPrioritizer>> *targetToPrioritizer;
|
||||
__weak GDTCORRegistrar *weakSelf = self;
|
||||
dispatch_sync(_registrarQueue, ^{
|
||||
GDTRegistrar *strongSelf = weakSelf;
|
||||
GDTCORRegistrar *strongSelf = weakSelf;
|
||||
if (strongSelf) {
|
||||
targetToPrioritizer = strongSelf->_targetToPrioritizer;
|
||||
}
|
||||
@@ -89,16 +90,16 @@
|
||||
return targetToPrioritizer;
|
||||
}
|
||||
|
||||
#pragma mark - GDTLifecycleProtocol
|
||||
#pragma mark - GDTCORLifecycleProtocol
|
||||
|
||||
- (void)appWillBackground:(nonnull GDTApplication *)app {
|
||||
- (void)appWillBackground:(nonnull GDTCORApplication *)app {
|
||||
dispatch_async(_registrarQueue, ^{
|
||||
for (id<GDTUploader> uploader in [self->_targetToUploader allValues]) {
|
||||
for (id<GDTCORUploader> uploader in [self->_targetToUploader allValues]) {
|
||||
if ([uploader respondsToSelector:@selector(appWillBackground:)]) {
|
||||
[uploader appWillBackground:app];
|
||||
}
|
||||
}
|
||||
for (id<GDTPrioritizer> prioritizer in [self->_targetToPrioritizer allValues]) {
|
||||
for (id<GDTCORPrioritizer> prioritizer in [self->_targetToPrioritizer allValues]) {
|
||||
if ([prioritizer respondsToSelector:@selector(appWillBackground:)]) {
|
||||
[prioritizer appWillBackground:app];
|
||||
}
|
||||
@@ -106,14 +107,14 @@
|
||||
});
|
||||
}
|
||||
|
||||
- (void)appWillForeground:(nonnull GDTApplication *)app {
|
||||
- (void)appWillForeground:(nonnull GDTCORApplication *)app {
|
||||
dispatch_async(_registrarQueue, ^{
|
||||
for (id<GDTUploader> uploader in [self->_targetToUploader allValues]) {
|
||||
for (id<GDTCORUploader> uploader in [self->_targetToUploader allValues]) {
|
||||
if ([uploader respondsToSelector:@selector(appWillForeground:)]) {
|
||||
[uploader appWillForeground:app];
|
||||
}
|
||||
}
|
||||
for (id<GDTPrioritizer> prioritizer in [self->_targetToPrioritizer allValues]) {
|
||||
for (id<GDTCORPrioritizer> prioritizer in [self->_targetToPrioritizer allValues]) {
|
||||
if ([prioritizer respondsToSelector:@selector(appWillForeground:)]) {
|
||||
[prioritizer appWillForeground:app];
|
||||
}
|
||||
@@ -121,14 +122,14 @@
|
||||
});
|
||||
}
|
||||
|
||||
- (void)appWillTerminate:(nonnull GDTApplication *)app {
|
||||
- (void)appWillTerminate:(nonnull GDTCORApplication *)app {
|
||||
dispatch_sync(_registrarQueue, ^{
|
||||
for (id<GDTUploader> uploader in [self->_targetToUploader allValues]) {
|
||||
for (id<GDTCORUploader> uploader in [self->_targetToUploader allValues]) {
|
||||
if ([uploader respondsToSelector:@selector(appWillTerminate:)]) {
|
||||
[uploader appWillTerminate:app];
|
||||
}
|
||||
}
|
||||
for (id<GDTPrioritizer> prioritizer in [self->_targetToPrioritizer allValues]) {
|
||||
for (id<GDTCORPrioritizer> prioritizer in [self->_targetToPrioritizer allValues]) {
|
||||
if ([prioritizer respondsToSelector:@selector(appWillTerminate:)]) {
|
||||
[prioritizer appWillTerminate:app];
|
||||
}
|
||||
@@ -0,0 +1,323 @@
|
||||
/*
|
||||
* 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 "GDTCORLibrary/Private/GDTCORStorage.h"
|
||||
#import "GDTCORLibrary/Private/GDTCORStorage_Private.h"
|
||||
|
||||
#import <GoogleDataTransport/GDTCORAssert.h>
|
||||
#import <GoogleDataTransport/GDTCORConsoleLogger.h>
|
||||
#import <GoogleDataTransport/GDTCORLifecycle.h>
|
||||
#import <GoogleDataTransport/GDTCORPrioritizer.h>
|
||||
#import <GoogleDataTransport/GDTCORStoredEvent.h>
|
||||
|
||||
#import "GDTCORLibrary/Private/GDTCOREvent_Private.h"
|
||||
#import "GDTCORLibrary/Private/GDTCORRegistrar_Private.h"
|
||||
#import "GDTCORLibrary/Private/GDTCORUploadCoordinator.h"
|
||||
|
||||
/** Creates and/or returns a singleton NSString that is the shared storage path.
|
||||
*
|
||||
* @return The SDK event storage path.
|
||||
*/
|
||||
static NSString *GDTCORStoragePath() {
|
||||
static NSString *storagePath;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
NSString *cachePath =
|
||||
NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES)[0];
|
||||
storagePath = [NSString stringWithFormat:@"%@/google-sdks-events", cachePath];
|
||||
});
|
||||
return storagePath;
|
||||
}
|
||||
|
||||
@implementation GDTCORStorage
|
||||
|
||||
+ (NSString *)archivePath {
|
||||
static NSString *archivePath;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
archivePath = [GDTCORStoragePath() stringByAppendingPathComponent:@"GDTCORStorageArchive"];
|
||||
});
|
||||
return archivePath;
|
||||
}
|
||||
|
||||
+ (instancetype)sharedInstance {
|
||||
static GDTCORStorage *sharedStorage;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
sharedStorage = [[GDTCORStorage alloc] init];
|
||||
});
|
||||
return sharedStorage;
|
||||
}
|
||||
|
||||
- (instancetype)init {
|
||||
self = [super init];
|
||||
if (self) {
|
||||
_storageQueue = dispatch_queue_create("com.google.GDTCORStorage", DISPATCH_QUEUE_SERIAL);
|
||||
_targetToEventSet = [[NSMutableDictionary alloc] init];
|
||||
_storedEvents = [[NSMutableOrderedSet alloc] init];
|
||||
_uploadCoordinator = [GDTCORUploadCoordinator sharedInstance];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)storeEvent:(GDTCOREvent *)event {
|
||||
if (event == nil) {
|
||||
return;
|
||||
}
|
||||
|
||||
[self createEventDirectoryIfNotExists];
|
||||
|
||||
__block GDTCORBackgroundIdentifier bgID = GDTCORBackgroundIdentifierInvalid;
|
||||
if (_runningInBackground) {
|
||||
bgID = [[GDTCORApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{
|
||||
if (bgID != GDTCORBackgroundIdentifierInvalid) {
|
||||
[[GDTCORApplication sharedApplication] endBackgroundTask:bgID];
|
||||
bgID = GDTCORBackgroundIdentifierInvalid;
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
||||
dispatch_async(_storageQueue, ^{
|
||||
// Check that a backend implementation is available for this target.
|
||||
NSInteger target = event.target;
|
||||
|
||||
// Check that a prioritizer is available for this target.
|
||||
id<GDTCORPrioritizer> prioritizer =
|
||||
[GDTCORRegistrar sharedInstance].targetToPrioritizer[@(target)];
|
||||
GDTCORAssert(prioritizer, @"There's no prioritizer registered for the given target.");
|
||||
|
||||
// Write the transport bytes to disk, get a filename.
|
||||
GDTCORAssert(event.dataObjectTransportBytes, @"The event should have been serialized to bytes");
|
||||
NSURL *eventFile = [self saveEventBytesToDisk:event.dataObjectTransportBytes
|
||||
eventHash:event.hash];
|
||||
GDTCORDataFuture *dataFuture = [[GDTCORDataFuture alloc] initWithFileURL:eventFile];
|
||||
GDTCORStoredEvent *storedEvent = [event storedEventWithDataFuture:dataFuture];
|
||||
|
||||
// Add event to tracking collections.
|
||||
[self addEventToTrackingCollections:storedEvent];
|
||||
|
||||
// Have the prioritizer prioritize the event.
|
||||
[prioritizer prioritizeEvent:storedEvent];
|
||||
|
||||
// Check the QoS, if it's high priority, notify the target that it has a high priority event.
|
||||
if (event.qosTier == GDTCOREventQoSFast) {
|
||||
[self.uploadCoordinator forceUploadForTarget:target];
|
||||
}
|
||||
|
||||
// Write state to disk.
|
||||
if (self->_runningInBackground) {
|
||||
if (@available(macOS 10.13, iOS 11.0, tvOS 11.0, *)) {
|
||||
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:self
|
||||
requiringSecureCoding:YES
|
||||
error:nil];
|
||||
[data writeToFile:[GDTCORStorage archivePath] atomically:YES];
|
||||
} else {
|
||||
#if !defined(TARGET_OS_MACCATALYST)
|
||||
[NSKeyedArchiver archiveRootObject:self toFile:[GDTCORStorage archivePath]];
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
// If running in the background, save state to disk and end the associated background task.
|
||||
if (bgID != GDTCORBackgroundIdentifierInvalid) {
|
||||
[[GDTCORApplication sharedApplication] endBackgroundTask:bgID];
|
||||
bgID = GDTCORBackgroundIdentifierInvalid;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
- (void)removeEvents:(NSSet<GDTCORStoredEvent *> *)events {
|
||||
NSSet<GDTCORStoredEvent *> *eventsToRemove = [events copy];
|
||||
dispatch_async(_storageQueue, ^{
|
||||
for (GDTCORStoredEvent *event in eventsToRemove) {
|
||||
// Remove from disk, first and foremost.
|
||||
NSError *error;
|
||||
if (event.dataFuture.fileURL) {
|
||||
NSURL *fileURL = event.dataFuture.fileURL;
|
||||
[[NSFileManager defaultManager] removeItemAtURL:fileURL error:&error];
|
||||
GDTCORAssert(error == nil, @"There was an error removing an event file: %@", error);
|
||||
}
|
||||
|
||||
// Remove from the tracking collections.
|
||||
[self.storedEvents removeObject:event];
|
||||
[self.targetToEventSet[event.target] removeObject:event];
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
#pragma mark - Private helper methods
|
||||
|
||||
/** Creates the storage directory if it does not exist. */
|
||||
- (void)createEventDirectoryIfNotExists {
|
||||
NSError *error;
|
||||
BOOL result = [[NSFileManager defaultManager] createDirectoryAtPath:GDTCORStoragePath()
|
||||
withIntermediateDirectories:YES
|
||||
attributes:0
|
||||
error:&error];
|
||||
if (!result || error) {
|
||||
GDTCORLogError(GDTCORMCEDirectoryCreationError, @"Error creating the directory: %@", error);
|
||||
}
|
||||
}
|
||||
|
||||
/** Saves the event's dataObjectTransportBytes to a file using NSData mechanisms.
|
||||
*
|
||||
* @note This method should only be called from a method within a block on _storageQueue to maintain
|
||||
* thread safety.
|
||||
*
|
||||
* @param transportBytes The transport bytes of the event.
|
||||
* @param eventHash The hash value of the event.
|
||||
* @return The filename
|
||||
*/
|
||||
- (NSURL *)saveEventBytesToDisk:(NSData *)transportBytes eventHash:(NSUInteger)eventHash {
|
||||
NSString *storagePath = GDTCORStoragePath();
|
||||
NSString *event = [NSString stringWithFormat:@"event-%lu", (unsigned long)eventHash];
|
||||
NSURL *eventFilePath = [NSURL fileURLWithPath:[storagePath stringByAppendingPathComponent:event]];
|
||||
|
||||
GDTCORAssert(![[NSFileManager defaultManager] fileExistsAtPath:eventFilePath.path],
|
||||
@"An event shouldn't already exist at this path: %@", eventFilePath.path);
|
||||
|
||||
BOOL writingSuccess = [transportBytes writeToURL:eventFilePath atomically:YES];
|
||||
if (!writingSuccess) {
|
||||
GDTCORLogError(GDTCORMCEFileWriteError, @"An event file could not be written: %@",
|
||||
eventFilePath);
|
||||
}
|
||||
|
||||
return eventFilePath;
|
||||
}
|
||||
|
||||
/** Adds the event to internal tracking collections.
|
||||
*
|
||||
* @note This method should only be called from a method within a block on _storageQueue to maintain
|
||||
* thread safety.
|
||||
*
|
||||
* @param event The event to track.
|
||||
*/
|
||||
- (void)addEventToTrackingCollections:(GDTCORStoredEvent *)event {
|
||||
[_storedEvents addObject:event];
|
||||
NSMutableSet<GDTCORStoredEvent *> *events = self.targetToEventSet[event.target];
|
||||
events = events ? events : [[NSMutableSet alloc] init];
|
||||
[events addObject:event];
|
||||
_targetToEventSet[event.target] = events;
|
||||
}
|
||||
|
||||
#pragma mark - GDTCORLifecycleProtocol
|
||||
|
||||
- (void)appWillForeground:(GDTCORApplication *)app {
|
||||
if (@available(macOS 10.13, iOS 11.0, tvOS 11.0, *)) {
|
||||
NSData *data = [NSData dataWithContentsOfFile:[GDTCORStorage archivePath]];
|
||||
[NSKeyedUnarchiver unarchivedObjectOfClass:[GDTCORStorage class] fromData:data error:nil];
|
||||
} else {
|
||||
#if !defined(TARGET_OS_MACCATALYST)
|
||||
[NSKeyedUnarchiver unarchiveObjectWithFile:[GDTCORStorage archivePath]];
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
- (void)appWillBackground:(GDTCORApplication *)app {
|
||||
self->_runningInBackground = YES;
|
||||
dispatch_async(_storageQueue, ^{
|
||||
if (@available(macOS 10.13, iOS 11.0, tvOS 11.0, *)) {
|
||||
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:self
|
||||
requiringSecureCoding:YES
|
||||
error:nil];
|
||||
[data writeToFile:[GDTCORStorage archivePath] atomically:YES];
|
||||
} else {
|
||||
#if !defined(TARGET_OS_MACCATALYST)
|
||||
[NSKeyedArchiver archiveRootObject:self toFile:[GDTCORStorage archivePath]];
|
||||
#endif
|
||||
}
|
||||
});
|
||||
|
||||
// Create an immediate background task to run until the end of the current queue of work.
|
||||
__block GDTCORBackgroundIdentifier bgID = [app beginBackgroundTaskWithExpirationHandler:^{
|
||||
if (bgID != GDTCORBackgroundIdentifierInvalid) {
|
||||
[app endBackgroundTask:bgID];
|
||||
bgID = GDTCORBackgroundIdentifierInvalid;
|
||||
}
|
||||
}];
|
||||
dispatch_async(_storageQueue, ^{
|
||||
if (bgID != GDTCORBackgroundIdentifierInvalid) {
|
||||
[app endBackgroundTask:bgID];
|
||||
bgID = GDTCORBackgroundIdentifierInvalid;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
- (void)appWillTerminate:(GDTCORApplication *)application {
|
||||
if (@available(macOS 10.13, iOS 11.0, tvOS 11.0, *)) {
|
||||
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:self
|
||||
requiringSecureCoding:YES
|
||||
error:nil];
|
||||
[data writeToFile:[GDTCORStorage archivePath] atomically:YES];
|
||||
} else {
|
||||
#if !defined(TARGET_OS_MACCATALYST)
|
||||
[NSKeyedArchiver archiveRootObject:self toFile:[GDTCORStorage archivePath]];
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - NSSecureCoding
|
||||
|
||||
/** The NSKeyedCoder key for the storedEvents property. */
|
||||
static NSString *const kGDTCORStorageStoredEventsKey = @"GDTCORStorageStoredEventsKey";
|
||||
|
||||
/** The NSKeyedCoder key for the targetToEventSet property. */
|
||||
static NSString *const kGDTCORStorageTargetToEventSetKey = @"GDTCORStorageTargetToEventSetKey";
|
||||
|
||||
/** The NSKeyedCoder key for the uploadCoordinator property. */
|
||||
static NSString *const kGDTCORStorageUploadCoordinatorKey = @"GDTCORStorageUploadCoordinatorKey";
|
||||
|
||||
+ (BOOL)supportsSecureCoding {
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (instancetype)initWithCoder:(NSCoder *)aDecoder {
|
||||
// Create the singleton and populate its ivars.
|
||||
GDTCORStorage *sharedInstance = [self.class sharedInstance];
|
||||
dispatch_sync(sharedInstance.storageQueue, ^{
|
||||
NSSet *classes =
|
||||
[NSSet setWithObjects:[NSMutableOrderedSet class], [GDTCORStoredEvent class], nil];
|
||||
sharedInstance->_storedEvents = [aDecoder decodeObjectOfClasses:classes
|
||||
forKey:kGDTCORStorageStoredEventsKey];
|
||||
classes = [NSSet setWithObjects:[NSMutableDictionary class], [NSMutableSet class],
|
||||
[GDTCORStoredEvent class], nil];
|
||||
sharedInstance->_targetToEventSet =
|
||||
[aDecoder decodeObjectOfClasses:classes forKey:kGDTCORStorageTargetToEventSetKey];
|
||||
sharedInstance->_uploadCoordinator =
|
||||
[aDecoder decodeObjectOfClass:[GDTCORUploadCoordinator class]
|
||||
forKey:kGDTCORStorageUploadCoordinatorKey];
|
||||
});
|
||||
return sharedInstance;
|
||||
}
|
||||
|
||||
- (void)encodeWithCoder:(NSCoder *)aCoder {
|
||||
GDTCORStorage *sharedInstance = [self.class sharedInstance];
|
||||
NSMutableOrderedSet<GDTCORStoredEvent *> *storedEvents = sharedInstance->_storedEvents;
|
||||
if (storedEvents) {
|
||||
[aCoder encodeObject:storedEvents forKey:kGDTCORStorageStoredEventsKey];
|
||||
}
|
||||
NSMutableDictionary<NSNumber *, NSMutableSet<GDTCORStoredEvent *> *> *targetToEventSet =
|
||||
sharedInstance->_targetToEventSet;
|
||||
if (targetToEventSet) {
|
||||
[aCoder encodeObject:targetToEventSet forKey:kGDTCORStorageTargetToEventSetKey];
|
||||
}
|
||||
GDTCORUploadCoordinator *uploadCoordinator = sharedInstance->_uploadCoordinator;
|
||||
if (uploadCoordinator) {
|
||||
[aCoder encodeObject:uploadCoordinator forKey:kGDTCORStorageUploadCoordinatorKey];
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
+15
-14
@@ -14,15 +14,16 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#import <GoogleDataTransport/GDTStoredEvent.h>
|
||||
#import <GoogleDataTransport/GDTCORStoredEvent.h>
|
||||
|
||||
#import <GoogleDataTransport/GDTClock.h>
|
||||
#import <GoogleDataTransport/GDTCORClock.h>
|
||||
|
||||
#import "GDTLibrary/Private/GDTStorage_Private.h"
|
||||
#import "GDTCORLibrary/Private/GDTCORStorage_Private.h"
|
||||
|
||||
@implementation GDTStoredEvent
|
||||
@implementation GDTCORStoredEvent
|
||||
|
||||
- (instancetype)initWithEvent:(GDTEvent *)event dataFuture:(nonnull GDTDataFuture *)dataFuture {
|
||||
- (instancetype)initWithEvent:(GDTCOREvent *)event
|
||||
dataFuture:(nonnull GDTCORDataFuture *)dataFuture {
|
||||
self = [super init];
|
||||
if (self) {
|
||||
_dataFuture = dataFuture;
|
||||
@@ -38,22 +39,22 @@
|
||||
#pragma mark - NSSecureCoding
|
||||
|
||||
/** Coding key for the dataFuture ivar. */
|
||||
static NSString *kDataFutureKey = @"GDTStoredEventDataFutureKey";
|
||||
static NSString *kDataFutureKey = @"GDTCORStoredEventDataFutureKey";
|
||||
|
||||
/** Coding key for mappingID ivar. */
|
||||
static NSString *kMappingIDKey = @"GDTStoredEventMappingIDKey";
|
||||
static NSString *kMappingIDKey = @"GDTCORStoredEventMappingIDKey";
|
||||
|
||||
/** Coding key for target ivar. */
|
||||
static NSString *kTargetKey = @"GDTStoredEventTargetKey";
|
||||
static NSString *kTargetKey = @"GDTCORStoredEventTargetKey";
|
||||
|
||||
/** Coding key for qosTier ivar. */
|
||||
static NSString *kQosTierKey = @"GDTStoredEventQosTierKey";
|
||||
static NSString *kQosTierKey = @"GDTCORStoredEventQosTierKey";
|
||||
|
||||
/** Coding key for clockSnapshot ivar. */
|
||||
static NSString *kClockSnapshotKey = @"GDTStoredEventClockSnapshotKey";
|
||||
static NSString *kClockSnapshotKey = @"GDTCORStoredEventClockSnapshotKey";
|
||||
|
||||
/** Coding key for customPrioritizationParams ivar. */
|
||||
static NSString *kCustomPrioritizationParamsKey = @"GDTStoredEventcustomPrioritizationParamsKey";
|
||||
static NSString *kCustomPrioritizationParamsKey = @"GDTCORStoredEventcustomPrioritizationParamsKey";
|
||||
|
||||
+ (BOOL)supportsSecureCoding {
|
||||
return YES;
|
||||
@@ -71,19 +72,19 @@ static NSString *kCustomPrioritizationParamsKey = @"GDTStoredEventcustomPrioriti
|
||||
- (nullable instancetype)initWithCoder:(nonnull NSCoder *)aDecoder {
|
||||
self = [self init];
|
||||
if (self) {
|
||||
_dataFuture = [aDecoder decodeObjectOfClass:[GDTDataFuture class] forKey:kDataFutureKey];
|
||||
_dataFuture = [aDecoder decodeObjectOfClass:[GDTCORDataFuture class] forKey:kDataFutureKey];
|
||||
_mappingID = [aDecoder decodeObjectOfClass:[NSString class] forKey:kMappingIDKey];
|
||||
_target = [aDecoder decodeObjectOfClass:[NSNumber class] forKey:kTargetKey];
|
||||
NSNumber *qosTier = [aDecoder decodeObjectOfClass:[NSNumber class] forKey:kQosTierKey];
|
||||
_qosTier = [qosTier intValue];
|
||||
_clockSnapshot = [aDecoder decodeObjectOfClass:[GDTClock class] forKey:kClockSnapshotKey];
|
||||
_clockSnapshot = [aDecoder decodeObjectOfClass:[GDTCORClock class] forKey:kClockSnapshotKey];
|
||||
_customPrioritizationParams = [aDecoder decodeObjectOfClass:[NSDictionary class]
|
||||
forKey:kCustomPrioritizationParamsKey];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (BOOL)isEqual:(GDTStoredEvent *)other {
|
||||
- (BOOL)isEqual:(GDTCORStoredEvent *)other {
|
||||
return [self hash] == [other hash];
|
||||
}
|
||||
|
||||
+113
@@ -0,0 +1,113 @@
|
||||
/*
|
||||
* 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 "GDTCORLibrary/Private/GDTCORTransformer.h"
|
||||
#import "GDTCORLibrary/Private/GDTCORTransformer_Private.h"
|
||||
|
||||
#import <GoogleDataTransport/GDTCORAssert.h>
|
||||
#import <GoogleDataTransport/GDTCORConsoleLogger.h>
|
||||
#import <GoogleDataTransport/GDTCOREventTransformer.h>
|
||||
#import <GoogleDataTransport/GDTCORLifecycle.h>
|
||||
|
||||
#import "GDTCORLibrary/Private/GDTCORStorage.h"
|
||||
|
||||
@implementation GDTCORTransformer
|
||||
|
||||
+ (instancetype)sharedInstance {
|
||||
static GDTCORTransformer *eventTransformer;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
eventTransformer = [[self alloc] init];
|
||||
});
|
||||
return eventTransformer;
|
||||
}
|
||||
|
||||
- (instancetype)init {
|
||||
self = [super init];
|
||||
if (self) {
|
||||
_eventWritingQueue =
|
||||
dispatch_queue_create("com.google.GDTCORTransformer", DISPATCH_QUEUE_SERIAL);
|
||||
_storageInstance = [GDTCORStorage sharedInstance];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)transformEvent:(GDTCOREvent *)event
|
||||
withTransformers:(NSArray<id<GDTCOREventTransformer>> *)transformers {
|
||||
GDTCORAssert(event, @"You can't write a nil event");
|
||||
|
||||
__block GDTCORBackgroundIdentifier bgID = GDTCORBackgroundIdentifierInvalid;
|
||||
if (_runningInBackground) {
|
||||
bgID = [[GDTCORApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{
|
||||
if (bgID != GDTCORBackgroundIdentifierInvalid) {
|
||||
[[GDTCORApplication sharedApplication] endBackgroundTask:bgID];
|
||||
bgID = GDTCORBackgroundIdentifierInvalid;
|
||||
}
|
||||
}];
|
||||
}
|
||||
dispatch_async(_eventWritingQueue, ^{
|
||||
GDTCOREvent *transformedEvent = event;
|
||||
for (id<GDTCOREventTransformer> transformer in transformers) {
|
||||
if ([transformer respondsToSelector:@selector(transform:)]) {
|
||||
transformedEvent = [transformer transform:transformedEvent];
|
||||
if (!transformedEvent) {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
GDTCORLogError(GDTCORMCETransformerDoesntImplementTransform,
|
||||
@"Transformer doesn't implement transform: %@", transformer);
|
||||
return;
|
||||
}
|
||||
}
|
||||
[self.storageInstance storeEvent:transformedEvent];
|
||||
if (self->_runningInBackground) {
|
||||
[[GDTCORApplication sharedApplication] endBackgroundTask:bgID];
|
||||
bgID = GDTCORBackgroundIdentifierInvalid;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
#pragma mark - GDTCORLifecycleProtocol
|
||||
|
||||
- (void)appWillForeground:(GDTCORApplication *)app {
|
||||
dispatch_async(_eventWritingQueue, ^{
|
||||
self->_runningInBackground = NO;
|
||||
});
|
||||
}
|
||||
|
||||
- (void)appWillBackground:(GDTCORApplication *)app {
|
||||
// Create an immediate background task to run until the end of the current queue of work.
|
||||
__block GDTCORBackgroundIdentifier bgID = [app beginBackgroundTaskWithExpirationHandler:^{
|
||||
if (bgID != GDTCORBackgroundIdentifierInvalid) {
|
||||
[app endBackgroundTask:bgID];
|
||||
bgID = GDTCORBackgroundIdentifierInvalid;
|
||||
}
|
||||
}];
|
||||
dispatch_async(_eventWritingQueue, ^{
|
||||
if (bgID != GDTCORBackgroundIdentifierInvalid) {
|
||||
[app endBackgroundTask:bgID];
|
||||
bgID = GDTCORBackgroundIdentifierInvalid;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
- (void)appWillTerminate:(GDTCORApplication *)application {
|
||||
// Flush the queue immediately.
|
||||
dispatch_sync(_eventWritingQueue, ^{
|
||||
});
|
||||
}
|
||||
|
||||
@end
|
||||
+68
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* 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 <GoogleDataTransport/GDTCORTransport.h>
|
||||
#import "GDTCORLibrary/Private/GDTCORTransport_Private.h"
|
||||
|
||||
#import <GoogleDataTransport/GDTCORAssert.h>
|
||||
#import <GoogleDataTransport/GDTCORClock.h>
|
||||
#import <GoogleDataTransport/GDTCOREvent.h>
|
||||
|
||||
#import "GDTCORLibrary/Private/GDTCORTransformer.h"
|
||||
|
||||
@implementation GDTCORTransport
|
||||
|
||||
- (instancetype)initWithMappingID:(NSString *)mappingID
|
||||
transformers:(nullable NSArray<id<GDTCOREventTransformer>> *)transformers
|
||||
target:(NSInteger)target {
|
||||
GDTCORAssert(mappingID.length > 0, @"A mapping ID cannot be nil or empty");
|
||||
GDTCORAssert(target > 0, @"A target cannot be negative or 0");
|
||||
if (mappingID == nil || mappingID.length == 0 || target <= 0) {
|
||||
return nil;
|
||||
}
|
||||
self = [super init];
|
||||
if (self) {
|
||||
_mappingID = mappingID;
|
||||
_transformers = transformers;
|
||||
_target = target;
|
||||
_transformerInstance = [GDTCORTransformer sharedInstance];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)sendTelemetryEvent:(GDTCOREvent *)event {
|
||||
// TODO: Determine if sending an event before registration is allowed.
|
||||
GDTCORAssert(event, @"You can't send a nil event");
|
||||
GDTCOREvent *copiedEvent = [event copy];
|
||||
copiedEvent.qosTier = GDTCOREventQoSTelemetry;
|
||||
copiedEvent.clockSnapshot = [GDTCORClock snapshot];
|
||||
[self.transformerInstance transformEvent:copiedEvent withTransformers:_transformers];
|
||||
}
|
||||
|
||||
- (void)sendDataEvent:(GDTCOREvent *)event {
|
||||
// TODO: Determine if sending an event before registration is allowed.
|
||||
GDTCORAssert(event, @"You can't send a nil event");
|
||||
GDTCORAssert(event.qosTier != GDTCOREventQoSTelemetry, @"Use -sendTelemetryEvent, please.");
|
||||
GDTCOREvent *copiedEvent = [event copy];
|
||||
copiedEvent.clockSnapshot = [GDTCORClock snapshot];
|
||||
[self.transformerInstance transformEvent:copiedEvent withTransformers:_transformers];
|
||||
}
|
||||
|
||||
- (GDTCOREvent *)eventForTransport {
|
||||
return [[GDTCOREvent alloc] initWithMappingID:_mappingID target:_target];
|
||||
}
|
||||
|
||||
@end
|
||||
+93
-60
@@ -14,23 +14,23 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#import "GDTLibrary/Private/GDTUploadCoordinator.h"
|
||||
#import "GDTCORLibrary/Private/GDTCORUploadCoordinator.h"
|
||||
|
||||
#import <GoogleDataTransport/GDTClock.h>
|
||||
#import <GoogleDataTransport/GDTConsoleLogger.h>
|
||||
#import <GoogleDataTransport/GDTCORAssert.h>
|
||||
#import <GoogleDataTransport/GDTCORClock.h>
|
||||
#import <GoogleDataTransport/GDTCORConsoleLogger.h>
|
||||
|
||||
#import "GDTLibrary/Private/GDTAssert.h"
|
||||
#import "GDTLibrary/Private/GDTReachability.h"
|
||||
#import "GDTLibrary/Private/GDTRegistrar_Private.h"
|
||||
#import "GDTLibrary/Private/GDTStorage.h"
|
||||
#import "GDTCORLibrary/Private/GDTCORReachability.h"
|
||||
#import "GDTCORLibrary/Private/GDTCORRegistrar_Private.h"
|
||||
#import "GDTCORLibrary/Private/GDTCORStorage.h"
|
||||
|
||||
@implementation GDTUploadCoordinator
|
||||
@implementation GDTCORUploadCoordinator
|
||||
|
||||
+ (instancetype)sharedInstance {
|
||||
static GDTUploadCoordinator *sharedUploader;
|
||||
static GDTCORUploadCoordinator *sharedUploader;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
sharedUploader = [[GDTUploadCoordinator alloc] init];
|
||||
sharedUploader = [[GDTCORUploadCoordinator alloc] init];
|
||||
[sharedUploader startTimer];
|
||||
});
|
||||
return sharedUploader;
|
||||
@@ -40,8 +40,8 @@
|
||||
self = [super init];
|
||||
if (self) {
|
||||
_coordinationQueue =
|
||||
dispatch_queue_create("com.google.GDTUploadCoordinator", DISPATCH_QUEUE_SERIAL);
|
||||
_registrar = [GDTRegistrar sharedInstance];
|
||||
dispatch_queue_create("com.google.GDTCORUploadCoordinator", DISPATCH_QUEUE_SERIAL);
|
||||
_registrar = [GDTCORRegistrar sharedInstance];
|
||||
_timerInterval = 30 * NSEC_PER_SEC;
|
||||
_timerLeeway = 5 * NSEC_PER_SEC;
|
||||
_targetToInFlightPackages = [[NSMutableDictionary alloc] init];
|
||||
@@ -49,21 +49,21 @@
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)forceUploadForTarget:(GDTTarget)target {
|
||||
- (void)forceUploadForTarget:(GDTCORTarget)target {
|
||||
dispatch_async(_coordinationQueue, ^{
|
||||
GDTUploadConditions conditions = [self uploadConditions];
|
||||
conditions |= GDTUploadConditionHighPriority;
|
||||
GDTCORUploadConditions conditions = [self uploadConditions];
|
||||
conditions |= GDTCORUploadConditionHighPriority;
|
||||
[self uploadTargets:@[ @(target) ] conditions:conditions];
|
||||
});
|
||||
}
|
||||
|
||||
#pragma mark - Property overrides
|
||||
|
||||
// GDTStorage and GDTUploadCoordinator +sharedInstance methods call each other, so this breaks
|
||||
// GDTCORStorage and GDTCORUploadCoordinator +sharedInstance methods call each other, so this breaks
|
||||
// the loop.
|
||||
- (GDTStorage *)storage {
|
||||
- (GDTCORStorage *)storage {
|
||||
if (!_storage) {
|
||||
_storage = [GDTStorage sharedInstance];
|
||||
_storage = [GDTCORStorage sharedInstance];
|
||||
}
|
||||
return _storage;
|
||||
}
|
||||
@@ -81,7 +81,7 @@
|
||||
self->_timerLeeway);
|
||||
dispatch_source_set_event_handler(self->_timer, ^{
|
||||
if (!self->_runningInBackground) {
|
||||
GDTUploadConditions conditions = [self uploadConditions];
|
||||
GDTCORUploadConditions conditions = [self uploadConditions];
|
||||
[self uploadTargets:[self.registrar.targetToUploader allKeys] conditions:conditions];
|
||||
}
|
||||
});
|
||||
@@ -101,9 +101,9 @@
|
||||
* @param targets An array of targets to trigger.
|
||||
* @param conditions The set of upload conditions.
|
||||
*/
|
||||
- (void)uploadTargets:(NSArray<NSNumber *> *)targets conditions:(GDTUploadConditions)conditions {
|
||||
- (void)uploadTargets:(NSArray<NSNumber *> *)targets conditions:(GDTCORUploadConditions)conditions {
|
||||
dispatch_async(_coordinationQueue, ^{
|
||||
if ((conditions & GDTUploadConditionNoNetwork) == GDTUploadConditionNoNetwork) {
|
||||
if ((conditions & GDTCORUploadConditionNoNetwork) == GDTCORUploadConditionNoNetwork) {
|
||||
return;
|
||||
}
|
||||
for (NSNumber *target in targets) {
|
||||
@@ -112,10 +112,10 @@
|
||||
continue;
|
||||
}
|
||||
// Ask the uploader if they can upload and do so, if it can.
|
||||
id<GDTUploader> uploader = self.registrar.targetToUploader[target];
|
||||
id<GDTCORUploader> uploader = self.registrar.targetToUploader[target];
|
||||
if ([uploader readyToUploadWithConditions:conditions]) {
|
||||
id<GDTPrioritizer> prioritizer = self.registrar.targetToPrioritizer[target];
|
||||
GDTUploadPackage *package = [prioritizer uploadPackageWithConditions:conditions];
|
||||
id<GDTCORPrioritizer> prioritizer = self.registrar.targetToPrioritizer[target];
|
||||
GDTCORUploadPackage *package = [prioritizer uploadPackageWithConditions:conditions];
|
||||
if (package.events.count) {
|
||||
self->_targetToInFlightPackages[target] = package;
|
||||
[uploader uploadPackage:package];
|
||||
@@ -131,8 +131,8 @@
|
||||
*
|
||||
* @return The current upload conditions.
|
||||
*/
|
||||
- (GDTUploadConditions)uploadConditions {
|
||||
SCNetworkReachabilityFlags currentFlags = [GDTReachability currentFlags];
|
||||
- (GDTCORUploadConditions)uploadConditions {
|
||||
SCNetworkReachabilityFlags currentFlags = [GDTCORReachability currentFlags];
|
||||
BOOL reachable =
|
||||
(currentFlags & kSCNetworkReachabilityFlagsReachable) == kSCNetworkReachabilityFlagsReachable;
|
||||
BOOL connectionRequired = (currentFlags & kSCNetworkReachabilityFlagsConnectionRequired) ==
|
||||
@@ -140,14 +140,14 @@
|
||||
BOOL networkConnected = reachable && !connectionRequired;
|
||||
|
||||
if (!networkConnected) {
|
||||
return GDTUploadConditionNoNetwork;
|
||||
return GDTCORUploadConditionNoNetwork;
|
||||
}
|
||||
|
||||
BOOL isWWAN = GDTReachabilityFlagsContainWWAN(currentFlags);
|
||||
BOOL isWWAN = GDTCORReachabilityFlagsContainWWAN(currentFlags);
|
||||
if (isWWAN) {
|
||||
return GDTUploadConditionMobileData;
|
||||
return GDTCORUploadConditionMobileData;
|
||||
} else {
|
||||
return GDTUploadConditionWifiData;
|
||||
return GDTCORUploadConditionWifiData;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -155,35 +155,42 @@
|
||||
|
||||
/** The NSKeyedCoder key for the targetToInFlightPackages property. */
|
||||
static NSString *const ktargetToInFlightPackagesKey =
|
||||
@"GDTUploadCoordinatortargetToInFlightPackages";
|
||||
@"GDTCORUploadCoordinatortargetToInFlightPackages";
|
||||
|
||||
+ (BOOL)supportsSecureCoding {
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (instancetype)initWithCoder:(NSCoder *)aDecoder {
|
||||
GDTUploadCoordinator *sharedCoordinator = [GDTUploadCoordinator sharedInstance];
|
||||
sharedCoordinator->_targetToInFlightPackages =
|
||||
[aDecoder decodeObjectOfClass:[NSMutableDictionary class]
|
||||
forKey:ktargetToInFlightPackagesKey];
|
||||
GDTCORUploadCoordinator *sharedCoordinator = [GDTCORUploadCoordinator sharedInstance];
|
||||
@try {
|
||||
sharedCoordinator->_targetToInFlightPackages =
|
||||
[aDecoder decodeObjectOfClass:[NSMutableDictionary class]
|
||||
forKey:ktargetToInFlightPackagesKey];
|
||||
|
||||
} @catch (NSException *exception) {
|
||||
sharedCoordinator->_targetToInFlightPackages = [NSMutableDictionary dictionary];
|
||||
}
|
||||
return sharedCoordinator;
|
||||
}
|
||||
|
||||
- (void)encodeWithCoder:(NSCoder *)aCoder {
|
||||
// All packages that have been given to uploaders need to be tracked so that their expiration
|
||||
// timers can be called.
|
||||
[aCoder encodeObject:_targetToInFlightPackages forKey:ktargetToInFlightPackagesKey];
|
||||
if (_targetToInFlightPackages.count > 0) {
|
||||
[aCoder encodeObject:_targetToInFlightPackages forKey:ktargetToInFlightPackagesKey];
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - GDTLifecycleProtocol
|
||||
#pragma mark - GDTCORLifecycleProtocol
|
||||
|
||||
- (void)appWillForeground:(GDTApplication *)app {
|
||||
- (void)appWillForeground:(GDTCORApplication *)app {
|
||||
// Not entirely thread-safe, but it should be fine.
|
||||
self->_runningInBackground = NO;
|
||||
[self startTimer];
|
||||
}
|
||||
|
||||
- (void)appWillBackground:(GDTApplication *)app {
|
||||
- (void)appWillBackground:(GDTCORApplication *)app {
|
||||
// Not entirely thread-safe, but it should be fine.
|
||||
self->_runningInBackground = YES;
|
||||
|
||||
@@ -191,49 +198,75 @@ static NSString *const ktargetToInFlightPackagesKey =
|
||||
[self stopTimer];
|
||||
|
||||
// Create an immediate background task to run until the end of the current queue of work.
|
||||
__block GDTBackgroundIdentifier bgID = [app beginBackgroundTaskWithExpirationHandler:^{
|
||||
[app endBackgroundTask:bgID];
|
||||
__block GDTCORBackgroundIdentifier bgID = [app beginBackgroundTaskWithExpirationHandler:^{
|
||||
if (bgID != GDTCORBackgroundIdentifierInvalid) {
|
||||
[app endBackgroundTask:bgID];
|
||||
bgID = GDTCORBackgroundIdentifierInvalid;
|
||||
}
|
||||
}];
|
||||
dispatch_async(_coordinationQueue, ^{
|
||||
[app endBackgroundTask:bgID];
|
||||
if (bgID != GDTCORBackgroundIdentifierInvalid) {
|
||||
[app endBackgroundTask:bgID];
|
||||
bgID = GDTCORBackgroundIdentifierInvalid;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
- (void)appWillTerminate:(GDTApplication *)application {
|
||||
- (void)appWillTerminate:(GDTCORApplication *)application {
|
||||
dispatch_sync(_coordinationQueue, ^{
|
||||
[self stopTimer];
|
||||
});
|
||||
}
|
||||
|
||||
#pragma mark - GDTUploadPackageProtocol
|
||||
#pragma mark - GDTCORUploadPackageProtocol
|
||||
|
||||
- (void)packageDelivered:(GDTUploadPackage *)package successful:(BOOL)successful {
|
||||
- (void)packageDelivered:(GDTCORUploadPackage *)package successful:(BOOL)successful {
|
||||
if (!_coordinationQueue) {
|
||||
return;
|
||||
}
|
||||
dispatch_async(_coordinationQueue, ^{
|
||||
NSNumber *targetNumber = @(package.target);
|
||||
[self->_targetToInFlightPackages removeObjectForKey:targetNumber];
|
||||
id<GDTPrioritizer> prioritizer = self->_registrar.targetToPrioritizer[targetNumber];
|
||||
if (!prioritizer) {
|
||||
GDTLogError(GDTMCEPrioritizerError, @"A prioritizer should be registered for this target: %@",
|
||||
targetNumber);
|
||||
NSMutableDictionary<NSNumber *, GDTCORUploadPackage *> *targetToInFlightPackages =
|
||||
self->_targetToInFlightPackages;
|
||||
GDTCORRegistrar *registrar = self->_registrar;
|
||||
if (targetToInFlightPackages) {
|
||||
[targetToInFlightPackages removeObjectForKey:targetNumber];
|
||||
}
|
||||
if ([prioritizer respondsToSelector:@selector(packageDelivered:successful:)]) {
|
||||
[prioritizer packageDelivered:package successful:successful];
|
||||
if (registrar) {
|
||||
id<GDTCORPrioritizer> prioritizer = registrar.targetToPrioritizer[targetNumber];
|
||||
if (!prioritizer) {
|
||||
GDTCORLogError(GDTCORMCEPrioritizerError,
|
||||
@"A prioritizer should be registered for this target: %@", targetNumber);
|
||||
}
|
||||
if ([prioritizer respondsToSelector:@selector(packageDelivered:successful:)]) {
|
||||
[prioritizer packageDelivered:package successful:successful];
|
||||
}
|
||||
}
|
||||
[self.storage removeEvents:package.events];
|
||||
});
|
||||
}
|
||||
|
||||
- (void)packageExpired:(GDTUploadPackage *)package {
|
||||
- (void)packageExpired:(GDTCORUploadPackage *)package {
|
||||
if (!_coordinationQueue) {
|
||||
return;
|
||||
}
|
||||
dispatch_async(_coordinationQueue, ^{
|
||||
NSNumber *targetNumber = @(package.target);
|
||||
[self->_targetToInFlightPackages removeObjectForKey:targetNumber];
|
||||
id<GDTPrioritizer> prioritizer = self->_registrar.targetToPrioritizer[targetNumber];
|
||||
id<GDTUploader> uploader = self->_registrar.targetToUploader[targetNumber];
|
||||
if ([prioritizer respondsToSelector:@selector(packageExpired:)]) {
|
||||
[prioritizer packageExpired:package];
|
||||
NSMutableDictionary<NSNumber *, GDTCORUploadPackage *> *targetToInFlightPackages =
|
||||
self->_targetToInFlightPackages;
|
||||
GDTCORRegistrar *registrar = self->_registrar;
|
||||
if (targetToInFlightPackages) {
|
||||
[targetToInFlightPackages removeObjectForKey:targetNumber];
|
||||
}
|
||||
if ([uploader respondsToSelector:@selector(packageExpired:)]) {
|
||||
[uploader packageExpired:package];
|
||||
if (registrar) {
|
||||
id<GDTCORPrioritizer> prioritizer = registrar.targetToPrioritizer[targetNumber];
|
||||
id<GDTCORUploader> uploader = registrar.targetToUploader[targetNumber];
|
||||
if ([prioritizer respondsToSelector:@selector(packageExpired:)]) {
|
||||
[prioritizer packageExpired:package];
|
||||
}
|
||||
if ([uploader respondsToSelector:@selector(packageExpired:)]) {
|
||||
[uploader packageExpired:package];
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
+28
-26
@@ -14,16 +14,17 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#import <GoogleDataTransport/GDTUploadPackage.h>
|
||||
#import <GoogleDataTransport/GDTCORUploadPackage.h>
|
||||
|
||||
#import <GoogleDataTransport/GDTClock.h>
|
||||
#import <GoogleDataTransport/GDTConsoleLogger.h>
|
||||
#import <GoogleDataTransport/GDTCORClock.h>
|
||||
#import <GoogleDataTransport/GDTCORConsoleLogger.h>
|
||||
#import <GoogleDataTransport/GDTCORStoredEvent.h>
|
||||
|
||||
#import "GDTLibrary/Private/GDTStorage_Private.h"
|
||||
#import "GDTLibrary/Private/GDTUploadCoordinator.h"
|
||||
#import "GDTLibrary/Private/GDTUploadPackage_Private.h"
|
||||
#import "GDTCORLibrary/Private/GDTCORStorage_Private.h"
|
||||
#import "GDTCORLibrary/Private/GDTCORUploadCoordinator.h"
|
||||
#import "GDTCORLibrary/Private/GDTCORUploadPackage_Private.h"
|
||||
|
||||
@implementation GDTUploadPackage {
|
||||
@implementation GDTCORUploadPackage {
|
||||
/** If YES, the package's -completeDelivery method has been called. */
|
||||
BOOL _isDelivered;
|
||||
|
||||
@@ -34,13 +35,13 @@
|
||||
NSTimer *_expirationTimer;
|
||||
}
|
||||
|
||||
- (instancetype)initWithTarget:(GDTTarget)target {
|
||||
- (instancetype)initWithTarget:(GDTCORTarget)target {
|
||||
self = [super init];
|
||||
if (self) {
|
||||
_target = target;
|
||||
_storage = [GDTStorage sharedInstance];
|
||||
_deliverByTime = [GDTClock clockSnapshotInTheFuture:180000];
|
||||
_handler = [GDTUploadCoordinator sharedInstance];
|
||||
_storage = [GDTCORStorage sharedInstance];
|
||||
_deliverByTime = [GDTCORClock clockSnapshotInTheFuture:180000];
|
||||
_handler = [GDTCORUploadCoordinator sharedInstance];
|
||||
_expirationTimer = [NSTimer scheduledTimerWithTimeInterval:5.0
|
||||
target:self
|
||||
selector:@selector(checkIfPackageIsExpired:)
|
||||
@@ -51,7 +52,7 @@
|
||||
}
|
||||
|
||||
- (instancetype)copy {
|
||||
GDTUploadPackage *newPackage = [[GDTUploadPackage alloc] initWithTarget:_target];
|
||||
GDTCORUploadPackage *newPackage = [[GDTCORUploadPackage alloc] initWithTarget:_target];
|
||||
newPackage->_events = [_events copy];
|
||||
return newPackage;
|
||||
}
|
||||
@@ -68,7 +69,7 @@
|
||||
[_expirationTimer invalidate];
|
||||
}
|
||||
|
||||
- (void)setStorage:(GDTStorage *)storage {
|
||||
- (void)setStorage:(GDTCORStorage *)storage {
|
||||
if (storage != _storage) {
|
||||
_storage = storage;
|
||||
}
|
||||
@@ -76,8 +77,8 @@
|
||||
|
||||
- (void)completeDelivery {
|
||||
if (_isDelivered) {
|
||||
GDTLogError(GDTMCEDeliverTwice, @"%@",
|
||||
@"It's an API violation to call -completeDelivery twice.");
|
||||
GDTCORLogError(GDTCORMCEDeliverTwice, @"%@",
|
||||
@"It's an API violation to call -completeDelivery twice.");
|
||||
}
|
||||
_isDelivered = YES;
|
||||
if (!_isHandled && _handler &&
|
||||
@@ -98,7 +99,7 @@
|
||||
}
|
||||
|
||||
- (void)checkIfPackageIsExpired:(NSTimer *)timer {
|
||||
if ([[GDTClock snapshot] isAfter:_deliverByTime]) {
|
||||
if ([[GDTCORClock snapshot] isAfter:_deliverByTime]) {
|
||||
if (_handler && [_handler respondsToSelector:@selector(packageExpired:)]) {
|
||||
_isHandled = YES;
|
||||
[_expirationTimer invalidate];
|
||||
@@ -110,19 +111,19 @@
|
||||
#pragma mark - NSSecureCoding
|
||||
|
||||
/** The keyed archiver key for the events property. */
|
||||
static NSString *const kEventsKey = @"GDTUploadPackageEventsKey";
|
||||
static NSString *const kEventsKey = @"GDTCORUploadPackageEventsKey";
|
||||
|
||||
/** The keyed archiver key for the _isHandled property. */
|
||||
static NSString *const kDeliverByTimeKey = @"GDTUploadPackageDeliveryByTimeKey";
|
||||
static NSString *const kDeliverByTimeKey = @"GDTCORUploadPackageDeliveryByTimeKey";
|
||||
|
||||
/** The keyed archiver key for the _isHandled ivar. */
|
||||
static NSString *const kIsHandledKey = @"GDTUploadPackageIsHandledKey";
|
||||
static NSString *const kIsHandledKey = @"GDTCORUploadPackageIsHandledKey";
|
||||
|
||||
/** The keyed archiver key for the handler property. */
|
||||
static NSString *const kHandlerKey = @"GDTUploadPackageHandlerKey";
|
||||
static NSString *const kHandlerKey = @"GDTCORUploadPackageHandlerKey";
|
||||
|
||||
/** The keyed archiver key for the target property. */
|
||||
static NSString *const kTargetKey = @"GDTUploadPackageTargetKey";
|
||||
static NSString *const kTargetKey = @"GDTCORUploadPackageTargetKey";
|
||||
|
||||
+ (BOOL)supportsSecureCoding {
|
||||
return YES;
|
||||
@@ -137,14 +138,15 @@ static NSString *const kTargetKey = @"GDTUploadPackageTargetKey";
|
||||
}
|
||||
|
||||
- (nullable instancetype)initWithCoder:(nonnull NSCoder *)aDecoder {
|
||||
GDTTarget target = [aDecoder decodeIntegerForKey:kTargetKey];
|
||||
GDTCORTarget target = [aDecoder decodeIntegerForKey:kTargetKey];
|
||||
self = [self initWithTarget:target];
|
||||
if (self) {
|
||||
_events = [aDecoder decodeObjectOfClass:[NSSet class] forKey:kEventsKey];
|
||||
_deliverByTime = [aDecoder decodeObjectOfClass:[GDTClock class] forKey:kDeliverByTimeKey];
|
||||
NSSet *classes = [NSSet setWithObjects:[NSSet class], [GDTCORStoredEvent class], nil];
|
||||
_events = [aDecoder decodeObjectOfClasses:classes forKey:kEventsKey];
|
||||
_deliverByTime = [aDecoder decodeObjectOfClass:[GDTCORClock class] forKey:kDeliverByTimeKey];
|
||||
_isHandled = [aDecoder decodeBoolForKey:kIsHandledKey];
|
||||
// Isn't technically NSSecureCoding, because we don't know the class of this object.
|
||||
_handler = [aDecoder decodeObjectForKey:kHandlerKey];
|
||||
// _handler isn't technically NSSecureCoding, because we don't know the class of this object.
|
||||
// but it gets decoded anyway.
|
||||
}
|
||||
return self;
|
||||
}
|
||||
+3
-3
@@ -14,13 +14,13 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#import <GoogleDataTransport/GDTEvent.h>
|
||||
#import <GoogleDataTransport/GDTCOREvent.h>
|
||||
|
||||
#import <GoogleDataTransport/GDTClock.h>
|
||||
#import <GoogleDataTransport/GDTCORClock.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface GDTEvent ()
|
||||
@interface GDTCOREvent ()
|
||||
|
||||
/** The serialized bytes of the event data object. */
|
||||
@property(nonatomic) NSData *dataObjectTransportBytes;
|
||||
+1
-1
@@ -21,7 +21,7 @@
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
/** This class helps determine upload conditions by determining connectivity. */
|
||||
@interface GDTReachability : NSObject
|
||||
@interface GDTCORReachability : NSObject
|
||||
|
||||
/** The current set flags indicating network conditions */
|
||||
+ (SCNetworkReachabilityFlags)currentFlags;
|
||||
+2
-2
@@ -14,9 +14,9 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#import "GDTLibrary/Private/GDTReachability.h"
|
||||
#import "GDTCORLibrary/Private/GDTCORReachability.h"
|
||||
|
||||
@interface GDTReachability ()
|
||||
@interface GDTCORReachability ()
|
||||
|
||||
/** Allows manually setting the flags for testing purposes. */
|
||||
@property(nonatomic, readwrite) SCNetworkReachabilityFlags flags;
|
||||
+4
-4
@@ -14,9 +14,9 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#import <GoogleDataTransport/GDTRegistrar.h>
|
||||
#import <GoogleDataTransport/GDTCORRegistrar.h>
|
||||
|
||||
@interface GDTRegistrar ()
|
||||
@interface GDTCORRegistrar ()
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@@ -24,11 +24,11 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
@property(nonatomic, readonly) dispatch_queue_t registrarQueue;
|
||||
|
||||
/** A map of targets to backend implementations. */
|
||||
@property(atomic, readonly) NSMutableDictionary<NSNumber *, id<GDTUploader>> *targetToUploader;
|
||||
@property(atomic, readonly) NSMutableDictionary<NSNumber *, id<GDTCORUploader>> *targetToUploader;
|
||||
|
||||
/** A map of targets to prioritizer implementations. */
|
||||
@property(atomic, readonly)
|
||||
NSMutableDictionary<NSNumber *, id<GDTPrioritizer>> *targetToPrioritizer;
|
||||
NSMutableDictionary<NSNumber *, id<GDTCORPrioritizer>> *targetToPrioritizer;
|
||||
|
||||
@end
|
||||
|
||||
+7
-7
@@ -16,15 +16,15 @@
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#import <GoogleDataTransport/GDTLifecycle.h>
|
||||
#import <GoogleDataTransport/GDTCORLifecycle.h>
|
||||
|
||||
@class GDTEvent;
|
||||
@class GDTStoredEvent;
|
||||
@class GDTCOREvent;
|
||||
@class GDTCORStoredEvent;
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
/** Manages the storage of events. This class is thread-safe. */
|
||||
@interface GDTStorage : NSObject <NSSecureCoding, GDTLifecycleProtocol>
|
||||
@interface GDTCORStorage : NSObject <NSSecureCoding, GDTCORLifecycleProtocol>
|
||||
|
||||
/** Creates and/or returns the storage singleton.
|
||||
*
|
||||
@@ -33,17 +33,17 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
+ (instancetype)sharedInstance;
|
||||
|
||||
/** Stores event.dataObjectTransportBytes into a shared on-device folder and tracks the event via
|
||||
* a GDTStoredEvent instance.
|
||||
* a GDTCORStoredEvent instance.
|
||||
*
|
||||
* @param event The event to store.
|
||||
*/
|
||||
- (void)storeEvent:(GDTEvent *)event;
|
||||
- (void)storeEvent:(GDTCOREvent *)event;
|
||||
|
||||
/** Removes a set of events from storage specified by their hash.
|
||||
*
|
||||
* @param events The set of stored events to remove.
|
||||
*/
|
||||
- (void)removeEvents:(NSSet<GDTStoredEvent *> *)events;
|
||||
- (void)removeEvents:(NSSet<GDTCORStoredEvent *> *)events;
|
||||
|
||||
@end
|
||||
|
||||
+7
-7
@@ -14,30 +14,30 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#import "GDTLibrary/Private/GDTStorage.h"
|
||||
#import "GDTCORLibrary/Private/GDTCORStorage.h"
|
||||
|
||||
@class GDTUploadCoordinator;
|
||||
@class GDTCORUploadCoordinator;
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface GDTStorage ()
|
||||
@interface GDTCORStorage ()
|
||||
|
||||
/** The queue on which all storage work will occur. */
|
||||
@property(nonatomic) dispatch_queue_t storageQueue;
|
||||
|
||||
/** A map of targets to a set of stored events. */
|
||||
@property(nonatomic)
|
||||
NSMutableDictionary<NSNumber *, NSMutableSet<GDTStoredEvent *> *> *targetToEventSet;
|
||||
NSMutableDictionary<NSNumber *, NSMutableSet<GDTCORStoredEvent *> *> *targetToEventSet;
|
||||
|
||||
/** All the events that have been stored. */
|
||||
@property(readonly, nonatomic) NSMutableOrderedSet<GDTStoredEvent *> *storedEvents;
|
||||
@property(readonly, nonatomic) NSMutableOrderedSet<GDTCORStoredEvent *> *storedEvents;
|
||||
|
||||
/** The upload coordinator instance used by this storage instance. */
|
||||
@property(nonatomic) GDTUploadCoordinator *uploadCoordinator;
|
||||
@property(nonatomic) GDTCORUploadCoordinator *uploadCoordinator;
|
||||
|
||||
/** If YES, every call to -storeLog results in background task and serializes the singleton to disk.
|
||||
*/
|
||||
@property(nonatomic, readonly) BOOL runningInBackground;
|
||||
@property(nonatomic) BOOL runningInBackground;
|
||||
|
||||
/** Returns the path to the keyed archive of the singleton. This is where the singleton is saved
|
||||
* to disk during certain app lifecycle events.
|
||||
+6
-6
@@ -16,11 +16,11 @@
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#import <GoogleDataTransport/GDTLifecycle.h>
|
||||
#import <GoogleDataTransport/GDTCORLifecycle.h>
|
||||
|
||||
@class GDTEvent;
|
||||
@class GDTCOREvent;
|
||||
|
||||
@protocol GDTEventTransformer;
|
||||
@protocol GDTCOREventTransformer;
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@@ -30,7 +30,7 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
* maintain state (or at least, there's nothing to stop them from doing that) and the same instances
|
||||
* may be used across multiple instances.
|
||||
*/
|
||||
@interface GDTTransformer : NSObject <GDTLifecycleProtocol>
|
||||
@interface GDTCORTransformer : NSObject <GDTCORLifecycleProtocol>
|
||||
|
||||
/** Instantiates or returns the event transformer singleton.
|
||||
*
|
||||
@@ -46,8 +46,8 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
* @param event The event to apply transformers on.
|
||||
* @param transformers The list of transformers to apply.
|
||||
*/
|
||||
- (void)transformEvent:(GDTEvent *)event
|
||||
withTransformers:(nullable NSArray<id<GDTEventTransformer>> *)transformers;
|
||||
- (void)transformEvent:(GDTCOREvent *)event
|
||||
withTransformers:(nullable NSArray<id<GDTCOREventTransformer>> *)transformers;
|
||||
|
||||
@end
|
||||
|
||||
+4
-4
@@ -14,19 +14,19 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#import "GDTLibrary/Private/GDTTransformer.h"
|
||||
#import "GDTCORLibrary/Private/GDTCORTransformer.h"
|
||||
|
||||
@class GDTStorage;
|
||||
@class GDTCORStorage;
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface GDTTransformer ()
|
||||
@interface GDTCORTransformer ()
|
||||
|
||||
/** The queue on which all work will occur. */
|
||||
@property(nonatomic) dispatch_queue_t eventWritingQueue;
|
||||
|
||||
/** The storage instance used to store events. Should only be used to inject a testing fake. */
|
||||
@property(nonatomic) GDTStorage *storageInstance;
|
||||
@property(nonatomic) GDTCORStorage *storageInstance;
|
||||
|
||||
/** If YES, every call to -transformEvent will result in a background task. */
|
||||
@property(nonatomic, readonly) BOOL runningInBackground;
|
||||
+5
-5
@@ -14,25 +14,25 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#import <GoogleDataTransport/GDTTransport.h>
|
||||
#import <GoogleDataTransport/GDTCORTransport.h>
|
||||
|
||||
@class GDTTransformer;
|
||||
@class GDTCORTransformer;
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface GDTTransport ()
|
||||
@interface GDTCORTransport ()
|
||||
|
||||
/** The mapping identifier that the target backend will use to map the transport bytes to proto. */
|
||||
@property(nonatomic) NSString *mappingID;
|
||||
|
||||
/** The transformers that will operate on events sent by this transport. */
|
||||
@property(nonatomic) NSArray<id<GDTEventTransformer>> *transformers;
|
||||
@property(nonatomic) NSArray<id<GDTCOREventTransformer>> *transformers;
|
||||
|
||||
/** The target backend of this transport. */
|
||||
@property(nonatomic) NSInteger target;
|
||||
|
||||
/** The transformer instance to used to transform events. Allows injecting a fake during testing. */
|
||||
@property(nonatomic) GDTTransformer *transformerInstance;
|
||||
@property(nonatomic) GDTCORTransformer *transformerInstance;
|
||||
|
||||
@end
|
||||
|
||||
+11
-11
@@ -16,21 +16,21 @@
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#import <GoogleDataTransport/GDTLifecycle.h>
|
||||
#import <GoogleDataTransport/GDTRegistrar.h>
|
||||
#import <GoogleDataTransport/GDTCORLifecycle.h>
|
||||
#import <GoogleDataTransport/GDTCORRegistrar.h>
|
||||
|
||||
#import "GDTLibrary/Private/GDTUploadPackage_Private.h"
|
||||
#import "GDTCORLibrary/Private/GDTCORUploadPackage_Private.h"
|
||||
|
||||
@class GDTClock;
|
||||
@class GDTStorage;
|
||||
@class GDTCORClock;
|
||||
@class GDTCORStorage;
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
/** This class connects storage and uploader implementations, providing events to an uploader
|
||||
* and informing the storage what events were successfully uploaded or not.
|
||||
*/
|
||||
@interface GDTUploadCoordinator
|
||||
: NSObject <NSSecureCoding, GDTLifecycleProtocol, GDTUploadPackageProtocol>
|
||||
@interface GDTCORUploadCoordinator
|
||||
: NSObject <NSSecureCoding, GDTCORLifecycleProtocol, GDTCORUploadPackageProtocol>
|
||||
|
||||
/** The queue on which all upload coordination will occur. Also used by a dispatch timer. */
|
||||
/** Creates and/or returrns the singleton.
|
||||
@@ -51,13 +51,13 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
/** The map of targets to in-flight packages. */
|
||||
@property(nonatomic, readonly)
|
||||
NSMutableDictionary<NSNumber *, GDTUploadPackage *> *targetToInFlightPackages;
|
||||
NSMutableDictionary<NSNumber *, GDTCORUploadPackage *> *targetToInFlightPackages;
|
||||
|
||||
/** The storage object the coordinator will use. Generally used for testing. */
|
||||
@property(nonatomic) GDTStorage *storage;
|
||||
@property(nonatomic) GDTCORStorage *storage;
|
||||
|
||||
/** The registrar object the coordinator will use. Generally used for testing. */
|
||||
@property(nonatomic) GDTRegistrar *registrar;
|
||||
@property(nonatomic) GDTCORRegistrar *registrar;
|
||||
|
||||
/** If YES, completion and other operations will result in serializing the singleton to disk. */
|
||||
@property(nonatomic, readonly) BOOL runningInBackground;
|
||||
@@ -67,7 +67,7 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
*
|
||||
* @param target The target that should force an upload.
|
||||
*/
|
||||
- (void)forceUploadForTarget:(GDTTarget)target;
|
||||
- (void)forceUploadForTarget:(GDTCORTarget)target;
|
||||
|
||||
/** Starts the upload timer. */
|
||||
- (void)startTimer;
|
||||
+5
-5
@@ -14,16 +14,16 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#import <GoogleDataTransport/GDTUploadPackage.h>
|
||||
#import <GoogleDataTransport/GDTCORUploadPackage.h>
|
||||
|
||||
@class GDTStorage;
|
||||
@class GDTCORStorage;
|
||||
|
||||
@interface GDTUploadPackage ()
|
||||
@interface GDTCORUploadPackage ()
|
||||
|
||||
/** The storage object this upload package will use to resolve event hashes to files. */
|
||||
@property(nonatomic) GDTStorage *storage;
|
||||
@property(nonatomic) GDTCORStorage *storage;
|
||||
|
||||
/** A handler that will receive callbacks for certain events. */
|
||||
@property(nonatomic) id<NSSecureCoding, GDTUploadPackageProtocol> handler;
|
||||
@property(nonatomic) id<NSSecureCoding, GDTCORUploadPackageProtocol> handler;
|
||||
|
||||
@end
|
||||
+91
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
* Copyright 2019 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>
|
||||
|
||||
#import <GoogleDataTransport/GDTCORConsoleLogger.h>
|
||||
|
||||
/** A block type that could be run instead of normal assertion logging. No return type, no params.
|
||||
*/
|
||||
typedef void (^GDTCORAssertionBlock)(void);
|
||||
|
||||
/** Returns the result of executing a soft-linked method present in unit tests that allows a block
|
||||
* to be run instead of normal assertion logging. This helps ameliorate issues with catching
|
||||
* exceptions that occur on a dispatch_queue.
|
||||
*
|
||||
* @return A block that can be run instead of normal assert printing.
|
||||
*/
|
||||
FOUNDATION_EXPORT GDTCORAssertionBlock _Nullable GDTCORAssertionBlockToRunInstead(void);
|
||||
|
||||
#if defined(NS_BLOCK_ASSERTIONS)
|
||||
|
||||
#define GDTCORAssert(condition, ...) \
|
||||
do { \
|
||||
} while (0);
|
||||
|
||||
#define GDTCORFatalAssert(condition, ...) \
|
||||
do { \
|
||||
} while (0);
|
||||
|
||||
#else // defined(NS_BLOCK_ASSERTIONS)
|
||||
|
||||
/** Asserts using a console log, unless a block was specified to be run instead.
|
||||
*
|
||||
* @param condition The condition you'd expect to be YES.
|
||||
*/
|
||||
#define GDTCORAssert(condition, ...) \
|
||||
do { \
|
||||
if (__builtin_expect(!(condition), 0)) { \
|
||||
GDTCORAssertionBlock assertionBlock = GDTCORAssertionBlockToRunInstead(); \
|
||||
if (assertionBlock) { \
|
||||
assertionBlock(); \
|
||||
} else { \
|
||||
__PRAGMA_PUSH_NO_EXTRA_ARG_WARNINGS \
|
||||
NSString *__assert_file__ = [NSString stringWithUTF8String:__FILE__]; \
|
||||
__assert_file__ = __assert_file__ ? __assert_file__ : @"<Unknown File>"; \
|
||||
GDTCORLogError(GDTCORMCEGeneralError, @"Assertion failed (%@:%d): %s,", __assert_file__, \
|
||||
__LINE__, ##__VA_ARGS__); \
|
||||
__PRAGMA_POP_NO_EXTRA_ARG_WARNINGS \
|
||||
} \
|
||||
} \
|
||||
} while (0);
|
||||
|
||||
/** Asserts by logging to the console and throwing an exception if NS_BLOCK_ASSERTIONS is not
|
||||
* defined.
|
||||
*
|
||||
* @param condition The condition you'd expect to be YES.
|
||||
*/
|
||||
#define GDTCORFatalAssert(condition, ...) \
|
||||
do { \
|
||||
__PRAGMA_PUSH_NO_EXTRA_ARG_WARNINGS \
|
||||
if (__builtin_expect(!(condition), 0)) { \
|
||||
NSString *__assert_file__ = [NSString stringWithUTF8String:__FILE__]; \
|
||||
__assert_file__ = __assert_file__ ? __assert_file__ : @"<Unknown File>"; \
|
||||
GDTCORLogError(GDTCORMCEFatalAssertion, \
|
||||
@"Fatal assertion encountered, please open an issue at " \
|
||||
"https://github.com/firebase/firebase-ios-sdk/issues " \
|
||||
"(%@:%d): %s,", \
|
||||
__assert_file__, __LINE__, ##__VA_ARGS__); \
|
||||
[[NSAssertionHandler currentHandler] handleFailureInMethod:_cmd \
|
||||
object:self \
|
||||
file:__assert_file__ \
|
||||
lineNumber:__LINE__ \
|
||||
description:@"%@", ##__VA_ARGS__]; \
|
||||
} \
|
||||
__PRAGMA_POP_NO_EXTRA_ARG_WARNINGS \
|
||||
} while (0);
|
||||
|
||||
#endif // defined(NS_BLOCK_ASSERTIONS)
|
||||
+5
-5
@@ -19,7 +19,7 @@
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
/** This class manages the device clock and produces snapshots of the current time. */
|
||||
@interface GDTClock : NSObject <NSSecureCoding>
|
||||
@interface GDTCORClock : NSObject <NSSecureCoding>
|
||||
|
||||
/** The wallclock time, UTC, in milliseconds. */
|
||||
@property(nonatomic, readonly) int64_t timeMillis;
|
||||
@@ -33,13 +33,13 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
/** The device uptime when this clock was created. */
|
||||
@property(nonatomic, readonly) int64_t uptime;
|
||||
|
||||
/** Creates a GDTClock object using the current time and offsets.
|
||||
/** Creates a GDTCORClock object using the current time and offsets.
|
||||
*
|
||||
* @return A new GDTClock object representing the current time state.
|
||||
* @return A new GDTCORClock object representing the current time state.
|
||||
*/
|
||||
+ (instancetype)snapshot;
|
||||
|
||||
/** Creates a GDTClock object representing a time in the future, relative to now.
|
||||
/** Creates a GDTCORClock object representing a time in the future, relative to now.
|
||||
*
|
||||
* @param millisInTheFuture The millis in the future from now this clock should represent.
|
||||
* @return An instance representing a future time.
|
||||
@@ -50,7 +50,7 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
*
|
||||
* @return YES if the calling clock's time is after the given clock's time.
|
||||
*/
|
||||
- (BOOL)isAfter:(GDTClock *)otherClock;
|
||||
- (BOOL)isAfter:(GDTCORClock *)otherClock;
|
||||
|
||||
@end
|
||||
|
||||
+23
-18
@@ -23,57 +23,62 @@
|
||||
* - MCW => MessageCodeWarning
|
||||
* - MCE => MessageCodeError
|
||||
*/
|
||||
typedef NS_ENUM(NSInteger, GDTMessageCode) {
|
||||
typedef NS_ENUM(NSInteger, GDTCORMessageCode) {
|
||||
|
||||
/** For warning messages concerning transportBytes: not being implemented by a data object. */
|
||||
GDTMCWDataObjectMissingBytesImpl = 1,
|
||||
GDTCORMCWDataObjectMissingBytesImpl = 1,
|
||||
|
||||
/** For warning messages concerning a failed event upload. */
|
||||
GDTMCWUploadFailed = 2,
|
||||
GDTCORMCWUploadFailed = 2,
|
||||
|
||||
/** For warning messages concerning a forced event upload. */
|
||||
GDTMCWForcedUpload = 3,
|
||||
GDTCORMCWForcedUpload = 3,
|
||||
|
||||
/** For warning messages concerning a failed reachability call. */
|
||||
GDTMCWReachabilityFailed = 4,
|
||||
GDTCORMCWReachabilityFailed = 4,
|
||||
|
||||
/** For error messages concerning transform: not being implemented by an event transformer. */
|
||||
GDTMCETransformerDoesntImplementTransform = 1000,
|
||||
GDTCORMCETransformerDoesntImplementTransform = 1000,
|
||||
|
||||
/** For error messages concerning the creation of a directory failing. */
|
||||
GDTMCEDirectoryCreationError = 1001,
|
||||
GDTCORMCEDirectoryCreationError = 1001,
|
||||
|
||||
/** For error messages concerning the writing of a event file. */
|
||||
GDTMCEFileWriteError = 1002,
|
||||
GDTCORMCEFileWriteError = 1002,
|
||||
|
||||
/** For error messages concerning the lack of a prioritizer for a given backend. */
|
||||
GDTMCEPrioritizerError = 1003,
|
||||
GDTCORMCEPrioritizerError = 1003,
|
||||
|
||||
/** For error messages concerning a package delivery API violation. */
|
||||
GDTMCEDeliverTwice = 1004,
|
||||
GDTCORMCEDeliverTwice = 1004,
|
||||
|
||||
/** For error messages concerning an error in an implementation of -transportBytes. */
|
||||
GDTMCETransportBytesError = 1005,
|
||||
GDTCORMCETransportBytesError = 1005,
|
||||
|
||||
/** For general purpose error messages in a dependency. */
|
||||
GDTMCEGeneralError = 1006
|
||||
GDTCORMCEGeneralError = 1006,
|
||||
|
||||
/** For fatal errors. Please go to https://github.com/firebase/firebase-ios-sdk/issues and open
|
||||
* an issue if you encounter an error with this code.
|
||||
*/
|
||||
GDTCORMCEFatalAssertion = 1007
|
||||
};
|
||||
|
||||
/** */
|
||||
FOUNDATION_EXPORT
|
||||
void GDTLog(GDTMessageCode code, NSString *_Nonnull format, ...);
|
||||
void GDTCORLog(GDTCORMessageCode code, NSString *_Nonnull format, ...);
|
||||
|
||||
/** Returns the string that represents some message code.
|
||||
*
|
||||
* @param code The code to convert to a string.
|
||||
* @return The string representing the message code.
|
||||
*/
|
||||
FOUNDATION_EXPORT NSString *_Nonnull GDTMessageCodeEnumToString(GDTMessageCode code);
|
||||
FOUNDATION_EXPORT NSString *_Nonnull GDTCORMessageCodeEnumToString(GDTCORMessageCode code);
|
||||
|
||||
// A define to wrap GULLogWarning with slightly more convenient usage.
|
||||
#define GDTLogWarning(MESSAGE_CODE, MESSAGE_FORMAT, ...) \
|
||||
GDTLog(MESSAGE_CODE, MESSAGE_FORMAT, __VA_ARGS__);
|
||||
#define GDTCORLogWarning(MESSAGE_CODE, MESSAGE_FORMAT, ...) \
|
||||
GDTCORLog(MESSAGE_CODE, MESSAGE_FORMAT, __VA_ARGS__);
|
||||
|
||||
// A define to wrap GULLogError with slightly more convenient usage and a failing assert.
|
||||
#define GDTLogError(MESSAGE_CODE, MESSAGE_FORMAT, ...) \
|
||||
GDTLog(MESSAGE_CODE, MESSAGE_FORMAT, __VA_ARGS__);
|
||||
#define GDTCORLogError(MESSAGE_CODE, MESSAGE_FORMAT, ...) \
|
||||
GDTCORLog(MESSAGE_CODE, MESSAGE_FORMAT, __VA_ARGS__);
|
||||
+1
-1
@@ -19,7 +19,7 @@
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
/** This class represents a future data object, determined at instantiation time. */
|
||||
@interface GDTDataFuture : NSObject <NSSecureCoding>
|
||||
@interface GDTCORDataFuture : NSObject <NSSecureCoding>
|
||||
|
||||
/** The data, computed on-demand, depending on the initializer. */
|
||||
@property(nullable, readonly, nonatomic) NSData *data;
|
||||
+19
-19
@@ -16,36 +16,36 @@
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#import <GoogleDataTransport/GDTEventDataObject.h>
|
||||
#import <GoogleDataTransport/GDTCOREventDataObject.h>
|
||||
|
||||
@class GDTClock;
|
||||
@class GDTDataFuture;
|
||||
@class GDTStoredEvent;
|
||||
@class GDTCORClock;
|
||||
@class GDTCORDataFuture;
|
||||
@class GDTCORStoredEvent;
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
/** The different possible quality of service specifiers. High values indicate high priority. */
|
||||
typedef NS_ENUM(NSInteger, GDTEventQoS) {
|
||||
typedef NS_ENUM(NSInteger, GDTCOREventQoS) {
|
||||
/** The QoS tier wasn't set, and won't ever be sent. */
|
||||
GDTEventQoSUnknown = 0,
|
||||
GDTCOREventQoSUnknown = 0,
|
||||
|
||||
/** This event is internal telemetry data that should not be sent on its own if possible. */
|
||||
GDTEventQoSTelemetry = 1,
|
||||
GDTCOREventQoSTelemetry = 1,
|
||||
|
||||
/** This event should be sent, but in a batch only roughly once per day. */
|
||||
GDTEventQoSDaily = 2,
|
||||
GDTCOREventQoSDaily = 2,
|
||||
|
||||
/** This event should be sent when requested by the uploader. */
|
||||
GDTEventQosDefault = 3,
|
||||
GDTCOREventQosDefault = 3,
|
||||
|
||||
/** This event should be sent immediately along with any other data that can be batched. */
|
||||
GDTEventQoSFast = 4,
|
||||
GDTCOREventQoSFast = 4,
|
||||
|
||||
/** This event should only be uploaded on wifi. */
|
||||
GDTEventQoSWifiOnly = 5,
|
||||
GDTCOREventQoSWifiOnly = 5,
|
||||
};
|
||||
|
||||
@interface GDTEvent : NSObject <NSSecureCoding>
|
||||
@interface GDTCOREvent : NSObject <NSSecureCoding>
|
||||
|
||||
/** The mapping identifier, to allow backends to map the transport bytes to a proto. */
|
||||
@property(readonly, nonatomic) NSString *mappingID;
|
||||
@@ -54,14 +54,14 @@ typedef NS_ENUM(NSInteger, GDTEventQoS) {
|
||||
@property(readonly, nonatomic) NSInteger target;
|
||||
|
||||
/** The data object encapsulated in the transport of your choice, as long as it implements
|
||||
* the GDTEventDataObject protocol. */
|
||||
@property(nullable, nonatomic) id<GDTEventDataObject> dataObject;
|
||||
* the GDTCOREventDataObject protocol. */
|
||||
@property(nullable, nonatomic) id<GDTCOREventDataObject> dataObject;
|
||||
|
||||
/** The quality of service tier this event belongs to. */
|
||||
@property(nonatomic) GDTEventQoS qosTier;
|
||||
@property(nonatomic) GDTCOREventQoS qosTier;
|
||||
|
||||
/** The clock snapshot at the time of the event. */
|
||||
@property(nonatomic) GDTClock *clockSnapshot;
|
||||
@property(nonatomic) GDTCORClock *clockSnapshot;
|
||||
|
||||
/** A dictionary provided to aid prioritizers by allowing the passing of arbitrary data. It will be
|
||||
* retained by a copy in -copy, but not used for -hash.
|
||||
@@ -82,12 +82,12 @@ typedef NS_ENUM(NSInteger, GDTEventQoS) {
|
||||
- (instancetype)initWithMappingID:(NSString *)mappingID
|
||||
target:(NSInteger)target NS_DESIGNATED_INITIALIZER;
|
||||
|
||||
/** Returns the GDTStoredEvent equivalent of self.
|
||||
/** Returns the GDTCORStoredEvent equivalent of self.
|
||||
*
|
||||
* @param dataFuture The data future representing the transport bytes of the original event.
|
||||
* @return An equivalent GDTStoredEvent.
|
||||
* @return An equivalent GDTCORStoredEvent.
|
||||
*/
|
||||
- (GDTStoredEvent *)storedEventWithDataFuture:(GDTDataFuture *)dataFuture;
|
||||
- (GDTCORStoredEvent *)storedEventWithDataFuture:(GDTCORDataFuture *)dataFuture;
|
||||
|
||||
@end
|
||||
|
||||
+1
-1
@@ -21,7 +21,7 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
/** This protocol defines the common interface that event protos should implement regardless of the
|
||||
* underlying transport technology (protobuf, nanopb, etc).
|
||||
*/
|
||||
@protocol GDTEventDataObject <NSObject>
|
||||
@protocol GDTCOREventDataObject <NSObject>
|
||||
|
||||
@required
|
||||
|
||||
+3
-3
@@ -16,12 +16,12 @@
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@class GDTEvent;
|
||||
@class GDTCOREvent;
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
/** Defines the API that event transformers must adopt. */
|
||||
@protocol GDTEventTransformer <NSObject>
|
||||
@protocol GDTCOREventTransformer <NSObject>
|
||||
|
||||
@required
|
||||
|
||||
@@ -31,7 +31,7 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
* @param event The event to transform.
|
||||
* @return A transformed event, or nil if the transformation dropped the event.
|
||||
*/
|
||||
- (GDTEvent *)transform:(GDTEvent *)event;
|
||||
- (GDTCOREvent *)transform:(GDTCOREvent *)event;
|
||||
|
||||
@end
|
||||
|
||||
+15
-14
@@ -16,35 +16,36 @@
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#import <GoogleDataTransport/GDTPlatform.h>
|
||||
#import <GoogleDataTransport/GDTCORPlatform.h>
|
||||
|
||||
@class GDTEvent;
|
||||
@class GDTCOREvent;
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
/** A protocol defining the lifecycle events objects in the library must respond to immediately. */
|
||||
@protocol GDTLifecycleProtocol <NSObject>
|
||||
@protocol GDTCORLifecycleProtocol <NSObject>
|
||||
|
||||
@optional
|
||||
|
||||
/** Indicates an imminent app termination in the rare occurrence when -applicationWillTerminate: has
|
||||
* been called.
|
||||
*
|
||||
* @param app The GDTApplication instance.
|
||||
* @param app The GDTCORApplication instance.
|
||||
*/
|
||||
- (void)appWillTerminate:(GDTApplication *)app;
|
||||
- (void)appWillTerminate:(GDTCORApplication *)app;
|
||||
|
||||
/** Indicates that the app is moving to background and eventual suspension.
|
||||
/** Indicates that the app is moving to background and eventual suspension or the current UIScene is
|
||||
* deactivating.
|
||||
*
|
||||
* @param app The GDTApplication instance.
|
||||
* @param app The GDTCORApplication instance.
|
||||
*/
|
||||
- (void)appWillBackground:(GDTApplication *)app;
|
||||
- (void)appWillBackground:(GDTCORApplication *)app;
|
||||
|
||||
/** Indicates that the app is resuming operation.
|
||||
/** Indicates that the app is resuming operation or a UIScene is activating.
|
||||
*
|
||||
* @param app The GDTApplication instance.
|
||||
* @param app The GDTCORApplication instance.
|
||||
*/
|
||||
- (void)appWillForeground:(GDTApplication *)app;
|
||||
- (void)appWillForeground:(GDTCORApplication *)app;
|
||||
|
||||
@end
|
||||
|
||||
@@ -52,10 +53,10 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
*
|
||||
* When backgrounding, the library doesn't stop processing events, it's just that several background
|
||||
* tasks will end up being created for every event that's sent, and the stateful objects of the
|
||||
* library (GDTStorage and GDTUploadCoordinator singletons) will deserialize themselves from and to
|
||||
* disk before and after every operation, respectively.
|
||||
* library (GDTCORStorage and GDTCORUploadCoordinator singletons) will deserialize themselves from
|
||||
* and to disk before and after every operation, respectively.
|
||||
*/
|
||||
@interface GDTLifecycle : NSObject <GDTApplicationDelegate>
|
||||
@interface GDTCORLifecycle : NSObject <GDTCORApplicationDelegate>
|
||||
|
||||
@end
|
||||
|
||||
+15
-15
@@ -26,61 +26,61 @@
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
/** A notification sent out if the app is backgrounding. */
|
||||
FOUNDATION_EXPORT NSString *const kGDTApplicationDidEnterBackgroundNotification;
|
||||
FOUNDATION_EXPORT NSString *const kGDTCORApplicationDidEnterBackgroundNotification;
|
||||
|
||||
/** A notification sent out if the app is foregrounding. */
|
||||
FOUNDATION_EXPORT NSString *const kGDTApplicationWillEnterForegroundNotification;
|
||||
FOUNDATION_EXPORT NSString *const kGDTCORApplicationWillEnterForegroundNotification;
|
||||
|
||||
/** A notification sent out if the app is terminating. */
|
||||
FOUNDATION_EXPORT NSString *const kGDTApplicationWillTerminateNotification;
|
||||
FOUNDATION_EXPORT NSString *const kGDTCORApplicationWillTerminateNotification;
|
||||
|
||||
/** Compares flags with the WWAN reachability flag, if available, and returns YES if present.
|
||||
*
|
||||
* @param flags The set of reachability flags.
|
||||
* @return YES if the WWAN flag is set, NO otherwise.
|
||||
*/
|
||||
BOOL GDTReachabilityFlagsContainWWAN(SCNetworkReachabilityFlags flags);
|
||||
BOOL GDTCORReachabilityFlagsContainWWAN(SCNetworkReachabilityFlags flags);
|
||||
|
||||
/** A typedef identify background identifiers. */
|
||||
typedef NSUInteger GDTBackgroundIdentifier;
|
||||
typedef volatile NSUInteger GDTCORBackgroundIdentifier;
|
||||
|
||||
/** A background task's invalid sentinel value. */
|
||||
FOUNDATION_EXPORT const GDTBackgroundIdentifier GDTBackgroundIdentifierInvalid;
|
||||
FOUNDATION_EXPORT const GDTCORBackgroundIdentifier GDTCORBackgroundIdentifierInvalid;
|
||||
|
||||
#if TARGET_OS_IOS || TARGET_OS_TV
|
||||
/** A protocol that wraps UIApplicationDelegate or NSObject protocol, depending on the platform. */
|
||||
@protocol GDTApplicationDelegate <UIApplicationDelegate>
|
||||
@protocol GDTCORApplicationDelegate <UIApplicationDelegate>
|
||||
#elif TARGET_OS_OSX
|
||||
@protocol GDTApplicationDelegate <NSApplicationDelegate>
|
||||
@protocol GDTCORApplicationDelegate <NSApplicationDelegate>
|
||||
#else
|
||||
@protocol GDTApplicationDelegate <NSObject>
|
||||
@protocol GDTCORApplicationDelegate <NSObject>
|
||||
#endif // TARGET_OS_IOS || TARGET_OS_TV
|
||||
|
||||
@end
|
||||
|
||||
/** A cross-platform application class. */
|
||||
@interface GDTApplication : NSObject <GDTApplicationDelegate>
|
||||
@interface GDTCORApplication : NSObject <GDTCORApplicationDelegate>
|
||||
|
||||
/** Creates and/or returns the shared application instance.
|
||||
*
|
||||
* @return The shared application instance.
|
||||
*/
|
||||
+ (nullable GDTApplication *)sharedApplication;
|
||||
+ (nullable GDTCORApplication *)sharedApplication;
|
||||
|
||||
/** Creates a background task with the returned identifier if on a suitable platform.
|
||||
*
|
||||
* @param handler The handler block that is called if the background task expires.
|
||||
* @return An identifier for the background task, or GDTBackgroundIdentifierInvalid if one couldn't
|
||||
* be created.
|
||||
* @return An identifier for the background task, or GDTCORBackgroundIdentifierInvalid if one
|
||||
* couldn't be created.
|
||||
*/
|
||||
- (GDTBackgroundIdentifier)beginBackgroundTaskWithExpirationHandler:
|
||||
- (GDTCORBackgroundIdentifier)beginBackgroundTaskWithExpirationHandler:
|
||||
(void (^__nullable)(void))handler;
|
||||
|
||||
/** Ends the background task if the identifier is valid.
|
||||
*
|
||||
* @param bgID The background task to end.
|
||||
*/
|
||||
- (void)endBackgroundTask:(GDTBackgroundIdentifier)bgID;
|
||||
- (void)endBackgroundTask:(GDTCORBackgroundIdentifier)bgID;
|
||||
|
||||
@end
|
||||
|
||||
+12
-12
@@ -16,39 +16,39 @@
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#import <GoogleDataTransport/GDTLifecycle.h>
|
||||
#import <GoogleDataTransport/GDTUploadPackage.h>
|
||||
#import <GoogleDataTransport/GDTCORLifecycle.h>
|
||||
#import <GoogleDataTransport/GDTCORUploadPackage.h>
|
||||
|
||||
@class GDTStoredEvent;
|
||||
@class GDTCORStoredEvent;
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
/** Options that define a set of upload conditions. This is used to help minimize end user data
|
||||
* consumption impact.
|
||||
*/
|
||||
typedef NS_OPTIONS(NSInteger, GDTUploadConditions) {
|
||||
typedef NS_OPTIONS(NSInteger, GDTCORUploadConditions) {
|
||||
|
||||
/** An upload shouldn't be attempted, because there's no network. */
|
||||
GDTUploadConditionNoNetwork = 1 << 0,
|
||||
GDTCORUploadConditionNoNetwork = 1 << 0,
|
||||
|
||||
/** An upload would likely use mobile data. */
|
||||
GDTUploadConditionMobileData = 1 << 1,
|
||||
GDTCORUploadConditionMobileData = 1 << 1,
|
||||
|
||||
/** An upload would likely use wifi data. */
|
||||
GDTUploadConditionWifiData = 1 << 2,
|
||||
GDTCORUploadConditionWifiData = 1 << 2,
|
||||
|
||||
/** An upload uses some sort of network connection, but it's unclear which. */
|
||||
GDTUploadConditionUnclearConnection = 1 << 3,
|
||||
GDTCORUploadConditionUnclearConnection = 1 << 3,
|
||||
|
||||
/** A high priority event has occurred. */
|
||||
GDTUploadConditionHighPriority = 1 << 4,
|
||||
GDTCORUploadConditionHighPriority = 1 << 4,
|
||||
};
|
||||
|
||||
/** This protocol defines the common interface of event prioritization. Prioritizers are
|
||||
* stateful objects that prioritize events upon insertion into storage and remain prepared to return
|
||||
* a set of filenames to the storage system.
|
||||
*/
|
||||
@protocol GDTPrioritizer <NSObject, GDTLifecycleProtocol, GDTUploadPackageProtocol>
|
||||
@protocol GDTCORPrioritizer <NSObject, GDTCORLifecycleProtocol, GDTCORUploadPackageProtocol>
|
||||
|
||||
@required
|
||||
|
||||
@@ -58,7 +58,7 @@ typedef NS_OPTIONS(NSInteger, GDTUploadConditions) {
|
||||
*
|
||||
* @param event The event to prioritize.
|
||||
*/
|
||||
- (void)prioritizeEvent:(GDTStoredEvent *)event;
|
||||
- (void)prioritizeEvent:(GDTCORStoredEvent *)event;
|
||||
|
||||
/** Returns a set of events to upload given a set of conditions.
|
||||
*
|
||||
@@ -66,7 +66,7 @@ typedef NS_OPTIONS(NSInteger, GDTUploadConditions) {
|
||||
* @return An object to be used by the uploader to determine file URLs to upload with respect to the
|
||||
* current conditions.
|
||||
*/
|
||||
- (GDTUploadPackage *)uploadPackageWithConditions:(GDTUploadConditions)conditions;
|
||||
- (GDTCORUploadPackage *)uploadPackageWithConditions:(GDTCORUploadConditions)conditions;
|
||||
|
||||
@end
|
||||
|
||||
+6
-6
@@ -16,14 +16,14 @@
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#import <GoogleDataTransport/GDTPrioritizer.h>
|
||||
#import <GoogleDataTransport/GDTTargets.h>
|
||||
#import <GoogleDataTransport/GDTUploader.h>
|
||||
#import <GoogleDataTransport/GDTCORPrioritizer.h>
|
||||
#import <GoogleDataTransport/GDTCORTargets.h>
|
||||
#import <GoogleDataTransport/GDTCORUploader.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
/** Manages the registration of targets with the transport SDK. */
|
||||
@interface GDTRegistrar : NSObject <GDTLifecycleProtocol>
|
||||
@interface GDTCORRegistrar : NSObject <GDTCORLifecycleProtocol>
|
||||
|
||||
/** Creates and/or returns the singleton instance.
|
||||
*
|
||||
@@ -36,14 +36,14 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
* @param backend The backend object to register.
|
||||
* @param target The target this backend object will be responsible for.
|
||||
*/
|
||||
- (void)registerUploader:(id<GDTUploader>)backend target:(GDTTarget)target;
|
||||
- (void)registerUploader:(id<GDTCORUploader>)backend target:(GDTCORTarget)target;
|
||||
|
||||
/** Registers a event prioritizer implementation with the GoogleDataTransport infrastructure.
|
||||
*
|
||||
* @param prioritizer The prioritizer object to register.
|
||||
* @param target The target this prioritizer object will be responsible for.
|
||||
*/
|
||||
- (void)registerPrioritizer:(id<GDTPrioritizer>)prioritizer target:(GDTTarget)target;
|
||||
- (void)registerPrioritizer:(id<GDTCORPrioritizer>)prioritizer target:(GDTCORTarget)target;
|
||||
|
||||
@end
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user