├── .gitignore
├── LICENSE
├── PrivacyPolicy.md
├── README.md
├── UTMBeGone.xcodeproj
├── project.pbxproj
└── project.xcworkspace
│ ├── contents.xcworkspacedata
│ └── xcshareddata
│ └── IDEWorkspaceChecks.plist
├── UTMBeGone
├── AppDelegate.swift
├── Assets.xcassets
│ ├── AppIcon.appiconset
│ │ ├── Contents.json
│ │ ├── UTMBeGone1024.png
│ │ ├── UTMBeGone128.png
│ │ ├── UTMBeGone256-1.png
│ │ ├── UTMBeGone256.png
│ │ ├── UTMBeGone32-1.png
│ │ ├── UTMBeGone32.png
│ │ ├── UTMBeGone512-1.png
│ │ ├── UTMBeGone512.png
│ │ └── UTMBeGone64.png
│ ├── Contents.json
│ └── icon.imageset
│ │ ├── Contents.json
│ │ └── icon.pdf
├── Base.lproj
│ └── MainMenu.xib
├── GarbageRemover
│ └── URLGarbageRemover.swift
├── Info.plist
├── Menu
│ └── MenuManager.swift
├── PasteboardCore
│ ├── PasteboardHandler.swift
│ └── PasteboardListener.swift
├── Preferences
│ ├── PreferencesViewController.swift
│ └── PreferencesViewController.xib
├── Shared
│ └── SharedConsts.swift
├── Storage
│ ├── QueryItem.swift
│ └── QueryItemsManager.swift
├── UTMBeGone.entitlements
└── Util
│ ├── LaunchAtLoginHelper.swift
│ ├── NotificationNames.swift
│ ├── OpenWebsiteHelper.swift
│ └── UTMBeGone-Bridging-Header.h
├── UTMBeGoneHelper
├── AppDelegate.swift
├── Assets.xcassets
│ ├── AccentColor.colorset
│ │ └── Contents.json
│ ├── AppIcon.appiconset
│ │ └── Contents.json
│ └── Contents.json
├── Base.lproj
│ └── Main.storyboard
├── Bundle+MainApp.swift
├── Info.plist
└── UTMBeGoneHelper.entitlements
├── UTMBeGoneTests
├── Info.plist
└── UTMBeGoneTests.swift
└── images
├── icon.png
├── screenshot.png
└── screenshot2.png
/.gitignore:
--------------------------------------------------------------------------------
1 | UTMBeGone.xcodeproj/xcuserdata
2 | .DS_Store
3 | *.xcuserstate
4 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | BSD 2-Clause License
2 |
3 | Copyright (c) 2020, Fernando Bunn
4 | All rights reserved.
5 |
6 | Redistribution and use in source and binary forms, with or without
7 | modification, are permitted provided that the following conditions are met:
8 |
9 | 1. Redistributions of source code must retain the above copyright notice, this
10 | list of conditions and the following disclaimer.
11 |
12 | 2. Redistributions in binary form must reproduce the above copyright notice,
13 | this list of conditions and the following disclaimer in the documentation
14 | and/or other materials provided with the distribution.
15 |
16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
20 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
23 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 |
--------------------------------------------------------------------------------
/PrivacyPolicy.md:
--------------------------------------------------------------------------------
1 | # Privacy Policy
2 |
3 | ## What we collect
4 | This app doesn't log any kind of data from you.
5 |
6 | It doesn't have analytics or crash reporting tools (besides the one provided automatically by Apple).
7 |
8 | It is a 100% offline app.
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | # UTMBeGone
7 |
8 | ## Real friends remove UTM tags before sharing links 😊
9 |
10 | Remove UTM tags (and more) when you copy URLs to your pasteboard.
11 |
12 | With UTMBeGone you can prevent people from tracking you and the friends you share links with. The app comes with a pre-set of UTM tags, but you can add/remove as many tags you want.
13 |
14 | # How it works?
15 | Every time you copy a valid URL to your pasteboard UTMBeGone will remove all queries that you configured on UTMBeGone.
16 |
17 | For example, if you copy "http://fakestalkerwebsite.com?randomQuery=123&utm_source=we_are_stalking_you, you will actually paste http://fakestalkerwebsite.com?randomQuery=123 to your friends.
18 |
19 | UTMBeGone comes with a preset of query items to be removed, but you can add or remove anything you like.
20 |
21 | Protect the people you share links with from being tracked :)
22 |
23 |
24 | ## Screenshots
25 |
26 |
27 |
28 |
29 |
30 |
31 | ## Privacy
32 | This project does not track anything you do ( it would be ironic right? 🙃), there are no analytics, no telemetry and it's a 100% offline app.
33 |
34 | ## Download
35 | UTMBeGone is a free and open source hobby project of mine. Feel free to download the project and run it anywhere you like!
36 | If you want to support its development you can buy it on the [App Store](https://apps.apple.com/us/app/utmbegone/id1530867730?mt=12) for those nice automatic updates :)
37 |
38 | ## FAQ
39 |
40 | ### I've removed the icon from the menu bar and now it's gone, how do I add it back?
41 | If you remove/hide the icon from the menu bar the app will keep running, if you want to see it back again just open your Application's folder and double click on the UTMBeGone icon to see it again.
42 |
43 | ### Will this app remove all "utm" tags from all texts I copy?
44 | No, UTMBeGone only removes these tags from valid URLs, which means they need to start with http(s):// . This is intentional because I didn't want to randomly remove tags from texts being copied, it would be very annoying.
45 |
--------------------------------------------------------------------------------
/UTMBeGone.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 50;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 314FD7D7277A3D0900D16AED /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 314FD7D6277A3D0900D16AED /* AppDelegate.swift */; };
11 | 314FD7DB277A3D0900D16AED /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 314FD7DA277A3D0900D16AED /* Assets.xcassets */; };
12 | 314FD7DE277A3D0900D16AED /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 314FD7DC277A3D0900D16AED /* Main.storyboard */; };
13 | 314FD7E4277A3D3B00D16AED /* Bundle+MainApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 314FD7E3277A3D3B00D16AED /* Bundle+MainApp.swift */; };
14 | 314FD7E5277A3D6B00D16AED /* UTMBeGoneHelper.app in CopyFiles */ = {isa = PBXBuildFile; fileRef = 314FD7D4277A3D0800D16AED /* UTMBeGoneHelper.app */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
15 | 31629499250D180C0015E908 /* NotificationNames.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31629498250D180C0015E908 /* NotificationNames.swift */; };
16 | 3192B4EF277919E400EFC6FB /* SharedConsts.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3192B4EE277919E400EFC6FB /* SharedConsts.swift */; };
17 | 3192B4F227791B7400EFC6FB /* LaunchAtLoginHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3192B4F127791B7400EFC6FB /* LaunchAtLoginHelper.swift */; };
18 | 31A1E5F4277E1BFA006079AE /* OpenWebsiteHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31A1E5F3277E1BFA006079AE /* OpenWebsiteHelper.swift */; };
19 | 31A6634924FDAB4400CDD04A /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31A6634824FDAB4400CDD04A /* AppDelegate.swift */; };
20 | 31A6634B24FDAB4400CDD04A /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 31A6634A24FDAB4400CDD04A /* Assets.xcassets */; };
21 | 31A6634E24FDAB4400CDD04A /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 31A6634C24FDAB4400CDD04A /* MainMenu.xib */; };
22 | 31A6635A24FDAB4500CDD04A /* UTMBeGoneTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31A6635924FDAB4500CDD04A /* UTMBeGoneTests.swift */; };
23 | 31A6636524FDAB5900CDD04A /* URLGarbageRemover.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31A6636424FDAB5900CDD04A /* URLGarbageRemover.swift */; };
24 | 31A6636824FDAB5E00CDD04A /* PasteboardHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31A6636624FDAB5E00CDD04A /* PasteboardHandler.swift */; };
25 | 31A6636924FDAB5E00CDD04A /* PasteboardListener.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31A6636724FDAB5E00CDD04A /* PasteboardListener.swift */; };
26 | 31A6636B24FDAB9C00CDD04A /* MenuManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31A6636A24FDAB9C00CDD04A /* MenuManager.swift */; };
27 | 31D95685250663D100DCD1D1 /* PreferencesViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31D95683250663D100DCD1D1 /* PreferencesViewController.swift */; };
28 | 31D95686250663D100DCD1D1 /* PreferencesViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 31D95684250663D100DCD1D1 /* PreferencesViewController.xib */; };
29 | 31D9568925066F2C00DCD1D1 /* QueryItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31D9568825066F2C00DCD1D1 /* QueryItem.swift */; };
30 | 31D9568B2506702F00DCD1D1 /* QueryItemsManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31D9568A2506702F00DCD1D1 /* QueryItemsManager.swift */; };
31 | /* End PBXBuildFile section */
32 |
33 | /* Begin PBXContainerItemProxy section */
34 | 31A6635624FDAB4500CDD04A /* PBXContainerItemProxy */ = {
35 | isa = PBXContainerItemProxy;
36 | containerPortal = 31A6633D24FDAB4400CDD04A /* Project object */;
37 | proxyType = 1;
38 | remoteGlobalIDString = 31A6634424FDAB4400CDD04A;
39 | remoteInfo = UTMBeGone;
40 | };
41 | /* End PBXContainerItemProxy section */
42 |
43 | /* Begin PBXCopyFilesBuildPhase section */
44 | 31A42F572779035200A0B82D /* CopyFiles */ = {
45 | isa = PBXCopyFilesBuildPhase;
46 | buildActionMask = 2147483647;
47 | dstPath = Contents/Library/LoginItems;
48 | dstSubfolderSpec = 1;
49 | files = (
50 | 314FD7E5277A3D6B00D16AED /* UTMBeGoneHelper.app in CopyFiles */,
51 | );
52 | runOnlyForDeploymentPostprocessing = 0;
53 | };
54 | /* End PBXCopyFilesBuildPhase section */
55 |
56 | /* Begin PBXFileReference section */
57 | 314FD7D4277A3D0800D16AED /* UTMBeGoneHelper.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = UTMBeGoneHelper.app; sourceTree = BUILT_PRODUCTS_DIR; };
58 | 314FD7D6277A3D0900D16AED /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
59 | 314FD7DA277A3D0900D16AED /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
60 | 314FD7DD277A3D0900D16AED /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; };
61 | 314FD7DF277A3D0900D16AED /* UTMBeGoneHelper.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = UTMBeGoneHelper.entitlements; sourceTree = ""; };
62 | 314FD7E3277A3D3B00D16AED /* Bundle+MainApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Bundle+MainApp.swift"; sourceTree = ""; };
63 | 314FD7E6277A3DAA00D16AED /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = Info.plist; sourceTree = ""; };
64 | 31629498250D180C0015E908 /* NotificationNames.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationNames.swift; sourceTree = ""; };
65 | 3192B4EE277919E400EFC6FB /* SharedConsts.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SharedConsts.swift; sourceTree = ""; };
66 | 3192B4F127791B7400EFC6FB /* LaunchAtLoginHelper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LaunchAtLoginHelper.swift; sourceTree = ""; };
67 | 31A1E5F3277E1BFA006079AE /* OpenWebsiteHelper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpenWebsiteHelper.swift; sourceTree = ""; };
68 | 31A42F5A2779037200A0B82D /* ServiceManagement.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ServiceManagement.framework; path = System/Library/Frameworks/ServiceManagement.framework; sourceTree = SDKROOT; };
69 | 31A6634524FDAB4400CDD04A /* UTMBeGone.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = UTMBeGone.app; sourceTree = BUILT_PRODUCTS_DIR; };
70 | 31A6634824FDAB4400CDD04A /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
71 | 31A6634A24FDAB4400CDD04A /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
72 | 31A6634D24FDAB4400CDD04A /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = ""; };
73 | 31A6634F24FDAB4400CDD04A /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
74 | 31A6635024FDAB4400CDD04A /* UTMBeGone.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = UTMBeGone.entitlements; sourceTree = ""; };
75 | 31A6635524FDAB4500CDD04A /* UTMBeGoneTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = UTMBeGoneTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
76 | 31A6635924FDAB4500CDD04A /* UTMBeGoneTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UTMBeGoneTests.swift; sourceTree = ""; };
77 | 31A6635B24FDAB4500CDD04A /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
78 | 31A6636424FDAB5900CDD04A /* URLGarbageRemover.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = URLGarbageRemover.swift; sourceTree = ""; };
79 | 31A6636624FDAB5E00CDD04A /* PasteboardHandler.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PasteboardHandler.swift; sourceTree = ""; };
80 | 31A6636724FDAB5E00CDD04A /* PasteboardListener.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PasteboardListener.swift; sourceTree = ""; };
81 | 31A6636A24FDAB9C00CDD04A /* MenuManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MenuManager.swift; sourceTree = ""; };
82 | 31D95683250663D100DCD1D1 /* PreferencesViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PreferencesViewController.swift; sourceTree = ""; };
83 | 31D95684250663D100DCD1D1 /* PreferencesViewController.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = PreferencesViewController.xib; sourceTree = ""; };
84 | 31D9568825066F2C00DCD1D1 /* QueryItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QueryItem.swift; sourceTree = ""; };
85 | 31D9568A2506702F00DCD1D1 /* QueryItemsManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QueryItemsManager.swift; sourceTree = ""; };
86 | 31D9568D2506818900DCD1D1 /* UTMBeGone-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "UTMBeGone-Bridging-Header.h"; sourceTree = ""; };
87 | /* End PBXFileReference section */
88 |
89 | /* Begin PBXFrameworksBuildPhase section */
90 | 314FD7D1277A3D0800D16AED /* Frameworks */ = {
91 | isa = PBXFrameworksBuildPhase;
92 | buildActionMask = 2147483647;
93 | files = (
94 | );
95 | runOnlyForDeploymentPostprocessing = 0;
96 | };
97 | 31A6634224FDAB4400CDD04A /* Frameworks */ = {
98 | isa = PBXFrameworksBuildPhase;
99 | buildActionMask = 2147483647;
100 | files = (
101 | );
102 | runOnlyForDeploymentPostprocessing = 0;
103 | };
104 | 31A6635224FDAB4500CDD04A /* Frameworks */ = {
105 | isa = PBXFrameworksBuildPhase;
106 | buildActionMask = 2147483647;
107 | files = (
108 | );
109 | runOnlyForDeploymentPostprocessing = 0;
110 | };
111 | /* End PBXFrameworksBuildPhase section */
112 |
113 | /* Begin PBXGroup section */
114 | 314FD7D5277A3D0800D16AED /* UTMBeGoneHelper */ = {
115 | isa = PBXGroup;
116 | children = (
117 | 314FD7E6277A3DAA00D16AED /* Info.plist */,
118 | 314FD7D6277A3D0900D16AED /* AppDelegate.swift */,
119 | 314FD7DA277A3D0900D16AED /* Assets.xcassets */,
120 | 314FD7DC277A3D0900D16AED /* Main.storyboard */,
121 | 314FD7DF277A3D0900D16AED /* UTMBeGoneHelper.entitlements */,
122 | 314FD7E3277A3D3B00D16AED /* Bundle+MainApp.swift */,
123 | );
124 | path = UTMBeGoneHelper;
125 | sourceTree = "";
126 | };
127 | 3192B4ED277919AB00EFC6FB /* Shared */ = {
128 | isa = PBXGroup;
129 | children = (
130 | 3192B4EE277919E400EFC6FB /* SharedConsts.swift */,
131 | );
132 | path = Shared;
133 | sourceTree = "";
134 | };
135 | 31A42F592779037200A0B82D /* Frameworks */ = {
136 | isa = PBXGroup;
137 | children = (
138 | 31A42F5A2779037200A0B82D /* ServiceManagement.framework */,
139 | );
140 | name = Frameworks;
141 | sourceTree = "";
142 | };
143 | 31A6633C24FDAB4400CDD04A = {
144 | isa = PBXGroup;
145 | children = (
146 | 31A6634724FDAB4400CDD04A /* UTMBeGone */,
147 | 31A6635824FDAB4500CDD04A /* UTMBeGoneTests */,
148 | 314FD7D5277A3D0800D16AED /* UTMBeGoneHelper */,
149 | 31A6634624FDAB4400CDD04A /* Products */,
150 | 31A42F592779037200A0B82D /* Frameworks */,
151 | );
152 | sourceTree = "";
153 | };
154 | 31A6634624FDAB4400CDD04A /* Products */ = {
155 | isa = PBXGroup;
156 | children = (
157 | 31A6634524FDAB4400CDD04A /* UTMBeGone.app */,
158 | 31A6635524FDAB4500CDD04A /* UTMBeGoneTests.xctest */,
159 | 314FD7D4277A3D0800D16AED /* UTMBeGoneHelper.app */,
160 | );
161 | name = Products;
162 | sourceTree = "";
163 | };
164 | 31A6634724FDAB4400CDD04A /* UTMBeGone */ = {
165 | isa = PBXGroup;
166 | children = (
167 | 3192B4ED277919AB00EFC6FB /* Shared */,
168 | 31D9568725066EFF00DCD1D1 /* Storage */,
169 | 31D95682250663B200DCD1D1 /* Preferences */,
170 | 31A6636E24FDAC8100CDD04A /* Menu */,
171 | 31A6636D24FDAC7800CDD04A /* GarbageRemover */,
172 | 31A6636C24FDAC6E00CDD04A /* PasteboardCore */,
173 | 31D9568C2506817C00DCD1D1 /* Util */,
174 | 31A6634824FDAB4400CDD04A /* AppDelegate.swift */,
175 | 31A6634A24FDAB4400CDD04A /* Assets.xcassets */,
176 | 31A6634C24FDAB4400CDD04A /* MainMenu.xib */,
177 | 31A6634F24FDAB4400CDD04A /* Info.plist */,
178 | 31A6635024FDAB4400CDD04A /* UTMBeGone.entitlements */,
179 | );
180 | path = UTMBeGone;
181 | sourceTree = "";
182 | };
183 | 31A6635824FDAB4500CDD04A /* UTMBeGoneTests */ = {
184 | isa = PBXGroup;
185 | children = (
186 | 31A6635924FDAB4500CDD04A /* UTMBeGoneTests.swift */,
187 | 31A6635B24FDAB4500CDD04A /* Info.plist */,
188 | );
189 | path = UTMBeGoneTests;
190 | sourceTree = "";
191 | };
192 | 31A6636C24FDAC6E00CDD04A /* PasteboardCore */ = {
193 | isa = PBXGroup;
194 | children = (
195 | 31A6636724FDAB5E00CDD04A /* PasteboardListener.swift */,
196 | 31A6636624FDAB5E00CDD04A /* PasteboardHandler.swift */,
197 | );
198 | path = PasteboardCore;
199 | sourceTree = "";
200 | };
201 | 31A6636D24FDAC7800CDD04A /* GarbageRemover */ = {
202 | isa = PBXGroup;
203 | children = (
204 | 31A6636424FDAB5900CDD04A /* URLGarbageRemover.swift */,
205 | );
206 | path = GarbageRemover;
207 | sourceTree = "";
208 | };
209 | 31A6636E24FDAC8100CDD04A /* Menu */ = {
210 | isa = PBXGroup;
211 | children = (
212 | 31A6636A24FDAB9C00CDD04A /* MenuManager.swift */,
213 | );
214 | path = Menu;
215 | sourceTree = "";
216 | };
217 | 31D95682250663B200DCD1D1 /* Preferences */ = {
218 | isa = PBXGroup;
219 | children = (
220 | 31D95683250663D100DCD1D1 /* PreferencesViewController.swift */,
221 | 31D95684250663D100DCD1D1 /* PreferencesViewController.xib */,
222 | );
223 | path = Preferences;
224 | sourceTree = "";
225 | };
226 | 31D9568725066EFF00DCD1D1 /* Storage */ = {
227 | isa = PBXGroup;
228 | children = (
229 | 31D9568825066F2C00DCD1D1 /* QueryItem.swift */,
230 | 31D9568A2506702F00DCD1D1 /* QueryItemsManager.swift */,
231 | );
232 | path = Storage;
233 | sourceTree = "";
234 | };
235 | 31D9568C2506817C00DCD1D1 /* Util */ = {
236 | isa = PBXGroup;
237 | children = (
238 | 31D9568D2506818900DCD1D1 /* UTMBeGone-Bridging-Header.h */,
239 | 31629498250D180C0015E908 /* NotificationNames.swift */,
240 | 3192B4F127791B7400EFC6FB /* LaunchAtLoginHelper.swift */,
241 | 31A1E5F3277E1BFA006079AE /* OpenWebsiteHelper.swift */,
242 | );
243 | path = Util;
244 | sourceTree = "";
245 | };
246 | /* End PBXGroup section */
247 |
248 | /* Begin PBXNativeTarget section */
249 | 314FD7D3277A3D0800D16AED /* UTMBeGoneHelper */ = {
250 | isa = PBXNativeTarget;
251 | buildConfigurationList = 314FD7E0277A3D0900D16AED /* Build configuration list for PBXNativeTarget "UTMBeGoneHelper" */;
252 | buildPhases = (
253 | 314FD7D0277A3D0800D16AED /* Sources */,
254 | 314FD7D1277A3D0800D16AED /* Frameworks */,
255 | 314FD7D2277A3D0800D16AED /* Resources */,
256 | );
257 | buildRules = (
258 | );
259 | dependencies = (
260 | );
261 | name = UTMBeGoneHelper;
262 | productName = UTMBeGoneHelper;
263 | productReference = 314FD7D4277A3D0800D16AED /* UTMBeGoneHelper.app */;
264 | productType = "com.apple.product-type.application";
265 | };
266 | 31A6634424FDAB4400CDD04A /* UTMBeGone */ = {
267 | isa = PBXNativeTarget;
268 | buildConfigurationList = 31A6635E24FDAB4500CDD04A /* Build configuration list for PBXNativeTarget "UTMBeGone" */;
269 | buildPhases = (
270 | 31A6634124FDAB4400CDD04A /* Sources */,
271 | 31A6634224FDAB4400CDD04A /* Frameworks */,
272 | 31A6634324FDAB4400CDD04A /* Resources */,
273 | 31A42F572779035200A0B82D /* CopyFiles */,
274 | );
275 | buildRules = (
276 | );
277 | dependencies = (
278 | );
279 | name = UTMBeGone;
280 | productName = UTMBeGone;
281 | productReference = 31A6634524FDAB4400CDD04A /* UTMBeGone.app */;
282 | productType = "com.apple.product-type.application";
283 | };
284 | 31A6635424FDAB4500CDD04A /* UTMBeGoneTests */ = {
285 | isa = PBXNativeTarget;
286 | buildConfigurationList = 31A6636124FDAB4500CDD04A /* Build configuration list for PBXNativeTarget "UTMBeGoneTests" */;
287 | buildPhases = (
288 | 31A6635124FDAB4500CDD04A /* Sources */,
289 | 31A6635224FDAB4500CDD04A /* Frameworks */,
290 | 31A6635324FDAB4500CDD04A /* Resources */,
291 | );
292 | buildRules = (
293 | );
294 | dependencies = (
295 | 31A6635724FDAB4500CDD04A /* PBXTargetDependency */,
296 | );
297 | name = UTMBeGoneTests;
298 | productName = UTMBeGoneTests;
299 | productReference = 31A6635524FDAB4500CDD04A /* UTMBeGoneTests.xctest */;
300 | productType = "com.apple.product-type.bundle.unit-test";
301 | };
302 | /* End PBXNativeTarget section */
303 |
304 | /* Begin PBXProject section */
305 | 31A6633D24FDAB4400CDD04A /* Project object */ = {
306 | isa = PBXProject;
307 | attributes = {
308 | LastSwiftUpdateCheck = 1320;
309 | LastUpgradeCheck = 1200;
310 | ORGANIZATIONNAME = "Fernando Bunn";
311 | TargetAttributes = {
312 | 314FD7D3277A3D0800D16AED = {
313 | CreatedOnToolsVersion = 13.2;
314 | };
315 | 31A6634424FDAB4400CDD04A = {
316 | CreatedOnToolsVersion = 11.6;
317 | LastSwiftMigration = 1170;
318 | };
319 | 31A6635424FDAB4500CDD04A = {
320 | CreatedOnToolsVersion = 11.6;
321 | TestTargetID = 31A6634424FDAB4400CDD04A;
322 | };
323 | };
324 | };
325 | buildConfigurationList = 31A6634024FDAB4400CDD04A /* Build configuration list for PBXProject "UTMBeGone" */;
326 | compatibilityVersion = "Xcode 9.3";
327 | developmentRegion = en;
328 | hasScannedForEncodings = 0;
329 | knownRegions = (
330 | en,
331 | Base,
332 | );
333 | mainGroup = 31A6633C24FDAB4400CDD04A;
334 | productRefGroup = 31A6634624FDAB4400CDD04A /* Products */;
335 | projectDirPath = "";
336 | projectRoot = "";
337 | targets = (
338 | 31A6634424FDAB4400CDD04A /* UTMBeGone */,
339 | 31A6635424FDAB4500CDD04A /* UTMBeGoneTests */,
340 | 314FD7D3277A3D0800D16AED /* UTMBeGoneHelper */,
341 | );
342 | };
343 | /* End PBXProject section */
344 |
345 | /* Begin PBXResourcesBuildPhase section */
346 | 314FD7D2277A3D0800D16AED /* Resources */ = {
347 | isa = PBXResourcesBuildPhase;
348 | buildActionMask = 2147483647;
349 | files = (
350 | 314FD7DB277A3D0900D16AED /* Assets.xcassets in Resources */,
351 | 314FD7DE277A3D0900D16AED /* Main.storyboard in Resources */,
352 | );
353 | runOnlyForDeploymentPostprocessing = 0;
354 | };
355 | 31A6634324FDAB4400CDD04A /* Resources */ = {
356 | isa = PBXResourcesBuildPhase;
357 | buildActionMask = 2147483647;
358 | files = (
359 | 31A6634B24FDAB4400CDD04A /* Assets.xcassets in Resources */,
360 | 31A6634E24FDAB4400CDD04A /* MainMenu.xib in Resources */,
361 | 31D95686250663D100DCD1D1 /* PreferencesViewController.xib in Resources */,
362 | );
363 | runOnlyForDeploymentPostprocessing = 0;
364 | };
365 | 31A6635324FDAB4500CDD04A /* Resources */ = {
366 | isa = PBXResourcesBuildPhase;
367 | buildActionMask = 2147483647;
368 | files = (
369 | );
370 | runOnlyForDeploymentPostprocessing = 0;
371 | };
372 | /* End PBXResourcesBuildPhase section */
373 |
374 | /* Begin PBXSourcesBuildPhase section */
375 | 314FD7D0277A3D0800D16AED /* Sources */ = {
376 | isa = PBXSourcesBuildPhase;
377 | buildActionMask = 2147483647;
378 | files = (
379 | 314FD7E4277A3D3B00D16AED /* Bundle+MainApp.swift in Sources */,
380 | 314FD7D7277A3D0900D16AED /* AppDelegate.swift in Sources */,
381 | );
382 | runOnlyForDeploymentPostprocessing = 0;
383 | };
384 | 31A6634124FDAB4400CDD04A /* Sources */ = {
385 | isa = PBXSourcesBuildPhase;
386 | buildActionMask = 2147483647;
387 | files = (
388 | 31A6636B24FDAB9C00CDD04A /* MenuManager.swift in Sources */,
389 | 31A6636524FDAB5900CDD04A /* URLGarbageRemover.swift in Sources */,
390 | 31A6634924FDAB4400CDD04A /* AppDelegate.swift in Sources */,
391 | 31A1E5F4277E1BFA006079AE /* OpenWebsiteHelper.swift in Sources */,
392 | 31A6636924FDAB5E00CDD04A /* PasteboardListener.swift in Sources */,
393 | 31A6636824FDAB5E00CDD04A /* PasteboardHandler.swift in Sources */,
394 | 3192B4F227791B7400EFC6FB /* LaunchAtLoginHelper.swift in Sources */,
395 | 31D9568B2506702F00DCD1D1 /* QueryItemsManager.swift in Sources */,
396 | 31629499250D180C0015E908 /* NotificationNames.swift in Sources */,
397 | 3192B4EF277919E400EFC6FB /* SharedConsts.swift in Sources */,
398 | 31D9568925066F2C00DCD1D1 /* QueryItem.swift in Sources */,
399 | 31D95685250663D100DCD1D1 /* PreferencesViewController.swift in Sources */,
400 | );
401 | runOnlyForDeploymentPostprocessing = 0;
402 | };
403 | 31A6635124FDAB4500CDD04A /* Sources */ = {
404 | isa = PBXSourcesBuildPhase;
405 | buildActionMask = 2147483647;
406 | files = (
407 | 31A6635A24FDAB4500CDD04A /* UTMBeGoneTests.swift in Sources */,
408 | );
409 | runOnlyForDeploymentPostprocessing = 0;
410 | };
411 | /* End PBXSourcesBuildPhase section */
412 |
413 | /* Begin PBXTargetDependency section */
414 | 31A6635724FDAB4500CDD04A /* PBXTargetDependency */ = {
415 | isa = PBXTargetDependency;
416 | target = 31A6634424FDAB4400CDD04A /* UTMBeGone */;
417 | targetProxy = 31A6635624FDAB4500CDD04A /* PBXContainerItemProxy */;
418 | };
419 | /* End PBXTargetDependency section */
420 |
421 | /* Begin PBXVariantGroup section */
422 | 314FD7DC277A3D0900D16AED /* Main.storyboard */ = {
423 | isa = PBXVariantGroup;
424 | children = (
425 | 314FD7DD277A3D0900D16AED /* Base */,
426 | );
427 | name = Main.storyboard;
428 | sourceTree = "";
429 | };
430 | 31A6634C24FDAB4400CDD04A /* MainMenu.xib */ = {
431 | isa = PBXVariantGroup;
432 | children = (
433 | 31A6634D24FDAB4400CDD04A /* Base */,
434 | );
435 | name = MainMenu.xib;
436 | sourceTree = "";
437 | };
438 | /* End PBXVariantGroup section */
439 |
440 | /* Begin XCBuildConfiguration section */
441 | 314FD7E1277A3D0900D16AED /* Debug */ = {
442 | isa = XCBuildConfiguration;
443 | buildSettings = {
444 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
445 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
446 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++17";
447 | CODE_SIGN_ENTITLEMENTS = UTMBeGoneHelper/UTMBeGoneHelper.entitlements;
448 | CODE_SIGN_STYLE = Automatic;
449 | COMBINE_HIDPI_IMAGES = YES;
450 | CURRENT_PROJECT_VERSION = 14;
451 | DEVELOPMENT_TEAM = B2RUA6XMHC;
452 | ENABLE_HARDENED_RUNTIME = YES;
453 | GENERATE_INFOPLIST_FILE = YES;
454 | INFOPLIST_FILE = UTMBeGoneHelper/Info.plist;
455 | INFOPLIST_KEY_CFBundleDisplayName = "";
456 | INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.utilities";
457 | INFOPLIST_KEY_NSHumanReadableCopyright = "Copyright © 2021 Fernando Bunn. All rights reserved.";
458 | INFOPLIST_KEY_NSMainStoryboardFile = Main;
459 | INFOPLIST_KEY_NSPrincipalClass = NSApplication;
460 | LD_RUNPATH_SEARCH_PATHS = (
461 | "$(inherited)",
462 | "@executable_path/../Frameworks",
463 | );
464 | MACOSX_DEPLOYMENT_TARGET = 10.15;
465 | MARKETING_VERSION = 1.3.0;
466 | PRODUCT_BUNDLE_IDENTIFIER = bunn.dev.UTMBeGoneHelper;
467 | PRODUCT_NAME = "$(TARGET_NAME)";
468 | SKIP_INSTALL = YES;
469 | SWIFT_EMIT_LOC_STRINGS = YES;
470 | SWIFT_VERSION = 5.0;
471 | };
472 | name = Debug;
473 | };
474 | 314FD7E2277A3D0900D16AED /* Release */ = {
475 | isa = XCBuildConfiguration;
476 | buildSettings = {
477 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
478 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
479 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++17";
480 | CODE_SIGN_ENTITLEMENTS = UTMBeGoneHelper/UTMBeGoneHelper.entitlements;
481 | CODE_SIGN_STYLE = Automatic;
482 | COMBINE_HIDPI_IMAGES = YES;
483 | CURRENT_PROJECT_VERSION = 14;
484 | DEVELOPMENT_TEAM = B2RUA6XMHC;
485 | ENABLE_HARDENED_RUNTIME = YES;
486 | GENERATE_INFOPLIST_FILE = YES;
487 | INFOPLIST_FILE = UTMBeGoneHelper/Info.plist;
488 | INFOPLIST_KEY_CFBundleDisplayName = "";
489 | INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.utilities";
490 | INFOPLIST_KEY_NSHumanReadableCopyright = "Copyright © 2021 Fernando Bunn. All rights reserved.";
491 | INFOPLIST_KEY_NSMainStoryboardFile = Main;
492 | INFOPLIST_KEY_NSPrincipalClass = NSApplication;
493 | LD_RUNPATH_SEARCH_PATHS = (
494 | "$(inherited)",
495 | "@executable_path/../Frameworks",
496 | );
497 | MACOSX_DEPLOYMENT_TARGET = 10.15;
498 | MARKETING_VERSION = 1.3.0;
499 | PRODUCT_BUNDLE_IDENTIFIER = bunn.dev.UTMBeGoneHelper;
500 | PRODUCT_NAME = "$(TARGET_NAME)";
501 | SKIP_INSTALL = YES;
502 | SWIFT_EMIT_LOC_STRINGS = YES;
503 | SWIFT_VERSION = 5.0;
504 | };
505 | name = Release;
506 | };
507 | 31A6635C24FDAB4500CDD04A /* Debug */ = {
508 | isa = XCBuildConfiguration;
509 | buildSettings = {
510 | ALWAYS_SEARCH_USER_PATHS = NO;
511 | CLANG_ANALYZER_NONNULL = YES;
512 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
513 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
514 | CLANG_CXX_LIBRARY = "libc++";
515 | CLANG_ENABLE_MODULES = YES;
516 | CLANG_ENABLE_OBJC_ARC = YES;
517 | CLANG_ENABLE_OBJC_WEAK = YES;
518 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
519 | CLANG_WARN_BOOL_CONVERSION = YES;
520 | CLANG_WARN_COMMA = YES;
521 | CLANG_WARN_CONSTANT_CONVERSION = YES;
522 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
523 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
524 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
525 | CLANG_WARN_EMPTY_BODY = YES;
526 | CLANG_WARN_ENUM_CONVERSION = YES;
527 | CLANG_WARN_INFINITE_RECURSION = YES;
528 | CLANG_WARN_INT_CONVERSION = YES;
529 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
530 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
531 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
532 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
533 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
534 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
535 | CLANG_WARN_STRICT_PROTOTYPES = YES;
536 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
537 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
538 | CLANG_WARN_UNREACHABLE_CODE = YES;
539 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
540 | COPY_PHASE_STRIP = NO;
541 | DEBUG_INFORMATION_FORMAT = dwarf;
542 | ENABLE_STRICT_OBJC_MSGSEND = YES;
543 | ENABLE_TESTABILITY = YES;
544 | GCC_C_LANGUAGE_STANDARD = gnu11;
545 | GCC_DYNAMIC_NO_PIC = NO;
546 | GCC_NO_COMMON_BLOCKS = YES;
547 | GCC_OPTIMIZATION_LEVEL = 0;
548 | GCC_PREPROCESSOR_DEFINITIONS = (
549 | "DEBUG=1",
550 | "$(inherited)",
551 | );
552 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
553 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
554 | GCC_WARN_UNDECLARED_SELECTOR = YES;
555 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
556 | GCC_WARN_UNUSED_FUNCTION = YES;
557 | GCC_WARN_UNUSED_VARIABLE = YES;
558 | MACOSX_DEPLOYMENT_TARGET = 10.15;
559 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
560 | MTL_FAST_MATH = YES;
561 | ONLY_ACTIVE_ARCH = YES;
562 | SDKROOT = macosx;
563 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
564 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
565 | };
566 | name = Debug;
567 | };
568 | 31A6635D24FDAB4500CDD04A /* Release */ = {
569 | isa = XCBuildConfiguration;
570 | buildSettings = {
571 | ALWAYS_SEARCH_USER_PATHS = NO;
572 | CLANG_ANALYZER_NONNULL = YES;
573 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
574 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
575 | CLANG_CXX_LIBRARY = "libc++";
576 | CLANG_ENABLE_MODULES = YES;
577 | CLANG_ENABLE_OBJC_ARC = YES;
578 | CLANG_ENABLE_OBJC_WEAK = YES;
579 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
580 | CLANG_WARN_BOOL_CONVERSION = YES;
581 | CLANG_WARN_COMMA = YES;
582 | CLANG_WARN_CONSTANT_CONVERSION = YES;
583 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
584 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
585 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
586 | CLANG_WARN_EMPTY_BODY = YES;
587 | CLANG_WARN_ENUM_CONVERSION = YES;
588 | CLANG_WARN_INFINITE_RECURSION = YES;
589 | CLANG_WARN_INT_CONVERSION = YES;
590 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
591 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
592 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
593 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
594 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
595 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
596 | CLANG_WARN_STRICT_PROTOTYPES = YES;
597 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
598 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
599 | CLANG_WARN_UNREACHABLE_CODE = YES;
600 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
601 | COPY_PHASE_STRIP = NO;
602 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
603 | ENABLE_NS_ASSERTIONS = NO;
604 | ENABLE_STRICT_OBJC_MSGSEND = YES;
605 | GCC_C_LANGUAGE_STANDARD = gnu11;
606 | GCC_NO_COMMON_BLOCKS = YES;
607 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
608 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
609 | GCC_WARN_UNDECLARED_SELECTOR = YES;
610 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
611 | GCC_WARN_UNUSED_FUNCTION = YES;
612 | GCC_WARN_UNUSED_VARIABLE = YES;
613 | MACOSX_DEPLOYMENT_TARGET = 10.15;
614 | MTL_ENABLE_DEBUG_INFO = NO;
615 | MTL_FAST_MATH = YES;
616 | SDKROOT = macosx;
617 | SWIFT_COMPILATION_MODE = wholemodule;
618 | SWIFT_OPTIMIZATION_LEVEL = "-O";
619 | };
620 | name = Release;
621 | };
622 | 31A6635F24FDAB4500CDD04A /* Debug */ = {
623 | isa = XCBuildConfiguration;
624 | buildSettings = {
625 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
626 | CLANG_ENABLE_MODULES = YES;
627 | CODE_SIGN_ENTITLEMENTS = UTMBeGone/UTMBeGone.entitlements;
628 | CODE_SIGN_IDENTITY = "Apple Development";
629 | CODE_SIGN_STYLE = Automatic;
630 | COMBINE_HIDPI_IMAGES = YES;
631 | CURRENT_PROJECT_VERSION = 14;
632 | DEVELOPMENT_TEAM = B2RUA6XMHC;
633 | ENABLE_HARDENED_RUNTIME = YES;
634 | INFOPLIST_FILE = UTMBeGone/Info.plist;
635 | LD_RUNPATH_SEARCH_PATHS = (
636 | "$(inherited)",
637 | "@executable_path/../Frameworks",
638 | );
639 | MARKETING_VERSION = 1.3.0;
640 | PRODUCT_BUNDLE_IDENTIFIER = bunn.dev.utmbegone;
641 | PRODUCT_NAME = "$(TARGET_NAME)";
642 | SWIFT_OBJC_BRIDGING_HEADER = "UTMBeGone/Util/UTMBeGone-Bridging-Header.h";
643 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
644 | SWIFT_VERSION = 5.0;
645 | };
646 | name = Debug;
647 | };
648 | 31A6636024FDAB4500CDD04A /* Release */ = {
649 | isa = XCBuildConfiguration;
650 | buildSettings = {
651 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
652 | CLANG_ENABLE_MODULES = YES;
653 | CODE_SIGN_ENTITLEMENTS = UTMBeGone/UTMBeGone.entitlements;
654 | CODE_SIGN_IDENTITY = "Apple Development";
655 | CODE_SIGN_STYLE = Automatic;
656 | COMBINE_HIDPI_IMAGES = YES;
657 | CURRENT_PROJECT_VERSION = 14;
658 | DEVELOPMENT_TEAM = B2RUA6XMHC;
659 | ENABLE_HARDENED_RUNTIME = YES;
660 | INFOPLIST_FILE = UTMBeGone/Info.plist;
661 | LD_RUNPATH_SEARCH_PATHS = (
662 | "$(inherited)",
663 | "@executable_path/../Frameworks",
664 | );
665 | MARKETING_VERSION = 1.3.0;
666 | PRODUCT_BUNDLE_IDENTIFIER = bunn.dev.utmbegone;
667 | PRODUCT_NAME = "$(TARGET_NAME)";
668 | SWIFT_OBJC_BRIDGING_HEADER = "UTMBeGone/Util/UTMBeGone-Bridging-Header.h";
669 | SWIFT_VERSION = 5.0;
670 | };
671 | name = Release;
672 | };
673 | 31A6636224FDAB4500CDD04A /* Debug */ = {
674 | isa = XCBuildConfiguration;
675 | buildSettings = {
676 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
677 | BUNDLE_LOADER = "$(TEST_HOST)";
678 | CODE_SIGN_STYLE = Automatic;
679 | COMBINE_HIDPI_IMAGES = YES;
680 | DEVELOPMENT_TEAM = B2RUA6XMHC;
681 | INFOPLIST_FILE = UTMBeGoneTests/Info.plist;
682 | LD_RUNPATH_SEARCH_PATHS = (
683 | "$(inherited)",
684 | "@executable_path/../Frameworks",
685 | "@loader_path/../Frameworks",
686 | );
687 | MACOSX_DEPLOYMENT_TARGET = 10.15;
688 | PRODUCT_BUNDLE_IDENTIFIER = bunn.dev.UTMBeGoneTests;
689 | PRODUCT_NAME = "$(TARGET_NAME)";
690 | SWIFT_VERSION = 5.0;
691 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/UTMBeGone.app/Contents/MacOS/UTMBeGone";
692 | };
693 | name = Debug;
694 | };
695 | 31A6636324FDAB4500CDD04A /* Release */ = {
696 | isa = XCBuildConfiguration;
697 | buildSettings = {
698 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
699 | BUNDLE_LOADER = "$(TEST_HOST)";
700 | CODE_SIGN_STYLE = Automatic;
701 | COMBINE_HIDPI_IMAGES = YES;
702 | DEVELOPMENT_TEAM = B2RUA6XMHC;
703 | INFOPLIST_FILE = UTMBeGoneTests/Info.plist;
704 | LD_RUNPATH_SEARCH_PATHS = (
705 | "$(inherited)",
706 | "@executable_path/../Frameworks",
707 | "@loader_path/../Frameworks",
708 | );
709 | MACOSX_DEPLOYMENT_TARGET = 10.15;
710 | PRODUCT_BUNDLE_IDENTIFIER = bunn.dev.UTMBeGoneTests;
711 | PRODUCT_NAME = "$(TARGET_NAME)";
712 | SWIFT_VERSION = 5.0;
713 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/UTMBeGone.app/Contents/MacOS/UTMBeGone";
714 | };
715 | name = Release;
716 | };
717 | /* End XCBuildConfiguration section */
718 |
719 | /* Begin XCConfigurationList section */
720 | 314FD7E0277A3D0900D16AED /* Build configuration list for PBXNativeTarget "UTMBeGoneHelper" */ = {
721 | isa = XCConfigurationList;
722 | buildConfigurations = (
723 | 314FD7E1277A3D0900D16AED /* Debug */,
724 | 314FD7E2277A3D0900D16AED /* Release */,
725 | );
726 | defaultConfigurationIsVisible = 0;
727 | defaultConfigurationName = Release;
728 | };
729 | 31A6634024FDAB4400CDD04A /* Build configuration list for PBXProject "UTMBeGone" */ = {
730 | isa = XCConfigurationList;
731 | buildConfigurations = (
732 | 31A6635C24FDAB4500CDD04A /* Debug */,
733 | 31A6635D24FDAB4500CDD04A /* Release */,
734 | );
735 | defaultConfigurationIsVisible = 0;
736 | defaultConfigurationName = Release;
737 | };
738 | 31A6635E24FDAB4500CDD04A /* Build configuration list for PBXNativeTarget "UTMBeGone" */ = {
739 | isa = XCConfigurationList;
740 | buildConfigurations = (
741 | 31A6635F24FDAB4500CDD04A /* Debug */,
742 | 31A6636024FDAB4500CDD04A /* Release */,
743 | );
744 | defaultConfigurationIsVisible = 0;
745 | defaultConfigurationName = Release;
746 | };
747 | 31A6636124FDAB4500CDD04A /* Build configuration list for PBXNativeTarget "UTMBeGoneTests" */ = {
748 | isa = XCConfigurationList;
749 | buildConfigurations = (
750 | 31A6636224FDAB4500CDD04A /* Debug */,
751 | 31A6636324FDAB4500CDD04A /* Release */,
752 | );
753 | defaultConfigurationIsVisible = 0;
754 | defaultConfigurationName = Release;
755 | };
756 | /* End XCConfigurationList section */
757 | };
758 | rootObject = 31A6633D24FDAB4400CDD04A /* Project object */;
759 | }
760 |
--------------------------------------------------------------------------------
/UTMBeGone.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/UTMBeGone.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/UTMBeGone/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // UTMBeGone
4 | //
5 | // Created by Fernando Bunn on 31/08/2020.
6 | // Copyright © 2020 Fernando Bunn. All rights reserved.
7 | //
8 |
9 | import Cocoa
10 |
11 | @NSApplicationMain
12 | class AppDelegate: NSObject, NSApplicationDelegate {
13 | let pasteboardHandler = PasteboardHandler()
14 | let menu = MenuManager()
15 |
16 | func applicationDidFinishLaunching(_ aNotification: Notification) {
17 | NSApplication.shared.setActivationPolicy(.accessory)
18 | pasteboardHandler.startListening()
19 | menu.setupMenu()
20 |
21 | LaunchAtLoginHelper().killHelperIfNecessary()
22 | }
23 |
24 | func applicationWillTerminate(_ aNotification: Notification) {
25 | pasteboardHandler.stopListening()
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/UTMBeGone/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "mac",
5 | "scale" : "1x",
6 | "size" : "16x16"
7 | },
8 | {
9 | "filename" : "UTMBeGone32-1.png",
10 | "idiom" : "mac",
11 | "scale" : "2x",
12 | "size" : "16x16"
13 | },
14 | {
15 | "filename" : "UTMBeGone32.png",
16 | "idiom" : "mac",
17 | "scale" : "1x",
18 | "size" : "32x32"
19 | },
20 | {
21 | "filename" : "UTMBeGone64.png",
22 | "idiom" : "mac",
23 | "scale" : "2x",
24 | "size" : "32x32"
25 | },
26 | {
27 | "filename" : "UTMBeGone128.png",
28 | "idiom" : "mac",
29 | "scale" : "1x",
30 | "size" : "128x128"
31 | },
32 | {
33 | "filename" : "UTMBeGone256-1.png",
34 | "idiom" : "mac",
35 | "scale" : "2x",
36 | "size" : "128x128"
37 | },
38 | {
39 | "filename" : "UTMBeGone256.png",
40 | "idiom" : "mac",
41 | "scale" : "1x",
42 | "size" : "256x256"
43 | },
44 | {
45 | "filename" : "UTMBeGone512-1.png",
46 | "idiom" : "mac",
47 | "scale" : "2x",
48 | "size" : "256x256"
49 | },
50 | {
51 | "filename" : "UTMBeGone512.png",
52 | "idiom" : "mac",
53 | "scale" : "1x",
54 | "size" : "512x512"
55 | },
56 | {
57 | "filename" : "UTMBeGone1024.png",
58 | "idiom" : "mac",
59 | "scale" : "2x",
60 | "size" : "512x512"
61 | }
62 | ],
63 | "info" : {
64 | "author" : "xcode",
65 | "version" : 1
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/UTMBeGone/Assets.xcassets/AppIcon.appiconset/UTMBeGone1024.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Bunn/UTMBeGone/5cfce9911498a836ce92521a21a811b65a21b28b/UTMBeGone/Assets.xcassets/AppIcon.appiconset/UTMBeGone1024.png
--------------------------------------------------------------------------------
/UTMBeGone/Assets.xcassets/AppIcon.appiconset/UTMBeGone128.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Bunn/UTMBeGone/5cfce9911498a836ce92521a21a811b65a21b28b/UTMBeGone/Assets.xcassets/AppIcon.appiconset/UTMBeGone128.png
--------------------------------------------------------------------------------
/UTMBeGone/Assets.xcassets/AppIcon.appiconset/UTMBeGone256-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Bunn/UTMBeGone/5cfce9911498a836ce92521a21a811b65a21b28b/UTMBeGone/Assets.xcassets/AppIcon.appiconset/UTMBeGone256-1.png
--------------------------------------------------------------------------------
/UTMBeGone/Assets.xcassets/AppIcon.appiconset/UTMBeGone256.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Bunn/UTMBeGone/5cfce9911498a836ce92521a21a811b65a21b28b/UTMBeGone/Assets.xcassets/AppIcon.appiconset/UTMBeGone256.png
--------------------------------------------------------------------------------
/UTMBeGone/Assets.xcassets/AppIcon.appiconset/UTMBeGone32-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Bunn/UTMBeGone/5cfce9911498a836ce92521a21a811b65a21b28b/UTMBeGone/Assets.xcassets/AppIcon.appiconset/UTMBeGone32-1.png
--------------------------------------------------------------------------------
/UTMBeGone/Assets.xcassets/AppIcon.appiconset/UTMBeGone32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Bunn/UTMBeGone/5cfce9911498a836ce92521a21a811b65a21b28b/UTMBeGone/Assets.xcassets/AppIcon.appiconset/UTMBeGone32.png
--------------------------------------------------------------------------------
/UTMBeGone/Assets.xcassets/AppIcon.appiconset/UTMBeGone512-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Bunn/UTMBeGone/5cfce9911498a836ce92521a21a811b65a21b28b/UTMBeGone/Assets.xcassets/AppIcon.appiconset/UTMBeGone512-1.png
--------------------------------------------------------------------------------
/UTMBeGone/Assets.xcassets/AppIcon.appiconset/UTMBeGone512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Bunn/UTMBeGone/5cfce9911498a836ce92521a21a811b65a21b28b/UTMBeGone/Assets.xcassets/AppIcon.appiconset/UTMBeGone512.png
--------------------------------------------------------------------------------
/UTMBeGone/Assets.xcassets/AppIcon.appiconset/UTMBeGone64.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Bunn/UTMBeGone/5cfce9911498a836ce92521a21a811b65a21b28b/UTMBeGone/Assets.xcassets/AppIcon.appiconset/UTMBeGone64.png
--------------------------------------------------------------------------------
/UTMBeGone/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/UTMBeGone/Assets.xcassets/icon.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "filename" : "icon.pdf",
5 | "idiom" : "universal",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "author" : "xcode",
19 | "version" : 1
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/UTMBeGone/Assets.xcassets/icon.imageset/icon.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Bunn/UTMBeGone/5cfce9911498a836ce92521a21a811b65a21b28b/UTMBeGone/Assets.xcassets/icon.imageset/icon.pdf
--------------------------------------------------------------------------------
/UTMBeGone/Base.lproj/MainMenu.xib:
--------------------------------------------------------------------------------
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 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
198 |
199 |
200 |
201 |
202 |
203 |
204 |
205 |
206 |
207 |
208 |
209 |
210 |
211 |
212 |
213 |
214 |
215 |
216 |
217 |
218 |
219 |
220 |
221 |
222 |
223 |
224 |
225 |
226 |
227 |
228 |
229 |
230 |
231 |
232 |
233 |
234 |
235 |
236 |
237 |
238 |
239 |
240 |
241 |
242 |
243 |
244 |
245 |
246 |
247 |
248 |
249 |
250 |
251 |
252 |
253 |
254 |
255 |
256 |
257 |
258 |
259 |
260 |
261 |
262 |
263 |
264 |
265 |
266 |
267 |
268 |
269 |
270 |
271 |
272 |
273 |
274 |
275 |
276 |
277 |
278 |
279 |
280 |
281 |
282 |
283 |
284 |
285 |
286 |
287 |
288 |
289 |
290 |
291 |
292 |
293 |
294 |
295 |
296 |
297 |
298 |
299 |
300 |
301 |
302 |
303 |
304 |
305 |
306 |
307 |
308 |
309 |
310 |
311 |
312 |
313 |
314 |
315 |
316 |
317 |
318 |
319 |
320 |
321 |
322 |
323 |
324 |
325 |
326 |
327 |
328 |
329 |
330 |
331 |
332 |
333 |
334 |
335 |
336 |
337 |
338 |
339 |
340 |
341 |
342 |
343 |
344 |
345 |
346 |
347 |
348 |
349 |
350 |
351 |
352 |
353 |
354 |
355 |
356 |
357 |
358 |
359 |
360 |
361 |
362 |
363 |
364 |
365 |
366 |
367 |
368 |
369 |
370 |
371 |
372 |
373 |
374 |
375 |
376 |
377 |
378 |
379 |
380 |
381 |
382 |
383 |
384 |
385 |
386 |
387 |
388 |
389 |
390 |
391 |
392 |
393 |
394 |
395 |
396 |
397 |
398 |
399 |
400 |
401 |
402 |
403 |
404 |
405 |
406 |
407 |
408 |
409 |
410 |
411 |
412 |
413 |
414 |
415 |
416 |
417 |
418 |
419 |
420 |
421 |
422 |
423 |
424 |
425 |
426 |
427 |
428 |
429 |
430 |
431 |
432 |
433 |
434 |
435 |
436 |
437 |
438 |
439 |
440 |
441 |
442 |
443 |
444 |
445 |
446 |
447 |
448 |
449 |
450 |
451 |
452 |
453 |
454 |
455 |
456 |
457 |
458 |
459 |
460 |
461 |
462 |
463 |
464 |
465 |
466 |
467 |
468 |
469 |
470 |
471 |
472 |
473 |
474 |
475 |
476 |
477 |
478 |
479 |
480 |
481 |
482 |
483 |
484 |
485 |
486 |
487 |
488 |
489 |
490 |
491 |
492 |
493 |
494 |
495 |
496 |
497 |
498 |
499 |
500 |
501 |
502 |
503 |
504 |
505 |
506 |
507 |
508 |
509 |
510 |
511 |
512 |
513 |
514 |
515 |
516 |
517 |
518 |
519 |
520 |
521 |
522 |
523 |
524 |
525 |
526 |
527 |
528 |
529 |
530 |
531 |
532 |
533 | Default
534 |
535 |
536 |
537 |
538 |
539 |
540 | Left to Right
541 |
542 |
543 |
544 |
545 |
546 |
547 | Right to Left
548 |
549 |
550 |
551 |
552 |
553 |
554 |
555 |
556 |
557 |
558 | Default
559 |
560 |
561 |
562 |
563 |
564 |
565 | Left to Right
566 |
567 |
568 |
569 |
570 |
571 |
572 | Right to Left
573 |
574 |
575 |
576 |
577 |
578 |
579 |
580 |
581 |
582 |
583 |
584 |
585 |
586 |
587 |
588 |
589 |
590 |
591 |
592 |
593 |
594 |
595 |
596 |
597 |
598 |
599 |
600 |
601 |
602 |
603 |
604 |
605 |
606 |
607 |
608 |
609 |
610 |
611 |
612 |
613 |
614 |
615 |
616 |
617 |
618 |
619 |
620 |
621 |
622 |
623 |
624 |
625 |
626 |
627 |
628 |
629 |
630 |
631 |
632 |
633 |
634 |
635 |
636 |
637 |
638 |
639 |
640 |
641 |
642 |
643 |
644 |
645 |
646 |
647 |
648 |
649 |
650 |
651 |
652 |
653 |
654 |
655 |
656 |
657 |
658 |
659 |
660 |
661 |
662 |
663 |
664 |
665 |
666 |
667 |
668 |
669 |
670 |
671 |
672 |
673 |
674 |
675 |
676 |
677 |
678 |
679 |
680 |
--------------------------------------------------------------------------------
/UTMBeGone/GarbageRemover/URLGarbageRemover.swift:
--------------------------------------------------------------------------------
1 | //
2 | // URLGarbageRemover.swift
3 | // UTMBeGone
4 | //
5 | // Created by Fernando Bunn on 31/08/2020.
6 | // Copyright © 2020 Fernando Bunn. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | struct URLGarbageRemover {
12 | static func removeGarbage(_ value: String, itemsToRemove: [String]) -> String {
13 |
14 | let sanitizedString = value.trimmingCharacters(in: .whitespacesAndNewlines)
15 |
16 | guard let url = URL(string: sanitizedString),
17 | var componenets = URLComponents(url: url, resolvingAgainstBaseURL: true),
18 | componenets.scheme != nil else {
19 | return value
20 | }
21 |
22 | componenets.queryItems = componenets.queryItems?.filter { queryItem in
23 | itemsToRemove.map { queryItem.name == $0 }.allSatisfy { $0 == false }
24 | }
25 |
26 | if var newURL = componenets.string {
27 | if newURL.last == "?" {
28 | newURL.removeLast()
29 | }
30 | return newURL
31 | }
32 | return value
33 | }
34 | }
35 |
36 |
--------------------------------------------------------------------------------
/UTMBeGone/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIconFile
10 |
11 | CFBundleIdentifier
12 | $(PRODUCT_BUNDLE_IDENTIFIER)
13 | CFBundleInfoDictionaryVersion
14 | 6.0
15 | CFBundleName
16 | $(PRODUCT_NAME)
17 | CFBundlePackageType
18 | $(PRODUCT_BUNDLE_PACKAGE_TYPE)
19 | CFBundleShortVersionString
20 | $(MARKETING_VERSION)
21 | CFBundleVersion
22 | $(CURRENT_PROJECT_VERSION)
23 | ITSAppUsesNonExemptEncryption
24 |
25 | LSApplicationCategoryType
26 | public.app-category.utilities
27 | LSMinimumSystemVersion
28 | $(MACOSX_DEPLOYMENT_TARGET)
29 | LSUIElement
30 |
31 | NSHumanReadableCopyright
32 | Copyright © 2020 Fernando Bunn. All rights reserved.
33 | NSMainNibFile
34 | MainMenu
35 | NSPrincipalClass
36 | NSApplication
37 | NSSupportsAutomaticTermination
38 |
39 | NSSupportsSuddenTermination
40 |
41 |
42 |
43 |
--------------------------------------------------------------------------------
/UTMBeGone/Menu/MenuManager.swift:
--------------------------------------------------------------------------------
1 | //
2 | // MenuManager.swift
3 | // UTMBeGone
4 | //
5 | // Created by Fernando Bunn on 31/08/2020.
6 | // Copyright © 2020 Fernando Bunn. All rights reserved.
7 | //
8 |
9 | import Cocoa
10 |
11 | class MenuManager: NSObject {
12 | private let item = NSStatusBar.system.statusItem(withLength: NSStatusItem.variableLength)
13 | private var windowController: NSWindowController?
14 | private var appURL: URL { Bundle.main.bundleURL }
15 | private static let removeItemAlertKey = "UTMBeGone.RemoveItemAlertKey"
16 | private static let stoppedKey = "UTMBeGone.Stopped"
17 |
18 | //Hacky way to figure it out if the user is trying to open the app if it's already running
19 | private var activeCounter = 0
20 |
21 | private var launchAtLoginEnabled: Bool {
22 | get {
23 | LaunchAtLoginHelper().checkEnabled()
24 | }
25 | set {
26 | LaunchAtLoginHelper().setEnabled(newValue)
27 | }
28 | }
29 |
30 | private var stopped: Bool {
31 | get {
32 | UserDefaults.standard.bool(forKey: MenuManager.stoppedKey)
33 | }
34 | set {
35 | UserDefaults.standard.set(newValue, forKey: MenuManager.stoppedKey)
36 | if newValue {
37 | NotificationCenter.default.post(name: .PasteboardShouldStopListening, object: nil)
38 | } else {
39 | NotificationCenter.default.post(name: .PasteboardShouldStartListening, object: nil)
40 | }
41 | setupMenu()
42 | }
43 | }
44 |
45 | @objc private func applicationDidBecomeActive(_ notification: Notification) {
46 | activeCounter += 1
47 | guard activeCounter > 1 else { return }
48 | if item.isVisible == false {
49 | item.isVisible = true
50 | }
51 | }
52 |
53 | public func setupMenu() {
54 | let menu = NSMenu()
55 |
56 | NotificationCenter.default.addObserver(self, selector: #selector(MenuManager.applicationDidBecomeActive), name: NSApplication.didBecomeActiveNotification, object: nil)
57 |
58 | let preferencesItem = NSMenuItem(title: "Preferences", action: #selector(MenuManager.openPreferences), keyEquivalent: "")
59 | preferencesItem.target = self
60 | menu.addItem(preferencesItem)
61 |
62 | if stopped {
63 | let resumeMenuItem = NSMenuItem(title: "Resume ", action: #selector(MenuManager.resume), keyEquivalent: "")
64 | resumeMenuItem.target = self
65 | menu.addItem(resumeMenuItem)
66 | } else {
67 | let stopMenuItem = NSMenuItem(title: "Stop ", action: #selector(MenuManager.stop), keyEquivalent: "")
68 | stopMenuItem.target = self
69 | menu.addItem(stopMenuItem)
70 | }
71 |
72 | let launchAtLoginItem = NSMenuItem(title: "Launch at Login ", action: #selector(MenuManager.toggleLaunchAtLogin), keyEquivalent: "")
73 | launchAtLoginItem.target = self
74 | launchAtLoginItem.state = launchAtLoginEnabled ? .on : .off
75 | menu.addItem(launchAtLoginItem)
76 |
77 | let removeFromMenuItem = NSMenuItem(title: "Hide Icon ", action: #selector(MenuManager.removeFromMenu), keyEquivalent: "")
78 | removeFromMenuItem.target = self
79 | menu.addItem(removeFromMenuItem)
80 |
81 | let websiteItem = NSMenuItem(title: "Project Website", action: #selector(MenuManager.openProjectWebsite), keyEquivalent: "")
82 | websiteItem.target = self
83 | menu.addItem(websiteItem)
84 |
85 | let quitMenuItem = NSMenuItem(title: "Quit", action: #selector(MenuManager.quit), keyEquivalent: "")
86 | quitMenuItem.target = self
87 | menu.addItem(quitMenuItem)
88 |
89 | let image = NSImage(named: .init("icon"))
90 | image?.isTemplate = true
91 |
92 | self.item.button?.image = image
93 | item.menu = menu
94 | item.behavior = .removalAllowed
95 | }
96 |
97 | private func displayRemoveMenuItemAlertIfNecessary() {
98 | if UserDefaults.standard.bool(forKey: MenuManager.removeItemAlertKey) == false {
99 | let alert = NSAlert()
100 | alert.messageText = "UTMBeGone is not gone 😉"
101 | alert.informativeText = "UTMBeGone will keep running in the background. If you wish to see the menu icon again, just double click on the application's icon in your application's folder."
102 | alert.alertStyle = .warning
103 | alert.addButton(withTitle: "Understood!")
104 | alert.runModal()
105 | UserDefaults.standard.set(true, forKey: MenuManager.removeItemAlertKey)
106 | }
107 | }
108 | }
109 |
110 |
111 | //MARK: - Menu Actions
112 |
113 | extension MenuManager {
114 |
115 | @objc private func openPreferences() {
116 | NSApp.activate(ignoringOtherApps: true)
117 | let preferences = PreferencesViewController()
118 | if windowController == nil {
119 | let window = NSWindow(contentViewController: preferences)
120 | window.delegate = self
121 | windowController = NSWindowController(window: window)
122 | }
123 | windowController?.showWindow(self)
124 | windowController?.window?.makeKey()
125 | }
126 |
127 | @objc private func toggleLaunchAtLogin() {
128 | launchAtLoginEnabled.toggle()
129 | setupMenu()
130 | }
131 |
132 | @objc private func openProjectWebsite() {
133 | OpenWebsiteHelper.openWebsite()
134 | }
135 |
136 | @objc private func quit() {
137 | NSApplication.shared.terminate(self)
138 | }
139 |
140 | @objc private func removeFromMenu() {
141 | displayRemoveMenuItemAlertIfNecessary()
142 | item.isVisible = false
143 | }
144 |
145 | @objc private func stop() {
146 | stopped = true
147 | }
148 |
149 | @objc private func resume() {
150 | stopped = false
151 | }
152 | }
153 |
154 |
155 | //MARK: - Window Delegate
156 |
157 | extension MenuManager: NSWindowDelegate {
158 |
159 | func windowWillClose(_ notification: Notification) {
160 | windowController = nil
161 | }
162 | }
163 |
--------------------------------------------------------------------------------
/UTMBeGone/PasteboardCore/PasteboardHandler.swift:
--------------------------------------------------------------------------------
1 | //
2 | // PasteboardHandler.swift
3 | // UTMBeGone
4 | //
5 | // Created by Fernando Bunn on 31/08/2020.
6 | // Copyright © 2020 Fernando Bunn. All rights reserved.
7 | //
8 |
9 | import Cocoa
10 |
11 | class PasteboardHandler: NSObject {
12 | let listerner = PasteboardListener()
13 |
14 | override init() {
15 | super.init()
16 | setupListeners()
17 | }
18 |
19 | private func setupListeners() {
20 | NotificationCenter.default.addObserver(self, selector: #selector(pasteboardShouldStopListening), name: .PasteboardShouldStopListening, object: nil)
21 | NotificationCenter.default.addObserver(self, selector: #selector(pasteboardShouldStartListening), name: .PasteboardShouldStartListening, object: nil)
22 | }
23 |
24 | func startListening() {
25 | NotificationCenter.default.addObserver(self, selector: #selector(onPasteboardChanged), name: .PasteboardDidChange, object: nil)
26 | listerner.startListening()
27 | }
28 |
29 | func stopListening() {
30 | NotificationCenter.default.removeObserver(self, name: .PasteboardDidChange, object: nil)
31 | listerner.stopListening()
32 | }
33 |
34 | @objc func pasteboardShouldStopListening(_ notification: Notification) {
35 | stopListening()
36 | }
37 |
38 | @objc func pasteboardShouldStartListening(_ notification: Notification) {
39 | startListening()
40 | }
41 |
42 | @objc func onPasteboardChanged(_ notification: Notification) {
43 | guard let pasteboard = notification.object as? NSPasteboard,
44 | let items = pasteboard.pasteboardItems,
45 | let item = items.first?.string(forType: .string) else { return }
46 |
47 | let itemsToRemove = QueryItemsManager().queryList.map { $0.value }
48 | let newItem = URLGarbageRemover.removeGarbage(item, itemsToRemove: itemsToRemove)
49 |
50 | if newItem != item {
51 | listerner.stopListening()
52 | let pasteboard = NSPasteboard.general
53 | pasteboard.clearContents()
54 | pasteboard.setString(newItem, forType: .string)
55 | listerner.startListening()
56 | }
57 | }
58 | }
59 |
60 |
--------------------------------------------------------------------------------
/UTMBeGone/PasteboardCore/PasteboardListener.swift:
--------------------------------------------------------------------------------
1 | //
2 | // PasteboardListener.swift
3 | // UTMBeGone
4 | //
5 | // Created by Fernando Bunn on 31/08/2020.
6 | // Copyright © 2020 Fernando Bunn. All rights reserved.
7 | //
8 |
9 | import Cocoa
10 |
11 | class PasteboardListener: NSObject {
12 | var changeCount: Int = 0
13 | var timer: Timer!
14 |
15 | func startListening() {
16 | let pasteboard: NSPasteboard = .general
17 |
18 | timer = Timer.scheduledTimer(withTimeInterval: 0.3, repeats: true) { _ in
19 | if self.changeCount != pasteboard.changeCount {
20 | self.changeCount = pasteboard.changeCount
21 | NotificationCenter.default.post(name: .PasteboardDidChange, object: pasteboard)
22 | }
23 | }
24 | }
25 |
26 | func stopListening() {
27 | timer.invalidate()
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/UTMBeGone/Preferences/PreferencesViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // PreferencesViewController.swift
3 | // UTMBeGone
4 | //
5 | // Created by Fernando Bunn on 07/09/2020.
6 | // Copyright © 2020 Fernando Bunn. All rights reserved.
7 | //
8 |
9 | import Cocoa
10 |
11 | class PreferencesViewController: NSViewController {
12 | private static let cellIdentifier = "DefaultTableCell"
13 | private let itemsManager = QueryItemsManager()
14 | @IBOutlet weak var tableView: NSTableView!
15 |
16 | override func viewDidLoad() {
17 | super.viewDidLoad()
18 | tableView.dataSource = self
19 | tableView.delegate = self
20 | title = "UTMBeGone Preferences"
21 | }
22 |
23 | @objc private func textDidChange(_ sender: NSTextField) {
24 | let row = tableView.row(for: sender)
25 | if row == -1 {
26 | return
27 | }
28 | itemsManager.item(for: row).value = sender.stringValue
29 | itemsManager.save()
30 | }
31 |
32 | @IBAction func addItemButtonClicked(_ sender: NSButton) {
33 | _ = itemsManager.createNewItem()
34 | tableView.reloadData()
35 | }
36 |
37 | @IBAction func removeItemButtonClicked(_ sender: NSButton) {
38 | let selectedRow = tableView.selectedRow
39 | if selectedRow == -1 {
40 | return
41 | }
42 | let item = itemsManager.item(for: selectedRow)
43 | itemsManager.delete(item)
44 | tableView.reloadData()
45 | }
46 |
47 | @IBAction func projectWebsiteButtonClicked(_ sender: NSButton) {
48 | OpenWebsiteHelper.openWebsite()
49 | }
50 | }
51 |
52 | extension PreferencesViewController: NSTableViewDelegate {
53 |
54 | func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? {
55 | let cell = tableView.makeView(withIdentifier: NSUserInterfaceItemIdentifier(rawValue: PreferencesViewController.cellIdentifier), owner: self) as? NSTableCellView
56 | cell?.textField?.stringValue = itemsManager.item(for: row).value
57 | cell?.textField?.target = self
58 | cell?.textField?.action = #selector(PreferencesViewController.textDidChange)
59 | return cell
60 | }
61 | }
62 |
63 | extension PreferencesViewController: NSTableViewDataSource {
64 |
65 | func numberOfRows(in tableView: NSTableView) -> Int {
66 | return itemsManager.numberOfItems
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/UTMBeGone/Preferences/PreferencesViewController.xib:
--------------------------------------------------------------------------------
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 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
--------------------------------------------------------------------------------
/UTMBeGone/Shared/SharedConsts.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SharedConsts.swift
3 | // UTMBeGone
4 | //
5 | // Created by Fernando Bunn on 26/12/2021.
6 | // Copyright © 2021 Fernando Bunn. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | extension Notification.Name {
12 | static let killLauncher = Notification.Name("killLauncher")
13 | }
14 |
15 | struct SharedConsts {
16 | static let mainAppID = "bunn.dev.utmbegone"
17 | static let launcherAppID = "bunn.dev.UTMBeGoneHelper"
18 | }
19 |
--------------------------------------------------------------------------------
/UTMBeGone/Storage/QueryItem.swift:
--------------------------------------------------------------------------------
1 | //
2 | // QueryItem.swift
3 | // UTMBeGone
4 | //
5 | // Created by Fernando Bunn on 07/09/2020.
6 | // Copyright © 2020 Fernando Bunn. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | class QueryItem: Codable, Equatable {
12 | static func == (lhs: QueryItem, rhs: QueryItem) -> Bool {
13 | lhs.creationDate == rhs.creationDate
14 | }
15 |
16 | var creationDate = Date()
17 | var value: String = "utm"
18 | }
19 |
20 |
--------------------------------------------------------------------------------
/UTMBeGone/Storage/QueryItemsManager.swift:
--------------------------------------------------------------------------------
1 | //
2 | // QueryItemsManager.swift
3 | // UTMBeGone
4 | //
5 | // Created by Fernando Bunn on 07/09/2020.
6 | // Copyright © 2020 Fernando Bunn. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 |
12 | class QueryItemsManager {
13 | private static let listKey = "QueryItemListKey"
14 | private(set) var queryList = [QueryItem]()
15 |
16 | init() {
17 | restoreAll()
18 | }
19 |
20 | var numberOfItems: Int {
21 | queryList.count
22 | }
23 |
24 | func item(for index: Int) -> QueryItem {
25 | queryList[index]
26 | }
27 |
28 | func delete(_ item: QueryItem) {
29 | guard let itemIndex = queryList.firstIndex(of: item) else { return }
30 | queryList.remove(at: itemIndex)
31 | save()
32 | }
33 |
34 | private func restoreAll() {
35 | queryList.removeAll()
36 | if let itemsData = UserDefaults.standard.data(forKey: QueryItemsManager.listKey) {
37 | do {
38 | let items = try JSONDecoder().decode([QueryItem].self, from: itemsData)
39 | queryList.append(contentsOf: items)
40 | } catch {
41 | print("Decoding error \(error)")
42 | }
43 | }
44 |
45 | if queryList.count == 0 {
46 | setupDefaultList()
47 | save()
48 | }
49 | }
50 |
51 | func createNewItem() -> QueryItem {
52 | let item = QueryItem()
53 | queryList.append(item)
54 | return item
55 | }
56 |
57 | func save() {
58 | let jsonEncoder = JSONEncoder()
59 | do {
60 | let encoded = try jsonEncoder.encode(queryList)
61 | UserDefaults.standard.set(encoded, forKey: QueryItemsManager.listKey)
62 | } catch {
63 | print("Error encoding \(error)")
64 | }
65 | }
66 |
67 | private func setupDefaultList() {
68 | _ = createNewItem().value = "utm"
69 | _ = createNewItem().value = "utm_source"
70 | _ = createNewItem().value = "utm_media"
71 | _ = createNewItem().value = "utm_campaign"
72 | _ = createNewItem().value = "utm_medium"
73 | _ = createNewItem().value = "utm_term"
74 | _ = createNewItem().value = "utm_content"
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/UTMBeGone/UTMBeGone.entitlements:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | com.apple.security.app-sandbox
6 |
7 | com.apple.security.files.user-selected.read-only
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/UTMBeGone/Util/LaunchAtLoginHelper.swift:
--------------------------------------------------------------------------------
1 | //
2 | // LaunchAtLoginHelper.swift
3 | // UTMBeGone
4 | //
5 | // Created by Fernando Bunn on 26/12/2021.
6 | // Copyright © 2021 Fernando Bunn. All rights reserved.
7 | //
8 |
9 | //Thanks to https://github.com/insidegui/StatusBuddy
10 |
11 | import Cocoa
12 | import ServiceManagement
13 |
14 | struct LaunchAtLoginHelper {
15 |
16 | func killHelperIfNecessary() {
17 | let runningApps = NSWorkspace.shared.runningApplications
18 | let isRunning = !runningApps.filter { $0.bundleIdentifier == SharedConsts.launcherAppID }.isEmpty
19 |
20 | if isRunning {
21 | DistributedNotificationCenter.default().post(name: .killLauncher, object: Bundle.main.bundleIdentifier!)
22 | }
23 | }
24 |
25 | func checkEnabled() -> Bool {
26 | // Not actually deprecated according to the headers.
27 | guard let jobDictsPtr = SMCopyAllJobDictionaries(kSMDomainUserLaunchd) else { return false }
28 |
29 | guard let dicts = jobDictsPtr.takeUnretainedValue() as? [[String: Any]] else { return false }
30 |
31 | return dicts.contains(where: { $0["Label"] as? String == SharedConsts.launcherAppID })
32 | }
33 |
34 | func setEnabled(_ enabled: Bool) {
35 | SMLoginItemSetEnabled(SharedConsts.launcherAppID as CFString, enabled)
36 | }
37 |
38 | }
39 |
--------------------------------------------------------------------------------
/UTMBeGone/Util/NotificationNames.swift:
--------------------------------------------------------------------------------
1 | //
2 | // NotificationNames.swift
3 | // UTMBeGone
4 | //
5 | // Created by Fernando Bunn on 12/09/2020.
6 | // Copyright © 2020 Fernando Bunn. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 |
12 | extension NSNotification.Name {
13 | public static let PasteboardDidChange = NSNotification.Name("pasteboardDidChangeNotification")
14 | public static let PasteboardShouldStopListening = NSNotification.Name("pasteboardShouldStopListening")
15 | public static let PasteboardShouldStartListening = NSNotification.Name("pasteboardShouldStartListening")
16 | }
17 |
--------------------------------------------------------------------------------
/UTMBeGone/Util/OpenWebsiteHelper.swift:
--------------------------------------------------------------------------------
1 | //
2 | // OpenWebsiteHelper.swift
3 | // UTMBeGone
4 | //
5 | // Created by Fernando Bunn on 30/12/2021.
6 | // Copyright © 2021 Fernando Bunn. All rights reserved.
7 | //
8 |
9 |
10 | import Cocoa
11 |
12 | struct OpenWebsiteHelper {
13 |
14 | static func openWebsite() {
15 | NSWorkspace.shared.open(URL(string: "https://github.com/Bunn/UTMBeGone")!)
16 |
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/UTMBeGone/Util/UTMBeGone-Bridging-Header.h:
--------------------------------------------------------------------------------
1 | //
2 | // Use this file to import your target's public headers that you would like to expose to Swift.
3 | //
4 |
--------------------------------------------------------------------------------
/UTMBeGoneHelper/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // UTMBeGoneHelper
4 | //
5 | // Created by Fernando Bunn on 27/12/2021.
6 | // Copyright © 2021 Fernando Bunn. All rights reserved.
7 | //
8 |
9 | import Cocoa
10 | import os.log
11 |
12 | @NSApplicationMain
13 | class AppDelegate: NSObject, NSApplicationDelegate {
14 |
15 | private let log = OSLog(subsystem: "bunn.dev.UTMBeGoneHelper", category: String(describing: AppDelegate.self))
16 |
17 | func applicationDidFinishLaunching(_ aNotification: Notification) {
18 | let config = NSWorkspace.OpenConfiguration()
19 | config.activates = false
20 | config.addsToRecentItems = false
21 | config.promptsUserIfNeeded = false
22 |
23 | NSWorkspace.shared.openApplication(
24 | at: Bundle.main.mainAppBundleURL,
25 | configuration: config) { _, error in
26 | if let error = error {
27 | os_log("Failed to launch main app: %{public}@", log: self.log, type: .fault, String(describing: error))
28 | } else {
29 | os_log("Main app launched successfully", log: self.log, type: .info)
30 | }
31 |
32 | DispatchQueue.main.async { NSApp?.terminate(nil) }
33 | }
34 | }
35 |
36 | }
37 |
38 |
--------------------------------------------------------------------------------
/UTMBeGoneHelper/Assets.xcassets/AccentColor.colorset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "colors" : [
3 | {
4 | "idiom" : "universal"
5 | }
6 | ],
7 | "info" : {
8 | "author" : "xcode",
9 | "version" : 1
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/UTMBeGoneHelper/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "mac",
5 | "scale" : "1x",
6 | "size" : "16x16"
7 | },
8 | {
9 | "idiom" : "mac",
10 | "scale" : "2x",
11 | "size" : "16x16"
12 | },
13 | {
14 | "idiom" : "mac",
15 | "scale" : "1x",
16 | "size" : "32x32"
17 | },
18 | {
19 | "idiom" : "mac",
20 | "scale" : "2x",
21 | "size" : "32x32"
22 | },
23 | {
24 | "idiom" : "mac",
25 | "scale" : "1x",
26 | "size" : "128x128"
27 | },
28 | {
29 | "idiom" : "mac",
30 | "scale" : "2x",
31 | "size" : "128x128"
32 | },
33 | {
34 | "idiom" : "mac",
35 | "scale" : "1x",
36 | "size" : "256x256"
37 | },
38 | {
39 | "idiom" : "mac",
40 | "scale" : "2x",
41 | "size" : "256x256"
42 | },
43 | {
44 | "idiom" : "mac",
45 | "scale" : "1x",
46 | "size" : "512x512"
47 | },
48 | {
49 | "idiom" : "mac",
50 | "scale" : "2x",
51 | "size" : "512x512"
52 | }
53 | ],
54 | "info" : {
55 | "author" : "xcode",
56 | "version" : 1
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/UTMBeGoneHelper/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/UTMBeGoneHelper/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 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
198 |
199 |
200 |
201 |
202 |
203 |
204 |
205 |
206 |
207 |
208 |
209 |
210 |
211 |
212 |
213 |
214 |
215 |
216 |
217 |
218 |
219 |
220 |
221 |
222 |
223 |
224 |
225 |
226 |
227 |
228 |
229 |
230 |
231 |
232 |
233 |
234 |
235 |
236 |
237 |
238 |
239 |
240 |
241 |
242 |
243 |
244 |
245 |
246 |
247 |
248 |
249 |
250 |
251 |
252 |
253 |
254 |
255 |
256 |
257 |
258 |
259 |
260 |
261 |
262 |
263 |
264 |
265 |
266 |
267 |
268 |
269 |
270 |
271 |
272 |
273 |
274 |
275 |
276 |
277 |
278 |
279 |
280 |
281 |
282 |
283 |
284 |
285 |
286 |
287 |
288 |
289 |
290 |
291 |
292 |
293 |
294 |
295 |
296 |
297 |
298 |
299 |
300 |
301 |
302 |
303 |
304 |
305 |
306 |
307 |
308 |
309 |
310 |
311 |
312 |
313 |
314 |
315 |
316 |
317 |
318 |
319 |
320 |
321 |
322 |
323 |
324 |
325 |
326 |
327 |
328 |
329 |
330 |
331 |
332 |
333 |
334 |
335 |
336 |
337 |
338 |
339 |
340 |
341 |
342 |
343 |
344 |
345 |
346 |
347 |
348 |
349 |
350 |
351 |
352 |
353 |
354 |
355 |
356 |
357 |
358 |
359 |
360 |
361 |
362 |
363 |
364 |
365 |
366 |
367 |
368 |
369 |
370 |
371 |
372 |
373 |
374 |
375 |
376 |
377 |
378 |
379 |
380 |
381 |
382 |
383 |
384 |
385 |
386 |
387 |
388 |
389 |
390 |
391 |
392 |
393 |
394 |
395 |
396 |
397 |
398 |
399 |
400 |
401 |
402 |
403 |
404 |
405 |
406 |
407 |
408 |
409 |
410 |
411 |
412 |
413 |
414 |
415 |
416 |
417 |
418 |
419 |
420 |
421 |
422 |
423 |
424 |
425 |
426 |
427 |
428 |
429 |
430 |
431 |
432 |
433 |
434 |
435 |
436 |
437 |
438 |
439 |
440 |
441 |
442 |
443 |
444 |
445 |
446 |
447 |
448 |
449 |
450 |
451 |
452 |
453 |
454 |
455 |
456 |
457 |
458 |
459 |
460 |
461 |
462 |
463 |
464 |
465 |
466 |
467 |
468 |
469 |
470 |
471 |
472 |
473 |
474 |
475 |
476 |
477 |
478 |
479 |
480 |
481 |
482 |
483 |
484 |
485 |
486 |
487 |
488 |
489 |
490 |
491 |
492 |
493 |
494 |
495 |
496 |
497 |
498 |
499 |
500 |
501 |
502 |
503 |
504 |
505 |
506 |
507 |
508 |
509 |
510 |
511 |
512 |
513 |
514 |
515 |
516 |
517 |
518 |
519 |
520 |
521 |
522 |
523 |
524 |
525 |
526 |
527 |
528 | Default
529 |
530 |
531 |
532 |
533 |
534 |
535 | Left to Right
536 |
537 |
538 |
539 |
540 |
541 |
542 | Right to Left
543 |
544 |
545 |
546 |
547 |
548 |
549 |
550 |
551 |
552 |
553 | Default
554 |
555 |
556 |
557 |
558 |
559 |
560 | Left to Right
561 |
562 |
563 |
564 |
565 |
566 |
567 | Right to Left
568 |
569 |
570 |
571 |
572 |
573 |
574 |
575 |
576 |
577 |
578 |
579 |
580 |
581 |
582 |
583 |
584 |
585 |
586 |
587 |
588 |
589 |
590 |
591 |
592 |
593 |
594 |
595 |
596 |
597 |
598 |
599 |
600 |
601 |
602 |
603 |
604 |
605 |
606 |
607 |
608 |
609 |
610 |
611 |
612 |
613 |
614 |
615 |
616 |
617 |
618 |
619 |
620 |
621 |
622 |
623 |
624 |
625 |
626 |
627 |
628 |
629 |
630 |
631 |
632 |
633 |
634 |
635 |
636 |
637 |
638 |
639 |
640 |
641 |
642 |
643 |
644 |
645 |
646 |
647 |
648 |
649 |
650 |
651 |
652 |
653 |
654 |
655 |
656 |
657 |
658 |
659 |
660 |
661 |
662 |
663 |
664 |
665 |
666 |
667 |
668 |
669 |
670 |
671 |
672 |
673 |
674 |
675 |
676 |
677 |
678 |
679 |
680 |
681 |
682 |
683 |
684 |
--------------------------------------------------------------------------------
/UTMBeGoneHelper/Bundle+MainApp.swift:
--------------------------------------------------------------------------------
1 |
2 | //https://github.com/insidegui/StatusBuddy
3 | //
4 | // Bundle+MainApp.swift
5 | // StatusBuddyHelper
6 | //
7 | // Created by Guilherme Rambo on 21/12/21.
8 | // Copyright © 2021 Guilherme Rambo. All rights reserved.
9 | //
10 |
11 | import Foundation
12 |
13 | extension Bundle {
14 |
15 | /// Returns the URL for the app's main bundle.
16 | public var mainAppBundleURL: URL {
17 | #if DEBUG
18 | guard !Bundle.main.bundleURL.path.contains("DerivedData") else {
19 | return derivedDataMainAppBundleURL
20 | }
21 | #endif
22 |
23 | return bundledMainAppBundleURL
24 | }
25 |
26 | /// Returns `true` if the app is running from within the Xcode DerivedData folder.
27 | /// Always returns `false` in release builds.
28 | /// Assumes the path for the folder contains `DerivedData`.
29 | public var isInDerivedDataFolder: Bool {
30 | #if DEBUG
31 | return bundlePath.contains("DerivedData")
32 | #else
33 | return false
34 | #endif
35 | }
36 |
37 | private var bundledMainAppBundleURL: URL {
38 | return bundleURL
39 | .deletingLastPathComponent() // UTMBeGone.app
40 | .deletingLastPathComponent() // LoginItems
41 | .deletingLastPathComponent() // Library
42 | .deletingLastPathComponent() // Contents
43 | }
44 |
45 | #if DEBUG
46 | /// Handles StatusBuddyHelper running directly from within Xcode, in which case it
47 | /// will be outside of the main app bundle.
48 | private var derivedDataMainAppBundleURL: URL {
49 | let mainAppURL = Bundle.main.bundleURL
50 | .deletingLastPathComponent()
51 | .appendingPathComponent("UTMBeGone.app")
52 |
53 | guard FileManager.default.fileExists(atPath: mainAppURL.path) else {
54 | return bundledMainAppBundleURL
55 | }
56 |
57 | return mainAppURL
58 | }
59 | #endif
60 |
61 | }
62 |
--------------------------------------------------------------------------------
/UTMBeGoneHelper/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | LSBackgroundOnly
6 |
7 | LSUIElement
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/UTMBeGoneHelper/UTMBeGoneHelper.entitlements:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | com.apple.security.app-sandbox
6 |
7 | com.apple.security.files.user-selected.read-only
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/UTMBeGoneTests/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | $(PRODUCT_BUNDLE_PACKAGE_TYPE)
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | 1
21 |
22 |
23 |
--------------------------------------------------------------------------------
/UTMBeGoneTests/UTMBeGoneTests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // UTMBeGoneTests.swift
3 | // UTMBeGoneTests
4 | //
5 | // Created by Fernando Bunn on 31/08/2020.
6 | // Copyright © 2020 Fernando Bunn. All rights reserved.
7 | //
8 |
9 | import XCTest
10 | @testable import UTMBeGone
11 |
12 | class UTMBeGoneTests: XCTestCase {
13 | let defaultItemsToRemove = ["utm", "utm_source", "utm_media", "utm_campaign", "utm_medium", "utm_term"]
14 |
15 | override func setUpWithError() throws {
16 | }
17 |
18 | override func tearDownWithError() throws {
19 | }
20 |
21 | func testQueryWithoutScheme() {
22 | let value = " "
23 | XCTAssertEqual(URLGarbageRemover.removeGarbage(value, itemsToRemove: defaultItemsToRemove), value)
24 | }
25 |
26 | func testURLsWithScheme() throws {
27 | let values = ["https://www.gog.com/news/25th_anniversary_look_back_at_phantasmagoria?utm_medium=social&utm_source=twitter&utm_campaign=20200824_phantasmagoriaeditorial_entw&utm_term=EN" :"https://www.gog.com/news/25th_anniversary_look_back_at_phantasmagoria",
28 |
29 | "https://casa.sapo.pt/detalhes.aspx?UID=9fa85847-82ee-4b0c-a830-44d0b391caf4&utm_medium=email&utm_campaign=alerts&utm_source=details" : "https://casa.sapo.pt/detalhes.aspx?UID=9fa85847-82ee-4b0c-a830-44d0b391caf4",
30 |
31 | "https://www.reddit.com/r/politics/comments/g6wrl2/trump_suggests_injecting_disinfectant_to_treat/?utm_medium=android_app&utm_source=share" : "https://www.reddit.com/r/politics/comments/g6wrl2/trump_suggests_injecting_disinfectant_to_treat/"
32 | ]
33 |
34 | for (badData, goodData) in values {
35 | XCTAssertEqual(URLGarbageRemover.removeGarbage(badData, itemsToRemove: defaultItemsToRemove), goodData)
36 | }
37 | }
38 |
39 | /*
40 | Every browser copies the scheme with the URL.
41 | If the URL doesn't have scheme I'm assuming the user is copying it from another place and we should probably not change it
42 | */
43 | func testURLsWithoutScheme() throws {
44 | let values = [
45 | "www.reddit.com/r/portugal/comments/esae9x/informação_útil_para_donos_de_nintendo_switch_e/?utm_medium=android_app&utm_source=share": "www.reddit.com/r/portugal/comments/esae9x/informação_útil_para_donos_de_nintendo_switch_e/?utm_medium=android_app&utm_source=share"
46 | ]
47 |
48 | for (badData, goodData) in values {
49 | XCTAssertEqual(URLGarbageRemover.removeGarbage(badData, itemsToRemove: defaultItemsToRemove), goodData)
50 | }
51 | }
52 |
53 | }
54 |
--------------------------------------------------------------------------------
/images/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Bunn/UTMBeGone/5cfce9911498a836ce92521a21a811b65a21b28b/images/icon.png
--------------------------------------------------------------------------------
/images/screenshot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Bunn/UTMBeGone/5cfce9911498a836ce92521a21a811b65a21b28b/images/screenshot.png
--------------------------------------------------------------------------------
/images/screenshot2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Bunn/UTMBeGone/5cfce9911498a836ce92521a21a811b65a21b28b/images/screenshot2.png
--------------------------------------------------------------------------------