| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156 |
- // Copyright 2020 Google LLC
- //
- // Licensed under the Apache License, Version 2.0 (the "License");
- // you may not use this file except in compliance with the License.
- // You may obtain a copy of the License at
- //
- // http://www.apache.org/licenses/LICENSE-2.0
- //
- // Unless required by applicable law or agreed to in writing, software
- // distributed under the License is distributed on an "AS IS" BASIS,
- // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- // See the License for the specific language governing permissions and
- // limitations under the License.
- #import "FirebasePerformance/Sources/Public/FirebasePerformance/FIRPerformance.h"
- #import "FirebasePerformance/Sources/FIRPerformance+Internal.h"
- #import "FirebasePerformance/Sources/FIRPerformance_Private.h"
- #import "FirebasePerformance/Sources/Common/FPRConstants.h"
- #import "FirebasePerformance/Sources/Configurations/FPRConfigurations.h"
- #import "FirebasePerformance/Sources/FPRClient+Private.h"
- #import "FirebasePerformance/Sources/FPRClient.h"
- #import "FirebasePerformance/Sources/FPRConsoleLogger.h"
- #import "FirebasePerformance/Sources/FPRDataUtils.h"
- #import "FirebasePerformance/Sources/Instrumentation/FPRInstrumentation.h"
- #import "FirebasePerformance/Sources/Timer/FIRTrace+Internal.h"
- static NSString *const kFirebasePerfErrorDomain = @"com.firebase.perf";
- @implementation FIRPerformance
- #pragma mark - Public methods
- + (instancetype)sharedInstance {
- static FIRPerformance *firebasePerformance = nil;
- static dispatch_once_t onceToken;
- dispatch_once(&onceToken, ^{
- firebasePerformance = [[FIRPerformance alloc] init];
- });
- return firebasePerformance;
- }
- + (FIRTrace *)startTraceWithName:(NSString *)name {
- FIRTrace *trace = [[self sharedInstance] traceWithName:name];
- [trace start];
- return trace;
- }
- - (FIRTrace *)traceWithName:(NSString *)name {
- if (![self isPerfConfigured]) {
- FPRLogError(kFPRTraceNotCreated, @"Failed creating trace %@. Firebase is not configured.",
- name);
- [NSException raise:kFirebasePerfErrorDomain
- format:@"The default Firebase app has not yet been configured. Add [FirebaseApp "
- @"configure] to your application initialization."];
- return nil;
- }
- FIRTrace *trace = [[FIRTrace alloc] initWithName:name];
- return trace;
- }
- /**
- * Checks if the SDK has been successfully configured.
- *
- * @return YES if SDK is configured successfully, otherwise NO.
- */
- - (BOOL)isPerfConfigured {
- return self.fprClient.isConfigured;
- }
- #pragma mark - Internal methods
- - (instancetype)init {
- self = [super init];
- if (self) {
- _customAttributes = [[NSMutableDictionary<NSString *, NSString *> alloc] init];
- _customAttributesSerialQueue =
- dispatch_queue_create("com.google.perf.customAttributes", DISPATCH_QUEUE_SERIAL);
- _fprClient = [FPRClient sharedInstance];
- }
- return self;
- }
- - (BOOL)isDataCollectionEnabled {
- return [FPRConfigurations sharedInstance].isDataCollectionEnabled;
- }
- - (void)setDataCollectionEnabled:(BOOL)dataCollectionEnabled {
- [[FPRConfigurations sharedInstance] setDataCollectionEnabled:dataCollectionEnabled];
- }
- - (BOOL)isInstrumentationEnabled {
- return self.fprClient.isSwizzled || [FPRConfigurations sharedInstance].isInstrumentationEnabled;
- }
- - (void)setInstrumentationEnabled:(BOOL)instrumentationEnabled {
- [[FPRConfigurations sharedInstance] setInstrumentationEnabled:instrumentationEnabled];
- if (instrumentationEnabled) {
- [self.fprClient checkAndStartInstrumentation];
- } else {
- if (self.fprClient.isSwizzled) {
- FPRLogError(kFPRInstrumentationDisabledAfterConfigure,
- @"Failed to disable instrumentation because Firebase Performance has already "
- @"been configured. It will be disabled when the app restarts.");
- }
- }
- }
- #pragma mark - Custom attributes related methods
- - (NSDictionary<NSString *, NSString *> *)attributes {
- return [self.customAttributes copy];
- }
- - (void)setValue:(NSString *)value forAttribute:(nonnull NSString *)attribute {
- NSString *validatedName = FPRReservableAttributeName(attribute);
- NSString *validatedValue = FPRValidatedAttributeValue(value);
- BOOL canAddAttribute = YES;
- if (validatedName == nil) {
- FPRLogError(kFPRAttributeNoName,
- @"Failed to initialize because of a nil or zero length attribute name.");
- canAddAttribute = NO;
- }
- if (validatedValue == nil) {
- FPRLogError(kFPRAttributeNoValue,
- @"Failed to initialize because of a nil or zero length attribute value.");
- canAddAttribute = NO;
- }
- if (self.customAttributes.allKeys.count >= kFPRMaxGlobalCustomAttributesCount) {
- FPRLogError(kFPRMaxAttributesReached,
- @"Only %d attributes allowed. Already reached maximum attribute count.",
- kFPRMaxGlobalCustomAttributesCount);
- canAddAttribute = NO;
- }
- if (canAddAttribute) {
- // Ensure concurrency during update of attributes.
- dispatch_sync(self.customAttributesSerialQueue, ^{
- self.customAttributes[validatedName] = validatedValue;
- });
- }
- }
- - (NSString *)valueForAttribute:(NSString *)attribute {
- // TODO(b/175053654): Should this be happening on the serial queue for thread safety?
- return self.customAttributes[attribute];
- }
- - (void)removeAttribute:(NSString *)attribute {
- [self.customAttributes removeObjectForKey:attribute];
- }
- @end
|