mirror of
https://github.com/firebase/firebase-ios-sdk
synced 2026-11-09 22:36:01 +05:45
218 lines
9.5 KiB
Objective-C
218 lines
9.5 KiB
Objective-C
/*
|
|
* 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 <TargetConditionals.h>
|
|
#if TARGET_OS_IOS || TARGET_OS_TV || TARGET_OS_VISION
|
|
|
|
#import "FirebaseCore/Extension/FirebaseCoreInternal.h"
|
|
|
|
#import "FirebaseInAppMessaging/Sources/Analytics/FIRIAMClearcutLogStorage.h"
|
|
#import "FirebaseInAppMessaging/Sources/FIRCore+InAppMessaging.h"
|
|
#import "FirebaseInAppMessaging/Sources/Private/Analytics/FIRIAMClearcutLogger.h"
|
|
#import "FirebaseInAppMessaging/Sources/Private/Analytics/FIRIAMClearcutUploader.h"
|
|
|
|
@interface FIRIAMClearcutLogger ()
|
|
|
|
// these two writable for assisting unit testing need
|
|
@property(readwrite, nonatomic) FIRIAMClearcutHttpRequestSender *requestSender;
|
|
@property(readwrite, nonatomic) id<FIRIAMTimeFetcher> timeFetcher;
|
|
|
|
@property(readonly, nonatomic) FIRIAMClientInfoFetcher *clientInfoFetcher;
|
|
@property(readonly, nonatomic) FIRIAMClearcutUploader *ctUploader;
|
|
|
|
@property(readonly, copy, nonatomic) NSString *fbProjectNumber;
|
|
@property(readonly, copy, nonatomic) NSString *fbAppId;
|
|
|
|
@end
|
|
|
|
@implementation FIRIAMClearcutLogger {
|
|
// Firebase installations ID.
|
|
NSString *_FID;
|
|
}
|
|
- (instancetype)initWithFBProjectNumber:(NSString *)fbProjectNumber
|
|
fbAppId:(NSString *)fbAppId
|
|
clientInfoFetcher:(FIRIAMClientInfoFetcher *)clientInfoFetcher
|
|
usingTimeFetcher:(id<FIRIAMTimeFetcher>)timeFetcher
|
|
usingUploader:(FIRIAMClearcutUploader *)uploader {
|
|
if (self = [super init]) {
|
|
_fbProjectNumber = fbProjectNumber;
|
|
_fbAppId = fbAppId;
|
|
_clientInfoFetcher = clientInfoFetcher;
|
|
_timeFetcher = timeFetcher;
|
|
_ctUploader = uploader;
|
|
}
|
|
return self;
|
|
}
|
|
|
|
+ (void)updateSourceExtensionDictWithAnalyticsEventEnumType:(FIRIAMAnalyticsLogEventType)eventType
|
|
forDict:(NSMutableDictionary *)dict {
|
|
switch (eventType) {
|
|
case FIRIAMAnalyticsEventMessageImpression:
|
|
dict[@"event_type"] = @"IMPRESSION_EVENT_TYPE";
|
|
break;
|
|
case FIRIAMAnalyticsEventActionURLFollow:
|
|
dict[@"event_type"] = @"CLICK_EVENT_TYPE";
|
|
break;
|
|
case FIRIAMAnalyticsEventMessageDismissAuto:
|
|
dict[@"dismiss_type"] = @"AUTO";
|
|
break;
|
|
case FIRIAMAnalyticsEventMessageDismissClick:
|
|
dict[@"dismiss_type"] = @"CLICK";
|
|
break;
|
|
case FIRIAMAnalyticsEventMessageDismissSwipe:
|
|
dict[@"dismiss_type"] = @"SWIPE";
|
|
break;
|
|
case FIRIAMAnalyticsEventImageFetchError:
|
|
dict[@"render_error_reason"] = @"IMAGE_FETCH_ERROR";
|
|
break;
|
|
case FIRIAMAnalyticsEventImageFormatUnsupported:
|
|
dict[@"render_error_reason"] = @"IMAGE_UNSUPPORTED_FORMAT";
|
|
break;
|
|
case FIRIAMAnalyticsEventFetchAPIClientError:
|
|
dict[@"fetch_error_reason"] = @"CLIENT_ERROR";
|
|
break;
|
|
case FIRIAMAnalyticsEventFetchAPIServerError:
|
|
dict[@"fetch_error_reason"] = @"SERVER_ERROR";
|
|
break;
|
|
case FIRIAMAnalyticsEventFetchAPINetworkError:
|
|
dict[@"fetch_error_reason"] = @"NETWORK_ERROR";
|
|
break;
|
|
case FIRIAMAnalyticsEventTestMessageImpression:
|
|
dict[@"event_type"] = @"TEST_MESSAGE_IMPRESSION_EVENT_TYPE";
|
|
break;
|
|
case FIRIAMAnalyticsEventTestMessageClick:
|
|
dict[@"event_type"] = @"TEST_MESSAGE_CLICK_EVENT_TYPE";
|
|
break;
|
|
case FIRIAMAnalyticsLogEventUnknown:
|
|
break;
|
|
}
|
|
}
|
|
|
|
// constructing CampaignAnalytics proto defined in campaign_analytics.proto and serialize it into
|
|
// a string.
|
|
// @return nil if error happened
|
|
- (NSString *)constructSourceExtensionJsonForClearcutWithEventType:
|
|
(FIRIAMAnalyticsLogEventType)eventType
|
|
forCampaignID:(NSString *)campaignID
|
|
eventTimeInMs:(NSNumber *)eventTimeInMs
|
|
installationID:(NSString *)installationID {
|
|
NSMutableDictionary *campaignAnalyticsDict = [[NSMutableDictionary alloc] init];
|
|
|
|
campaignAnalyticsDict[@"project_number"] = self.fbProjectNumber;
|
|
campaignAnalyticsDict[@"campaign_id"] = campaignID;
|
|
campaignAnalyticsDict[@"client_app"] =
|
|
@{@"google_app_id" : self.fbAppId, @"firebase_instance_id" : installationID};
|
|
campaignAnalyticsDict[@"client_timestamp_millis"] = eventTimeInMs;
|
|
[self.class updateSourceExtensionDictWithAnalyticsEventEnumType:eventType
|
|
forDict:campaignAnalyticsDict];
|
|
|
|
campaignAnalyticsDict[@"fiam_sdk_version"] = [self.clientInfoFetcher getIAMSDKVersion];
|
|
|
|
// turn campaignAnalyticsDict into a json string
|
|
NSError *error;
|
|
NSData *jsonData = [NSJSONSerialization
|
|
dataWithJSONObject:campaignAnalyticsDict // Here you can pass array or dictionary
|
|
options:0 // Pass 0 if you don't care about the readability of the generated
|
|
// string
|
|
error:&error];
|
|
|
|
if (jsonData) {
|
|
NSString *jsonString;
|
|
jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
|
|
FIRLogDebug(kFIRLoggerInAppMessaging, @"I-IAM210006",
|
|
@"Source extension json string produced as %@", jsonString);
|
|
return jsonString;
|
|
} else {
|
|
FIRLogWarning(kFIRLoggerInAppMessaging, @"I-IAM210007",
|
|
@"Error in generating source extension json string: %@", error);
|
|
return nil;
|
|
}
|
|
}
|
|
|
|
- (void)logAnalyticsEventForType:(FIRIAMAnalyticsLogEventType)eventType
|
|
forCampaignID:(NSString *)campaignID
|
|
withEventTimeInMs:(nullable NSNumber *)eventTimeInMs
|
|
FID:(NSString *)FID
|
|
completion:(void (^)(BOOL success))completion {
|
|
NSTimeInterval nowInMs = [self.timeFetcher currentTimestampInSeconds] * 1000;
|
|
if (eventTimeInMs == nil) {
|
|
eventTimeInMs = @((long)nowInMs);
|
|
}
|
|
|
|
if (!FID) {
|
|
FIRLogWarning(kFIRLoggerInAppMessaging, @"I-IAM210009",
|
|
@"Instance ID is nil, event %ld for campaign ID %@ will not be sent",
|
|
(long)eventType, campaignID);
|
|
return;
|
|
}
|
|
|
|
NSString *sourceExtensionJsonString =
|
|
[self constructSourceExtensionJsonForClearcutWithEventType:eventType
|
|
forCampaignID:campaignID
|
|
eventTimeInMs:eventTimeInMs
|
|
installationID:FID];
|
|
|
|
FIRIAMClearcutLogRecord *newRecord = [[FIRIAMClearcutLogRecord alloc]
|
|
initWithExtensionJsonString:sourceExtensionJsonString
|
|
eventTimestampInSeconds:eventTimeInMs.integerValue / 1000];
|
|
[self.ctUploader addNewLogRecord:newRecord];
|
|
FIRLogDebug(kFIRLoggerInAppMessaging, @"I-IAM210003",
|
|
@"One more clearcut log record created and sent to uploader with source extension %@",
|
|
sourceExtensionJsonString);
|
|
completion(YES);
|
|
}
|
|
|
|
- (void)logAnalyticsEventForType:(FIRIAMAnalyticsLogEventType)eventType
|
|
forCampaignID:(NSString *)campaignID
|
|
withCampaignName:(NSString *)campaignName
|
|
eventTimeInMs:(nullable NSNumber *)eventTimeInMs
|
|
completion:(void (^)(BOOL success))completion {
|
|
if (!_FID) {
|
|
[self.clientInfoFetcher
|
|
fetchFirebaseInstallationDataWithProjectNumber:self.fbProjectNumber
|
|
withCompletion:^(NSString *_Nullable FID,
|
|
NSString *_Nullable FISToken,
|
|
NSError *_Nullable error) {
|
|
if (error) {
|
|
FIRLogWarning(
|
|
kFIRLoggerInAppMessaging, @"I-IAM210001",
|
|
@"Failed to get iid value for clearcut logging %@",
|
|
error);
|
|
completion(NO);
|
|
} else {
|
|
// persist FID through the whole life-cycle
|
|
self->_FID = FID;
|
|
[self logAnalyticsEventForType:eventType
|
|
forCampaignID:campaignID
|
|
withEventTimeInMs:eventTimeInMs
|
|
FID:FID
|
|
completion:completion];
|
|
}
|
|
}];
|
|
} else {
|
|
FIRLogDebug(kFIRLoggerInAppMessaging, @"I-IAM210004",
|
|
@"Using remembered iid for event logging");
|
|
[self logAnalyticsEventForType:eventType
|
|
forCampaignID:campaignID
|
|
withEventTimeInMs:eventTimeInMs
|
|
FID:_FID
|
|
completion:completion];
|
|
}
|
|
}
|
|
@end
|
|
|
|
#endif // TARGET_OS_IOS || TARGET_OS_TV || TARGET_OS_VISION
|