Proyectos de Subversion Iphone Microlearning

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 1
// Copyright 2019 Google
2
//
3
// Licensed under the Apache License, Version 2.0 (the "License");
4
// you may not use this file except in compliance with the License.
5
// You may obtain a copy of the License at
6
//
7
//      http://www.apache.org/licenses/LICENSE-2.0
8
//
9
// Unless required by applicable law or agreed to in writing, software
10
// distributed under the License is distributed on an "AS IS" BASIS,
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
// See the License for the specific language governing permissions and
13
// limitations under the License.
14
 
15
#include <stdatomic.h>
16
 
17
#if __has_include(<FBLPromises/FBLPromises.h>)
18
#import <FBLPromises/FBLPromises.h>
19
#else
20
#import "FBLPromises.h"
21
#endif
22
 
23
#include "Crashlytics/Crashlytics/Components/FIRCLSCrashedMarkerFile.h"
24
#include "Crashlytics/Crashlytics/Components/FIRCLSGlobals.h"
25
#import "Crashlytics/Crashlytics/Components/FIRCLSHost.h"
26
#include "Crashlytics/Crashlytics/Components/FIRCLSUserLogging.h"
27
#import "Crashlytics/Crashlytics/DataCollection/FIRCLSDataCollectionArbiter.h"
28
#import "Crashlytics/Crashlytics/DataCollection/FIRCLSDataCollectionToken.h"
29
#import "Crashlytics/Crashlytics/FIRCLSUserDefaults/FIRCLSUserDefaults.h"
30
#include "Crashlytics/Crashlytics/Handlers/FIRCLSException.h"
31
#import "Crashlytics/Crashlytics/Helpers/FIRCLSDefines.h"
32
#include "Crashlytics/Crashlytics/Helpers/FIRCLSProfiling.h"
33
#include "Crashlytics/Crashlytics/Helpers/FIRCLSUtility.h"
34
#import "Crashlytics/Crashlytics/Models/FIRCLSFileManager.h"
35
#import "Crashlytics/Crashlytics/Models/FIRCLSSettings.h"
36
#import "Crashlytics/Crashlytics/Settings/Models/FIRCLSApplicationIdentifierModel.h"
37
 
38
#import "Crashlytics/Crashlytics/Helpers/FIRCLSLogger.h"
39
#import "Crashlytics/Shared/FIRCLSByteUtility.h"
40
#import "Crashlytics/Shared/FIRCLSConstants.h"
41
#import "Crashlytics/Shared/FIRCLSFABHost.h"
42
 
43
#import "Crashlytics/Crashlytics/Controllers/FIRCLSAnalyticsManager.h"
44
#import "Crashlytics/Crashlytics/Controllers/FIRCLSExistingReportManager.h"
45
#import "Crashlytics/Crashlytics/Controllers/FIRCLSManagerData.h"
46
#import "Crashlytics/Crashlytics/Controllers/FIRCLSNotificationManager.h"
47
#import "Crashlytics/Crashlytics/Controllers/FIRCLSReportManager.h"
48
#import "Crashlytics/Crashlytics/Controllers/FIRCLSReportUploader.h"
49
#import "Crashlytics/Crashlytics/Private/FIRCLSExistingReportManager_Private.h"
50
#import "Crashlytics/Crashlytics/Private/FIRCLSOnDemandModel_Private.h"
51
#import "Crashlytics/Crashlytics/Private/FIRExceptionModel_Private.h"
52
 
53
#import "FirebaseCore/Sources/Private/FirebaseCoreInternal.h"
54
#import "FirebaseInstallations/Source/Library/Private/FirebaseInstallationsInternal.h"
55
#import "Interop/Analytics/Public/FIRAnalyticsInterop.h"
56
 
57
#import <GoogleDataTransport/GoogleDataTransport.h>
58
 
59
#if TARGET_OS_IPHONE
60
#import <UIKit/UIKit.h>
61
#endif
62
 
63
FIRCLSContext _firclsContext;
64
dispatch_queue_t _firclsLoggingQueue;
65
dispatch_queue_t _firclsBinaryImageQueue;
66
dispatch_queue_t _firclsExceptionQueue;
67
 
68
static atomic_bool _hasInitializedInstance;
69
 
70
NSString *const FIRCLSGoogleTransportMappingID = @"1206";
71
 
72
/// Empty protocol to register with FirebaseCore's component system.
73
@protocol FIRCrashlyticsInstanceProvider <NSObject>
74
@end
75
 
