├── .github
├── FUNDING.yml
└── ISSUE_TEMPLATE
│ └── bug_report.md
├── .gitignore
├── .swift-version
├── .swiftlint.yml
├── .travis.yml
├── CHANGELOG.md
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── ISSUE_TEMPLATE.md
├── LICENSE.md
├── PULL_REQUEST_TEMPLATE.md
├── README.md
├── Sketch Cache Cleaner.xcodeproj
└── project.pbxproj
├── Sketch Cache Cleaner
├── AppDelegate.swift
├── Assets.xcassets
│ ├── AppIcon.appiconset
│ │ ├── Contents.json
│ │ ├── icon_128x128.png
│ │ ├── icon_128x128@2x.png
│ │ ├── icon_16x16.png
│ │ ├── icon_16x16@2x.png
│ │ ├── icon_256x256.png
│ │ ├── icon_256x256@2x.png
│ │ ├── icon_32x32.png
│ │ ├── icon_32x32@2x.png
│ │ ├── icon_512x512.png
│ │ └── icon_512x512@2x.png
│ ├── Contents.json
│ ├── bg.imageset
│ │ ├── Contents.json
│ │ └── bg.pdf
│ ├── boxWithSketch.imageset
│ │ ├── Contents.json
│ │ └── boxWithSketch.pdf
│ ├── cleared.imageset
│ │ ├── Contents.json
│ │ └── cleared.pdf
│ ├── closedBox.imageset
│ │ ├── Contents.json
│ │ └── closedBox.pdf
│ ├── facebookButton.imageset
│ │ ├── Contents.json
│ │ └── facebookButton.pdf
│ ├── loader.imageset
│ │ ├── Contents.json
│ │ └── loader.png
│ ├── note.imageset
│ │ ├── Contents.json
│ │ └── note.pdf
│ ├── openBox.imageset
│ │ ├── Contents.json
│ │ └── openBox.pdf
│ ├── start.imageset
│ │ ├── Contents.json
│ │ └── start2.pdf
│ └── tweeterButton.imageset
│ │ ├── Contents.json
│ │ └── tweeterButton.pdf
├── Controllers
│ └── MainViewController.swift
├── Extensions
│ ├── NSButton+Extensions.swift
│ ├── NSFont+Extensions.swift
│ ├── NSView+Extensions.swift
│ └── String+Extensions.swift
├── Info.plist
├── Main.storyboard
├── SanFranciscoDisplay-Semibold.otf
├── Scripts
│ ├── calculate_cache_size.sh
│ ├── clear_cache.sh
│ └── stop_cache.sh
├── Utils
│ ├── ButtonText.swift
│ ├── Colors.swift
│ ├── Environment.swift
│ ├── STPrivilegedTask.h
│ ├── STPrivilegedTask.m
│ ├── Share.swift
│ └── Sketch Cache Cleaner-Bridging-Header.h
└── Views
│ └── MainWindow.swift
├── assets
├── RELEASE_NOTES.md
├── RELEASE_NOTES.pdf
├── Sketch Cache Cleaner.md
├── SketchCacheCleaner.sketch
├── Sketch_Cache_Cleaner_Logo.png
└── catalina
│ ├── catalina_1.png
│ ├── catalina_2.png
│ ├── catalina_3.png
│ ├── catalina_4.png
│ └── catalina_5.png
└── docs
└── index.html
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | patreon: minikin
2 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/bug_report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Bug report
3 | about: Create a report to help us improve
4 |
5 | ---
6 |
7 | **Describe the bug**
8 | A clear and concise description of what the bug is.
9 |
10 | **To Reproduce**
11 | Steps to reproduce the behavior:
12 | 1. Go to '...'
13 | 2. Click on '....'
14 | 3. Scroll down to '....'
15 | 4. See error
16 |
17 | **Expected behavior**
18 | A clear and concise description of what you expected to happen.
19 |
20 | **Screenshots**
21 | If applicable, add screenshots to help explain your problem.
22 |
23 | **Desktop (please complete the following information):**
24 | - OS: [e.g. iOS]
25 | - Browser [e.g. chrome, safari]
26 | - Version [e.g. 22]
27 |
28 | **Smartphone (please complete the following information):**
29 | - Device: [e.g. iPhone6]
30 | - OS: [e.g. iOS8.1]
31 | - Browser [e.g. stock browser, safari]
32 | - Version [e.g. 22]
33 |
34 | **Additional context**
35 | Add any other context about the problem here.
36 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | ### macOS ###
2 | *.DS_Store
3 | .AppleDouble
4 | .LSOverride
5 |
6 | # Icon must end with two \r
7 | Icon
8 |
9 |
10 | # Thumbnails
11 | ._*
12 |
13 | # Files that might appear in the root of a volume
14 | .DocumentRevisions-V100
15 | .fseventsd
16 | .Spotlight-V100
17 | .TemporaryItems
18 | .Trashes
19 | .VolumeIcon.icns
20 | .com.apple.timemachine.donotpresent
21 |
22 | # Directories potentially created on remote AFP share
23 | .AppleDB
24 | .AppleDesktop
25 | Network Trash Folder
26 | Temporary Items
27 | .apdisk
28 |
29 | ### Objective-C ###
30 | # Xcode
31 | #
32 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore
33 |
34 | ## Build generated
35 | build/
36 | DerivedData/
37 |
38 | ## Various settings
39 | *.pbxuser
40 | !default.pbxuser
41 | *.mode1v3
42 | !default.mode1v3
43 | *.mode2v3
44 | !default.mode2v3
45 | *.perspectivev3
46 | !default.perspectivev3
47 | xcuserdata/
48 |
49 | ## Other
50 | *.moved-aside
51 | *.xccheckout
52 | *.xcscmblueprint
53 |
54 | ## Obj-C/Swift specific
55 | *.hmap
56 | *.ipa
57 | *.dSYM.zip
58 | *.dSYM
59 |
60 | # CocoaPods
61 | #
62 | # We recommend against adding the Pods directory to your .gitignore. However
63 | # you should judge for yourself, the pros and cons are mentioned at:
64 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
65 | #
66 | # Pods/
67 |
68 | # Carthage
69 | #
70 | # Add this line if you want to avoid checking in source code from Carthage dependencies.
71 | # Carthage/Checkouts
72 |
73 | Carthage/Build
74 |
75 | # fastlane
76 | #
77 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the
78 | # screenshots whenever they are needed.
79 | # For more information about the recommended setup visit:
80 | # https://github.com/fastlane/fastlane/blob/master/fastlane/docs/Gitignore.md
81 |
82 | fastlane/report.xml
83 | fastlane/Preview.html
84 | fastlane/screenshots
85 | fastlane/test_output
86 |
87 | # Code Injection
88 | #
89 | # After new code Injection tools there's a generated folder /iOSInjectionProject
90 | # https://github.com/johnno1962/injectionforxcode
91 |
92 | iOSInjectionProject/
93 |
94 | ### Objective-C Patch ###
95 |
96 | ### Swift ###
97 | # Xcode
98 | #
99 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore
100 |
101 | ## Build generated
102 |
103 | ## Various settings
104 |
105 | ## Other
106 |
107 | ## Obj-C/Swift specific
108 |
109 | ## Playgrounds
110 | timeline.xctimeline
111 | playground.xcworkspace
112 |
113 | # Swift Package Manager
114 | #
115 | # Add this line if you want to avoid checking in source code from Swift Package Manager dependencies.
116 | # Packages/
117 | # Package.pins
118 | .build/
119 |
120 | # CocoaPods
121 | #
122 | # We recommend against adding the Pods directory to your .gitignore. However
123 | # you should judge for yourself, the pros and cons are mentioned at:
124 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
125 | #
126 | # Pods/
127 |
128 | # Carthage
129 | #
130 | # Add this line if you want to avoid checking in source code from Carthage dependencies.
131 | # Carthage/Checkouts
132 |
133 |
134 | # fastlane
135 | #
136 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the
137 | # screenshots whenever they are needed.
138 | # For more information about the recommended setup visit:
139 | # https://github.com/fastlane/fastlane/blob/master/fastlane/docs/Gitignore.md
140 |
141 |
142 | ### Xcode ###
143 | build
144 | *.xcodeproj/*
145 | !*.xcodeproj/project.pbxproj
146 | !*.xcworkspace/contents.xcworkspacedata
147 | /*.gcno
148 |
149 | ### VisualStudioCode ###
150 | .vscode/*
151 | !.vscode/settings.json
152 | !.vscode/tasks.json
153 | !.vscode/launch.json
154 | !.vscode/extensions.json
155 | .history
156 |
--------------------------------------------------------------------------------
/.swift-version:
--------------------------------------------------------------------------------
1 | 5.2
--------------------------------------------------------------------------------
/.swiftlint.yml:
--------------------------------------------------------------------------------
1 | disabled_rules:
2 | - vertical_parameter_alignment
3 | excluded: # paths to ignore during linting. Takes precedence over `included`.
4 | - Carthage
5 | - Pods
6 | # configurable rules can be customized from this configuration file
7 | # binary rules can set their severity level
8 | force_cast: warning # implicitly
9 | force_try:
10 | severity: warning # explicitly
11 | # rules that have both warning and error levels, can set just the warning level
12 | # implicitly
13 | line_length: 200
14 | # they can set both implicitly with an array
15 | type_body_length:
16 | - 300 # warning
17 | - 400 # error
18 | # or they can set both explicitly
19 | file_length:
20 | warning: 500
21 | error: 1200
22 | # naming rules can set warnings/errors for min_length and max_length
23 | # additionally they can set excluded names
24 | type_name:
25 | min_length: 3 # only warning
26 | max_length: # warning and error
27 | warning: 40
28 | error: 50
29 | excluded: iPhone # excluded via string
30 | identifier_name:
31 | min_length: # only min_length
32 | error: 2 # only error
33 | excluded: # excluded via string array
34 | - x
35 | - y
36 | - id
37 | - URL
38 | reporter: "xcode" # reporter type (xcode, json, csv, checkstyle, junit, html, emoji)
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: swift
2 | osx_image: xcode9.2
3 | branches:
4 | only:
5 | - master
6 | env:
7 | global:
8 | - LC_CTYPE=en_US.UTF-8
9 | - LANG=en_US.UTF-8
10 | - WORKSPACE=Sketch\ Cache\ Cleaner.xcodeproj
11 | - MACOS_SCHEME="Sketch Cache Cleaner"
12 | matrix:
13 | - DESTINATION="arch=x86_64" SCHEME="$MACOS_SCHEME" RUN_TESTS="NO"
14 | script:
15 | - set -o pipefail
16 | - xcodebuild -version
17 | - xcodebuild -showsdks
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Changelog
2 |
3 | All notable changes to this project will be documented in this file.
4 |
5 | ## Changelog
6 |
7 | ## [1.0.7] - 2020-30-03
8 |
9 | - Add macOS Catalina support
10 | - Bump minimum macOS version to 10.13
11 | - Build with Xcode 11.4
12 |
13 | ### Changed
14 |
15 | ## [1.0.5] - 2019-05-02
16 |
17 | ### Changed
18 |
19 | - Migrate to Swift 5
20 |
21 | ## [1.0.4] - 2018-10-21
22 |
23 | ### Changed
24 |
25 | - Build with Xcode 10 and macOS Mojave
26 | - Migrate to Swift 4.2
27 |
28 | ## [1.0.3] - 2018-03-27
29 |
30 | ### Added
31 |
32 | - Add social sharing
33 |
34 | ### Changed
35 |
36 | - Code refactor
37 | - Build with new Xcode's build system
38 |
39 | ## [1.0.2] - 2017-09-24
40 |
41 | ### Changed
42 |
43 | - Update to Swift 4
44 | - Compiled with Xcode 9
45 |
46 | ## [1.0.1] - 2017-07-14
47 |
48 | ### Fixed
49 |
50 | - Fix compatibility issues with 10.11, 10.12beta
51 |
52 | ## [1.0.0] - 2017-07-11
53 |
54 | - Initial release
55 |
--------------------------------------------------------------------------------
/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | # Contributor Covenant Code of Conduct
2 |
3 | ## Our Pledge
4 |
5 | In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.
6 |
7 | ## Our Standards
8 |
9 | Examples of behavior that contributes to creating a positive environment include:
10 |
11 | * Using welcoming and inclusive language
12 | * Being respectful of differing viewpoints and experiences
13 | * Gracefully accepting constructive criticism
14 | * Focusing on what is best for the community
15 | * Showing empathy towards other community members
16 |
17 | Examples of unacceptable behavior by participants include:
18 |
19 | * The use of sexualized language or imagery and unwelcome sexual attention or advances
20 | * Trolling, insulting/derogatory comments, and personal or political attacks
21 | * Public or private harassment
22 | * Publishing others' private information, such as a physical or electronic address, without explicit permission
23 | * Other conduct which could reasonably be considered inappropriate in a professional setting
24 |
25 | ## Our Responsibilities
26 |
27 | Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.
28 |
29 | Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
30 |
31 | ## Scope
32 |
33 | This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.
34 |
35 | ## Enforcement
36 |
37 | Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at djminikin@gmail.com. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
38 |
39 | Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
40 |
41 | ## Attribution
42 |
43 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version]
44 |
45 | [homepage]: http://contributor-covenant.org
46 | [version]: http://contributor-covenant.org/version/1/4/
47 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | ## Preparing for development
2 |
3 | 1. Make sure you have [Xcode](https://developer.apple.com/xcode/) installed.
4 | 2. Check out this repository.
5 | 3. Open `Sketch Cache Cleaner.xcodeproj` and start hacking!
6 |
7 | ## About contributions
8 |
9 | There are multiple ways you can contribute to this project.
10 |
11 | The easiest way to contribute is to report possible bugs, request features, [discuss ideas](https://github.com/yo-op/sketchcachecleaner/issues) and share excitement about this project.
12 |
13 | You can also make pull requests. Other than bug fixes, please make sure you discuss your contribution in Issues first.
14 |
15 | ## Submitting a Pull Request
16 |
17 | When submitting new code, please make sure that it is backed by tests.
18 |
19 | ## Developer's Certificate of Origin 1.1
20 |
21 | By making a contribution to this project, I certify that:
22 |
23 | - (a) The contribution was created in whole or in part by me and I
24 | have the right to submit it under the open source license
25 | indicated in the file; or
26 |
27 | - (b) The contribution is based upon previous work that, to the best
28 | of my knowledge, is covered under an appropriate open source
29 | license and I have the right under that license to submit that
30 | work with modifications, whether created in whole or in part
31 | by me, under the same open source license (unless I am
32 | permitted to submit under a different license), as indicated
33 | in the file; or
34 |
35 | - (c) The contribution was provided directly to me by some other
36 | person who certified (a), (b) or (c) and I have not modified
37 | it.
38 |
39 | - (d) I understand and agree that this project and the contribution
40 | are public and that a record of the contribution (including all
41 | personal information I submit with it, including my sign-off) is
42 | maintained indefinitely and may be redistributed consistent with
43 | this project or the open source license(s) involved.
44 |
45 | *Wording of statement copied from [elinux.org](http://elinux.org/Developer_Certificate_Of_Origin)*
46 |
--------------------------------------------------------------------------------
/ISSUE_TEMPLATE.md:
--------------------------------------------------------------------------------
1 | ### Expected behaviour
2 | ### Actual behaviour
3 | ### Steps to reproduce the behaviour
4 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2017 Sasha Prokhorenko & Yuriy Oparenko
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 NONINFRINGEMENT. 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 |
--------------------------------------------------------------------------------
/PULL_REQUEST_TEMPLATE.md:
--------------------------------------------------------------------------------
1 | # Description
2 |
3 | Please include a summary of the change and which issue is fixed. Please also include relevant motivation and context. List any dependencies that are required for this change.
4 |
5 | Fixes # (issue)
6 |
7 | ## Type of change
8 |
9 | Please delete options that are not relevant.
10 |
11 | - [ ] Bug fix (non-breaking change which fixes an issue)
12 | - [ ] New feature (non-breaking change which adds functionality)
13 | - [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected)
14 | - [ ] This change requires a documentation update
15 |
16 | # How Has This Been Tested?
17 |
18 | Please describe the tests that you ran to verify your changes. Provide instructions so we can reproduce. Please also list any relevant details for your test configuration.
19 | # Checklist:
20 |
21 | - [ ] I have performed a self-review of my own code
22 | - [ ] I have commented my code, particularly in hard-to-understand areas
23 | - [ ] I have made corresponding changes to the documentation
24 | - [ ] My changes generate no new warnings
25 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | [](https://vshymanskyy.github.io/StandWithUkraine)
2 |
3 |
11 |
12 |
13 | Sketch Cache Cleaner is a macOS app that deletes hidden Sketch history files that can take a lot of space on your hard drive and that you would probably never use.
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 | 1. [Warning](#warning)
47 | 2. [System Requirements](#system-requirements)
48 | 3. [Changelog](https://github.com/yo-op/sketchcachecleaner/blob/master/CHANGELOG.md)
49 | 4. [Tips](#tips)
50 | 5. [Authors](#authors)
51 | 6. [License](#license)
52 |
53 | ---
54 |
55 | ## Warning
56 |
57 | The app idea inspired by two blog posts: [How Sketch took over 200GB of our MacBooks](https://medium.com/@thomasdegry/how-sketch-took-over-200gb-of-our-macbooks-cb7dd10c8163) & [How to recover 50 GB or even more by deleting Sketch caches files](https://medium.com/sketch-app-sources/how-to-recover-50-go-or-even-more-by-deleting-sketch-caches-files-e5829dba20e1)
58 |
59 | Please, read them in case you want to know how it works.
60 |
61 | If your **workflow** relies on **automatic versioning** by macOS
62 | (Time Machine etc.) - **DO NOT USE THIS APP!**
63 |
64 | The app will remove all files in folder: /.DocumentRevisions-V100/
65 |
66 | ---
67 |
68 | ### System Requirements
69 |
70 | - macOS 10.13+
71 | - Xcode 11.4+
72 | - Swift 5.2+
73 |
74 | ---
75 |
76 | ### Authors
77 |
78 | Idea & design: [Yuriy Oparenko](http://oparenko.com/)
79 |
80 | Development: [Sasha Prokhorenko](https://twitter.com/minikin)
81 |
82 | ---
83 |
84 | ### Tips
85 |
86 | - Use this app wisely.
87 | - Reboot your Mac after app use.
88 |
89 | ---
90 |
91 | ### License
92 |
93 | Sketch Cache Cleaner is distributed under the [MIT license](https://github.com/yo-op/sketchcachecleaner/blob/master/LICENSE.md).
94 |
--------------------------------------------------------------------------------
/Sketch Cache Cleaner.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 54;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 035AF2A11F0585FB003CD85B /* MainViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 035AF2A01F0585FB003CD85B /* MainViewController.swift */; };
11 | 038FCAE91F058A2100755E96 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 038FCAE81F058A2100755E96 /* Main.storyboard */; };
12 | CE109E5D1F05A01400C4BF25 /* SanFranciscoDisplay-Semibold.otf in Resources */ = {isa = PBXBuildFile; fileRef = CE109E5C1F05A01400C4BF25 /* SanFranciscoDisplay-Semibold.otf */; };
13 | CE25F7D71E490FA00049CF23 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE25F7D61E490FA00049CF23 /* AppDelegate.swift */; };
14 | CE25F7DB1E490FA00049CF23 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = CE25F7DA1E490FA00049CF23 /* Assets.xcassets */; };
15 | CE25F7EB1E4914340049CF23 /* calculate_cache_size.sh in Resources */ = {isa = PBXBuildFile; fileRef = CE25F7EA1E4914340049CF23 /* calculate_cache_size.sh */; };
16 | CE25F7ED1E49145A0049CF23 /* clear_cache.sh in Resources */ = {isa = PBXBuildFile; fileRef = CE25F7EC1E49145A0049CF23 /* clear_cache.sh */; };
17 | CE25F7F21E4915190049CF23 /* STPrivilegedTask.m in Sources */ = {isa = PBXBuildFile; fileRef = CE25F7F01E4915190049CF23 /* STPrivilegedTask.m */; };
18 | CE25F7F41E491BE30049CF23 /* stop_cache.sh in Resources */ = {isa = PBXBuildFile; fileRef = CE25F7F31E491BE30049CF23 /* stop_cache.sh */; };
19 | CEA190B11F02FE3B00C9F30A /* Environment.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEA190B01F02FE3B00C9F30A /* Environment.swift */; };
20 | FC4D46CD1FE92BE10012B681 /* NSFont+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = FC4D46CC1FE92BE10012B681 /* NSFont+Extensions.swift */; };
21 | FC4D46CF1FE92C770012B681 /* NSView+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = FC4D46CE1FE92C770012B681 /* NSView+Extensions.swift */; };
22 | FC4D46D11FE92C940012B681 /* NSButton+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = FC4D46D01FE92C940012B681 /* NSButton+Extensions.swift */; };
23 | FC4D46D31FE92CBA0012B681 /* String+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = FC4D46D21FE92CBA0012B681 /* String+Extensions.swift */; };
24 | FC4D46D61FE92E7B0012B681 /* MainWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = FC4D46D51FE92E7B0012B681 /* MainWindow.swift */; };
25 | FC81FE04206A80CB00BA1282 /* Colors.swift in Sources */ = {isa = PBXBuildFile; fileRef = FC81FE03206A80CB00BA1282 /* Colors.swift */; };
26 | FCB22D2C201FC4F40054F43E /* Share.swift in Sources */ = {isa = PBXBuildFile; fileRef = FCB22D2B201FC4F40054F43E /* Share.swift */; };
27 | FCBCBF9D200385B3008CC9CA /* ButtonText.swift in Sources */ = {isa = PBXBuildFile; fileRef = FCBCBF9C200385B3008CC9CA /* ButtonText.swift */; };
28 | /* End PBXBuildFile section */
29 |
30 | /* Begin PBXFileReference section */
31 | 035AF2A01F0585FB003CD85B /* MainViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = MainViewController.swift; path = "Sketch Cache Cleaner/Controllers/MainViewController.swift"; sourceTree = SOURCE_ROOT; };
32 | 038FCAE81F058A2100755E96 /* Main.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = Main.storyboard; sourceTree = ""; };
33 | CE109E5C1F05A01400C4BF25 /* SanFranciscoDisplay-Semibold.otf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "SanFranciscoDisplay-Semibold.otf"; sourceTree = ""; };
34 | CE25F7D31E490FA00049CF23 /* Sketch Cache Cleaner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Sketch Cache Cleaner.app"; sourceTree = BUILT_PRODUCTS_DIR; };
35 | CE25F7D61E490FA00049CF23 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
36 | CE25F7DA1E490FA00049CF23 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
37 | CE25F7DF1E490FA00049CF23 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
38 | CE25F7EA1E4914340049CF23 /* calculate_cache_size.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = calculate_cache_size.sh; sourceTree = ""; };
39 | CE25F7EC1E49145A0049CF23 /* clear_cache.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = clear_cache.sh; sourceTree = ""; };
40 | CE25F7EF1E4915190049CF23 /* Sketch Cache Cleaner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Sketch Cache Cleaner-Bridging-Header.h"; sourceTree = ""; };
41 | CE25F7F01E4915190049CF23 /* STPrivilegedTask.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = STPrivilegedTask.m; sourceTree = ""; };
42 | CE25F7F11E4915190049CF23 /* STPrivilegedTask.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = STPrivilegedTask.h; sourceTree = ""; };
43 | CE25F7F31E491BE30049CF23 /* stop_cache.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = stop_cache.sh; sourceTree = ""; };
44 | CEA190B01F02FE3B00C9F30A /* Environment.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Environment.swift; sourceTree = ""; };
45 | FC4D46CC1FE92BE10012B681 /* NSFont+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NSFont+Extensions.swift"; sourceTree = ""; };
46 | FC4D46CE1FE92C770012B681 /* NSView+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NSView+Extensions.swift"; sourceTree = ""; };
47 | FC4D46D01FE92C940012B681 /* NSButton+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NSButton+Extensions.swift"; sourceTree = ""; };
48 | FC4D46D21FE92CBA0012B681 /* String+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "String+Extensions.swift"; sourceTree = ""; };
49 | FC4D46D51FE92E7B0012B681 /* MainWindow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainWindow.swift; sourceTree = ""; };
50 | FC81FE03206A80CB00BA1282 /* Colors.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Colors.swift; sourceTree = ""; };
51 | FCB22D2B201FC4F40054F43E /* Share.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Share.swift; sourceTree = ""; };
52 | FCBCBF9C200385B3008CC9CA /* ButtonText.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ButtonText.swift; sourceTree = ""; };
53 | /* End PBXFileReference section */
54 |
55 | /* Begin PBXFrameworksBuildPhase section */
56 | CE25F7D01E490FA00049CF23 /* Frameworks */ = {
57 | isa = PBXFrameworksBuildPhase;
58 | buildActionMask = 2147483647;
59 | files = (
60 | );
61 | runOnlyForDeploymentPostprocessing = 0;
62 | };
63 | /* End PBXFrameworksBuildPhase section */
64 |
65 | /* Begin PBXGroup section */
66 | 038FCAEA1F058A5800755E96 /* Storyboards & Xibs */ = {
67 | isa = PBXGroup;
68 | children = (
69 | 038FCAE81F058A2100755E96 /* Main.storyboard */,
70 | );
71 | name = "Storyboards & Xibs";
72 | sourceTree = "";
73 | };
74 | CE25F7CA1E490FA00049CF23 = {
75 | isa = PBXGroup;
76 | children = (
77 | CE25F7D51E490FA00049CF23 /* Sketch Cache Cleaner */,
78 | CE25F7D41E490FA00049CF23 /* Products */,
79 | );
80 | sourceTree = "";
81 | };
82 | CE25F7D41E490FA00049CF23 /* Products */ = {
83 | isa = PBXGroup;
84 | children = (
85 | CE25F7D31E490FA00049CF23 /* Sketch Cache Cleaner.app */,
86 | );
87 | name = Products;
88 | sourceTree = "";
89 | };
90 | CE25F7D51E490FA00049CF23 /* Sketch Cache Cleaner */ = {
91 | isa = PBXGroup;
92 | children = (
93 | CE25F7DA1E490FA00049CF23 /* Assets.xcassets */,
94 | CEE6384A1F78279F00C908C5 /* Controllers */,
95 | CE91327A1EA50C1A007F1ADD /* Extensions */,
96 | CE25F7E91E4913EE0049CF23 /* Scripts */,
97 | 038FCAEA1F058A5800755E96 /* Storyboards & Xibs */,
98 | CE25F7EE1E4914930049CF23 /* Supporting Files */,
99 | CE25F7E71E490FDB0049CF23 /* Utils */,
100 | FC4D46D41FE92CE00012B681 /* Views */,
101 | );
102 | path = "Sketch Cache Cleaner";
103 | sourceTree = "";
104 | };
105 | CE25F7E71E490FDB0049CF23 /* Utils */ = {
106 | isa = PBXGroup;
107 | children = (
108 | FCBCBF9C200385B3008CC9CA /* ButtonText.swift */,
109 | FC81FE03206A80CB00BA1282 /* Colors.swift */,
110 | CEA190B01F02FE3B00C9F30A /* Environment.swift */,
111 | FCB22D2B201FC4F40054F43E /* Share.swift */,
112 | CE25F7EF1E4915190049CF23 /* Sketch Cache Cleaner-Bridging-Header.h */,
113 | CE25F7F11E4915190049CF23 /* STPrivilegedTask.h */,
114 | CE25F7F01E4915190049CF23 /* STPrivilegedTask.m */,
115 | );
116 | path = Utils;
117 | sourceTree = "";
118 | };
119 | CE25F7E91E4913EE0049CF23 /* Scripts */ = {
120 | isa = PBXGroup;
121 | children = (
122 | CE25F7EA1E4914340049CF23 /* calculate_cache_size.sh */,
123 | CE25F7EC1E49145A0049CF23 /* clear_cache.sh */,
124 | CE25F7F31E491BE30049CF23 /* stop_cache.sh */,
125 | );
126 | path = Scripts;
127 | sourceTree = "";
128 | };
129 | CE25F7EE1E4914930049CF23 /* Supporting Files */ = {
130 | isa = PBXGroup;
131 | children = (
132 | CE109E5C1F05A01400C4BF25 /* SanFranciscoDisplay-Semibold.otf */,
133 | CE25F7DF1E490FA00049CF23 /* Info.plist */,
134 | CE25F7D61E490FA00049CF23 /* AppDelegate.swift */,
135 | );
136 | name = "Supporting Files";
137 | sourceTree = "";
138 | };
139 | CE91327A1EA50C1A007F1ADD /* Extensions */ = {
140 | isa = PBXGroup;
141 | children = (
142 | FC4D46D01FE92C940012B681 /* NSButton+Extensions.swift */,
143 | FC4D46CE1FE92C770012B681 /* NSView+Extensions.swift */,
144 | FC4D46D21FE92CBA0012B681 /* String+Extensions.swift */,
145 | FC4D46CC1FE92BE10012B681 /* NSFont+Extensions.swift */,
146 | );
147 | path = Extensions;
148 | sourceTree = "";
149 | };
150 | CEE6384A1F78279F00C908C5 /* Controllers */ = {
151 | isa = PBXGroup;
152 | children = (
153 | 035AF2A01F0585FB003CD85B /* MainViewController.swift */,
154 | );
155 | path = Controllers;
156 | sourceTree = "";
157 | };
158 | FC4D46D41FE92CE00012B681 /* Views */ = {
159 | isa = PBXGroup;
160 | children = (
161 | FC4D46D51FE92E7B0012B681 /* MainWindow.swift */,
162 | );
163 | path = Views;
164 | sourceTree = "";
165 | };
166 | /* End PBXGroup section */
167 |
168 | /* Begin PBXNativeTarget section */
169 | CE25F7D21E490FA00049CF23 /* Sketch Cache Cleaner */ = {
170 | isa = PBXNativeTarget;
171 | buildConfigurationList = CE25F7E21E490FA00049CF23 /* Build configuration list for PBXNativeTarget "Sketch Cache Cleaner" */;
172 | buildPhases = (
173 | CE25F7CF1E490FA00049CF23 /* Sources */,
174 | CE25F7D01E490FA00049CF23 /* Frameworks */,
175 | CE25F7D11E490FA00049CF23 /* Resources */,
176 | FCB22D27201FC2570054F43E /* SwiftLint */,
177 | );
178 | buildRules = (
179 | );
180 | dependencies = (
181 | );
182 | name = "Sketch Cache Cleaner";
183 | packageProductDependencies = (
184 | );
185 | productName = "Sketch Cache Cleaner";
186 | productReference = CE25F7D31E490FA00049CF23 /* Sketch Cache Cleaner.app */;
187 | productType = "com.apple.product-type.application";
188 | };
189 | /* End PBXNativeTarget section */
190 |
191 | /* Begin PBXProject section */
192 | CE25F7CB1E490FA00049CF23 /* Project object */ = {
193 | isa = PBXProject;
194 | attributes = {
195 | LastSwiftUpdateCheck = 0820;
196 | LastUpgradeCheck = 1220;
197 | ORGANIZATIONNAME = "Sasha Prokhorenko";
198 | TargetAttributes = {
199 | CE25F7D21E490FA00049CF23 = {
200 | CreatedOnToolsVersion = 8.2.1;
201 | DevelopmentTeam = GW82A8W73Z;
202 | LastSwiftMigration = 1020;
203 | ProvisioningStyle = Automatic;
204 | };
205 | };
206 | };
207 | buildConfigurationList = CE25F7CE1E490FA00049CF23 /* Build configuration list for PBXProject "Sketch Cache Cleaner" */;
208 | compatibilityVersion = "Xcode 12.0";
209 | developmentRegion = en;
210 | hasScannedForEncodings = 0;
211 | knownRegions = (
212 | en,
213 | Base,
214 | );
215 | mainGroup = CE25F7CA1E490FA00049CF23;
216 | packageReferences = (
217 | );
218 | productRefGroup = CE25F7D41E490FA00049CF23 /* Products */;
219 | projectDirPath = "";
220 | projectRoot = "";
221 | targets = (
222 | CE25F7D21E490FA00049CF23 /* Sketch Cache Cleaner */,
223 | );
224 | };
225 | /* End PBXProject section */
226 |
227 | /* Begin PBXResourcesBuildPhase section */
228 | CE25F7D11E490FA00049CF23 /* Resources */ = {
229 | isa = PBXResourcesBuildPhase;
230 | buildActionMask = 2147483647;
231 | files = (
232 | CE109E5D1F05A01400C4BF25 /* SanFranciscoDisplay-Semibold.otf in Resources */,
233 | CE25F7DB1E490FA00049CF23 /* Assets.xcassets in Resources */,
234 | 038FCAE91F058A2100755E96 /* Main.storyboard in Resources */,
235 | CE25F7ED1E49145A0049CF23 /* clear_cache.sh in Resources */,
236 | CE25F7EB1E4914340049CF23 /* calculate_cache_size.sh in Resources */,
237 | CE25F7F41E491BE30049CF23 /* stop_cache.sh in Resources */,
238 | );
239 | runOnlyForDeploymentPostprocessing = 0;
240 | };
241 | /* End PBXResourcesBuildPhase section */
242 |
243 | /* Begin PBXShellScriptBuildPhase section */
244 | FCB22D27201FC2570054F43E /* SwiftLint */ = {
245 | isa = PBXShellScriptBuildPhase;
246 | buildActionMask = 2147483647;
247 | files = (
248 | );
249 | inputPaths = (
250 | );
251 | name = SwiftLint;
252 | outputPaths = (
253 | );
254 | runOnlyForDeploymentPostprocessing = 0;
255 | shellPath = /bin/sh;
256 | shellScript = "if which swiftlint >/dev/null; then\nswiftlint\nelse\necho \"warning: SwiftLint not installed, download from https://github.com/realm/SwiftLint\"\nfi";
257 | };
258 | /* End PBXShellScriptBuildPhase section */
259 |
260 | /* Begin PBXSourcesBuildPhase section */
261 | CE25F7CF1E490FA00049CF23 /* Sources */ = {
262 | isa = PBXSourcesBuildPhase;
263 | buildActionMask = 2147483647;
264 | files = (
265 | FC4D46D11FE92C940012B681 /* NSButton+Extensions.swift in Sources */,
266 | FC4D46D61FE92E7B0012B681 /* MainWindow.swift in Sources */,
267 | FCB22D2C201FC4F40054F43E /* Share.swift in Sources */,
268 | 035AF2A11F0585FB003CD85B /* MainViewController.swift in Sources */,
269 | CEA190B11F02FE3B00C9F30A /* Environment.swift in Sources */,
270 | FC4D46D31FE92CBA0012B681 /* String+Extensions.swift in Sources */,
271 | FC4D46CF1FE92C770012B681 /* NSView+Extensions.swift in Sources */,
272 | FCBCBF9D200385B3008CC9CA /* ButtonText.swift in Sources */,
273 | FC81FE04206A80CB00BA1282 /* Colors.swift in Sources */,
274 | FC4D46CD1FE92BE10012B681 /* NSFont+Extensions.swift in Sources */,
275 | CE25F7D71E490FA00049CF23 /* AppDelegate.swift in Sources */,
276 | CE25F7F21E4915190049CF23 /* STPrivilegedTask.m in Sources */,
277 | );
278 | runOnlyForDeploymentPostprocessing = 0;
279 | };
280 | /* End PBXSourcesBuildPhase section */
281 |
282 | /* Begin XCBuildConfiguration section */
283 | CE25F7E01E490FA00049CF23 /* Debug */ = {
284 | isa = XCBuildConfiguration;
285 | buildSettings = {
286 | ALWAYS_SEARCH_USER_PATHS = NO;
287 | CLANG_ANALYZER_NONNULL = YES;
288 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
289 | CLANG_CXX_LIBRARY = "libc++";
290 | CLANG_ENABLE_MODULES = YES;
291 | CLANG_ENABLE_OBJC_ARC = YES;
292 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
293 | CLANG_WARN_BOOL_CONVERSION = YES;
294 | CLANG_WARN_COMMA = YES;
295 | CLANG_WARN_CONSTANT_CONVERSION = YES;
296 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
297 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
298 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
299 | CLANG_WARN_EMPTY_BODY = YES;
300 | CLANG_WARN_ENUM_CONVERSION = YES;
301 | CLANG_WARN_INFINITE_RECURSION = YES;
302 | CLANG_WARN_INT_CONVERSION = YES;
303 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
304 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
305 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
306 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
307 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
308 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
309 | CLANG_WARN_STRICT_PROTOTYPES = YES;
310 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
311 | CLANG_WARN_UNREACHABLE_CODE = YES;
312 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
313 | CODE_SIGN_IDENTITY = "-";
314 | COPY_PHASE_STRIP = NO;
315 | DEBUG_INFORMATION_FORMAT = dwarf;
316 | ENABLE_STRICT_OBJC_MSGSEND = YES;
317 | ENABLE_TESTABILITY = YES;
318 | GCC_C_LANGUAGE_STANDARD = gnu99;
319 | GCC_DYNAMIC_NO_PIC = NO;
320 | GCC_NO_COMMON_BLOCKS = YES;
321 | GCC_OPTIMIZATION_LEVEL = 0;
322 | GCC_PREPROCESSOR_DEFINITIONS = (
323 | "DEBUG=1",
324 | "$(inherited)",
325 | );
326 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
327 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
328 | GCC_WARN_UNDECLARED_SELECTOR = YES;
329 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
330 | GCC_WARN_UNUSED_FUNCTION = YES;
331 | GCC_WARN_UNUSED_VARIABLE = YES;
332 | MACOSX_DEPLOYMENT_TARGET = 10.13;
333 | MTL_ENABLE_DEBUG_INFO = YES;
334 | ONLY_ACTIVE_ARCH = YES;
335 | SDKROOT = macosx;
336 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
337 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
338 | };
339 | name = Debug;
340 | };
341 | CE25F7E11E490FA00049CF23 /* Release */ = {
342 | isa = XCBuildConfiguration;
343 | buildSettings = {
344 | ALWAYS_SEARCH_USER_PATHS = NO;
345 | CLANG_ANALYZER_NONNULL = YES;
346 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
347 | CLANG_CXX_LIBRARY = "libc++";
348 | CLANG_ENABLE_MODULES = YES;
349 | CLANG_ENABLE_OBJC_ARC = YES;
350 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
351 | CLANG_WARN_BOOL_CONVERSION = YES;
352 | CLANG_WARN_COMMA = YES;
353 | CLANG_WARN_CONSTANT_CONVERSION = YES;
354 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
355 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
356 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
357 | CLANG_WARN_EMPTY_BODY = YES;
358 | CLANG_WARN_ENUM_CONVERSION = YES;
359 | CLANG_WARN_INFINITE_RECURSION = YES;
360 | CLANG_WARN_INT_CONVERSION = YES;
361 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
362 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
363 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
364 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
365 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
366 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
367 | CLANG_WARN_STRICT_PROTOTYPES = YES;
368 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
369 | CLANG_WARN_UNREACHABLE_CODE = YES;
370 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
371 | CODE_SIGN_IDENTITY = "-";
372 | COPY_PHASE_STRIP = NO;
373 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
374 | ENABLE_NS_ASSERTIONS = NO;
375 | ENABLE_STRICT_OBJC_MSGSEND = YES;
376 | GCC_C_LANGUAGE_STANDARD = gnu99;
377 | GCC_NO_COMMON_BLOCKS = YES;
378 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
379 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
380 | GCC_WARN_UNDECLARED_SELECTOR = YES;
381 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
382 | GCC_WARN_UNUSED_FUNCTION = YES;
383 | GCC_WARN_UNUSED_VARIABLE = YES;
384 | MACOSX_DEPLOYMENT_TARGET = 10.13;
385 | MTL_ENABLE_DEBUG_INFO = NO;
386 | SDKROOT = macosx;
387 | SWIFT_COMPILATION_MODE = wholemodule;
388 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
389 | };
390 | name = Release;
391 | };
392 | CE25F7E31E490FA00049CF23 /* Debug */ = {
393 | isa = XCBuildConfiguration;
394 | buildSettings = {
395 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
396 | CLANG_ENABLE_MODULES = YES;
397 | CLANG_ENABLE_OBJC_WEAK = YES;
398 | CODE_SIGN_IDENTITY = "Apple Development";
399 | COMBINE_HIDPI_IMAGES = YES;
400 | DEVELOPMENT_TEAM = GW82A8W73Z;
401 | ENABLE_HARDENED_RUNTIME = YES;
402 | INFOPLIST_FILE = "Sketch Cache Cleaner/Info.plist";
403 | LD_RUNPATH_SEARCH_PATHS = (
404 | "$(inherited)",
405 | "@executable_path/../Frameworks",
406 | );
407 | MACOSX_DEPLOYMENT_TARGET = 10.13;
408 | MARKETING_VERSION = 1.0.8b;
409 | PRODUCT_BUNDLE_IDENTIFIER = "me.minikin.Sketch-Cache-Cleaner";
410 | PRODUCT_NAME = "$(TARGET_NAME)";
411 | SWIFT_OBJC_BRIDGING_HEADER = "Sketch Cache Cleaner/Utils/Sketch Cache Cleaner-Bridging-Header.h";
412 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
413 | SWIFT_VERSION = 5.0;
414 | };
415 | name = Debug;
416 | };
417 | CE25F7E41E490FA00049CF23 /* Release */ = {
418 | isa = XCBuildConfiguration;
419 | buildSettings = {
420 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
421 | CLANG_ENABLE_MODULES = YES;
422 | CLANG_ENABLE_OBJC_WEAK = YES;
423 | CODE_SIGN_IDENTITY = "Apple Development";
424 | COMBINE_HIDPI_IMAGES = YES;
425 | DEVELOPMENT_TEAM = GW82A8W73Z;
426 | ENABLE_HARDENED_RUNTIME = YES;
427 | INFOPLIST_FILE = "Sketch Cache Cleaner/Info.plist";
428 | LD_RUNPATH_SEARCH_PATHS = (
429 | "$(inherited)",
430 | "@executable_path/../Frameworks",
431 | );
432 | MACOSX_DEPLOYMENT_TARGET = 10.13;
433 | MARKETING_VERSION = 1.0.8b;
434 | PRODUCT_BUNDLE_IDENTIFIER = "me.minikin.Sketch-Cache-Cleaner";
435 | PRODUCT_NAME = "$(TARGET_NAME)";
436 | SWIFT_OBJC_BRIDGING_HEADER = "Sketch Cache Cleaner/Utils/Sketch Cache Cleaner-Bridging-Header.h";
437 | SWIFT_VERSION = 5.0;
438 | };
439 | name = Release;
440 | };
441 | /* End XCBuildConfiguration section */
442 |
443 | /* Begin XCConfigurationList section */
444 | CE25F7CE1E490FA00049CF23 /* Build configuration list for PBXProject "Sketch Cache Cleaner" */ = {
445 | isa = XCConfigurationList;
446 | buildConfigurations = (
447 | CE25F7E01E490FA00049CF23 /* Debug */,
448 | CE25F7E11E490FA00049CF23 /* Release */,
449 | );
450 | defaultConfigurationIsVisible = 0;
451 | defaultConfigurationName = Release;
452 | };
453 | CE25F7E21E490FA00049CF23 /* Build configuration list for PBXNativeTarget "Sketch Cache Cleaner" */ = {
454 | isa = XCConfigurationList;
455 | buildConfigurations = (
456 | CE25F7E31E490FA00049CF23 /* Debug */,
457 | CE25F7E41E490FA00049CF23 /* Release */,
458 | );
459 | defaultConfigurationIsVisible = 0;
460 | defaultConfigurationName = Release;
461 | };
462 | /* End XCConfigurationList section */
463 | };
464 | rootObject = CE25F7CB1E490FA00049CF23 /* Project object */;
465 | }
466 |
--------------------------------------------------------------------------------
/Sketch Cache Cleaner/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // Sketch Cache Cleaner
4 | //
5 | // Created by Sasha Prokhorenko on 2/6/17.
6 | // Copyright © 2017 Sasha Prokhorenko. All rights reserved.
7 | //
8 |
9 | import Cocoa
10 |
11 | @NSApplicationMain
12 | class AppDelegate: NSObject, NSApplicationDelegate {
13 | func applicationDidFinishLaunching(_: Notification) {}
14 | }
15 |
--------------------------------------------------------------------------------
/Sketch Cache Cleaner/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "size" : "16x16",
5 | "idiom" : "mac",
6 | "filename" : "icon_16x16.png",
7 | "scale" : "1x"
8 | },
9 | {
10 | "size" : "16x16",
11 | "idiom" : "mac",
12 | "filename" : "icon_16x16@2x.png",
13 | "scale" : "2x"
14 | },
15 | {
16 | "size" : "32x32",
17 | "idiom" : "mac",
18 | "filename" : "icon_32x32.png",
19 | "scale" : "1x"
20 | },
21 | {
22 | "size" : "32x32",
23 | "idiom" : "mac",
24 | "filename" : "icon_32x32@2x.png",
25 | "scale" : "2x"
26 | },
27 | {
28 | "size" : "128x128",
29 | "idiom" : "mac",
30 | "filename" : "icon_128x128.png",
31 | "scale" : "1x"
32 | },
33 | {
34 | "size" : "128x128",
35 | "idiom" : "mac",
36 | "filename" : "icon_128x128@2x.png",
37 | "scale" : "2x"
38 | },
39 | {
40 | "size" : "256x256",
41 | "idiom" : "mac",
42 | "filename" : "icon_256x256.png",
43 | "scale" : "1x"
44 | },
45 | {
46 | "size" : "256x256",
47 | "idiom" : "mac",
48 | "filename" : "icon_256x256@2x.png",
49 | "scale" : "2x"
50 | },
51 | {
52 | "size" : "512x512",
53 | "idiom" : "mac",
54 | "filename" : "icon_512x512.png",
55 | "scale" : "1x"
56 | },
57 | {
58 | "size" : "512x512",
59 | "idiom" : "mac",
60 | "filename" : "icon_512x512@2x.png",
61 | "scale" : "2x"
62 | }
63 | ],
64 | "info" : {
65 | "version" : 1,
66 | "author" : "xcode"
67 | }
68 | }
--------------------------------------------------------------------------------
/Sketch Cache Cleaner/Assets.xcassets/AppIcon.appiconset/icon_128x128.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yo-op/sketchcachecleaner/94f1580fe4c16db2addf827facd2cbf65431cffb/Sketch Cache Cleaner/Assets.xcassets/AppIcon.appiconset/icon_128x128.png
--------------------------------------------------------------------------------
/Sketch Cache Cleaner/Assets.xcassets/AppIcon.appiconset/icon_128x128@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yo-op/sketchcachecleaner/94f1580fe4c16db2addf827facd2cbf65431cffb/Sketch Cache Cleaner/Assets.xcassets/AppIcon.appiconset/icon_128x128@2x.png
--------------------------------------------------------------------------------
/Sketch Cache Cleaner/Assets.xcassets/AppIcon.appiconset/icon_16x16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yo-op/sketchcachecleaner/94f1580fe4c16db2addf827facd2cbf65431cffb/Sketch Cache Cleaner/Assets.xcassets/AppIcon.appiconset/icon_16x16.png
--------------------------------------------------------------------------------
/Sketch Cache Cleaner/Assets.xcassets/AppIcon.appiconset/icon_16x16@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yo-op/sketchcachecleaner/94f1580fe4c16db2addf827facd2cbf65431cffb/Sketch Cache Cleaner/Assets.xcassets/AppIcon.appiconset/icon_16x16@2x.png
--------------------------------------------------------------------------------
/Sketch Cache Cleaner/Assets.xcassets/AppIcon.appiconset/icon_256x256.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yo-op/sketchcachecleaner/94f1580fe4c16db2addf827facd2cbf65431cffb/Sketch Cache Cleaner/Assets.xcassets/AppIcon.appiconset/icon_256x256.png
--------------------------------------------------------------------------------
/Sketch Cache Cleaner/Assets.xcassets/AppIcon.appiconset/icon_256x256@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yo-op/sketchcachecleaner/94f1580fe4c16db2addf827facd2cbf65431cffb/Sketch Cache Cleaner/Assets.xcassets/AppIcon.appiconset/icon_256x256@2x.png
--------------------------------------------------------------------------------
/Sketch Cache Cleaner/Assets.xcassets/AppIcon.appiconset/icon_32x32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yo-op/sketchcachecleaner/94f1580fe4c16db2addf827facd2cbf65431cffb/Sketch Cache Cleaner/Assets.xcassets/AppIcon.appiconset/icon_32x32.png
--------------------------------------------------------------------------------
/Sketch Cache Cleaner/Assets.xcassets/AppIcon.appiconset/icon_32x32@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yo-op/sketchcachecleaner/94f1580fe4c16db2addf827facd2cbf65431cffb/Sketch Cache Cleaner/Assets.xcassets/AppIcon.appiconset/icon_32x32@2x.png
--------------------------------------------------------------------------------
/Sketch Cache Cleaner/Assets.xcassets/AppIcon.appiconset/icon_512x512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yo-op/sketchcachecleaner/94f1580fe4c16db2addf827facd2cbf65431cffb/Sketch Cache Cleaner/Assets.xcassets/AppIcon.appiconset/icon_512x512.png
--------------------------------------------------------------------------------
/Sketch Cache Cleaner/Assets.xcassets/AppIcon.appiconset/icon_512x512@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yo-op/sketchcachecleaner/94f1580fe4c16db2addf827facd2cbf65431cffb/Sketch Cache Cleaner/Assets.xcassets/AppIcon.appiconset/icon_512x512@2x.png
--------------------------------------------------------------------------------
/Sketch Cache Cleaner/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/Sketch Cache Cleaner/Assets.xcassets/bg.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "bg.pdf",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/Sketch Cache Cleaner/Assets.xcassets/bg.imageset/bg.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yo-op/sketchcachecleaner/94f1580fe4c16db2addf827facd2cbf65431cffb/Sketch Cache Cleaner/Assets.xcassets/bg.imageset/bg.pdf
--------------------------------------------------------------------------------
/Sketch Cache Cleaner/Assets.xcassets/boxWithSketch.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "boxWithSketch.pdf",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/Sketch Cache Cleaner/Assets.xcassets/boxWithSketch.imageset/boxWithSketch.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yo-op/sketchcachecleaner/94f1580fe4c16db2addf827facd2cbf65431cffb/Sketch Cache Cleaner/Assets.xcassets/boxWithSketch.imageset/boxWithSketch.pdf
--------------------------------------------------------------------------------
/Sketch Cache Cleaner/Assets.xcassets/cleared.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "cleared.pdf",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/Sketch Cache Cleaner/Assets.xcassets/cleared.imageset/cleared.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yo-op/sketchcachecleaner/94f1580fe4c16db2addf827facd2cbf65431cffb/Sketch Cache Cleaner/Assets.xcassets/cleared.imageset/cleared.pdf
--------------------------------------------------------------------------------
/Sketch Cache Cleaner/Assets.xcassets/closedBox.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "closedBox.pdf",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/Sketch Cache Cleaner/Assets.xcassets/closedBox.imageset/closedBox.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yo-op/sketchcachecleaner/94f1580fe4c16db2addf827facd2cbf65431cffb/Sketch Cache Cleaner/Assets.xcassets/closedBox.imageset/closedBox.pdf
--------------------------------------------------------------------------------
/Sketch Cache Cleaner/Assets.xcassets/facebookButton.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "facebookButton.pdf",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/Sketch Cache Cleaner/Assets.xcassets/facebookButton.imageset/facebookButton.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yo-op/sketchcachecleaner/94f1580fe4c16db2addf827facd2cbf65431cffb/Sketch Cache Cleaner/Assets.xcassets/facebookButton.imageset/facebookButton.pdf
--------------------------------------------------------------------------------
/Sketch Cache Cleaner/Assets.xcassets/loader.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "loader.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/Sketch Cache Cleaner/Assets.xcassets/loader.imageset/loader.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yo-op/sketchcachecleaner/94f1580fe4c16db2addf827facd2cbf65431cffb/Sketch Cache Cleaner/Assets.xcassets/loader.imageset/loader.png
--------------------------------------------------------------------------------
/Sketch Cache Cleaner/Assets.xcassets/note.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "note.pdf",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/Sketch Cache Cleaner/Assets.xcassets/note.imageset/note.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yo-op/sketchcachecleaner/94f1580fe4c16db2addf827facd2cbf65431cffb/Sketch Cache Cleaner/Assets.xcassets/note.imageset/note.pdf
--------------------------------------------------------------------------------
/Sketch Cache Cleaner/Assets.xcassets/openBox.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "openBox.pdf",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/Sketch Cache Cleaner/Assets.xcassets/openBox.imageset/openBox.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yo-op/sketchcachecleaner/94f1580fe4c16db2addf827facd2cbf65431cffb/Sketch Cache Cleaner/Assets.xcassets/openBox.imageset/openBox.pdf
--------------------------------------------------------------------------------
/Sketch Cache Cleaner/Assets.xcassets/start.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "start2.pdf",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/Sketch Cache Cleaner/Assets.xcassets/start.imageset/start2.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yo-op/sketchcachecleaner/94f1580fe4c16db2addf827facd2cbf65431cffb/Sketch Cache Cleaner/Assets.xcassets/start.imageset/start2.pdf
--------------------------------------------------------------------------------
/Sketch Cache Cleaner/Assets.xcassets/tweeterButton.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "tweeterButton.pdf",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/Sketch Cache Cleaner/Assets.xcassets/tweeterButton.imageset/tweeterButton.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yo-op/sketchcachecleaner/94f1580fe4c16db2addf827facd2cbf65431cffb/Sketch Cache Cleaner/Assets.xcassets/tweeterButton.imageset/tweeterButton.pdf
--------------------------------------------------------------------------------
/Sketch Cache Cleaner/Controllers/MainViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.swift
3 | // Sketch Cache Cleaner
4 | //
5 | // Created by Sasha Prokhorenko on 2/6/17.
6 | // Copyright © 2017 Sasha Prokhorenko. All rights reserved.
7 | //
8 |
9 | import Cocoa
10 |
11 | final class MainViewController: NSViewController {
12 | // MARK: - IBOutlets
13 |
14 | @IBOutlet private var backgroundView: NSView!
15 | @IBOutlet private var button: NSButton!
16 | @IBOutlet private var shareToTweeterButton: NSButton!
17 | @IBOutlet private var shareToFaceBookButton: NSButton!
18 | @IBOutlet private var mainImage: NSImageView!
19 | @IBOutlet private var backgroundImage: NSImageView!
20 | @IBOutlet private var cacheCleared: NSImageView!
21 | @IBOutlet private var notificationLabel: NSTextField!
22 | @IBOutlet private var sketchLabel: NSTextField!
23 | @IBOutlet private var progress: NSProgressIndicator!
24 |
25 | // MARK: - Instance Properties
26 |
27 | private var permissionGranted = false
28 | private var stringToTest = ""
29 | private let privilegedTask = STPrivilegedTask()
30 | private let bashPath = Environment.bashPath
31 | private let calculateCacheSizeTask = [Environment.calculateCacheScriptPath]
32 | private let clearCacheTask = [Environment.clearCacheScriptPath]
33 |
34 | // MARK: - ViewController lifecycle
35 |
36 | override func viewDidLoad() {
37 | super.viewDidLoad()
38 | configureInitialVCState()
39 | }
40 |
41 | override func viewWillAppear() {
42 | super.viewWillAppear()
43 | additionalVCConfigure()
44 | }
45 |
46 | // MARK: - Initial state
47 |
48 | private func configureInitialVCState() {
49 | backgroundImage.isHidden = true
50 | cacheCleared.isHidden = true
51 | notificationLabel.isHidden = true
52 | shareToTweeterButton.isHidden = true
53 | shareToFaceBookButton.isHidden = true
54 | }
55 |
56 | private func additionalVCConfigure() {
57 | view.window?.titlebarAppearsTransparent = true
58 | view.window?.backgroundColor = Colors.background
59 | view.window?.contentView?.setFrameSize(CGSize(width: (view.window?.contentView?.frame.width)!,
60 | height: (view.window?.contentView?.frame.height)! + 20))
61 | NSButton.setButton(button, title: ButtonText.enableAndScan)
62 | }
63 |
64 | private func appState() {
65 | switch (permissionGranted, button.title) {
66 | case (false, ButtonText.enableAndScan):
67 | button.title = ButtonText.enableAndScan
68 | askPermission()
69 | case (true, ButtonText.scanning):
70 | checkSizeOfCache()
71 | case (true, stringToTest):
72 | clearCache()
73 | default:
74 | break
75 | }
76 | }
77 |
78 | // MARK: - Helpers
79 |
80 | private func askPermission() {
81 | privilegedTask.launchPath = bashPath
82 | privilegedTask.arguments = calculateCacheSizeTask
83 | privilegedTask.currentDirectoryPath = Bundle.main.resourcePath
84 | let err = privilegedTask.launch()
85 | if err != errAuthorizationSuccess {
86 | if err == errAuthorizationCanceled {
87 | permissionGranted = false
88 | return
89 | } else {
90 | print("Something went wrong:", err)
91 | // For error codes, see http://www.opensource.apple.com/source/libsecurity_authorization/libsecurity_authorization-36329/lib/Authorization.h
92 | }
93 | }
94 | privilegedTask.waitUntilExit()
95 | permissionGranted = true
96 | backgroundImage.isHidden = false
97 | progress.startAnimation(self)
98 | button.isEnabled = false
99 | NSButton.setButton(button, title: ButtonText.scanning)
100 | mainImage.cell?.image = #imageLiteral(resourceName: "closedBox")
101 | DispatchQueue.main.asyncAfter(deadline: .now() + .seconds(1)) {
102 | self.button.isEnabled = true
103 | self.checkSizeOfCache()
104 | }
105 | }
106 |
107 | private func checkSizeOfCache() {
108 | progress.stopAnimation(self)
109 | let readHandle = privilegedTask.outputFileHandle
110 | let outputData = readHandle?.readDataToEndOfFile()
111 | let outputString = String(data: outputData!, encoding: .utf8)
112 | let stringArray = outputString?.components(separatedBy: "/")
113 | guard let stringToDispaly = stringArray?[0] else { return }
114 | if stringToDispaly.trim() == "0B" || stringToDispaly == "" {
115 | finalUIState()
116 | } else {
117 | stringToTest = "Clear \(stringToDispaly.trim())B"
118 | NSButton.setButton(button, title: "Clear \(stringToDispaly.trim())B")
119 | mainImage.cell?.image = #imageLiteral(resourceName: "boxWithSketch")
120 | notificationLabel.isHidden = false
121 | }
122 | }
123 |
124 | private func clearCache() {
125 | privilegedTask.launchPath = bashPath
126 | privilegedTask.arguments = clearCacheTask
127 | privilegedTask.currentDirectoryPath = Bundle.main.resourcePath
128 | let err = privilegedTask.launch()
129 | if err != errAuthorizationSuccess {
130 | if err == errAuthorizationCanceled {
131 | print("User cancelled", permissionGranted)
132 | return
133 | } else {
134 | print("Something went wrong:", err)
135 | }
136 | }
137 | privilegedTask.waitUntilExit()
138 | finalUIState()
139 | }
140 |
141 | private func finalUIState() {
142 | mainImage.cell?.image = #imageLiteral(resourceName: "openBox")
143 | button.isHidden = true
144 | cacheCleared.isHidden = false
145 | notificationLabel.isHidden = true
146 | shareToTweeterButton.isHidden = false
147 | shareToFaceBookButton.isHidden = false
148 | }
149 |
150 | // MARK: - Actions
151 |
152 | @IBAction private func buttonPressed(_: NSButton) {
153 | appState()
154 | }
155 |
156 | @IBAction private func shareToTweeterDidPress(_: NSButton) {
157 | NSWorkspace.shared.open(Share.twitterMessage(stringToTest))
158 | }
159 |
160 | @IBAction private func shareToFacebookrDidPress(_: NSButton) {
161 | NSWorkspace.shared.open(Share.facebookMessage(stringToTest))
162 | }
163 | }
164 |
--------------------------------------------------------------------------------
/Sketch Cache Cleaner/Extensions/NSButton+Extensions.swift:
--------------------------------------------------------------------------------
1 | //
2 | // NSButtonExtensions.swift
3 | // Sketch Cache Cleaner
4 | //
5 | // Created by Sasha Prokhorenko on 19.12.17.
6 | // Copyright © 2017 Sasha Prokhorenko. All rights reserved.
7 | //
8 |
9 | import Cocoa
10 |
11 | extension NSButton {
12 | @discardableResult
13 | static func setButton(_ button: NSButton, title: String) -> NSButton {
14 | button.title = title
15 | button.backgroundColor = NSColor(red: 1.0, green: 0.70, blue: 0.0, alpha: 1.00)
16 | let textColor = NSColor(red: 1.0, green: 1.0, blue: 1.0, alpha: 1.00)
17 | let style = NSMutableParagraphStyle()
18 | style.alignment = .center
19 |
20 | let font = NSFont.mainFont(ofSize: 14)
21 | let attributes = [NSAttributedString.Key.foregroundColor: textColor,
22 | NSAttributedString.Key.font: font,
23 | NSAttributedString.Key.paragraphStyle: style] as [NSAttributedString.Key: Any]
24 | button.attributedTitle = NSAttributedString(string: title, attributes: attributes)
25 | button.layer?.cornerRadius = 3.0
26 | button.layer?.masksToBounds = true
27 | return button
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/Sketch Cache Cleaner/Extensions/NSFont+Extensions.swift:
--------------------------------------------------------------------------------
1 | //
2 | // NSFontExtensions.swift
3 | // Sketch Cache Cleaner
4 | //
5 | // Created by Sasha Prokhorenko on 19.12.17.
6 | // Copyright © 2017 Sasha Prokhorenko. All rights reserved.
7 | //
8 |
9 | import Cocoa
10 |
11 | extension NSFont {
12 | private static func customFont(name: String, size: CGFloat) -> NSFont {
13 | let font = NSFont(name: name, size: size)
14 | assert(font != nil, "Can't load font: \(name)")
15 | return font ?? NSFont.systemFont(ofSize: size)
16 | }
17 |
18 | /// Main font
19 | static func mainFont(ofSize size: CGFloat) -> NSFont {
20 | customFont(name: "San Francisco Display Semibold", size: size)
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/Sketch Cache Cleaner/Extensions/NSView+Extensions.swift:
--------------------------------------------------------------------------------
1 | //
2 | // NSViewExtensions.swift
3 | // Sketch Cache Cleaner
4 | //
5 | // Created by Sasha Prokhorenko on 19.12.17.
6 | // Copyright © 2017 Sasha Prokhorenko. All rights reserved.
7 | //
8 |
9 | import Cocoa
10 |
11 | extension NSView {
12 | var backgroundColor: NSColor? {
13 | get {
14 | guard let colorRef = layer?.backgroundColor else { return nil }
15 | return NSColor(cgColor: colorRef)
16 | }
17 | set {
18 | wantsLayer = true
19 | layer?.backgroundColor = newValue?.cgColor
20 | }
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/Sketch Cache Cleaner/Extensions/String+Extensions.swift:
--------------------------------------------------------------------------------
1 | //
2 | // StringExtensions.swift
3 | // Sketch Cache Cleaner
4 | //
5 | // Created by Sasha Prokhorenko on 19.12.17.
6 | // Copyright © 2017 Sasha Prokhorenko. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | extension String {
12 | func trim() -> String {
13 | trimmingCharacters(in: CharacterSet.whitespaces)
14 | }
15 |
16 | func urlEncode() -> String {
17 | addingPercentEncoding(withAllowedCharacters: .urlHostAllowed) ?? "none"
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/Sketch Cache Cleaner/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | ATSApplicationFontsPath
6 | SanFranciscoDisplay-Semibold.otf
7 | CFBundleDevelopmentRegion
8 | en
9 | CFBundleExecutable
10 | $(EXECUTABLE_NAME)
11 | CFBundleIconFile
12 |
13 | CFBundleIdentifier
14 | $(PRODUCT_BUNDLE_IDENTIFIER)
15 | CFBundleInfoDictionaryVersion
16 | 6.0
17 | CFBundleName
18 | $(PRODUCT_NAME)
19 | CFBundlePackageType
20 | APPL
21 | CFBundleShortVersionString
22 | $(MARKETING_VERSION)
23 | CFBundleVersion
24 | 1
25 | LSApplicationCategoryType
26 | public.app-category.utilities
27 | LSMinimumSystemVersion
28 | $(MACOSX_DEPLOYMENT_TARGET)
29 | NSHumanReadableCopyright
30 | Copyright © 2017 Sasha Prokhorenko. All rights reserved.
31 | NSMainStoryboardFile
32 | Main
33 | NSPrincipalClass
34 | NSApplication
35 |
36 |
37 |
--------------------------------------------------------------------------------
/Sketch Cache Cleaner/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 | YnBsaXN0MDDUAQIDBAUGTE1YJHZlcnNpb25YJG9iamVjdHNZJGFyY2hpdmVyVCR0b3ASAAGGoK8QEQcI
272 | ERYbHCgpKi41Njs+QUZJVSRudWxs1AkKCwwNDg8QViRjbGFzc1xOU0ltYWdlRmxhZ3NWTlNSZXBzV05T
273 | Q29sb3KAEBIAwAAAgAKADtISCRMVWk5TLm9iamVjdHOhFIADgA3SEgkXGqIYGYAEgAWADBAA1x0JHh8g
274 | ISIjJCUmGxsnVk5TU2l6ZVlOU1BERkRhdGFfEBBOU0NvbG9yU3BhY2VOYW1lXxAZTlNJbnRlcm5hbExh
275 | eW91dERpcmVjdGlvbl8QD05TQml0c1BlclNhbXBsZVxOU0NvbG9yU3BhY2WABoALgAqAB4AIWXsxOTIs
276 | IDE2fV8QGU5TQ2FsaWJyYXRlZFJHQkNvbG9yU3BhY2XSKwksLVROU0lEEAGACdIvMDEyWiRjbGFzc25h
277 | bWVYJGNsYXNzZXNcTlNDb2xvclNwYWNlojM0XE5TQ29sb3JTcGFjZVhOU09iamVjdE8RPmMlUERGLTEu
278 | MwolxOXy5eun86DQxMYKNCAwIG9iago8PCAvTGVuZ3RoIDUgMCBSIC9GaWx0ZXIgL0ZsYXRlRGVjb2Rl
279 | ID4+CnN0cmVhbQp4AY1SwU7DMAy95ysetw6pWeykaXtl4sINUWlCiMMUNm2iBW2D/8fu0k2AkFDTuo6f
280 | X/Js73GPPcoqoOQa3jkEeQ9rLPGG+eJISEfQ+BwTnI3YCZ7g5CkJHEARacBNZ0pnXRvRJVDIcbHWO+LY
281 | ViCPbsC8S8rWbfCE4vF9hjI6FJ/ZHtSSKZD9h2xfxVaEYp39D/VbFCn722ynvEX2VzMjfL9xE8+E3yle
282 | cMcfPBN/P8bN+fxVxut99R4T30vOv5rhGd0dbjsprxa4AWMAkfXkaymbkRIFG5vILWu5GoxVOwMuPxoT
283 | QPoGl5wLlebyJXym5fHUhC2W19LMP3p8aql0mqXT5tzp0kMWsy6Zhk1WIc0e4GUK5MeB2Gqn9QJu3NWI
284 | +g7J5KAAM37UKJmadPpE1SbjI1esVUDmbtCjQiuwXvZrG0wvelWy7pxS3RjTnF4F/lOfjGNoA1WuMs42
285 | HNkHGWVL3DZ17SETXla6OOo66f4CldKfmQplbmRzdHJlYW0KZW5kb2JqCjUgMCBvYmoKMzc0CmVuZG9i
286 | agoyIDAgb2JqCjw8IC9UeXBlIC9QYWdlIC9QYXJlbnQgMyAwIFIgL1Jlc291cmNlcyA2IDAgUiAvQ29u
287 | dGVudHMgNCAwIFIgL01lZGlhQm94IFswIDAgMTkyIDE2XQo+PgplbmRvYmoKNiAwIG9iago8PCAvUHJv
288 | Y1NldCBbIC9QREYgL1RleHQgXSAvQ29sb3JTcGFjZSA8PCAvQ3MxIDcgMCBSIC9DczIgOSAwIFIgPj4g
289 | L0ZvbnQgPDwKL1RjMSA4IDAgUiA+PiA+PgplbmRvYmoKMTAgMCBvYmoKPDwgL0xlbmd0aCAxMSAwIFIg
290 | L04gMyAvQWx0ZXJuYXRlIC9EZXZpY2VSR0IgL0ZpbHRlciAvRmxhdGVEZWNvZGUgPj4Kc3RyZWFtCngB
291 | hVVbiBtVGP6TOckKu87T2tUtpEO9dCm7S7YV3aW0mluTtGsastnVFkGzk5NkzOwkzkzSC30qguKLq75J
292 | Qby9LQiC0nrB1gf7UqlQVnfrIig+tHhBKPRFt/E7k2QmWWqbZc988/3f+W/nnxmigbVCva77FaIlwzZz
293 | yajy3NFjysA6+ekhGqRRGiyoVj2Szc4SfkIrrv2/Wz+QTzBXJ+5s71dvuRsscksl8t0Hvla01CXgE0SB
294 | s2rdtIkGhsFPH7frAoschk0kCPyiwOU2ho2GF9v4NUeTz8WgOQssq5VCEXgFeHyxhy/34HYOUMBPkhvc
295 | 1FRF9CJr1kqazh1De7mHuUd5N7ikN1Cz89uBdciqzh3GdQy1v1IsxAWeBF5RC4k54EeArzW1hUwH367b
296 | 0RzwY0T+nY3qfAR4N3CqZB6cB4Yfv1lppLr4nVOV/LPgt4H/xljMHOnsXVOtGHpJO8HfrvC06G+ISFI0
297 | O50Hhh/pgFnLCT1ykEpFHk8AjwO/Xq0dFjnAp/SZ1ZwTvMhn7VQlJvIU/OWXCoeywKPAv3I9KfSIJf1b
298 | t7OdHFjI0DMiLmKxOLeceuGHhexKPgUecZlum/nOXrZc0g6mO/pPKmZK8GLvtbruzChyC/jNRk7UjliB
299 | yYKZSALDZyDLjXnRT4GbtOArEKcaLWJVyaBNUihHSYriWicTlhJppIPhsHIwHHddzYSzz6IqeI2ajs3C
300 | mnWU7Z1drUJlsAZdd7QqxUIfUQOeKvQH2IrrU6EY7hrgyv/jp53LjY6fGhthYbYX//vYLNvPptkMKewp
301 | 9jQ7wOJgZ9g+13cWe7oViXxuIErbz8uIyB3dAmq/iBptKmD9BYoaWa6Hvq4sjzbGPMsZ8wVNvfLG3z29
302 | 0rCz6iom+jp65F49D/wWuB5Yxboe2HB9KIGfAhv4W0dvvFpqnr3TZXFSGk601qfbehZdVQSV6s7OJXRB
303 | Q828p+aJXh+XTn/5oBdtlZ17/urQpdMlY3nUY0UX+KuZWxk6M+6x4R/Df4ZXw++FPwz/Lr0tfSp9JZ2X
304 | PpcukyJdkC5KX0vfSh9LX7j6u82Qe/YkMhdzJfIW09WtsLfXmFg5Km+XH5bj8g75UXnWVSnyiDwlp+Rd
305 | sGx3z82bb6W3cvTlKKJ1+3PnWOJZ0VxPOAPf/ZgAzYvYNwPzyFij4/Bpot9i3gw6CW3vk9epiIXYFEtv
306 | me5pMfNd38FEMB6MkBLcHZwJTgUPCdx9loO7YJvBmujNDfPhKvoq5TY/Ib4nFKvVT5pauWIre8LhJ5UI
307 | Pn1cSRvq5LhS0HXFMVmKyS1uNnlxksR3U+wjuplzvoe+bVc8zn6GaP9fePd973HHGkQrFtHI4x43hnfl
308 | A+8SnXtCbZjNtj/y+b4jskp79zj3vqEo3l8/t1o38R4beIto881W65/3W63ND+B/g+iC/h+gn3xVCmVu
309 | ZHN0cmVhbQplbmRvYmoKMTEgMCBvYmoKMTA3OQplbmRvYmoKNyAwIG9iagpbIC9JQ0NCYXNlZCAxMCAw
310 | IFIgXQplbmRvYmoKMTIgMCBvYmoKPDwgL0xlbmd0aCAxMyAwIFIgL04gMyAvQWx0ZXJuYXRlIC9EZXZp
311 | Y2VSR0IgL0ZpbHRlciAvRmxhdGVEZWNvZGUgPj4Kc3RyZWFtCngBnZZ3VFPZFofPvTe90BIiICX0GnoJ
312 | INI7SBUEUYlJgFAChoQmdkQFRhQRKVZkVMABR4ciY0UUC4OCYtcJ8hBQxsFRREXl3YxrCe+tNfPemv3H
313 | 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
355 | Jm1m5t/3hPP7CmVuZHN0cmVhbQplbmRvYmoKMTMgMCBvYmoKMjYxMgplbmRvYmoKOSAwIG9iagpbIC9J
356 | Q0NCYXNlZCAxMiAwIFIgXQplbmRvYmoKMyAwIG9iago8PCAvVHlwZSAvUGFnZXMgL01lZGlhQm94IFsw
357 | IDAgMTkyIDE2XSAvQ291bnQgMSAvS2lkcyBbIDIgMCBSIF0gPj4KZW5kb2JqCjE0IDAgb2JqCjw8IC9U
358 | eXBlIC9DYXRhbG9nIC9QYWdlcyAzIDAgUiA+PgplbmRvYmoKOCAwIG9iago8PCAvVHlwZSAvRm9udCAv
359 | U3VidHlwZSAvVHlwZTEgL0Jhc2VGb250IC9CWlZNQk4rU2FuRnJhbmNpc2NvRGlzcGxheS1TZW1pYm9s
360 | ZAovRm9udERlc2NyaXB0b3IgMTUgMCBSIC9FbmNvZGluZyAvTWFjUm9tYW5FbmNvZGluZyAvRmlyc3RD
361 | aGFyIDMyIC9MYXN0Q2hhcgoxMTcgL1dpZHRocyBbIDE5OCAyNjYgMCAwIDAgMCAwIDAgMCAwIDAgMCAw
362 | IDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwCjAgMCAwIDAgMCAwIDAgNjIwIDAgMCAwIDAgMCAw
363 | IDAgMCAwIDAgMCAwIDAgMCAwIDU4MiAwIDAgMCAwIDAgNTUzIDAgMCAwIDAKMCAwIDAgNTI4IDAgNTIw
364 | IDU4MyA1MzkgMCAwIDU3OCAyNTkgMCA1MTEgMjU2IDAgMCA1NTcgMCAwIDM2NCA0OTkgMzYxIDU3NApd
365 | ID4+CmVuZG9iagoxNSAwIG9iago8PCAvVHlwZSAvRm9udERlc2NyaXB0b3IgL0ZvbnROYW1lIC9CWlZN
366 | Qk4rU2FuRnJhbmNpc2NvRGlzcGxheS1TZW1pYm9sZCAvRmxhZ3MKMzIgL0ZvbnRCQm94IFstMjM4IC0y
367 | NTIgMTAzNiA5NTBdIC9JdGFsaWNBbmdsZSAwIC9Bc2NlbnQgOTUyIC9EZXNjZW50IC0yNDEKL0NhcEhl
368 | aWdodCA2ODAgL1N0ZW1WIDExNyAvWEhlaWdodCA1MjYgL1N0ZW1IIDk3IC9BdmdXaWR0aCA1MDEgL01h
369 | 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
523 | SI48j3e6QyJbyNvdIYNBPl+Tizc0LWwHWVSmQUywidPovChmErTMMJcWf67qjYkkKX9EQFiphfsskFqT
524 | RWWG5OvjIJheHaAjIfG6GEcvmgNh0g50FQxxVFiHU2uqOBQLs8PHjXpv3mQJO/AzVx6c+aWVdtn3Z5hN
525 | 2fUGG4ZGtibKRYoUfKfZBAw8ZDvyJ+xzqOQUFT0Qkm9HJs9uW6A1oarf0ZUHrvjbNenoKSTiBTkukD+i
526 | qYdqZlz00oyVg76vL+uTVYuWjwyUrlYZ2tBj64lyDhQsSl3IUesqUZinRqlBmKMEqXE0Y/EGHSSzVMKj
527 | j3aQcq6BT7mNZDacIUCA3eqreNAKvMpGQigb0ctqe4FwObFBwkvnADMEpUKpgFy1QolQXkCB8z65DJ5S
528 | rGXBBmGuhHu1Nc7ALX44jzBKO5gg7DCI1dXfXk2sFmKqE69+W26IiU5MpMLKaLq6erL66rdJ1dF0J0bL
529 | 3CdDBL9L0+EoBITSzKCIe0TTJg1vMUf31qnDGLTi1inDmFBqiBaoa5L2qKKXIzqGx+WEF2nmO2rGYjf7
530 | enTQnpYYhOwFr6otqK7plEWQsTmXMWtiRmdrwSABmkrbIa4VGTr60xe/hMcq/TBx/jNNN6VQHoJRklhj
531 | ZZiv2Hlxv0HEAbz4XyZPVB0KZW5kc3RyZWFtCmVuZG9iagoxNyAwIG9iago5NjIyCmVuZG9iagoxOCAw
532 | IG9iagooTWFjIE9TIFggMTAuMTIuNCBRdWFydHogUERGQ29udGV4dCkKZW5kb2JqCjE5IDAgb2JqCihE
533 | OjIwMTcwNTAxMTMyMTM4WjAwJzAwJykKZW5kb2JqCjEgMCBvYmoKPDwgL1Byb2R1Y2VyIDE4IDAgUiAv
534 | Q3JlYXRpb25EYXRlIDE5IDAgUiAvTW9kRGF0ZSAxOSAwIFIgPj4KZW5kb2JqCnhyZWYKMCAyMAowMDAw
535 | MDAwMDAwIDY1NTM1IGYgCjAwMDAwMTUzMzggMDAwMDAgbiAKMDAwMDAwMDQ4OSAwMDAwMCBuIAowMDAw
536 | MDA0NzExIDAwMDAwIG4gCjAwMDAwMDAwMjIgMDAwMDAgbiAKMDAwMDAwMDQ3MCAwMDAwMCBuIAowMDAw
537 | MDAwNTkyIDAwMDAwIG4gCjAwMDAwMDE5MDMgMDAwMDAgbiAKMDAwMDAwNDg0MyAwMDAwMCBuIAowMDAw
538 | MDA0Njc1IDAwMDAwIG4gCjAwMDAwMDA3MDAgMDAwMDAgbiAKMDAwMDAwMTg4MiAwMDAwMCBuIAowMDAw
539 | MDAxOTM5IDAwMDAwIG4gCjAwMDAwMDQ2NTQgMDAwMDAgbiAKMDAwMDAwNDc5MyAwMDAwMCBuIAowMDAw
540 | MDA1MjM4IDAwMDAwIG4gCjAwMDAwMDU1MDcgMDAwMDAgbiAKMDAwMDAxNTIyMiAwMDAwMCBuIAowMDAw
541 | MDE1MjQzIDAwMDAwIG4gCjAwMDAwMTUyOTYgMDAwMDAgbiAKdHJhaWxlcgo8PCAvU2l6ZSAyMCAvUm9v
542 | dCAxNCAwIFIgL0luZm8gMSAwIFIgL0lEIFsgPDE1ZmJhOGYyNzkzZTUxMGRlYjhmZjljNGM1YjkyY2Zl
543 | Pgo8MTVmYmE4ZjI3OTNlNTEwZGViOGZmOWM0YzViOTJjZmU+IF0gPj4Kc3RhcnR4cmVmCjE1NDEzCiUl
544 | RU9GCtIvMDc4XU5TUERGSW1hZ2VSZXCjOTo0XU5TUERGSW1hZ2VSZXBaTlNJbWFnZVJlcNIvMDw9V05T
545 | QXJyYXmiPDTSLzA/QF5OU011dGFibGVBcnJheaM/PDTTQiIJQ0RFV05TV2hpdGVEMCAwABADgA/SLzBH
546 | SFdOU0NvbG9yokc00i8wSktXTlNJbWFnZaJKNF8QD05TS2V5ZWRBcmNoaXZlctFOT1Ryb290gAEACAAR
547 | ABoAIwAtADIANwBLAFEAWgBhAG4AdQB9AH8AhACGAIgAjQCYAJoAnACeAKMApgCoAKoArACuAL0AxADO
548 | AOEA/QEPARwBHgEgASIBJAEmATABTAFRAVYBWAFaAV8BagFzAYABgwGQAZlAAEAFQBNAF0AlQDBANUA9
549 | QEBARUBUQFhAX0BnQGxAbkBwQHVAfUCAQIVAjUCQQKJApUCqAAAAAAAAAgEAAAAAAAAAUAAAAAAAAAAA
550 | AAAAAAAAQKw
551 |
552 |
553 |
554 |
555 |
556 |
557 |
--------------------------------------------------------------------------------
/Sketch Cache Cleaner/SanFranciscoDisplay-Semibold.otf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yo-op/sketchcachecleaner/94f1580fe4c16db2addf827facd2cbf65431cffb/Sketch Cache Cleaner/SanFranciscoDisplay-Semibold.otf
--------------------------------------------------------------------------------
/Sketch Cache Cleaner/Scripts/calculate_cache_size.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | # calculate_cache_size.sh
4 | # Sketch Cache Cleaner
5 | #
6 | # Created by Sasha Prokhorenko on 2/6/17.
7 | # Copyright © 2017 Sasha Prokhorenko. All rights reserved.
8 |
9 |
10 | du -sh /.DocumentRevisions-V100/
11 |
12 | exit 5
13 |
--------------------------------------------------------------------------------
/Sketch Cache Cleaner/Scripts/clear_cache.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | # clear_cache.sh
4 | # Sketch Cache Cleaner
5 | #
6 | # Created by Sasha Prokhorenko on 2/6/17.
7 | # Copyright © 2017 Sasha Prokhorenko. All rights reserved.
8 |
9 | # that's exectly the place where sketch save versions
10 | #rm -rf /.DocumentRevisions-V100/.cs/{*,.*}
11 |
12 | # looks like we need to remove all folders
13 | rm -rf /.DocumentRevisions-V100/{*,.*}
14 |
15 | exit 5
16 |
--------------------------------------------------------------------------------
/Sketch Cache Cleaner/Scripts/stop_cache.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | # stop_cache.sh
4 | # Sketch Cache Cleaner
5 | #
6 | # Created by Sasha Prokhorenko on 2/6/17.
7 | # Copyright © 2017 Sasha Prokhorenko. All rights reserved.
8 |
9 | # defaults write -app Sketch ApplePersistence -bool no
10 | # exit 5
11 |
--------------------------------------------------------------------------------
/Sketch Cache Cleaner/Utils/ButtonText.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ButtonText.swift
3 | // Sketch Cache Cleaner
4 | //
5 | // Created by Sasha Prokhorenko on 08.01.18.
6 | // Copyright © 2018 Sasha Prokhorenko. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | enum ButtonText {
12 | static let enableAndScan = "Enable and Scan"
13 | static let scanning = "Scanning..."
14 | }
15 |
--------------------------------------------------------------------------------
/Sketch Cache Cleaner/Utils/Colors.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Colors.swift
3 | // Sketch Cache Cleaner
4 | //
5 | // Created by Sasha Prokhorenko on 27.03.18.
6 | // Copyright © 2018 Sasha Prokhorenko. All rights reserved.
7 | //
8 |
9 | enum Colors {
10 | static let background = NSColor(red: 0.07, green: 0.04, blue: 0.20, alpha: 1.00)
11 | }
12 |
--------------------------------------------------------------------------------
/Sketch Cache Cleaner/Utils/Environment.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Environment.swift
3 | // Sketch Cache Cleaner
4 | //
5 | // Created by Sasha Prokhorenko on 6/27/17.
6 | // Copyright © 2017 Sasha Prokhorenko. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | enum Environment {
12 | static let bashPath = "/bin/sh"
13 | static let calculateCacheScriptPath = "calculate_cache_size.sh"
14 | static let clearCacheScriptPath = "clear_cache.sh"
15 | static let webPage = "https://yo-op.github.io/sketchcachecleaner/"
16 | static let sentry = "https://90daa0afc9e04716a579a237e92d021b@sentry.io/5179181"
17 | }
18 |
--------------------------------------------------------------------------------
/Sketch Cache Cleaner/Utils/STPrivilegedTask.h:
--------------------------------------------------------------------------------
1 | /*
2 | # STPrivilegedTask - NSTask-like wrapper around AuthorizationExecuteWithPrivileges
3 | # Copyright (C) 2009-2016 Sveinbjorn Thordarson
4 | #
5 | # BSD License
6 | # Redistribution and use in source and binary forms, with or without
7 | # modification, are permitted provided that the following conditions are met:
8 | # * Redistributions of source code must retain the above copyright
9 | # notice, this list of conditions and the following disclaimer.
10 | # * Redistributions in binary form must reproduce the above copyright
11 | # notice, this list of conditions and the following disclaimer in the
12 | # documentation and/or other materials provided with the distribution.
13 | # * Neither the name of Sveinbjorn Thordarson nor that of any other
14 | # contributors may be used to endorse or promote products
15 | # derived from this software without specific prior written permission.
16 | #
17 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
18 | # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 | # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 | # DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY
21 | # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22 | # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23 | # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24 | # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 | # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26 | # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 | */
28 |
29 | #import
30 |
31 | #define STPrivilegedTaskDidTerminateNotification @"STPrivilegedTaskDidTerminateNotification"
32 |
33 | // Defines error value for when AuthorizationExecuteWithPrivileges no longer exists
34 | // Rather than defining a new enum, we just create a global constant
35 | extern const OSStatus errAuthorizationFnNoLongerExists;
36 |
37 | @interface STPrivilegedTask : NSObject
38 |
39 | @property (copy) NSArray *arguments;
40 | @property (copy) NSString *currentDirectoryPath;
41 | @property (copy) NSString *launchPath;
42 |
43 | @property (readonly) NSFileHandle *outputFileHandle;
44 | @property (readonly) BOOL isRunning;
45 | @property (readonly) pid_t processIdentifier;
46 | @property (readonly) int terminationStatus;
47 |
48 | @property (copy) void (^terminationHandler)(STPrivilegedTask *);
49 |
50 | - (instancetype)initWithLaunchPath:(NSString *)path;
51 | - (instancetype)initWithLaunchPath:(NSString *)path arguments:(NSArray *)args;
52 | - (instancetype)initWithLaunchPath:(NSString *)path arguments:(NSArray *)args currentDirectory:(NSString *)cwd;
53 |
54 | + (STPrivilegedTask *)launchedPrivilegedTaskWithLaunchPath:(NSString *)path;
55 | + (STPrivilegedTask *)launchedPrivilegedTaskWithLaunchPath:(NSString *)path arguments:(NSArray *)args;
56 | + (STPrivilegedTask *)launchedPrivilegedTaskWithLaunchPath:(NSString *)path arguments:(NSArray *)args currentDirectory:(NSString *)cwd;
57 |
58 | - (OSStatus)launch;
59 | - (void)terminate; // doesn't work
60 | - (void)waitUntilExit;
61 |
62 | @end
63 |
64 |
--------------------------------------------------------------------------------
/Sketch Cache Cleaner/Utils/STPrivilegedTask.m:
--------------------------------------------------------------------------------
1 | /*
2 | # STPrivilegedTask - NSTask-like wrapper around AuthorizationExecuteWithPrivileges
3 | # Copyright (C) 2009-2016 Sveinbjorn Thordarson
4 | #
5 | # BSD License
6 | # Redistribution and use in source and binary forms, with or without
7 | # modification, are permitted provided that the following conditions are met:
8 | # * Redistributions of source code must retain the above copyright
9 | # notice, this list of conditions and the following disclaimer.
10 | # * Redistributions in binary form must reproduce the above copyright
11 | # notice, this list of conditions and the following disclaimer in the
12 | # documentation and/or other materials provided with the distribution.
13 | # * Neither the name of Sveinbjorn Thordarson nor that of any other
14 | # contributors may be used to endorse or promote products
15 | # derived from this software without specific prior written permission.
16 | #
17 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
18 | # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 | # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 | # DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY
21 | # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22 | # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23 | # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24 | # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 | # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26 | # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 | */
28 |
29 | #import "STPrivilegedTask.h"
30 |
31 | #import
32 | #import
33 | #import
34 | #import
35 | #import
36 |
37 | // New error code denoting that AuthorizationExecuteWithPrivileges no longer exists
38 | OSStatus const errAuthorizationFnNoLongerExists = -70001;
39 |
40 | @implementation STPrivilegedTask
41 | {
42 | NSTimer *_checkStatusTimer;
43 | }
44 |
45 | - (instancetype)init
46 | {
47 | self = [super init];
48 | if (self) {
49 | _launchPath = nil;
50 | _arguments = nil;
51 | _isRunning = NO;
52 | _outputFileHandle = nil;
53 | _terminationHandler = nil;
54 | _currentDirectoryPath = [[NSFileManager defaultManager] currentDirectoryPath];
55 | }
56 | return self;
57 | }
58 |
59 | - (instancetype)initWithLaunchPath:(NSString *)path
60 | {
61 | self = [self init];
62 | if (self) {
63 | self.launchPath = path;
64 | }
65 | return self;
66 | }
67 |
68 | - (instancetype)initWithLaunchPath:(NSString *)path arguments:(NSArray *)args
69 | {
70 | self = [self initWithLaunchPath:path];
71 | if (self) {
72 | self.arguments = args;
73 | }
74 | return self;
75 | }
76 |
77 | - (instancetype)initWithLaunchPath:(NSString *)path arguments:(NSArray *)args currentDirectory:(NSString *)cwd
78 | {
79 | self = [self initWithLaunchPath:path arguments:args];
80 | if (self) {
81 | self.currentDirectoryPath = cwd;
82 | }
83 | return self;
84 | }
85 |
86 | #pragma mark -
87 |
88 | + (STPrivilegedTask *)launchedPrivilegedTaskWithLaunchPath:(NSString *)path
89 | {
90 | STPrivilegedTask *task = [[STPrivilegedTask alloc] initWithLaunchPath:path];
91 | #if !__has_feature(objc_arc)
92 | [task autorelease];
93 | #endif
94 | [task launch];
95 | [task waitUntilExit];
96 | return task;
97 | }
98 |
99 | + (STPrivilegedTask *)launchedPrivilegedTaskWithLaunchPath:(NSString *)path arguments:(NSArray *)args
100 | {
101 | STPrivilegedTask *task = [[STPrivilegedTask alloc] initWithLaunchPath:path arguments:args];
102 | #if !__has_feature(objc_arc)
103 | [task autorelease];
104 | #endif
105 |
106 | [task launch];
107 | [task waitUntilExit];
108 | return task;
109 | }
110 |
111 | + (STPrivilegedTask *)launchedPrivilegedTaskWithLaunchPath:(NSString *)path arguments:(NSArray *)args currentDirectory:(NSString *)cwd
112 | {
113 | STPrivilegedTask *task = [[STPrivilegedTask alloc] initWithLaunchPath:path arguments:args currentDirectory:cwd];
114 | #if !__has_feature(objc_arc)
115 | [task autorelease];
116 | #endif
117 |
118 | [task launch];
119 | [task waitUntilExit];
120 | return task;
121 | }
122 |
123 | # pragma mark -
124 |
125 | // return 0 for success
126 | - (OSStatus)launch
127 | {
128 | if (_isRunning) {
129 | NSLog(@"Task already running: %@", [self description]);
130 | return 0;
131 | }
132 |
133 | OSStatus err = noErr;
134 | const char *toolPath = [self.launchPath fileSystemRepresentation];
135 |
136 | AuthorizationRef authorizationRef;
137 | AuthorizationItem myItems = { kAuthorizationRightExecute, strlen(toolPath), &toolPath, 0 };
138 | AuthorizationRights myRights = { 1, &myItems };
139 | AuthorizationFlags flags = kAuthorizationFlagDefaults | kAuthorizationFlagInteractionAllowed | kAuthorizationFlagPreAuthorize | kAuthorizationFlagExtendRights;
140 |
141 | NSArray *arguments = self.arguments;
142 | NSUInteger numberOfArguments = [arguments count];
143 | char *args[numberOfArguments + 1];
144 | FILE *outputFile;
145 |
146 | // Create fn pointer to AuthorizationExecuteWithPrivileges in case it doesn't exist
147 | // in this version of MacOS
148 | static OSStatus (*_AuthExecuteWithPrivsFn)(
149 | AuthorizationRef authorization, const char *pathToTool, AuthorizationFlags options,
150 | char * const *arguments, FILE **communicationsPipe) = NULL;
151 |
152 | // Check to see if we have the correct function in our loaded libraries
153 | if (!_AuthExecuteWithPrivsFn) {
154 | // On 10.7, AuthorizationExecuteWithPrivileges is deprecated. We want
155 | // to still use it since there's no good alternative (without requiring
156 | // code signing). We'll look up the function through dyld and fail if
157 | // it is no longer accessible. If Apple removes the function entirely
158 | // this will fail gracefully. If they keep the function and throw some
159 | // sort of exception, this won't fail gracefully, but that's a risk
160 | // we'll have to take for now.
161 | // Pattern by Andy Kim from Potion Factory LLC
162 | _AuthExecuteWithPrivsFn = dlsym(RTLD_DEFAULT, "AuthorizationExecuteWithPrivileges");
163 | if (!_AuthExecuteWithPrivsFn) {
164 | // This version of OS X has finally removed this function. Return with an error.
165 | return errAuthorizationFnNoLongerExists;
166 | }
167 | }
168 |
169 | // Use Apple's Authentication Manager APIs to get an Authorization Reference
170 | // These Apple APIs are quite possibly the most horrible of the Mac OS X APIs
171 |
172 | // create authorization reference
173 | err = AuthorizationCreate(NULL, kAuthorizationEmptyEnvironment, kAuthorizationFlagDefaults, &authorizationRef);
174 | if (err != errAuthorizationSuccess) {
175 | return err;
176 | }
177 |
178 | // pre-authorize the privileged operation
179 | err = AuthorizationCopyRights(authorizationRef, &myRights, kAuthorizationEmptyEnvironment, flags, NULL);
180 | if (err != errAuthorizationSuccess) {
181 | return err;
182 | }
183 |
184 | // OK, at this point we have received authorization for the task.
185 | // Let's prepare to launch it
186 |
187 | // first, construct an array of c strings from NSArray w. arguments
188 | for (int i = 0; i < numberOfArguments; i++) {
189 | NSString *argString = arguments[i];
190 | NSUInteger stringLength = [argString length];
191 |
192 | args[i] = malloc((stringLength + 1) * sizeof(char));
193 | snprintf(args[i], stringLength + 1, "%s", [argString fileSystemRepresentation]);
194 | }
195 | args[numberOfArguments] = NULL;
196 |
197 | // change to the current dir specified
198 | char *prevCwd = (char *)getcwd(nil, 0);
199 | chdir([self.currentDirectoryPath fileSystemRepresentation]);
200 |
201 | //use Authorization Reference to execute script with privileges
202 | err = _AuthExecuteWithPrivsFn(authorizationRef, toolPath, kAuthorizationFlagDefaults, args, &outputFile);
203 |
204 | // OK, now we're done executing, let's change back to old dir
205 | chdir(prevCwd);
206 |
207 | // free the malloc'd argument strings
208 | for (int i = 0; i < numberOfArguments; i++) {
209 | free(args[i]);
210 | }
211 |
212 | // free the auth ref
213 | AuthorizationFree(authorizationRef, kAuthorizationFlagDefaults);
214 |
215 | // we return err if execution failed
216 | if (err != errAuthorizationSuccess) {
217 | return err;
218 | } else {
219 | _isRunning = YES;
220 | }
221 |
222 | // get file handle for the command output
223 | _outputFileHandle = [[NSFileHandle alloc] initWithFileDescriptor:fileno(outputFile) closeOnDealloc:YES];
224 | _processIdentifier = fcntl(fileno(outputFile), F_GETOWN, 0);
225 |
226 | // start monitoring task
227 | _checkStatusTimer = [NSTimer scheduledTimerWithTimeInterval:0.05 target:self selector:@selector(checkTaskStatus) userInfo:nil repeats:YES];
228 |
229 | return err;
230 | }
231 |
232 | - (void)terminate
233 | {
234 | // This doesn't work without a PID, and we can't get one. Stupid Security API
235 | // int ret = kill(pid, SIGKILL);
236 | //
237 | // if (ret != 0) {
238 | // NSLog(@"Error %d", errno);
239 | // }
240 | }
241 |
242 | // hang until task is done
243 | - (void)waitUntilExit
244 | {
245 | if (!_isRunning) {
246 | NSLog(@"Task %@ is not running", [super description]);
247 | return;
248 | }
249 |
250 | [_checkStatusTimer invalidate];
251 |
252 | int status;
253 | pid_t pid = 0;
254 | while ((pid = waitpid(_processIdentifier, &status, WNOHANG)) == 0) {
255 | // do nothing
256 | }
257 | _terminationStatus = WEXITSTATUS(status);
258 | _isRunning = NO;
259 | }
260 |
261 | // check if task has terminated
262 | - (void)checkTaskStatus
263 | {
264 | int status;
265 | pid_t pid = waitpid(_processIdentifier, &status, WNOHANG);
266 | if (pid != 0) {
267 | _isRunning = NO;
268 | _terminationStatus = WEXITSTATUS(status);
269 | [_checkStatusTimer invalidate];
270 | [[NSNotificationCenter defaultCenter] postNotificationName:STPrivilegedTaskDidTerminateNotification object:self];
271 | if (_terminationHandler) {
272 | _terminationHandler(self);
273 | }
274 | }
275 | }
276 |
277 | #pragma mark -
278 |
279 | // Nice description for debugging
280 | - (NSString *)description
281 | {
282 | NSString *commandDescription = [NSString stringWithString:self.launchPath];
283 |
284 | for (NSString *arg in self.arguments) {
285 | commandDescription = [commandDescription stringByAppendingFormat:@" '%@'", arg];
286 | }
287 | [commandDescription stringByAppendingFormat:@" (CWD:%@)", self.currentDirectoryPath];
288 |
289 | return [[super description] stringByAppendingFormat:@" %@", commandDescription];
290 | }
291 |
292 | @end
293 |
--------------------------------------------------------------------------------
/Sketch Cache Cleaner/Utils/Share.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Share.swift
3 | // Sketch Cache Cleaner
4 | //
5 | // Created by Sasha Prokhorenko on 29.01.18.
6 | // Copyright © 2018 Sasha Prokhorenko. All rights reserved.
7 | //
8 |
9 | enum Share {
10 | static func twitterMessage(_ text: String) -> URL {
11 | let tweet = "https://twitter.com/intent/tweet?text=Just%20cleared%20"
12 | + "\(text.urlEncode())%20of%20space%20on%20my%20disk%20thanks%20"
13 | + "to%20Sketch%20Cache%20Cleaner!%20Check%20it%20out:%20"
14 | + "https%3A%2F%2Fyo-op.github.io%2Fsketchcachecleaner%2F%0A"
15 | guard let url = URL(string: tweet) else {
16 | return URL(string: Environment.webPage)!
17 | }
18 | return url
19 | }
20 |
21 | static func facebookMessage(_ text: String) -> URL {
22 | let facebook = "https://www.facebook.com/dialog/share?%20app_id=1778148252492778" +
23 | "&href=https%3A%2F%2Fyo-op.github.io%2Fsketchcachecleaner%2F%0A" +
24 | ""e=Just%20cleared%20" +
25 | "\(text.urlEncode())%20of%20space%20on%20my%20disk%20thanks%20" +
26 | "to%20Sketch%20Cache%20Cleaner!%20Check%20it%20out:%20" +
27 | "&redirect_uri=https%3A%2F%2F.facebook.com"
28 | guard let url = URL(string: facebook) else {
29 | return URL(string: Environment.webPage)!
30 | }
31 | return url
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/Sketch Cache Cleaner/Utils/Sketch Cache Cleaner-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 |
5 | #import "STPrivilegedTask.h"
6 |
--------------------------------------------------------------------------------
/Sketch Cache Cleaner/Views/MainWindow.swift:
--------------------------------------------------------------------------------
1 | //
2 | // MainWindow.swift
3 | // Sketch Cache Cleaner
4 | //
5 | // Created by Sasha Prokhorenko on 19.12.17.
6 | // Copyright © 2017 Sasha Prokhorenko. All rights reserved.
7 | //
8 |
9 | import Cocoa
10 |
11 | final class MainWindow: NSWindow {
12 | // Keep this class
13 | }
14 |
--------------------------------------------------------------------------------
/assets/RELEASE_NOTES.md:
--------------------------------------------------------------------------------
1 | # Sketch Cache Cleaner
2 |
3 | 
4 |
5 | Sketch Cache Cleaner is an app that deletes hidden Sketch history files that can take a lot of space on your hard drive and that you would probably never use.
6 |
7 | ---
8 |
9 | 1. [Warning](#warning)
10 | 2. [System Requirements](#system-requirements)
11 | 3. [Changelog](#changelog)
12 | 4. [Tips](#tips)
13 | 5. [Authors](#authors)
14 | 6. [License](#license)
15 |
16 | ---
17 |
18 | ## Warning
19 |
20 | The app idea inspired by two blog posts: [How Sketch took over 200GB of our MacBooks](https://medium.com/@thomasdegry/how-sketch-took-over-200gb-of-our-macbooks-cb7dd10c8163) & [How to recover 50 GB or even more by deleting Sketch caches files](https://medium.com/sketch-app-sources/how-to-recover-50-go-or-even-more-by-deleting-sketch-caches-files-e5829dba20e1)
21 |
22 | Please, read them in case you want to know how it works.
23 |
24 | If your **workflow** relies on **automatic versioning** by macOS
25 | (Time Machine etc.) - **DO NOT USE THIS APP!**
26 |
27 | The app will remove all files in folder: `/.DocumentRevisions-V100/`
28 |
29 | ---
30 |
31 | ## System Requirements
32 |
33 | - macOS 10.13+
34 | - Xcode 11.4+
35 | - Swift 5.2+
36 |
37 | ---
38 |
39 | ## Changelog
40 |
41 | ## [1.0.7] - 2020-30-03
42 |
43 | - Add macOS Catalina support
44 | - Bump minimum macOS version to 10.13
45 | - Build with Xcode 11.4
46 |
47 | ## [1.0.6] - 2020-16-01
48 |
49 | ### Changed
50 |
51 | - Add macOS Catalina support
52 | - Build with Xcode 11
53 |
54 | ## [1.0.5] - 2019-05-02
55 |
56 | ### Changed
57 |
58 | - Migrate to Swift 5
59 |
60 | ## [1.0.4] - 2018-10-21
61 |
62 | ### Changed
63 |
64 | - Build with Xcode 10 and macOS Mojave
65 | - Migrate to Swift 4.2
66 |
67 | ## [1.0.3] - 2018-03-27
68 |
69 | ### Added
70 |
71 | - Add social sharing
72 |
73 | ### Changed
74 |
75 | - Code refactor
76 | - Build with new Xcode's build system
77 |
78 | ## [1.0.2] - 2017-09-24
79 |
80 | ### Changed
81 |
82 | - Update to Swift 4
83 | - Compiled with Xcode 9
84 |
85 | ## [1.0.1] - 2017-07-14
86 |
87 | ### Fixed
88 |
89 | - Fix compatibility issues with 10.11, 10.12beta
90 |
91 | ## [1.0.0] - 2017-07-11
92 |
93 | - Initial release
94 |
95 | ---
96 |
97 | ## Authors
98 |
99 | Idea & design: [Yuriy Oparenko](http://oparenko.com/)
100 |
101 | Development: [Sasha Prokhorenko](https://twitter.com/minikin)
102 |
103 | ---
104 |
105 | ## Tips
106 |
107 | - Use this app wisely.
108 | - Reboot your Mac after app use.
109 |
110 | ---
111 |
112 | ## License
113 |
114 | Sketch Cache Cleaner is distributed under the [MIT license](https://github.com/yo-op/sketchcachecleaner/blob/master/LICENSE.md).
115 |
--------------------------------------------------------------------------------
/assets/RELEASE_NOTES.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yo-op/sketchcachecleaner/94f1580fe4c16db2addf827facd2cbf65431cffb/assets/RELEASE_NOTES.pdf
--------------------------------------------------------------------------------
/assets/Sketch Cache Cleaner.md:
--------------------------------------------------------------------------------
1 | # Sketch Cache Cleaner
2 |
3 | 
4 |
5 | Sketch Cache Cleaner is an app that deletes hidden Sketch history files that can take a lot of space on your hard drive and that you would probably never use.
6 |
7 | ---
8 |
9 | 1. [Warning](#warning)
10 |
11 | 2. [System Requirements](#system-requirements)
12 |
13 | 3. [Changelog](#changelog)
14 |
15 | 4. [Tips](#tips)
16 |
17 | 5. [Authors](#authors)
18 |
19 | 6. [License](#license)
20 |
21 | ## Warning
22 |
23 | The app idea inspired by two blog posts: [How Sketch took over 200GB of our MacBooks](https://medium.com/@thomasdegry/how-sketch-took-over-200gb-of-our-macbooks-cb7dd10c8163) & [How to recover 50 GB or even more by deleting Sketch caches files](https://medium.com/sketch-app-sources/how-to-recover-50-go-or-even-more-by-deleting-sketch-caches-files-e5829dba20e1)
24 |
25 | Please, read them in case you want to know how it works.
26 |
27 | If your **workflow** relies on **automatic versioning** by macOS
28 |
29 | (Time Machine etc.) - **DO NOT USE THIS APP!**
30 |
31 | The app will remove all files in folder: `/.DocumentRevisions-V100/`
32 |
33 | ## System Requirements
34 |
35 | - macOS 10.11+
36 |
37 | - Xcode 10.0+
38 |
39 | - Swift 4.2+
40 |
41 | ---
42 |
43 | ## Changelog
44 |
45 | ## [1.0.6] - 2020-16-01
46 |
47 | ### Changed
48 |
49 | - Add macOS Catalina support
50 | - Build with Xcode 11
51 |
52 | ## Changelog
53 |
54 | ## [1.0.5] - 2019-05-02
55 |
56 | ### Changed
57 |
58 | - Migrate to Swift 5
59 |
60 | ## [1.0.4] - 2018-10-21
61 |
62 | ### Changed
63 |
64 | - Build with Xcode 10 and macOS Mojave
65 |
66 | - Migrate to Swift 4.2
67 |
68 | ## [1.0.3] - 2018-03-27
69 |
70 | ### Added
71 |
72 | - Add social sharing
73 |
74 | ### Changed
75 |
76 | - Code refactor
77 |
78 | - Build with new Xcode's build system
79 |
80 | ## [1.0.2] - 2017-09-24
81 |
82 | ### Changed
83 |
84 | - Update to Swift 4
85 |
86 | - Compiled with Xcode 9
87 |
88 | ## [1.0.1] - 2017-07-14
89 |
90 | ### Fixed
91 |
92 | - Fix compatibility issues with 10.11, 10.12beta
93 |
94 | ## [1.0.0] - 2017-07-11
95 |
96 | - Initial release
97 |
98 | ---
99 |
100 | ## Authors
101 |
102 | Idea & design: [Yuriy Oparenko](http://oparenko.com/)
103 |
104 | Development: [Sasha Prokhorenko](https://twitter.com/minikin)
105 |
106 | ---
107 |
108 | ## Tips
109 |
110 | - Use this app wisely.
111 |
112 | - Reboot your Mac after app use.
113 |
114 | ---
115 |
116 | ## License
117 |
118 | Sketch Cache Cleaner is distributed under the [MIT license](https://github.com/yo-op/sketchcachecleaner/blob/master/LICENSE.md).
119 |
--------------------------------------------------------------------------------
/assets/SketchCacheCleaner.sketch:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yo-op/sketchcachecleaner/94f1580fe4c16db2addf827facd2cbf65431cffb/assets/SketchCacheCleaner.sketch
--------------------------------------------------------------------------------
/assets/Sketch_Cache_Cleaner_Logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yo-op/sketchcachecleaner/94f1580fe4c16db2addf827facd2cbf65431cffb/assets/Sketch_Cache_Cleaner_Logo.png
--------------------------------------------------------------------------------
/assets/catalina/catalina_1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yo-op/sketchcachecleaner/94f1580fe4c16db2addf827facd2cbf65431cffb/assets/catalina/catalina_1.png
--------------------------------------------------------------------------------
/assets/catalina/catalina_2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yo-op/sketchcachecleaner/94f1580fe4c16db2addf827facd2cbf65431cffb/assets/catalina/catalina_2.png
--------------------------------------------------------------------------------
/assets/catalina/catalina_3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yo-op/sketchcachecleaner/94f1580fe4c16db2addf827facd2cbf65431cffb/assets/catalina/catalina_3.png
--------------------------------------------------------------------------------
/assets/catalina/catalina_4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yo-op/sketchcachecleaner/94f1580fe4c16db2addf827facd2cbf65431cffb/assets/catalina/catalina_4.png
--------------------------------------------------------------------------------
/assets/catalina/catalina_5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yo-op/sketchcachecleaner/94f1580fe4c16db2addf827facd2cbf65431cffb/assets/catalina/catalina_5.png
--------------------------------------------------------------------------------