| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258 |
- // 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.
- // Non-google3 relative import to support building with Xcode.
- #import "TracesViewController.h"
- #import "../Models/AccessibilityItem.h"
- #import "../Models/PerfLogger.h"
- #import "../Views/PerfTraceView+Accessibility.h"
- #import "../Views/PerfTraceView.h"
- #import "TracesViewController+Accessibility.h"
- #import "FirebasePerformance/Sources/Public/FirebasePerformance/FIRPerformance.h"
- /** Edge insets used by internal subviews. */
- static const CGFloat kEdgeInsetsTop = 10.0f;
- static const CGFloat kEdgeInsetsBottom = 10.0f;
- static const CGFloat kEdgeInsetsLeft = 20.0f;
- static const CGFloat kEdgeInsetsRight = 20.0f;
- @interface TracesViewController () <PerfTraceViewDelegate>
- /** The scroll view where all the PerfTraceViews are added. */
- @property(nonatomic) UIScrollView *contentView;
- /** Button to add a new PerfTraceView. */
- @property(nonatomic) UIButton *addTraceButton;
- /** A counter to maintain the number of traces created. Used for the unique names for traces. */
- @property(nonatomic, assign) NSInteger traceCounter;
- /** The most recently created PerfTraceView. */
- @property(nonatomic) PerfTraceView *recentTraceView;
- /**
- * The bottom constraint which manages the content size of the content view (UIScrollView). This is
- * usually the constraint of the most recently added PerfTraceView's bottom to be equal to the
- * bottom of the content view.
- */
- @property(nonatomic) NSLayoutConstraint *bottomConstraint;
- @end
- @implementation TracesViewController
- #pragma mark - View life cycle
- - (void)loadView {
- UIView *perfView = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
- perfView.backgroundColor = [UIColor whiteColor];
- self.view = perfView;
- [self createViewTree];
- [self constrainViews];
- }
- #pragma mark - Properties
- - (UIScrollView *)contentView {
- if (!_contentView) {
- _contentView = [[UIScrollView alloc] init];
- _contentView.translatesAutoresizingMaskIntoConstraints = NO;
- _contentView.backgroundColor = [UIColor whiteColor];
- _contentView.showsHorizontalScrollIndicator = NO;
- _contentView.showsVerticalScrollIndicator = YES;
- _contentView.accessibilityLabel = @"ContentView";
- }
- return _contentView;
- }
- - (UIButton *)addTraceButton {
- if (!_addTraceButton) {
- _addTraceButton = [[UIButton alloc] init];
- _addTraceButton.translatesAutoresizingMaskIntoConstraints = NO;
- [_addTraceButton setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
- [_addTraceButton setTitleColor:[UIColor lightGrayColor] forState:UIControlStateDisabled];
- _addTraceButton.titleLabel.font = [UIFont systemFontOfSize:12.0];
- _addTraceButton.contentEdgeInsets =
- UIEdgeInsetsMake(kEdgeInsetsTop, kEdgeInsetsLeft, kEdgeInsetsBottom, kEdgeInsetsRight);
- _addTraceButton.layer.cornerRadius = 3.0f;
- _addTraceButton.layer.borderColor = [[UIColor blackColor] CGColor];
- _addTraceButton.layer.borderWidth = 1.0f;
- [_addTraceButton setTitle:@"Add trace" forState:UIControlStateNormal];
- AccessibilityItem *item = [[self class] addTraceAccessibilityItem];
- _addTraceButton.accessibilityIdentifier = item.accessibilityID;
- _addTraceButton.accessibilityLabel = item.accessibilityLabel;
- [_addTraceButton addTarget:self
- action:@selector(createAndPositionNewTraceView:)
- forControlEvents:UIControlEventTouchDown];
- }
- return _addTraceButton;
- }
- #pragma mark - Private Methods
- #pragma mark - View hierarchy methods
- - (void)constrainViews {
- [self addConstraintsString:@"H:|-40-[_addTraceButton]-40-|"
- forViewsBinding:NSDictionaryOfVariableBindings(_addTraceButton)];
- [self addConstraintsString:@"V:|-60-[_addTraceButton(40)]-10-[_contentView]-|"
- forViewsBinding:NSDictionaryOfVariableBindings(_addTraceButton, _contentView)];
- [self addConstraintsString:@"H:|[_contentView]|"
- forViewsBinding:NSDictionaryOfVariableBindings(_contentView)];
- }
- - (void)addConstraintsString:(NSString *)string forViewsBinding:(NSDictionary *)viewsBinding {
- NSArray *constraints = [NSLayoutConstraint constraintsWithVisualFormat:string
- options:kNilOptions
- metrics:nil
- views:viewsBinding];
- [self.view addConstraints:constraints];
- }
- - (void)createViewTree {
- [self.view addSubview:self.contentView];
- [self.view addSubview:self.addTraceButton];
- }
- /**
- * Creates a new trace and adds a PerfTraceView in the view hierarchy.
- *
- * @param button Button that initiated the request.
- */
- - (void)createAndPositionNewTraceView:(UIButton *)button {
- PerfTraceView *traceView = [self createTraceView];
- if (!traceView) {
- NSLog(@"Trace creation disabled.");
- return;
- }
- [self.contentView addSubview:traceView];
- // Add constraints to position the new trace view at the bottom of the list of trace views.
- if (self.recentTraceView) {
- [self.contentView addConstraint:[NSLayoutConstraint constraintWithItem:self.recentTraceView
- attribute:NSLayoutAttributeTop
- relatedBy:NSLayoutRelationEqual
- toItem:traceView
- attribute:NSLayoutAttributeBottom
- multiplier:1.0f
- constant:10.0f]];
- [self.contentView addConstraint:[NSLayoutConstraint constraintWithItem:traceView
- attribute:NSLayoutAttributeLeft
- relatedBy:NSLayoutRelationEqual
- toItem:self.recentTraceView
- attribute:NSLayoutAttributeLeft
- multiplier:1.0f
- constant:0.0f]];
- [self.contentView addConstraint:[NSLayoutConstraint constraintWithItem:traceView
- attribute:NSLayoutAttributeRight
- relatedBy:NSLayoutRelationEqual
- toItem:self.recentTraceView
- attribute:NSLayoutAttributeRight
- multiplier:1.0f
- constant:0.0f]];
- } else {
- [self.contentView addConstraint:[NSLayoutConstraint constraintWithItem:self.contentView
- attribute:NSLayoutAttributeBottom
- relatedBy:NSLayoutRelationEqual
- toItem:traceView
- attribute:NSLayoutAttributeBottom
- multiplier:1.0
- constant:10.0f]];
- [self.contentView addConstraint:[NSLayoutConstraint constraintWithItem:traceView
- attribute:NSLayoutAttributeLeft
- relatedBy:NSLayoutRelationEqual
- toItem:self.contentView
- attribute:NSLayoutAttributeLeft
- multiplier:1.0f
- constant:10.0f]];
- [self.contentView addConstraint:[NSLayoutConstraint constraintWithItem:traceView
- attribute:NSLayoutAttributeRight
- relatedBy:NSLayoutRelationEqual
- toItem:self.contentView
- attribute:NSLayoutAttributeRight
- multiplier:1.0f
- constant:-10.0f]];
- }
- [self.contentView addConstraint:[NSLayoutConstraint constraintWithItem:traceView
- attribute:NSLayoutAttributeCenterX
- relatedBy:NSLayoutRelationEqual
- toItem:self.contentView
- attribute:NSLayoutAttributeCenterX
- multiplier:1.0f
- constant:0.0f]];
- if (self.bottomConstraint) {
- [self.contentView removeConstraint:self.bottomConstraint];
- }
- self.bottomConstraint = [NSLayoutConstraint constraintWithItem:traceView
- attribute:NSLayoutAttributeTop
- relatedBy:NSLayoutRelationEqual
- toItem:self.contentView
- attribute:NSLayoutAttributeTop
- multiplier:1.0f
- constant:10.0f];
- [self.contentView addConstraint:self.bottomConstraint];
- self.recentTraceView = traceView;
- }
- /**
- * Creates a new PerfTraceView object with a valid unique name and returns back the object.
- *
- * @return Instance of PerfTraceView.
- */
- - (PerfTraceView *)createTraceView {
- PerfLog(@"Create trace view");
- PerfTraceView *traceView = nil;
- NSString *traceName = [NSString stringWithFormat:@"Trace %ld", ++self.traceCounter];
- FIRTrace *trace = [[FIRPerformance sharedInstance] traceWithName:traceName];
- if (trace) {
- [trace start];
- traceView = [[PerfTraceView alloc] initWithTrace:trace frame:CGRectZero];
- traceView.accessibilityLabel = @"traceView";
- traceView.backgroundColor = [UIColor colorWithWhite:0.9f alpha:0.5f];
- traceView.translatesAutoresizingMaskIntoConstraints = NO;
- traceView.delegate = self;
- } else {
- --self.traceCounter;
- }
- return traceView;
- }
- #pragma mark - PerfTraceViewDelegate methods
- - (void)perfTraceViewTraceStopped:(PerfTraceView *)traceView {
- PerfLog(@"Stop trace");
- [traceView.trace stop];
- }
- @end
|