76
@interface FIRCrashlytics () <FIRLibrary, FIRCrashlyticsInstanceProvider>
77
 
78
@property(nonatomic) BOOL didPreviouslyCrash;
79
@property(nonatomic, copy) NSString *googleAppID;
80
@property(nonatomic) FIRCLSDataCollectionArbiter *dataArbiter;
81
@property(nonatomic) FIRCLSFileManager *fileManager;
82
 
83
@property(nonatomic) FIRCLSReportManager *reportManager;
84
 
85
@property(nonatomic) FIRCLSReportUploader *reportUploader;
86
 
87
@property(nonatomic, strong) FIRCLSExistingReportManager *existingReportManager;
88
 
89
@property(nonatomic, strong) FIRCLSAnalyticsManager *analyticsManager;
90
 
91
// Dependencies common to each of the Controllers
92
@property(nonatomic, strong) FIRCLSManagerData *managerData;
93
 
94
@end
95
 
96
@implementation FIRCrashlytics
97
 
98
#pragma mark - Singleton Support
99
 
100
- (instancetype)initWithApp:(FIRApp *)app
101
                    appInfo:(NSDictionary *)appInfo
102
              installations:(FIRInstallations *)installations
103
                  analytics:(id<FIRAnalyticsInterop>)analytics {
104
  self = [super init];
105
 
106
  if (self) {
107
    bool expectedCalled = NO;
108
    if (!atomic_compare_exchange_strong(&_hasInitializedInstance, &expectedCalled, YES)) {
109
      FIRCLSErrorLog(@"Cannot instantiate more than one instance of Crashlytics.");
110
      return nil;
111
    }
112
 
113
    FIRCLSProfileMark mark = FIRCLSProfilingStart();
114
 
115
    NSLog(@"[Firebase/Crashlytics] Version %@", FIRCLSSDKVersion());
116
 
117
    FIRCLSDeveloperLog("Crashlytics", @"Running on %@, %@ (%@)", FIRCLSHostModelInfo(),
118
                       FIRCLSHostOSDisplayVersion(), FIRCLSHostOSBuildVersion());
119
 
120
    GDTCORTransport *googleTransport =
121
        [[GDTCORTransport alloc] initWithMappingID:FIRCLSGoogleTransportMappingID
122
                                      transformers:nil
123
                                            target:kGDTCORTargetCSH];
124
 
125
    _fileManager = [[FIRCLSFileManager alloc] init];
126
    _googleAppID = app.options.googleAppID;
127
    _dataArbiter = [[FIRCLSDataCollectionArbiter alloc] initWithApp:app withAppInfo:appInfo];
128
 
129
    FIRCLSApplicationIdentifierModel *appModel = [[FIRCLSApplicationIdentifierModel alloc] init];
130
    FIRCLSSettings *settings = [[FIRCLSSettings alloc] initWithFileManager:_fileManager
131
                                                                appIDModel:appModel];
132
 
133
    FIRCLSOnDemandModel *onDemandModel =
134
        [[FIRCLSOnDemandModel alloc] initWithFIRCLSSettings:settings];
135
    _managerData = [[FIRCLSManagerData alloc] initWithGoogleAppID:_googleAppID
136
                                                  googleTransport:googleTransport
137
                                                    installations:installations
138
                                                        analytics:analytics
139
                                                      fileManager:_fileManager
140
                                                      dataArbiter:_dataArbiter
141
                                                         settings:settings
142
                                                    onDemandModel:onDemandModel];
143
 
144
    _reportUploader = [[FIRCLSReportUploader alloc] initWithManagerData:_managerData];
145
 
146
    _existingReportManager =
147
        [[FIRCLSExistingReportManager alloc] initWithManagerData:_managerData
148
                                                  reportUploader:_reportUploader];
149
 
150
    _analyticsManager = [[FIRCLSAnalyticsManager alloc] initWithAnalytics:analytics];
151
 
152
    _reportManager = [[FIRCLSReportManager alloc] initWithManagerData:_managerData
153
                                                existingReportManager:_existingReportManager
154
                                                     analyticsManager:_analyticsManager];
155
 
156
    _didPreviouslyCrash = [_fileManager didCrashOnPreviousExecution];
157
    // Process did crash during previous execution
158
    if (_didPreviouslyCrash) {
159
      // Delete the crash file marker in the background ensure start up is as fast as possible
160
      dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
161
        NSString *crashedMarkerFileFullPath = [[self.fileManager rootPath]
162
            stringByAppendingPathComponent:[NSString
163
                                               stringWithUTF8String:FIRCLSCrashedMarkerFileName]];
164
        [self.fileManager removeItemAtPath:crashedMarkerFileFullPath];
165
      });
166
    }
