Skip to content

Commit

Permalink
Merge branch 'JimRoepcke-customize-visibility'
Browse files Browse the repository at this point in the history
  • Loading branch information
krzysztofzablocki committed Oct 25, 2017
2 parents 26c9029 + f6d8e6d commit 3741239
Show file tree
Hide file tree
Showing 6 changed files with 101 additions and 4 deletions.
2 changes: 1 addition & 1 deletion LifetimeTracker.podspec
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = "LifetimeTracker"
s.version = "1.0.9"
s.version = "1.1.0"
s.summary = "Framework to visually warn you when retain cycle / leak happens."
s.description = <<-DESC
Mini framework that can surface retain cycle issues sooner.
Expand Down
8 changes: 8 additions & 0 deletions LifetimeTracker.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@
objects = {

/* Begin PBXBuildFile section */
383869131F9FEE7800B1A6AB /* VisibilityTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 383869121F9FEE7800B1A6AB /* VisibilityTests.swift */; };
383869141F9FEE7E00B1A6AB /* VisibilityTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 383869121F9FEE7800B1A6AB /* VisibilityTests.swift */; };
383869151F9FEE7F00B1A6AB /* VisibilityTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 383869121F9FEE7800B1A6AB /* VisibilityTests.swift */; };
52D6D9871BEFF229002C0205 /* LifetimeTracker.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 52D6D97C1BEFF229002C0205 /* LifetimeTracker.framework */; };
8933C7851EB5B820000D00A4 /* LifetimeTracker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8933C7841EB5B820000D00A4 /* LifetimeTracker.swift */; };
8933C7861EB5B820000D00A4 /* LifetimeTracker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8933C7841EB5B820000D00A4 /* LifetimeTracker.swift */; };
Expand Down Expand Up @@ -51,6 +54,7 @@
/* End PBXContainerItemProxy section */

