├── .gitignore
├── performance_view.PNG
├── performance_view_2.PNG
├── performance_view_3.PNG
├── performance_view_4.PNG
├── GDPerformanceView.xcodeproj
├── xcuserdata
│ ├── Daniil.xcuserdatad
│ │ ├── xcdebugger
│ │ │ └── Breakpoints_v2.xcbkptlist
│ │ └── xcschemes
│ │ │ ├── xcschememanagement.plist
│ │ │ └── FSPerfomanceView.xcscheme
│ └── daniilmbox.xcuserdatad
│ │ ├── xcdebugger
│ │ └── Breakpoints_v2.xcbkptlist
│ │ └── xcschemes
│ │ ├── xcschememanagement.plist
│ │ └── GDPerformanceView.xcscheme
├── project.xcworkspace
│ ├── xcuserdata
│ │ └── daniilmbox.xcuserdatad
│ │ │ └── UserInterfaceState.xcuserstate
│ └── contents.xcworkspacedata
└── project.pbxproj
├── .github
└── FUNDING.yml
├── GDPerformanceView.podspec
├── LICENSE
├── GDPerformanceView
├── GDPerformanceMonitoring
│ ├── GDMarginLabel.h
│ ├── GDPerformanceMonitorProtocol.h
│ ├── GDWindowViewController.h
│ ├── GDMarginLabel.m
│ ├── GDWindowViewController.m
│ ├── GDPerformanceView.h
│ ├── GDPerformanceMonitor.h
│ ├── GDPerformanceMonitor.m
│ └── GDPerformanceView.m
├── AppDelegate.h
├── main.m
├── Info.plist
├── Base.lproj
│ ├── LaunchScreen.storyboard
│ └── Main.storyboard
├── Assets.xcassets
│ └── AppIcon.appiconset
│ │ └── Contents.json
└── AppDelegate.m
└── README.md
/.gitignore:
--------------------------------------------------------------------------------
1 | # Xcode
2 | .DS_Store
3 | build/
4 | DerivedData
5 | .idea/
--------------------------------------------------------------------------------
/performance_view.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dani-gavrilov/GDPerformanceView/HEAD/performance_view.PNG
--------------------------------------------------------------------------------
/performance_view_2.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dani-gavrilov/GDPerformanceView/HEAD/performance_view_2.PNG
--------------------------------------------------------------------------------
/performance_view_3.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dani-gavrilov/GDPerformanceView/HEAD/performance_view_3.PNG
--------------------------------------------------------------------------------
/performance_view_4.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dani-gavrilov/GDPerformanceView/HEAD/performance_view_4.PNG
--------------------------------------------------------------------------------
/GDPerformanceView.xcodeproj/xcuserdata/Daniil.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
--------------------------------------------------------------------------------
/GDPerformanceView.xcodeproj/xcuserdata/daniilmbox.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
--------------------------------------------------------------------------------
/GDPerformanceView.xcodeproj/project.xcworkspace/xcuserdata/daniilmbox.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dani-gavrilov/GDPerformanceView/HEAD/GDPerformanceView.xcodeproj/project.xcworkspace/xcuserdata/daniilmbox.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/GDPerformanceView.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/GDPerformanceView.xcodeproj/xcuserdata/Daniil.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | FSPerfomanceView.xcscheme
8 |
9 | orderHint
10 | 0
11 |
12 |
13 | SuppressBuildableAutocreation
14 |
15 | A5C8CEBD1DB6203D008D8E15
16 |
17 | primary
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/GDPerformanceView.xcodeproj/xcuserdata/daniilmbox.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | GDPerformanceView.xcscheme
8 |
9 | orderHint
10 | 0
11 |
12 |
13 | SuppressBuildableAutocreation
14 |
15 | A5C8CEBD1DB6203D008D8E15
16 |
17 | primary
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | # These are supported funding model platforms
2 |
3 | github: ['dani-gavrilov']
4 | # patreon: # Replace with a single Patreon username
5 | # open_collective: # Replace with a single Open Collective username
6 | # ko_fi: # Replace with a single Ko-fi username
7 | # tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
8 | # community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
9 | # liberapay: # Replace with a single Liberapay username
10 | # issuehunt: # Replace with a single IssueHunt username
11 | # otechie: # Replace with a single Otechie username
12 | # custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
13 |
--------------------------------------------------------------------------------
/GDPerformanceView.podspec:
--------------------------------------------------------------------------------
1 | Pod::Spec.new do |s|
2 | s.name = "GDPerformanceView"
3 | s.version = "1.3.1"
4 | s.summary = "Shows FPS, CPU usage, app and iOS versions above the status bar and report FPS and CPU usage via delegate."
5 | s.homepage = "https://github.com/dani-gavrilov/GDPerformanceView"
6 | s.license = { :type => "MIT", :file => "LICENSE" }
7 | s.author = { "Gavrilov Daniil" => "daniilmbox@gmail.com" }
8 | s.platform = :ios, "8.0"
9 | s.ios.deployment_target = "8.0"
10 | s.source = { :git => "https://github.com/dani-gavrilov/GDPerformanceView.git", :tag => "1.3.1" }
11 | s.source_files = "GDPerformanceView/GDPerformanceMonitoring/*"
12 | s.frameworks = "UIKit", "Foundation", "QuartzCore"
13 | s.requires_arc = true
14 | end
15 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2016 Gavrilov Daniil
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/GDPerformanceView/GDPerformanceMonitoring/GDMarginLabel.h:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright © 2017 Gavrilov Daniil
3 | //
4 | // Permission is hereby granted, free of charge, to any person obtaining a copy
5 | // of this software and associated documentation files (the "Software"), to deal
6 | // in the Software without restriction, including without limitation the rights
7 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | // copies of the Software, and to permit persons to whom the Software is
9 | // furnished to do so, subject to the following conditions:
10 | //
11 | // The above copyright notice and this permission notice shall be included in
12 | // all copies or substantial portions of the Software.
13 | //
14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | // THE SOFTWARE.
21 | //
22 |
23 | #import
24 |
25 | @interface GDMarginLabel : UILabel
26 |
27 | @end
28 |
--------------------------------------------------------------------------------
/GDPerformanceView/AppDelegate.h:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright © 2017 Gavrilov Daniil
3 | //
4 | // Permission is hereby granted, free of charge, to any person obtaining a copy
5 | // of this software and associated documentation files (the "Software"), to deal
6 | // in the Software without restriction, including without limitation the rights
7 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | // copies of the Software, and to permit persons to whom the Software is
9 | // furnished to do so, subject to the following conditions:
10 | //
11 | // The above copyright notice and this permission notice shall be included in
12 | // all copies or substantial portions of the Software.
13 | //
14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | // THE SOFTWARE.
21 | //
22 |
23 | #import
24 |
25 | @interface AppDelegate : UIResponder
26 |
27 | @property (strong, nonatomic) UIWindow *window;
28 |
29 | @end
30 |
31 |
--------------------------------------------------------------------------------
/GDPerformanceView/GDPerformanceMonitoring/GDPerformanceMonitorProtocol.h:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright © 2017 Gavrilov Daniil
3 | //
4 | // Permission is hereby granted, free of charge, to any person obtaining a copy
5 | // of this software and associated documentation files (the "Software"), to deal
6 | // in the Software without restriction, including without limitation the rights
7 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | // copies of the Software, and to permit persons to whom the Software is
9 | // furnished to do so, subject to the following conditions:
10 | //
11 | // The above copyright notice and this permission notice shall be included in
12 | // all copies or substantial portions of the Software.
13 | //
14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | // THE SOFTWARE.
21 | //
22 |
23 | #import
24 |
25 | @protocol GDPerformanceMonitorDelegate
26 |
27 | - (void)performanceMonitorDidReportFPS:(int)fpsValue CPU:(float)cpuValue;
28 |
29 | @end
30 |
--------------------------------------------------------------------------------
/GDPerformanceView/main.m:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright © 2017 Gavrilov Daniil
3 | //
4 | // Permission is hereby granted, free of charge, to any person obtaining a copy
5 | // of this software and associated documentation files (the "Software"), to deal
6 | // in the Software without restriction, including without limitation the rights
7 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | // copies of the Software, and to permit persons to whom the Software is
9 | // furnished to do so, subject to the following conditions:
10 | //
11 | // The above copyright notice and this permission notice shall be included in
12 | // all copies or substantial portions of the Software.
13 | //
14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | // THE SOFTWARE.
21 | //
22 |
23 | #import
24 | #import "AppDelegate.h"
25 |
26 | int main(int argc, char * argv[]) {
27 | @autoreleasepool {
28 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/GDPerformanceView/GDPerformanceMonitoring/GDWindowViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright © 2017 Gavrilov Daniil
3 | //
4 | // Permission is hereby granted, free of charge, to any person obtaining a copy
5 | // of this software and associated documentation files (the "Software"), to deal
6 | // in the Software without restriction, including without limitation the rights
7 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | // copies of the Software, and to permit persons to whom the Software is
9 | // furnished to do so, subject to the following conditions:
10 | //
11 | // The above copyright notice and this permission notice shall be included in
12 | // all copies or substantial portions of the Software.
13 | //
14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | // THE SOFTWARE.
21 | //
22 |
23 | #import
24 |
25 | @interface GDWindowViewController : UIViewController
26 |
27 | - (void)configureStatusBarAppearanceWithPrefersStatusBarHidden:(BOOL)prefersStatusBarHidden preferredStatusBarStyle:(UIStatusBarStyle)preferredStatusBarStyle;
28 |
29 | @end
30 |
--------------------------------------------------------------------------------
/GDPerformanceView/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | 1.3.1
19 | CFBundleVersion
20 | 1
21 | LSRequiresIPhoneOS
22 |
23 | UILaunchStoryboardName
24 | LaunchScreen
25 | UIMainStoryboardFile
26 | Main
27 | UIRequiredDeviceCapabilities
28 |
29 | armv7
30 |
31 | UISupportedInterfaceOrientations
32 |
33 | UIInterfaceOrientationPortrait
34 | UIInterfaceOrientationLandscapeLeft
35 | UIInterfaceOrientationLandscapeRight
36 | UIInterfaceOrientationPortraitUpsideDown
37 |
38 | UISupportedInterfaceOrientations~ipad
39 |
40 | UIInterfaceOrientationPortrait
41 | UIInterfaceOrientationPortraitUpsideDown
42 | UIInterfaceOrientationLandscapeLeft
43 | UIInterfaceOrientationLandscapeRight
44 |
45 |
46 |
47 |
--------------------------------------------------------------------------------
/GDPerformanceView/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/GDPerformanceView/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "20x20",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "20x20",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "29x29",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "29x29",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "40x40",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "40x40",
31 | "scale" : "3x"
32 | },
33 | {
34 | "idiom" : "iphone",
35 | "size" : "60x60",
36 | "scale" : "2x"
37 | },
38 | {
39 | "idiom" : "iphone",
40 | "size" : "60x60",
41 | "scale" : "3x"
42 | },
43 | {
44 | "idiom" : "ipad",
45 | "size" : "20x20",
46 | "scale" : "1x"
47 | },
48 | {
49 | "idiom" : "ipad",
50 | "size" : "20x20",
51 | "scale" : "2x"
52 | },
53 | {
54 | "idiom" : "ipad",
55 | "size" : "29x29",
56 | "scale" : "1x"
57 | },
58 | {
59 | "idiom" : "ipad",
60 | "size" : "29x29",
61 | "scale" : "2x"
62 | },
63 | {
64 | "idiom" : "ipad",
65 | "size" : "40x40",
66 | "scale" : "1x"
67 | },
68 | {
69 | "idiom" : "ipad",
70 | "size" : "40x40",
71 | "scale" : "2x"
72 | },
73 | {
74 | "idiom" : "ipad",
75 | "size" : "76x76",
76 | "scale" : "1x"
77 | },
78 | {
79 | "idiom" : "ipad",
80 | "size" : "76x76",
81 | "scale" : "2x"
82 | },
83 | {
84 | "idiom" : "ipad",
85 | "size" : "83.5x83.5",
86 | "scale" : "2x"
87 | }
88 | ],
89 | "info" : {
90 | "version" : 1,
91 | "author" : "xcode"
92 | }
93 | }
--------------------------------------------------------------------------------
/GDPerformanceView/GDPerformanceMonitoring/GDMarginLabel.m:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright © 2017 Gavrilov Daniil
3 | //
4 | // Permission is hereby granted, free of charge, to any person obtaining a copy
5 | // of this software and associated documentation files (the "Software"), to deal
6 | // in the Software without restriction, including without limitation the rights
7 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | // copies of the Software, and to permit persons to whom the Software is
9 | // furnished to do so, subject to the following conditions:
10 | //
11 | // The above copyright notice and this permission notice shall be included in
12 | // all copies or substantial portions of the Software.
13 | //
14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | // THE SOFTWARE.
21 | //
22 |
23 | #import "GDMarginLabel.h"
24 |
25 | @interface GDMarginLabel ()
26 |
27 | @property (nonatomic, assign) UIEdgeInsets edgeInsets;
28 |
29 | @end
30 |
31 | @implementation GDMarginLabel
32 |
33 | #pragma mark -
34 | #pragma mark - Init Methods & Superclass Overriders
35 |
36 | - (id)initWithFrame:(CGRect)frame {
37 | self = [super initWithFrame:frame];
38 | if (self) {
39 | self.edgeInsets = UIEdgeInsetsMake(0.0f, 5.0f, 0.0f, 5.0f);
40 | }
41 | return self;
42 | }
43 |
44 | - (void)drawTextInRect:(CGRect)rect {
45 | [super drawTextInRect:UIEdgeInsetsInsetRect(rect, self.edgeInsets)];
46 | }
47 |
48 | - (CGSize)intrinsicContentSize {
49 | CGSize size = [super intrinsicContentSize];
50 | size.width += self.edgeInsets.left + self.edgeInsets.right;
51 | size.height += self.edgeInsets.top + self.edgeInsets.bottom;
52 | return size;
53 | }
54 |
55 | - (CGSize)sizeThatFits:(CGSize)size {
56 | CGSize sizeThatFits = [super sizeThatFits:size];
57 | sizeThatFits.width += self.edgeInsets.left + self.edgeInsets.right;
58 | sizeThatFits.height += self.edgeInsets.top + self.edgeInsets.bottom;
59 | return sizeThatFits;
60 | }
61 |
62 | @end
63 |
--------------------------------------------------------------------------------
/GDPerformanceView/GDPerformanceMonitoring/GDWindowViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright © 2017 Gavrilov Daniil
3 | //
4 | // Permission is hereby granted, free of charge, to any person obtaining a copy
5 | // of this software and associated documentation files (the "Software"), to deal
6 | // in the Software without restriction, including without limitation the rights
7 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | // copies of the Software, and to permit persons to whom the Software is
9 | // furnished to do so, subject to the following conditions:
10 | //
11 | // The above copyright notice and this permission notice shall be included in
12 | // all copies or substantial portions of the Software.
13 | //
14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | // THE SOFTWARE.
21 | //
22 |
23 | #import "GDWindowViewController.h"
24 |
25 | @interface GDWindowViewController ()
26 |
27 | @property (nonatomic) BOOL selectedStatusBarHidden;
28 |
29 | @property (nonatomic) UIStatusBarStyle selectedStatusBarStyle;
30 |
31 | @end
32 |
33 | @implementation GDWindowViewController
34 |
35 | #pragma mark -
36 | #pragma mark - Init Methods & Superclass Overriders
37 |
38 | - (instancetype)init {
39 | self = [super init];
40 | if (self) {
41 | [self setSelectedStatusBarHidden:NO];
42 | [self setSelectedStatusBarStyle:UIStatusBarStyleDefault];
43 | }
44 | return self;
45 | }
46 |
47 | - (void)viewDidLoad {
48 | [super viewDidLoad];
49 |
50 | [self.view setBackgroundColor:[UIColor clearColor]];
51 | }
52 |
53 | - (void)didReceiveMemoryWarning {
54 | [super didReceiveMemoryWarning];
55 | }
56 |
57 | - (BOOL)prefersStatusBarHidden {
58 | return self.selectedStatusBarHidden;
59 | }
60 |
61 | - (UIStatusBarStyle)preferredStatusBarStyle {
62 | return self.selectedStatusBarStyle;
63 | }
64 |
65 | #pragma mark -
66 | #pragma mark - Public Methods
67 |
68 | - (void)configureStatusBarAppearanceWithPrefersStatusBarHidden:(BOOL)prefersStatusBarHidden preferredStatusBarStyle:(UIStatusBarStyle)preferredStatusBarStyle {
69 | self.selectedStatusBarHidden = prefersStatusBarHidden;
70 | self.selectedStatusBarStyle = preferredStatusBarStyle;
71 | }
72 |
73 | @end
74 |
--------------------------------------------------------------------------------
/GDPerformanceView/GDPerformanceMonitoring/GDPerformanceView.h:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright © 2017 Gavrilov Daniil
3 | //
4 | // Permission is hereby granted, free of charge, to any person obtaining a copy
5 | // of this software and associated documentation files (the "Software"), to deal
6 | // in the Software without restriction, including without limitation the rights
7 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | // copies of the Software, and to permit persons to whom the Software is
9 | // furnished to do so, subject to the following conditions:
10 | //
11 | // The above copyright notice and this permission notice shall be included in
12 | // all copies or substantial portions of the Software.
13 | //
14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | // THE SOFTWARE.
21 | //
22 |
23 | #import
24 |
25 | #import "GDPerformanceMonitorProtocol.h"
26 |
27 | @interface GDPerformanceView : UIWindow
28 |
29 | /**
30 | GDPerformanceMonitorDelegate delegate.
31 | */
32 | @property (nonatomic, weak) id performanceDelegate;
33 |
34 | /**
35 | Change it to hide or show application version from monitoring view. Default is NO.
36 | */
37 | @property (nonatomic, getter=isAppVersionHidden) BOOL appVersionHidden;
38 |
39 | /**
40 | Change it to hide or show device iOS version from monitoring view. Default is NO.
41 | */
42 | @property (nonatomic, getter=isDeviceVersionHidden) BOOL deviceVersionHidden;
43 |
44 | /**
45 | Override this properties to return the desired status bar attributes.
46 |
47 | Default prefersStatusBarHidden is false, preferredStatusBarStyle is UIStatusBarStyle.default.
48 | */
49 | @property (nonatomic) BOOL prefersStatusBarHidden;
50 |
51 | @property (nonatomic) UIStatusBarStyle preferredStatusBarStyle;
52 |
53 |
54 | /**
55 | Returns weak monitoring text label.
56 | */
57 | - (UILabel *)textLabel;
58 |
59 | /**
60 | Pauses performance monitoring and hides monitoring view.
61 | */
62 | - (void)pauseMonitoring;
63 |
64 | /**
65 | Resumes performance monitoring and shows monitoring view.
66 | */
67 | - (void)resumeMonitoringAndShowMonitoringView:(BOOL)showMonitoringView;
68 |
69 | /**
70 | Hides monitoring view.
71 | */
72 | - (void)hideMonitoring;
73 |
74 | /**
75 | Adds monitoring view above the status bar.
76 | */
77 | - (void)addMonitoringViewAboveStatusBar;
78 |
79 | /**
80 | Configures root view controller with prefersStatusBarHidden and preferredStatusBarStyle.
81 | */
82 | - (void)configureRootViewController;
83 |
84 | /**
85 | Stops and removes monitoring view. Call when you're done with performance monitoring.
86 | */
87 | - (void)stopMonitoring;
88 |
89 | @end
90 |
--------------------------------------------------------------------------------
/GDPerformanceView/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/GDPerformanceView/GDPerformanceMonitoring/GDPerformanceMonitor.h:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright © 2017 Gavrilov Daniil
3 | //
4 | // Permission is hereby granted, free of charge, to any person obtaining a copy
5 | // of this software and associated documentation files (the "Software"), to deal
6 | // in the Software without restriction, including without limitation the rights
7 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | // copies of the Software, and to permit persons to whom the Software is
9 | // furnished to do so, subject to the following conditions:
10 | //
11 | // The above copyright notice and this permission notice shall be included in
12 | // all copies or substantial portions of the Software.
13 | //
14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | // THE SOFTWARE.
21 | //
22 |
23 | #import
24 |
25 | #import "GDPerformanceMonitorProtocol.h"
26 |
27 | @class UILabel;
28 |
29 | @interface GDPerformanceMonitor : NSObject
30 |
31 | /**
32 | GDPerformanceMonitorDelegate delegate.
33 | */
34 | @property (nonatomic, weak) id delegate;
35 |
36 | /**
37 | Change it to hide or show application version from monitoring view. Default is NO.
38 | */
39 | @property (nonatomic, getter=isAppVersionHidden) BOOL appVersionHidden;
40 |
41 | /**
42 | Change it to hide or show device iOS version from monitoring view. Default is NO.
43 | */
44 | @property (nonatomic, getter=isDeviceVersionHidden) BOOL deviceVersionHidden;
45 |
46 |
47 | /**
48 | Creates and returns instance of GDPerformanceMonitor, as singleton.
49 | */
50 | + (instancetype)sharedInstance;
51 |
52 | /**
53 | Creates and returns instance of GDPerformanceMonitor.
54 | */
55 | - (instancetype)init NS_DESIGNATED_INITIALIZER;
56 |
57 | /**
58 | Overrides prefersStatusBarHidden and preferredStatusBarStyle properties to return the desired status bar attributes.
59 |
60 | Default prefersStatusBarHidden is NO, preferredStatusBarStyle is UIStatusBarStyleDefault.
61 | */
62 | - (void)configureStatusBarAppearanceWithPrefersStatusBarHidden:(BOOL)prefersStatusBarHidden preferredStatusBarStyle:(NSInteger)preferredStatusBarStyle;
63 |
64 | /**
65 | Starts or resumes performance monitoring, initialize monitoring view if not initialized and shows monitoring view. Use configuration block to change appearance as you like.
66 | */
67 | - (void)startMonitoringWithConfiguration:(void (^)(UILabel *textLabel))configuration;
68 |
69 | /**
70 | Starts or resumes performance monitoring, initialize monitoring view if not initialized and shows monitoring view.
71 | */
72 | - (void)startMonitoring;
73 |
74 | /**
75 | Pauses performance monitoring and hides monitoring view.
76 | */
77 | - (void)pauseMonitoring;
78 |
79 | /**
80 | Hides monitoring view.
81 | */
82 | - (void)hideMonitoring;
83 |
84 | /**
85 | Stops and removes monitoring view. Call when you're done with performance monitoring.
86 | */
87 | - (void)stopMonitoring;
88 |
89 | /**
90 | Use configuration block to change appearance as you like.
91 | */
92 | - (void)configureWithConfiguration:(void (^)(UILabel *textLabel))configuration;
93 |
94 | @end
95 |
--------------------------------------------------------------------------------
/GDPerformanceView/AppDelegate.m:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright © 2017 Gavrilov Daniil
3 | //
4 | // Permission is hereby granted, free of charge, to any person obtaining a copy
5 | // of this software and associated documentation files (the "Software"), to deal
6 | // in the Software without restriction, including without limitation the rights
7 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | // copies of the Software, and to permit persons to whom the Software is
9 | // furnished to do so, subject to the following conditions:
10 | //
11 | // The above copyright notice and this permission notice shall be included in
12 | // all copies or substantial portions of the Software.
13 | //
14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | // THE SOFTWARE.
21 | //
22 |
23 | #import "AppDelegate.h"
24 |
25 | #import "GDPerformanceMonitor.h"
26 |
27 | @interface AppDelegate ()
28 |
29 | @end
30 |
31 | @implementation AppDelegate
32 |
33 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
34 | // Override point for customization after application launch.
35 |
36 | #ifdef DEBUG
37 | [[GDPerformanceMonitor sharedInstance] startMonitoring];
38 | [[GDPerformanceMonitor sharedInstance] configureWithConfiguration:^(UILabel *textLabel) {
39 | [textLabel setBackgroundColor:[UIColor blackColor]];
40 | [textLabel setTextColor:[UIColor whiteColor]];
41 | [textLabel.layer setBorderColor:[[UIColor blackColor] CGColor]];
42 | }];
43 | #endif
44 |
45 | return YES;
46 | }
47 |
48 | - (void)applicationWillResignActive:(UIApplication *)application {
49 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
50 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.
51 | }
52 |
53 | - (void)applicationDidEnterBackground:(UIApplication *)application {
54 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
55 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
56 | }
57 |
58 | - (void)applicationWillEnterForeground:(UIApplication *)application {
59 | // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
60 | }
61 |
62 | - (void)applicationDidBecomeActive:(UIApplication *)application {
63 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
64 | }
65 |
66 | - (void)applicationWillTerminate:(UIApplication *)application {
67 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
68 |
69 | #ifdef DEBUG
70 | [[GDPerformanceMonitor sharedInstance] stopMonitoring];
71 | #endif
72 |
73 | }
74 |
75 | @end
76 |
--------------------------------------------------------------------------------
/GDPerformanceView.xcodeproj/xcuserdata/Daniil.xcuserdatad/xcschemes/FSPerfomanceView.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
39 |
40 |
41 |
42 |
43 |
44 |
54 |
56 |
62 |
63 |
64 |
65 |
66 |
67 |
73 |
75 |
81 |
82 |
83 |
84 |
86 |
87 |
90 |
91 |
92 |
--------------------------------------------------------------------------------
/GDPerformanceView.xcodeproj/xcuserdata/daniilmbox.xcuserdatad/xcschemes/GDPerformanceView.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
39 |
40 |
41 |
42 |
43 |
44 |
54 |
56 |
62 |
63 |
64 |
65 |
66 |
67 |
73 |
75 |
81 |
82 |
83 |
84 |
86 |
87 |
90 |
91 |
92 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | #GDPerformanceView
2 | Shows FPS, CPU usage, app and iOS versions above the status bar and report FPS and CPU usage via delegate.
3 |
4 | [](https://cocoapods.org/)
5 | 
6 | 
7 | 
8 | 
9 |
10 | 
11 | 
12 | 
13 | 
14 |
15 | ## Installation
16 | Simply add GDPerformanceMonitoring folder with files to your project, or use CocoaPods.
17 |
18 | #### Podfile
19 | You can use [CocoaPods](http://cocoapods.org/) to install `GDPerformanceView` by adding it to your `Podfile`:
20 |
21 | ```ruby
22 | platform :ios, '8.0'
23 | use_frameworks!
24 |
25 | target 'project_name' do
26 | pod 'GDPerformanceView', '~> 1.3.1'
27 | end
28 | ```
29 | Don't forget to import GDPerformanceView by adding:
30 |
31 | ```objective-c
32 | #import
33 | ```
34 |
35 | ## Usage example
36 |
37 | Simply start monitoring. Performance view will be added above the status bar automatically.
38 | Also, you can configure appearance as you like or just hide the monitoring view and use its delegate.
39 |
40 | #### Start monitoring
41 |
42 | Call to start or resume monitoring and show monitoring view.
43 |
44 | ```objective-c
45 | [[GDPerformanceMonitor sharedInstance] startMonitoring];
46 | ```
47 |
48 | ```objective-c
49 | self.performanceMonitor = [GDPerformanceMonitor alloc] init];
50 | [self.performanceMonitor startMonitoring];
51 | ```
52 |
53 | #### Stop monitoring
54 |
55 | Call when you're done with performance monitoring.
56 |
57 | ```objective-c
58 | [self.performanceMonitor stopMonitoring];
59 | ```
60 |
61 | Call to hide and pause monitoring.
62 |
63 | ```objective-c
64 | [self.performanceMonitor pauseMonitoring];
65 | ```
66 |
67 | #### Configuration
68 |
69 | Call to change appearance.
70 |
71 | ```objective-c
72 | [self.performanceMonitor configureWithConfiguration:^(UILabel *textLabel) {
73 | [textLabel setBackgroundColor:[UIColor blackColor]];
74 | [textLabel setTextColor:[UIColor whiteColor]];
75 | [textLabel.layer setBorderColor:[[UIColor blackColor] CGColor]];
76 | }];
77 | ```
78 |
79 | Call to change output information.
80 |
81 | ```objective-c
82 | [self.performanceMonitor setAppVersionHidden:YES]
83 | ```
84 | ```objective-c
85 | [self.performanceMonitor setDeviceVersionHidden:YES];
86 | ```
87 |
88 | Call to hide monitoring view.
89 |
90 | ```objective-c
91 | [self.performanceMonitor hideMonitoring];
92 | ```
93 |
94 | Call to change status bar appearance.
95 |
96 | ```objective-c
97 | [self.performanceMonitor configureStatusBarAppearanceWithPrefersStatusBarHidden:NO preferredStatusBarStyle:UIStatusBarStyleLightContent];
98 | ```
99 |
100 | #### Start monitoring and configure
101 |
102 | ```objective-c
103 | [self.performanceMonitor startMonitoringWithConfiguration:^(UILabel *textLabel) {
104 | [textLabel setBackgroundColor:[UIColor blackColor]];
105 | [textLabel setTextColor:[UIColor whiteColor]];
106 | [textLabel.layer setBorderColor:[[UIColor blackColor] CGColor]];
107 | }];
108 | ```
109 |
110 | #### Delegate
111 |
112 | Set the delegate and implement its method.
113 |
114 | ```objective-c
115 | [self.performanceMonitor setDelegate:self];
116 | ```
117 |
118 | ```objective-c
119 | - (void)performanceMonitorDidReportFPS:(int)fpsValue CPU:(float)cpuValue {
120 | NSLog(@"%d %f", fpsValue, cpuValue);
121 | }
122 | ```
123 |
124 | ## Requirements
125 | - iOS 8.0+
126 | - xCode 8.2+
127 |
128 | ## Meta
129 |
130 | Daniil Gavrilov - [VK](https://vk.com/dani_gavrilov) - [FB](https://www.facebook.com/danigavrilov)
131 |
132 | GDPerformanceView is available under the MIT license. See the LICENSE file for more info.
133 |
--------------------------------------------------------------------------------
/GDPerformanceView/GDPerformanceMonitoring/GDPerformanceMonitor.m:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright © 2017 Gavrilov Daniil
3 | //
4 | // Permission is hereby granted, free of charge, to any person obtaining a copy
5 | // of this software and associated documentation files (the "Software"), to deal
6 | // in the Software without restriction, including without limitation the rights
7 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | // copies of the Software, and to permit persons to whom the Software is
9 | // furnished to do so, subject to the following conditions:
10 | //
11 | // The above copyright notice and this permission notice shall be included in
12 | // all copies or substantial portions of the Software.
13 | //
14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | // THE SOFTWARE.
21 | //
22 |
23 | #import "GDPerformanceMonitor.h"
24 |
25 | #import "GDPerformanceView.h"
26 |
27 | @interface GDPerformanceMonitor ()
28 |
29 | @property (nonatomic, strong) GDPerformanceView *performanceView;
30 |
31 | @property (nonatomic, getter=isPerformanceViewPaused) BOOL performanceViewPaused;
32 |
33 | @property (nonatomic, getter=isPerformanceViewHidden) BOOL performanceViewHidden;
34 |
35 | @property (nonatomic, getter=isPerformanceViewStopped) BOOL performanceViewStopped;
36 |
37 | @property (nonatomic) BOOL prefersStatusBarHidden;
38 |
39 | @property (nonatomic) UIStatusBarStyle preferredStatusBarStyle;
40 |
41 | @end
42 |
43 | @implementation GDPerformanceMonitor
44 |
45 | #pragma mark -
46 | #pragma mark - Init Methods & Superclass Overriders
47 |
48 | + (instancetype)sharedInstance {
49 | static id instance;
50 | static dispatch_once_t onceToken;
51 | dispatch_once(&onceToken, ^ {
52 | instance = [[self alloc] init];
53 | });
54 | return instance;
55 | }
56 |
57 | - (instancetype)init {
58 | self = [super init];
59 | if (self) {
60 | [self subscribeToNotifications];
61 | }
62 | return self;
63 | }
64 |
65 | - (void)dealloc {
66 | [[NSNotificationCenter defaultCenter] removeObserver:self];
67 | }
68 |
69 | #pragma mark -
70 | #pragma mark - Notifications & Observers
71 |
72 | - (void)applicationDidBecomeActive:(NSNotification *)notification {
73 | if (self.isPerformanceViewPaused) {
74 | return;
75 | }
76 |
77 | [self startOrResumeMonitoring];
78 | }
79 |
80 | - (void)applicationWillResignActive:(NSNotification *)notification {
81 | [self.performanceView pauseMonitoring];
82 | }
83 |
84 | #pragma mark -
85 | #pragma mark - Public Methods
86 |
87 | - (void)configureStatusBarAppearanceWithPrefersStatusBarHidden:(BOOL)prefersStatusBarHidden preferredStatusBarStyle:(NSInteger)preferredStatusBarStyle {
88 | self.prefersStatusBarHidden = prefersStatusBarHidden;
89 | self.preferredStatusBarStyle = preferredStatusBarStyle;
90 |
91 | [self checkAndApplyStatusBarAppearanceWithPrefersStatusBarHidden:prefersStatusBarHidden preferredStatusBarStyle:preferredStatusBarStyle];
92 | }
93 |
94 | - (void)startMonitoringWithConfiguration:(void (^)(UILabel *))configuration {
95 | self.performanceViewPaused = NO;
96 | self.performanceViewHidden = NO;
97 | self.performanceViewStopped = NO;
98 |
99 | [self startOrResumeMonitoring];
100 |
101 | if (configuration) {
102 | UILabel *textLabel = [self.performanceView textLabel];
103 | configuration(textLabel);
104 | }
105 | }
106 |
107 | - (void)startMonitoring {
108 | self.performanceViewPaused = NO;
109 | self.performanceViewHidden = NO;
110 | self.performanceViewStopped = NO;
111 |
112 | [self startOrResumeMonitoring];
113 | }
114 |
115 | - (void)pauseMonitoring {
116 | self.performanceViewPaused = YES;
117 |
118 | [self.performanceView pauseMonitoring];
119 | }
120 |
121 | - (void)hideMonitoring {
122 | self.performanceViewHidden = YES;
123 |
124 | [self.performanceView hideMonitoring];
125 | }
126 |
127 | - (void)stopMonitoring {
128 | self.performanceViewStopped = YES;
129 |
130 | [self.performanceView stopMonitoring];
131 | self.performanceView = nil;
132 | }
133 |
134 | - (void)configureWithConfiguration:(void (^)(UILabel *))configuration {
135 | if (!self.performanceView) {
136 | return;
137 | }
138 |
139 | if (configuration) {
140 | UILabel *textLabel = [self.performanceView textLabel];
141 | configuration(textLabel);
142 | }
143 | }
144 |
145 | #pragma mark -
146 | #pragma mark - Private Methods
147 |
148 | #pragma mark - Default Setups
149 |
150 | - (void)subscribeToNotifications {
151 | [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationDidBecomeActive:) name:UIApplicationDidBecomeActiveNotification object:nil];
152 | [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationWillResignActive:) name:UIApplicationWillResignActiveNotification object:nil];
153 | }
154 |
155 | #pragma mark - Monitoring
156 |
157 | - (void)startOrResumeMonitoring {
158 | if (!self.performanceView) {
159 | [self setupPerformanceView];
160 | } else {
161 | [self.performanceView resumeMonitoringAndShowMonitoringView:!self.isPerformanceViewHidden];
162 | }
163 |
164 | if ([[UIApplication sharedApplication] applicationState] == UIApplicationStateActive) {
165 | [self.performanceView addMonitoringViewAboveStatusBar];
166 | }
167 | }
168 |
169 | - (void)setupPerformanceView {
170 | if (self.isPerformanceViewStopped) {
171 | return;
172 | }
173 |
174 | self.performanceView = [[GDPerformanceView alloc] init];
175 | [self.performanceView setAppVersionHidden:self.appVersionHidden];
176 | [self.performanceView setDeviceVersionHidden:self.deviceVersionHidden];
177 | [self.performanceView setPerformanceDelegate:self.delegate];
178 | [self checkAndApplyStatusBarAppearanceWithPrefersStatusBarHidden:self.prefersStatusBarHidden preferredStatusBarStyle:self.preferredStatusBarStyle];
179 |
180 | if (self.isPerformanceViewPaused) {
181 | [self.performanceView pauseMonitoring];
182 | }
183 | if (self.isPerformanceViewHidden) {
184 | [self.performanceView hideMonitoring];
185 | }
186 | }
187 |
188 | #pragma mark - Other Methods
189 |
190 | - (void)checkAndApplyStatusBarAppearanceWithPrefersStatusBarHidden:(BOOL)prefersStatusBarHidden preferredStatusBarStyle:(UIStatusBarStyle)preferredStatusBarStyle {
191 | if (!self.performanceView) {
192 | return;
193 | }
194 |
195 | if (self.performanceView.prefersStatusBarHidden != prefersStatusBarHidden || self.performanceView.preferredStatusBarStyle != preferredStatusBarStyle) {
196 | self.performanceView.prefersStatusBarHidden = prefersStatusBarHidden;
197 | self.performanceView.preferredStatusBarStyle = preferredStatusBarStyle;
198 |
199 | [self.performanceView configureRootViewController];
200 | }
201 | }
202 |
203 | #pragma mark -
204 | #pragma mark - Setters & Getters
205 |
206 | - (void)setDelegate:(id)delegate {
207 | _delegate = delegate;
208 |
209 | [self.performanceView setPerformanceDelegate:delegate];
210 | }
211 |
212 | - (void)setAppVersionHidden:(BOOL)appVersionHidden {
213 | _appVersionHidden = appVersionHidden;
214 |
215 | if (self.performanceView) {
216 | [self.performanceView setAppVersionHidden:appVersionHidden];
217 | }
218 | }
219 |
220 | - (void)setDeviceVersionHidden:(BOOL)deviceVersionHidden {
221 | _deviceVersionHidden = deviceVersionHidden;
222 |
223 | if (self.performanceView) {
224 | [self.performanceView setDeviceVersionHidden:deviceVersionHidden];
225 | }
226 | }
227 |
228 | @end
229 |
--------------------------------------------------------------------------------
/GDPerformanceView/GDPerformanceMonitoring/GDPerformanceView.m:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright © 2017 Gavrilov Daniil
3 | //
4 | // Permission is hereby granted, free of charge, to any person obtaining a copy
5 | // of this software and associated documentation files (the "Software"), to deal
6 | // in the Software without restriction, including without limitation the rights
7 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | // copies of the Software, and to permit persons to whom the Software is
9 | // furnished to do so, subject to the following conditions:
10 | //
11 | // The above copyright notice and this permission notice shall be included in
12 | // all copies or substantial portions of the Software.
13 | //
14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | // THE SOFTWARE.
21 | //
22 |
23 | #import "GDPerformanceView.h"
24 |
25 | #import
26 | #import
27 |
28 | #import "GDMarginLabel.h"
29 | #import "GDWindowViewController.h"
30 |
31 | @interface GDPerformanceView ()
32 |
33 | @property (nonatomic, strong) CADisplayLink *displayLink;
34 |
35 | @property (nonatomic, strong) GDMarginLabel *monitoringTextLabel;
36 |
37 | @property (nonatomic) int screenUpdatesCount;
38 |
39 | @property (nonatomic) CFTimeInterval screenUpdatesBeginTime;
40 |
41 | @property (nonatomic) CFTimeInterval averageScreenUpdatesTime;
42 |
43 | @property (nonatomic) NSString *versionsString;
44 |
45 | @end
46 |
47 | @implementation GDPerformanceView
48 |
49 | #pragma mark -
50 | #pragma mark - Init Methods & Superclass Overriders
51 |
52 | - (instancetype)init {
53 | self = [super initWithFrame:[GDPerformanceView windowFrame]];
54 | if (self) {
55 | [self setupWindowAndDefaultVariables];
56 | [self setupDisplayLink];
57 | [self setupTextLayers];
58 | [self subscribeToNotifications];
59 | [self configureVersionsString];
60 | }
61 | return self;
62 | }
63 |
64 | - (void)layoutSubviews {
65 | [super layoutSubviews];
66 |
67 | [self layoutWindow];
68 | }
69 |
70 | - (void)becomeKeyWindow {
71 | [self setHidden:YES];
72 |
73 | dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (1.0f * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
74 | [self setHidden:NO];
75 | });
76 | }
77 |
78 | - (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event {
79 | return NO;
80 | }
81 |
82 | - (void)dealloc {
83 | [[NSNotificationCenter defaultCenter] removeObserver:self];
84 | }
85 |
86 | #pragma mark -
87 | #pragma mark - Notifications & Observers
88 |
89 | - (void)applicationWillChangeStatusBarFrame:(NSNotification *)notification {
90 | dispatch_async(dispatch_get_main_queue(), ^{
91 | [self layoutWindow];
92 | });
93 | }
94 |
95 | #pragma mark -
96 | #pragma mark - Public Methods
97 |
98 | - (UILabel *)textLabel {
99 | __weak UILabel *weakTextLabel = self.monitoringTextLabel;
100 | return weakTextLabel;
101 | }
102 |
103 | - (void)pauseMonitoring {
104 | [self.displayLink setPaused:YES];
105 |
106 | [self.monitoringTextLabel removeFromSuperview];
107 | }
108 |
109 | - (void)resumeMonitoringAndShowMonitoringView:(BOOL)showMonitoringView {
110 | [self.displayLink setPaused:NO];
111 |
112 | if (showMonitoringView) {
113 | [self addSubview:self.monitoringTextLabel];
114 | }
115 | }
116 |
117 | - (void)hideMonitoring {
118 | [self.monitoringTextLabel removeFromSuperview];
119 | }
120 |
121 | - (void)addMonitoringViewAboveStatusBar {
122 | if (![self isHidden]) {
123 | return;
124 | }
125 |
126 | [self setHidden:NO];
127 | }
128 |
129 | - (void)configureRootViewController {
130 | GDWindowViewController *rootViewController = [[GDWindowViewController alloc] init];
131 | [rootViewController configureStatusBarAppearanceWithPrefersStatusBarHidden:self.prefersStatusBarHidden preferredStatusBarStyle:self.preferredStatusBarStyle];
132 |
133 | self.rootViewController = rootViewController;
134 | }
135 |
136 | - (void)stopMonitoring {
137 | [self.displayLink invalidate];
138 | self.displayLink = nil;
139 | }
140 |
141 | #pragma mark -
142 | #pragma mark - Private Methods
143 |
144 | #pragma mark - Default Setups
145 |
146 | - (void)setupWindowAndDefaultVariables {
147 | self.prefersStatusBarHidden = NO;
148 | self.preferredStatusBarStyle = UIStatusBarStyleDefault;
149 | self.screenUpdatesCount = 0;
150 | self.screenUpdatesBeginTime = 0.0f;
151 | self.averageScreenUpdatesTime = 0.017f;
152 |
153 | GDWindowViewController *rootViewController = [[GDWindowViewController alloc] init];
154 |
155 | [self setRootViewController:rootViewController];
156 | [self setWindowLevel:(UIWindowLevelStatusBar + 1.0f)];
157 | [self setBackgroundColor:[UIColor clearColor]];
158 | [self setClipsToBounds:YES];
159 | [self setHidden:YES];
160 | }
161 |
162 | - (void)setupDisplayLink {
163 | self.displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(displayLinkAction:)];
164 | [self.displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];
165 | }
166 |
167 | - (void)setupTextLayers {
168 | self.monitoringTextLabel = [[GDMarginLabel alloc] init];
169 | [self.monitoringTextLabel setTextAlignment:NSTextAlignmentCenter];
170 | [self.monitoringTextLabel setNumberOfLines:2];
171 | [self.monitoringTextLabel setBackgroundColor:[UIColor blackColor]];
172 | [self.monitoringTextLabel setTextColor:[UIColor whiteColor]];
173 | [self.monitoringTextLabel setClipsToBounds:YES];
174 | [self.monitoringTextLabel setFont:[UIFont systemFontOfSize:8.0f]];
175 | [self.monitoringTextLabel.layer setBorderWidth:1.0f];
176 | [self.monitoringTextLabel.layer setBorderColor:[[UIColor blackColor] CGColor]];
177 | [self.monitoringTextLabel.layer setCornerRadius:5.0f];
178 |
179 | [self addSubview:self.monitoringTextLabel];
180 | }
181 |
182 | - (void)subscribeToNotifications {
183 | [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationWillChangeStatusBarFrame:) name:UIApplicationWillChangeStatusBarFrameNotification object:nil];
184 | }
185 |
186 | #pragma mark - Monitoring
187 |
188 | - (void)displayLinkAction:(CADisplayLink *)displayLink {
189 | if (self.screenUpdatesBeginTime == 0.0f) {
190 | self.screenUpdatesBeginTime = displayLink.timestamp;
191 | } else {
192 | self.screenUpdatesCount += 1;
193 |
194 | CFTimeInterval screenUpdatesTime = self.displayLink.timestamp - self.screenUpdatesBeginTime;
195 |
196 | if (screenUpdatesTime >= 1.0) {
197 | CFTimeInterval updatesOverSecond = screenUpdatesTime - 1.0f;
198 | int framesOverSecond = updatesOverSecond / self.averageScreenUpdatesTime;
199 |
200 | self.screenUpdatesCount -= framesOverSecond;
201 | if (self.screenUpdatesCount < 0) {
202 | self.screenUpdatesCount = 0;
203 | }
204 |
205 | [self takeReadings];
206 | }
207 | }
208 | }
209 |
210 | - (void)takeReadings {
211 | int fps = self.screenUpdatesCount;
212 | float cpu = [self cpuUsage];
213 |
214 | self.screenUpdatesCount = 0;
215 | self.screenUpdatesBeginTime = 0.0f;
216 |
217 | [self reportFPS:fps CPU:cpu];
218 | [self updateMonitoringLabelWithFPS:fps CPU:cpu];
219 | }
220 |
221 | - (float)cpuUsage {
222 | kern_return_t kern;
223 |
224 | thread_array_t threadList;
225 | mach_msg_type_number_t threadCount;
226 |
227 | thread_info_data_t threadInfo;
228 | mach_msg_type_number_t threadInfoCount;
229 |
230 | thread_basic_info_t threadBasicInfo;
231 | uint32_t threadStatistic = 0;
232 |
233 | kern = task_threads(mach_task_self(), &threadList, &threadCount);
234 | if (kern != KERN_SUCCESS) {
235 | return -1;
236 | }
237 | if (threadCount > 0) {
238 | threadStatistic += threadCount;
239 | }
240 |
241 | float totalUsageOfCPU = 0;
242 |
243 | for (int i = 0; i < threadCount; i++) {
244 | threadInfoCount = THREAD_INFO_MAX;
245 | kern = thread_info(threadList[i], THREAD_BASIC_INFO, (thread_info_t)threadInfo, &threadInfoCount);
246 | if (kern != KERN_SUCCESS) {
247 | return -1;
248 | }
249 |
250 | threadBasicInfo = (thread_basic_info_t)threadInfo;
251 |
252 | if (!(threadBasicInfo -> flags & TH_FLAGS_IDLE)) {
253 | totalUsageOfCPU = totalUsageOfCPU + threadBasicInfo -> cpu_usage / (float)TH_USAGE_SCALE * 100.0f;
254 | }
255 | }
256 |
257 | kern = vm_deallocate(mach_task_self(), (vm_offset_t)threadList, threadCount * sizeof(thread_t));
258 |
259 | return totalUsageOfCPU;
260 | }
261 |
262 | #pragma mark - Other Methods
263 |
264 | + (CGRect)windowFrame {
265 | CGRect frame = CGRectZero;
266 | UIWindow *window = [[[UIApplication sharedApplication] delegate] window];
267 | if (window) {
268 | frame = CGRectMake(0.0f, 0.0f, CGRectGetWidth(window.bounds), 20.0f);
269 | }
270 | return frame;
271 | }
272 |
273 | - (void)reportFPS:(int)fpsValue CPU:(float)cpuValue {
274 | if (!self.performanceDelegate || ![self.performanceDelegate respondsToSelector:@selector(performanceMonitorDidReportFPS:CPU:)]) {
275 | return;
276 | }
277 |
278 | [self.performanceDelegate performanceMonitorDidReportFPS:fpsValue CPU:cpuValue];
279 | }
280 |
281 | - (void)updateMonitoringLabelWithFPS:(int)fpsValue CPU:(float)cpuValue {
282 | NSString *monitoringString = [NSString stringWithFormat:@"FPS : %d CPU : %.1f%%%@", fpsValue, cpuValue, self.versionsString];
283 |
284 | [self.monitoringTextLabel setText:monitoringString];
285 | [self layoutTextLabel];
286 | }
287 |
288 | - (void)layoutTextLabel {
289 | CGFloat windowWidth = CGRectGetWidth(self.bounds);
290 | CGFloat windowHeight = CGRectGetHeight(self.bounds);
291 | CGSize labelSize = [self.monitoringTextLabel sizeThatFits:CGSizeMake(windowWidth, windowHeight)];
292 |
293 | [self.monitoringTextLabel setFrame:CGRectMake((windowWidth - labelSize.width) / 2.0f, (windowHeight - labelSize.height) / 2.0f, labelSize.width, labelSize.height)];
294 | }
295 |
296 | - (void)layoutWindow {
297 | [self setFrame:[GDPerformanceView windowFrame]];
298 | [self layoutTextLabel];
299 | }
300 |
301 | - (void)configureVersionsString {
302 | if (!self.appVersionHidden || !self.deviceVersionHidden) {
303 | NSString *applicationVersion = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleShortVersionString"];
304 | NSString *applicationBuild = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleVersion"];
305 | NSString *systemVersion = [[UIDevice currentDevice] systemVersion];
306 |
307 | if (!self.appVersionHidden && !self.deviceVersionHidden) {
308 | self.versionsString = [NSString stringWithFormat:@"\napp v%@ (%@) iOS v%@", applicationVersion, applicationBuild, systemVersion];
309 | } else if (!self.appVersionHidden) {
310 | self.versionsString = [NSString stringWithFormat:@"\napp v%@ (%@)", applicationVersion, applicationBuild];
311 | } else if (!self.deviceVersionHidden) {
312 | self.versionsString = [NSString stringWithFormat:@"\niOS v%@", systemVersion];
313 | }
314 | } else {
315 | self.versionsString = @"";
316 | }
317 | }
318 |
319 | #pragma mark -
320 | #pragma mark - Setters & Getters
321 |
322 | - (void)setAppVersionHidden:(BOOL)appVersionHidden {
323 | if (appVersionHidden == _appVersionHidden) {
324 | return;
325 | }
326 |
327 | _appVersionHidden = appVersionHidden;
328 |
329 | [self configureVersionsString];
330 | }
331 |
332 | - (void)setDeviceVersionHidden:(BOOL)deviceVersionHidden {
333 | if (deviceVersionHidden == _deviceVersionHidden) {
334 | return;
335 | }
336 |
337 | _deviceVersionHidden = deviceVersionHidden;
338 |
339 | [self configureVersionsString];
340 | }
341 |
342 | @end
343 |
--------------------------------------------------------------------------------
/GDPerformanceView.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 46;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 4277368A1E2BD55100E59793 /* GDWindowViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 427736891E2BD55100E59793 /* GDWindowViewController.m */; };
11 | A537615E1DB76D81000007B7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = A53761511DB76D81000007B7 /* AppDelegate.m */; };
12 | A537615F1DB76D81000007B7 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = A53761521DB76D81000007B7 /* Assets.xcassets */; };
13 | A53761601DB76D81000007B7 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = A53761531DB76D81000007B7 /* LaunchScreen.storyboard */; };
14 | A53761611DB76D81000007B7 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = A53761551DB76D81000007B7 /* Main.storyboard */; };
15 | A53761621DB76D81000007B7 /* GDPerformanceMonitor.m in Sources */ = {isa = PBXBuildFile; fileRef = A53761591DB76D81000007B7 /* GDPerformanceMonitor.m */; };
16 | A53761631DB76D81000007B7 /* GDPerformanceView.m in Sources */ = {isa = PBXBuildFile; fileRef = A537615B1DB76D81000007B7 /* GDPerformanceView.m */; };
17 | A53761651DB76D81000007B7 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = A537615D1DB76D81000007B7 /* main.m */; };
18 | A5DAC0811DB7B1A600AF26E6 /* GDMarginLabel.m in Sources */ = {isa = PBXBuildFile; fileRef = A5DAC0801DB7B1A600AF26E6 /* GDMarginLabel.m */; };
19 | /* End PBXBuildFile section */
20 |
21 | /* Begin PBXFileReference section */
22 | 427736881E2BD55100E59793 /* GDWindowViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GDWindowViewController.h; sourceTree = ""; };
23 | 427736891E2BD55100E59793 /* GDWindowViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GDWindowViewController.m; sourceTree = ""; };
24 | 428FE57D1E1D19D100F85C8B /* GDPerformanceMonitorProtocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GDPerformanceMonitorProtocol.h; sourceTree = ""; };
25 | A53761501DB76D81000007B7 /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; };
26 | A53761511DB76D81000007B7 /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; };
27 | A53761521DB76D81000007B7 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
28 | A53761541DB76D81000007B7 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; };
29 | A53761561DB76D81000007B7 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; };
30 | A53761581DB76D81000007B7 /* GDPerformanceMonitor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GDPerformanceMonitor.h; sourceTree = ""; };
31 | A53761591DB76D81000007B7 /* GDPerformanceMonitor.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GDPerformanceMonitor.m; sourceTree = ""; };
32 | A537615A1DB76D81000007B7 /* GDPerformanceView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GDPerformanceView.h; sourceTree = ""; };
33 | A537615B1DB76D81000007B7 /* GDPerformanceView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GDPerformanceView.m; sourceTree = ""; };
34 | A537615C1DB76D81000007B7 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
35 | A537615D1DB76D81000007B7 /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; };
36 | A5C8CEBE1DB6203D008D8E15 /* GDPerformanceView.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = GDPerformanceView.app; sourceTree = BUILT_PRODUCTS_DIR; };
37 | A5DAC07F1DB7B1A600AF26E6 /* GDMarginLabel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GDMarginLabel.h; sourceTree = ""; };
38 | A5DAC0801DB7B1A600AF26E6 /* GDMarginLabel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GDMarginLabel.m; sourceTree = ""; };
39 | /* End PBXFileReference section */
40 |
41 | /* Begin PBXFrameworksBuildPhase section */
42 | A5C8CEBB1DB6203D008D8E15 /* Frameworks */ = {
43 | isa = PBXFrameworksBuildPhase;
44 | buildActionMask = 2147483647;
45 | files = (
46 | );
47 | runOnlyForDeploymentPostprocessing = 0;
48 | };
49 | /* End PBXFrameworksBuildPhase section */
50 |
51 | /* Begin PBXGroup section */
52 | A537614F1DB76D81000007B7 /* GDPerformanceView */ = {
53 | isa = PBXGroup;
54 | children = (
55 | A53761571DB76D81000007B7 /* GDPerformanceMonitoring */,
56 | A53761501DB76D81000007B7 /* AppDelegate.h */,
57 | A53761511DB76D81000007B7 /* AppDelegate.m */,
58 | A53761521DB76D81000007B7 /* Assets.xcassets */,
59 | A53761531DB76D81000007B7 /* LaunchScreen.storyboard */,
60 | A53761551DB76D81000007B7 /* Main.storyboard */,
61 | A537615C1DB76D81000007B7 /* Info.plist */,
62 | A537615D1DB76D81000007B7 /* main.m */,
63 | );
64 | path = GDPerformanceView;
65 | sourceTree = "";
66 | };
67 | A53761571DB76D81000007B7 /* GDPerformanceMonitoring */ = {
68 | isa = PBXGroup;
69 | children = (
70 | A53761581DB76D81000007B7 /* GDPerformanceMonitor.h */,
71 | A53761591DB76D81000007B7 /* GDPerformanceMonitor.m */,
72 | A537615A1DB76D81000007B7 /* GDPerformanceView.h */,
73 | A537615B1DB76D81000007B7 /* GDPerformanceView.m */,
74 | A5DAC07F1DB7B1A600AF26E6 /* GDMarginLabel.h */,
75 | A5DAC0801DB7B1A600AF26E6 /* GDMarginLabel.m */,
76 | 427736881E2BD55100E59793 /* GDWindowViewController.h */,
77 | 427736891E2BD55100E59793 /* GDWindowViewController.m */,
78 | 428FE57D1E1D19D100F85C8B /* GDPerformanceMonitorProtocol.h */,
79 | );
80 | path = GDPerformanceMonitoring;
81 | sourceTree = "";
82 | };
83 | A5C8CEB51DB6203D008D8E15 = {
84 | isa = PBXGroup;
85 | children = (
86 | A537614F1DB76D81000007B7 /* GDPerformanceView */,
87 | A5C8CEBF1DB6203D008D8E15 /* Products */,
88 | );
89 | sourceTree = "";
90 | };
91 | A5C8CEBF1DB6203D008D8E15 /* Products */ = {
92 | isa = PBXGroup;
93 | children = (
94 | A5C8CEBE1DB6203D008D8E15 /* GDPerformanceView.app */,
95 | );
96 | name = Products;
97 | sourceTree = "";
98 | };
99 | /* End PBXGroup section */
100 |
101 | /* Begin PBXNativeTarget section */
102 | A5C8CEBD1DB6203D008D8E15 /* GDPerformanceView */ = {
103 | isa = PBXNativeTarget;
104 | buildConfigurationList = A5C8CED51DB6203D008D8E15 /* Build configuration list for PBXNativeTarget "GDPerformanceView" */;
105 | buildPhases = (
106 | A5C8CEBA1DB6203D008D8E15 /* Sources */,
107 | A5C8CEBB1DB6203D008D8E15 /* Frameworks */,
108 | A5C8CEBC1DB6203D008D8E15 /* Resources */,
109 | );
110 | buildRules = (
111 | );
112 | dependencies = (
113 | );
114 | name = GDPerformanceView;
115 | productName = FSPerfomanceView;
116 | productReference = A5C8CEBE1DB6203D008D8E15 /* GDPerformanceView.app */;
117 | productType = "com.apple.product-type.application";
118 | };
119 | /* End PBXNativeTarget section */
120 |
121 | /* Begin PBXProject section */
122 | A5C8CEB61DB6203D008D8E15 /* Project object */ = {
123 | isa = PBXProject;
124 | attributes = {
125 | CLASSPREFIX = GD;
126 | LastUpgradeCheck = 0820;
127 | ORGANIZATIONNAME = "Gavrilov Daniil";
128 | TargetAttributes = {
129 | A5C8CEBD1DB6203D008D8E15 = {
130 | CreatedOnToolsVersion = 8.0;
131 | ProvisioningStyle = Automatic;
132 | };
133 | };
134 | };
135 | buildConfigurationList = A5C8CEB91DB6203D008D8E15 /* Build configuration list for PBXProject "GDPerformanceView" */;
136 | compatibilityVersion = "Xcode 3.2";
137 | developmentRegion = English;
138 | hasScannedForEncodings = 0;
139 | knownRegions = (
140 | en,
141 | Base,
142 | );
143 | mainGroup = A5C8CEB51DB6203D008D8E15;
144 | productRefGroup = A5C8CEBF1DB6203D008D8E15 /* Products */;
145 | projectDirPath = "";
146 | projectRoot = "";
147 | targets = (
148 | A5C8CEBD1DB6203D008D8E15 /* GDPerformanceView */,
149 | );
150 | };
151 | /* End PBXProject section */
152 |
153 | /* Begin PBXResourcesBuildPhase section */
154 | A5C8CEBC1DB6203D008D8E15 /* Resources */ = {
155 | isa = PBXResourcesBuildPhase;
156 | buildActionMask = 2147483647;
157 | files = (
158 | A53761611DB76D81000007B7 /* Main.storyboard in Resources */,
159 | A537615F1DB76D81000007B7 /* Assets.xcassets in Resources */,
160 | A53761601DB76D81000007B7 /* LaunchScreen.storyboard in Resources */,
161 | );
162 | runOnlyForDeploymentPostprocessing = 0;
163 | };
164 | /* End PBXResourcesBuildPhase section */
165 |
166 | /* Begin PBXSourcesBuildPhase section */
167 | A5C8CEBA1DB6203D008D8E15 /* Sources */ = {
168 | isa = PBXSourcesBuildPhase;
169 | buildActionMask = 2147483647;
170 | files = (
171 | A53761621DB76D81000007B7 /* GDPerformanceMonitor.m in Sources */,
172 | 4277368A1E2BD55100E59793 /* GDWindowViewController.m in Sources */,
173 | A537615E1DB76D81000007B7 /* AppDelegate.m in Sources */,
174 | A53761651DB76D81000007B7 /* main.m in Sources */,
175 | A53761631DB76D81000007B7 /* GDPerformanceView.m in Sources */,
176 | A5DAC0811DB7B1A600AF26E6 /* GDMarginLabel.m in Sources */,
177 | );
178 | runOnlyForDeploymentPostprocessing = 0;
179 | };
180 | /* End PBXSourcesBuildPhase section */
181 |
182 | /* Begin PBXVariantGroup section */
183 | A53761531DB76D81000007B7 /* LaunchScreen.storyboard */ = {
184 | isa = PBXVariantGroup;
185 | children = (
186 | A53761541DB76D81000007B7 /* Base */,
187 | );
188 | name = LaunchScreen.storyboard;
189 | sourceTree = "";
190 | };
191 | A53761551DB76D81000007B7 /* Main.storyboard */ = {
192 | isa = PBXVariantGroup;
193 | children = (
194 | A53761561DB76D81000007B7 /* Base */,
195 | );
196 | name = Main.storyboard;
197 | sourceTree = "";
198 | };
199 | /* End PBXVariantGroup section */
200 |
201 | /* Begin XCBuildConfiguration section */
202 | A5C8CED31DB6203D008D8E15 /* Debug */ = {
203 | isa = XCBuildConfiguration;
204 | buildSettings = {
205 | ALWAYS_SEARCH_USER_PATHS = NO;
206 | CLANG_ANALYZER_NONNULL = YES;
207 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
208 | CLANG_CXX_LIBRARY = "libc++";
209 | CLANG_ENABLE_MODULES = YES;
210 | CLANG_ENABLE_OBJC_ARC = YES;
211 | CLANG_WARN_BOOL_CONVERSION = YES;
212 | CLANG_WARN_CONSTANT_CONVERSION = YES;
213 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
214 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
215 | CLANG_WARN_EMPTY_BODY = YES;
216 | CLANG_WARN_ENUM_CONVERSION = YES;
217 | CLANG_WARN_INFINITE_RECURSION = YES;
218 | CLANG_WARN_INT_CONVERSION = YES;
219 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
220 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
221 | CLANG_WARN_SUSPICIOUS_MOVES = YES;
222 | CLANG_WARN_UNREACHABLE_CODE = YES;
223 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
224 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
225 | COPY_PHASE_STRIP = NO;
226 | DEBUG_INFORMATION_FORMAT = dwarf;
227 | ENABLE_STRICT_OBJC_MSGSEND = YES;
228 | ENABLE_TESTABILITY = YES;
229 | GCC_C_LANGUAGE_STANDARD = gnu99;
230 | GCC_DYNAMIC_NO_PIC = NO;
231 | GCC_NO_COMMON_BLOCKS = YES;
232 | GCC_OPTIMIZATION_LEVEL = 0;
233 | GCC_PREPROCESSOR_DEFINITIONS = (
234 | "DEBUG=1",
235 | "$(inherited)",
236 | );
237 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
238 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
239 | GCC_WARN_UNDECLARED_SELECTOR = YES;
240 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
241 | GCC_WARN_UNUSED_FUNCTION = YES;
242 | GCC_WARN_UNUSED_VARIABLE = YES;
243 | IPHONEOS_DEPLOYMENT_TARGET = 8.0;
244 | MTL_ENABLE_DEBUG_INFO = YES;
245 | ONLY_ACTIVE_ARCH = YES;
246 | SDKROOT = iphoneos;
247 | TARGETED_DEVICE_FAMILY = "1,2";
248 | };
249 | name = Debug;
250 | };
251 | A5C8CED41DB6203D008D8E15 /* Release */ = {
252 | isa = XCBuildConfiguration;
253 | buildSettings = {
254 | ALWAYS_SEARCH_USER_PATHS = NO;
255 | CLANG_ANALYZER_NONNULL = YES;
256 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
257 | CLANG_CXX_LIBRARY = "libc++";
258 | CLANG_ENABLE_MODULES = YES;
259 | CLANG_ENABLE_OBJC_ARC = YES;
260 | CLANG_WARN_BOOL_CONVERSION = YES;
261 | CLANG_WARN_CONSTANT_CONVERSION = YES;
262 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
263 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
264 | CLANG_WARN_EMPTY_BODY = YES;
265 | CLANG_WARN_ENUM_CONVERSION = YES;
266 | CLANG_WARN_INFINITE_RECURSION = YES;
267 | CLANG_WARN_INT_CONVERSION = YES;
268 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
269 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
270 | CLANG_WARN_SUSPICIOUS_MOVES = YES;
271 | CLANG_WARN_UNREACHABLE_CODE = YES;
272 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
273 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
274 | COPY_PHASE_STRIP = NO;
275 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
276 | ENABLE_NS_ASSERTIONS = NO;
277 | ENABLE_STRICT_OBJC_MSGSEND = YES;
278 | GCC_C_LANGUAGE_STANDARD = gnu99;
279 | GCC_NO_COMMON_BLOCKS = YES;
280 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
281 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
282 | GCC_WARN_UNDECLARED_SELECTOR = YES;
283 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
284 | GCC_WARN_UNUSED_FUNCTION = YES;
285 | GCC_WARN_UNUSED_VARIABLE = YES;
286 | IPHONEOS_DEPLOYMENT_TARGET = 8.0;
287 | MTL_ENABLE_DEBUG_INFO = NO;
288 | SDKROOT = iphoneos;
289 | TARGETED_DEVICE_FAMILY = "1,2";
290 | VALIDATE_PRODUCT = YES;
291 | };
292 | name = Release;
293 | };
294 | A5C8CED61DB6203D008D8E15 /* Debug */ = {
295 | isa = XCBuildConfiguration;
296 | buildSettings = {
297 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
298 | DEVELOPMENT_TEAM = "";
299 | INFOPLIST_FILE = GDPerformanceView/Info.plist;
300 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
301 | PRODUCT_BUNDLE_IDENTIFIER = GD.GDPerformanceView;
302 | PRODUCT_NAME = "$(TARGET_NAME)";
303 | TARGETED_DEVICE_FAMILY = "1,2";
304 | };
305 | name = Debug;
306 | };
307 | A5C8CED71DB6203D008D8E15 /* Release */ = {
308 | isa = XCBuildConfiguration;
309 | buildSettings = {
310 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
311 | DEVELOPMENT_TEAM = "";
312 | INFOPLIST_FILE = GDPerformanceView/Info.plist;
313 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
314 | PRODUCT_BUNDLE_IDENTIFIER = GD.GDPerformanceView;
315 | PRODUCT_NAME = "$(TARGET_NAME)";
316 | TARGETED_DEVICE_FAMILY = "1,2";
317 | };
318 | name = Release;
319 | };
320 | /* End XCBuildConfiguration section */
321 |
322 | /* Begin XCConfigurationList section */
323 | A5C8CEB91DB6203D008D8E15 /* Build configuration list for PBXProject "GDPerformanceView" */ = {
324 | isa = XCConfigurationList;
325 | buildConfigurations = (
326 | A5C8CED31DB6203D008D8E15 /* Debug */,
327 | A5C8CED41DB6203D008D8E15 /* Release */,
328 | );
329 | defaultConfigurationIsVisible = 0;
330 | defaultConfigurationName = Release;
331 | };
332 | A5C8CED51DB6203D008D8E15 /* Build configuration list for PBXNativeTarget "GDPerformanceView" */ = {
333 | isa = XCConfigurationList;
334 | buildConfigurations = (
335 | A5C8CED61DB6203D008D8E15 /* Debug */,
336 | A5C8CED71DB6203D008D8E15 /* Release */,
337 | );
338 | defaultConfigurationIsVisible = 0;
339 | defaultConfigurationName = Release;
340 | };
341 | /* End XCConfigurationList section */
342 | };
343 | rootObject = A5C8CEB61DB6203D008D8E15 /* Project object */;
344 | }
345 |
--------------------------------------------------------------------------------