167
 
168
    [[[_reportManager startWithProfilingMark:mark] then:^id _Nullable(NSNumber *_Nullable value) {
169
      if (![value boolValue]) {
170
        FIRCLSErrorLog(@"Crash reporting could not be initialized");
171
      }
172
      return value;
173
    }] catch:^void(NSError *error) {
174
      FIRCLSErrorLog(@"Crash reporting failed to initialize with error: %@", error);
175
    }];
176
  }
177
 
178
  return self;
179
}
180
 
181
+ (void)load {
182
  [FIRApp registerInternalLibrary:(Class<FIRLibrary>)self withName:@"firebase-crashlytics"];
183
}
184
 
185
+ (NSArray<FIRComponent *> *)componentsToRegister {
186
  FIRDependency *analyticsDep =
187
      [FIRDependency dependencyWithProtocol:@protocol(FIRAnalyticsInterop)];
188
 
189
  FIRComponentCreationBlock creationBlock =
190
      ^id _Nullable(FIRComponentContainer *container, BOOL *isCacheable) {
191
    if (!container.app.isDefaultApp) {
192
      FIRCLSErrorLog(@"Crashlytics must be used with the default Firebase app.");
193
      return nil;
194
    }
195
 
196
    id<FIRAnalyticsInterop> analytics = FIR_COMPONENT(FIRAnalyticsInterop, container);
197
 
198
    FIRInstallations *installations = [FIRInstallations installationsWithApp:container.app];
199
 
200
    *isCacheable = YES;
201
 
202
    return [[FIRCrashlytics alloc] initWithApp:container.app
203
                                       appInfo:NSBundle.mainBundle.infoDictionary
204
                                 installations:installations
205
                                     analytics:analytics];
206
  };
207
 
208
  FIRComponent *component =
209
      [FIRComponent componentWithProtocol:@protocol(FIRCrashlyticsInstanceProvider)
210
                      instantiationTiming:FIRInstantiationTimingEagerInDefaultApp
211
                             dependencies:@[ analyticsDep ]
212
                            creationBlock:creationBlock];
213
  return @[ component ];
214
}
215
 
216
+ (instancetype)crashlytics {
217
  // The container will return the same instance since isCacheable is set
218
 
219
  FIRApp *defaultApp = [FIRApp defaultApp];  // Missing configure will be logged here.
220
 
221
  // Get the instance from the `FIRApp`'s container. This will create a new instance the
222
  // first time it is called, and since `isCacheable` is set in the component creation
223
  // block, it will return the existing instance on subsequent calls.
224
  id<FIRCrashlyticsInstanceProvider> instance =
225
      FIR_COMPONENT(FIRCrashlyticsInstanceProvider, defaultApp.container);
226
 
227
  // In the component creation block, we return an instance of `FIRCrashlytics`. Cast it and
228
  // return it.
229
  return (FIRCrashlytics *)instance;
230
}
231
 
232
- (void)setCrashlyticsCollectionEnabled:(BOOL)enabled {
233
  [self.dataArbiter setCrashlyticsCollectionEnabled:enabled];
234
}
235
 
236
- (BOOL)isCrashlyticsCollectionEnabled {
237
  return [self.dataArbiter isCrashlyticsCollectionEnabled];
238
}
239
 
240
#pragma mark - API: didCrashDuringPreviousExecution
241
 
242
- (BOOL)didCrashDuringPreviousExecution {
243
  return self.didPreviouslyCrash;
244
}
245
 
246
- (void)processDidCrashDuringPreviousExecution {
247
  NSString *crashedMarkerFileName = [NSString stringWithUTF8String:FIRCLSCrashedMarkerFileName];
248
  NSString *crashedMarkerFileFullPath =
249
      [[self.fileManager rootPath] stringByAppendingPathComponent:crashedMarkerFileName];
250
  self.didPreviouslyCrash = [self.fileManager fileExistsAtPath:crashedMarkerFileFullPath];
251
 
252
  if (self.didPreviouslyCrash) {
253
    // Delete the crash file marker in the background ensure start up is as fast as possible
254
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
255
      [self.fileManager removeItemAtPath:crashedMarkerFileFullPath];
256
    });
257
  }
258
}
259
 
