AutorÃa | Ultima modificación | Ver Log |
/*
* 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
#import "FirebaseCore/Sources/Private/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