/* Begin PBXFileReference section */
383869121F9FEE7800B1A6AB /* VisibilityTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = VisibilityTests.swift; sourceTree = "<group>"; };
52D6D97C1BEFF229002C0205 /* LifetimeTracker.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = LifetimeTracker.framework; sourceTree = BUILT_PRODUCTS_DIR; };
52D6D9861BEFF229002C0205 /* LifetimeTracker-iOS Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "LifetimeTracker-iOS Tests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; };
52D6D9E21BEFFF6E002C0205 /* LifetimeTracker.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = LifetimeTracker.framework; sourceTree = BUILT_PRODUCTS_DIR; };
Expand Down Expand Up @@ -172,6 +176,7 @@
isa = PBXGroup;
children = (
8933C7891EB5B82A000D00A4 /* LifetimeTrackerTests.swift */,
383869121F9FEE7800B1A6AB /* VisibilityTests.swift */,
);
name = Tests;
path = Tests/LifetimeTrackerTests;
Expand Down Expand Up @@ -495,6 +500,7 @@
buildActionMask = 2147483647;
files = (
8933C7901EB5B82D000D00A4 /* LifetimeTrackerTests.swift in Sources */,
383869131F9FEE7800B1A6AB /* VisibilityTests.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down Expand Up @@ -530,6 +536,7 @@
buildActionMask = 2147483647;
files = (
8933C78F1EB5B82C000D00A4 /* LifetimeTrackerTests.swift in Sources */,
383869141F9FEE7E00B1A6AB /* VisibilityTests.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand All @@ -538,6 +545,7 @@
buildActionMask = 2147483647;
files = (
8933C78E1EB5B82C000D00A4 /* LifetimeTrackerTests.swift in Sources */,
383869151F9FEE7F00B1A6AB /* VisibilityTests.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,12 @@ To Integrate visual notifications simply add following line at the start of `App

```swift
#if DEBUG
LifetimeTracker.setup(onUpdate: LifetimeTrackerDashboardIntegration().refreshUI)
LifetimeTracker.setup(onUpdate: LifetimeTrackerDashboardIntegration(visibility: .visibleWithIssuesDetected).refreshUI)
#endif
```

You can control when the dashboard is visible: `alwaysVisible`, `alwaysHidden`, or `visibleWithIssuesDetected`.

## Tracking key actors

Usually you want to use LifetimeTracker to track only key actors in your app, like ViewModels / Controllers etc.
Expand Down
29 changes: 27 additions & 2 deletions Sources/LifetimeTracker+DashboardView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -45,11 +45,29 @@ public final class LifetimeTrackerDashboardIntegration {
return window
}()

public init() {}
public enum Visibility {
case alwaysHidden
case alwaysVisible
case visibleWithIssuesDetected

func windowIsHidden(hasIssuesToDisplay: Bool) -> Bool {
switch self {
case .alwaysHidden: return true
case .alwaysVisible: return false
case .visibleWithIssuesDetected: return !hasIssuesToDisplay
}
}
}

public var visibility: Visibility

public init(visibility: Visibility = .alwaysVisible) {
self.visibility = visibility
}

public func refreshUI(counts: [String: LifetimeTracker.Entry], fullEntries: [String: LifetimeTracker.Entry]) {
DispatchQueue.main.async {
self.window.isHidden = false
self.window.isHidden = self.visibility.windowIsHidden(hasIssuesToDisplay: counts.hasIssuesToDisplay)
let vm = DashboardViewModel(summary: self.summary(from: counts), entries: self.entries(from: fullEntries))
self.vc.update(with: vm)
}
Expand Down Expand Up @@ -84,3 +102,10 @@ public final class LifetimeTrackerDashboardIntegration {
}
}
}

extension Dictionary where Key == String, Value == LifetimeTracker.Entry {
var hasIssuesToDisplay: Bool {
let aDetectedIssue = keys.first { self[$0]?.shouldDisplay == true }
return aDetectedIssue != nil
}
}
61 changes: 61 additions & 0 deletions Tests/LifetimeTrackerTests/VisibilityTests.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
//
// VisibilityTests.swift
// LifetimeTracker
//
// Created by Jim Roepcke on 2017-10-24.
// Copyright © 2017 LifetimeTracker. All rights reserved.
//

import Foundation
import XCTest
@testable import LifetimeTracker

private typealias Visibility = LifetimeTrackerDashboardIntegration.Visibility

class VisibilityTests: XCTestCase {

func testHidesWindowWhenBehaviorIsAlwaysHiddenAndThereAreNoIssuesToDisplay() {
let behavior = Visibility.alwaysHidden
let hasIssuesToDisplay = false
XCTAssertTrue(behavior.windowIsHidden(hasIssuesToDisplay: hasIssuesToDisplay))
}

func testHidesWindowWhenBehaviorIsAlwaysHiddenAndThereAreIssuesToDisplay() {
let behavior = Visibility.alwaysHidden
let hasIssuesToDisplay = true
XCTAssertTrue(behavior.windowIsHidden(hasIssuesToDisplay: hasIssuesToDisplay))
}

func testDoesNotHideWindowWhenBehaviorIsAlwaysVisibleAndThereAreNoIssuesToDisplay() {
let behavior = Visibility.alwaysVisible
let hasIssuesToDisplay = false
XCTAssertFalse(behavior.windowIsHidden(hasIssuesToDisplay: hasIssuesToDisplay))
}

func testDoesNotHideWindowWhenBehaviorIsAlwaysVisibleAndThereAreIssuesToDisplay() {
let behavior = Visibility.alwaysVisible
let hasIssuesToDisplay = true
XCTAssertFalse(behavior.windowIsHidden(hasIssuesToDisplay: hasIssuesToDisplay))
}

func testHidesWindowWhenBehaviorIsVisibleWithIssuesDetectedAndThereAreNoIssuesToDisplay() {
let behavior = Visibility.visibleWithIssuesDetected
let hasIssuesToDisplay = false
XCTAssertTrue(behavior.windowIsHidden(hasIssuesToDisplay: hasIssuesToDisplay))
}

func testDoesNotHideWindowWhenBehaviorIsVisibleWithIssuesDetectedAndThereAreIssuesToDisplay() {
let behavior = Visibility.visibleWithIssuesDetected
let hasIssuesToDisplay = true
XCTAssertFalse(behavior.windowIsHidden(hasIssuesToDisplay: hasIssuesToDisplay))
}

static var allTests = [
("testHidesWindowWhenBehaviorIsAlwaysHiddenAndThereAreNoIssuesToDisplay", testHidesWindowWhenBehaviorIsAlwaysHiddenAndThereAreNoIssuesToDisplay),
("testHidesWindowWhenBehaviorIsAlwaysHiddenAndThereAreIssuesToDisplay", testHidesWindowWhenBehaviorIsAlwaysHiddenAndThereAreIssuesToDisplay),
("testDoesNotHideWindowWhenBehaviorIsAlwaysVisibleAndThereAreNoIssuesToDisplay", testDoesNotHideWindowWhenBehaviorIsAlwaysVisibleAndThereAreNoIssuesToDisplay),
("testDoesNotHideWindowWhenBehaviorIsAlwaysVisibleAndThereAreIssuesToDisplay", testDoesNotHideWindowWhenBehaviorIsAlwaysVisibleAndThereAreIssuesToDisplay),
("testHidesWindowWhenBehaviorIsVisibleWithIssuesDetectedAndThereAreNoIssuesToDisplay", testHidesWindowWhenBehaviorIsVisibleWithIssuesDetectedAndThereAreNoIssuesToDisplay),
("testDoesNotHideWindowWhenBehaviorIsVisibleWithIssuesDetectedAndThereAreIssuesToDisplay", testDoesNotHideWindowWhenBehaviorIsVisibleWithIssuesDetectedAndThereAreIssuesToDisplay),
]
}
1 change: 1 addition & 0 deletions Tests/LinuxMain.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ import XCTest

XCTMain([
testCase(LifetimeTrackerTests.allTests),
testCase(VisibilityTests.allTests),
])

0 comments on commit 3741239

Please sign in to comment.