260
#pragma mark - API: Logging
261
- (void)log:(NSString *)msg {
262
  FIRCLSLog(@"%@", msg);
263
}
264
 
265
- (void)logWithFormat:(NSString *)format, ... {
266
  va_list args;
267
  va_start(args, format);
268
  [self logWithFormat:format arguments:args];
269
  va_end(args);
270
}
271
 
272
- (void)logWithFormat:(NSString *)format arguments:(va_list)args {
273
  [self log:[[NSString alloc] initWithFormat:format arguments:args]];
274
}
275
 
276
#pragma mark - API: Accessors
277
 
278
- (void)checkForUnsentReportsWithCompletion:(void (^)(BOOL))completion {
279
  [[self.reportManager checkForUnsentReports]
280
      then:^id _Nullable(FIRCrashlyticsReport *_Nullable value) {
281
        completion(value ? true : false);
282
        return nil;
283
      }];
284
}
285
 
286
- (void)checkAndUpdateUnsentReportsWithCompletion:
287
    (void (^)(FIRCrashlyticsReport *_Nonnull))completion {
288
  [[self.reportManager checkForUnsentReports]
289
      then:^id _Nullable(FIRCrashlyticsReport *_Nullable value) {
290
        completion(value);
291
        return nil;
292
      }];
293
}
294
 
295
- (void)sendUnsentReports {
296
  [self.reportManager sendUnsentReports];
297
}
298
 
299
- (void)deleteUnsentReports {
300
  [self.reportManager deleteUnsentReports];
301
}
302
 
303
#pragma mark - API: setUserID
304
- (void)setUserID:(nullable NSString *)userID {
305
  FIRCLSUserLoggingRecordInternalKeyValue(FIRCLSUserIdentifierKey, userID);
306
}
307
 
308
#pragma mark - API: setCustomValue
309
 
310
- (void)setCustomValue:(nullable id)value forKey:(NSString *)key {
311
  FIRCLSUserLoggingRecordUserKeyValue(key, value);
312
}
313
 
314
- (void)setCustomKeysAndValues:(NSDictionary *)keysAndValues {
315
  FIRCLSUserLoggingRecordUserKeysAndValues(keysAndValues);
316
}
317
 
318
#pragma mark - API: Development Platform
319
// These two methods are depercated by our own API, so
320
// its ok to implement them
321
#pragma clang diagnostic push
322
#pragma clang diagnostic ignored "-Wdeprecated-implementations"
323
+ (void)setDevelopmentPlatformName:(NSString *)name {
324
  [[self crashlytics] setDevelopmentPlatformName:name];
325
}
326
 
327
+ (void)setDevelopmentPlatformVersion:(NSString *)version {
328
  [[self crashlytics] setDevelopmentPlatformVersion:version];
329
}
330
#pragma clang diagnostic pop
331
 
332
- (NSString *)developmentPlatformName {
333
  FIRCLSErrorLog(@"developmentPlatformName is write-only");
334
  return nil;
335
}
336
 
337
- (void)setDevelopmentPlatformName:(NSString *)developmentPlatformName {
338
  FIRCLSUserLoggingRecordInternalKeyValue(FIRCLSDevelopmentPlatformNameKey,
339
                                          developmentPlatformName);
340
}
341
 
342
- (NSString *)developmentPlatformVersion {
343
  FIRCLSErrorLog(@"developmentPlatformVersion is write-only");
344
  return nil;
345
}
346
 
347
- (void)setDevelopmentPlatformVersion:(NSString *)developmentPlatformVersion {
348
  FIRCLSUserLoggingRecordInternalKeyValue(FIRCLSDevelopmentPlatformVersionKey,
349
                                          developmentPlatformVersion);
350
}
351
 
352
#pragma mark - API: Errors and Exceptions
353
- (void)recordError:(NSError *)error {
354
  FIRCLSUserLoggingRecordError(error, nil);
355
}
356
 
357
- (void)recordExceptionModel:(FIRExceptionModel *)exceptionModel {
358
  FIRCLSExceptionRecordModel(exceptionModel);
359
}
360
 
361
- (void)recordOnDemandExceptionModel:(FIRExceptionModel *)exceptionModel {
362
  [self.managerData.onDemandModel
363
      recordOnDemandExceptionIfQuota:exceptionModel
364
           withDataCollectionEnabled:[self.dataArbiter isCrashlyticsCollectionEnabled]
365
          usingExistingReportManager:self.existingReportManager];
366
}
367
 
368
@end