Skip to content

Commit fb16aaa

Browse files
authored
Merge pull request #4 from IrelDev/develop
Release v1.1
2 parents 98c7a79 + a6033e0 commit fb16aaa

20 files changed

+259
-90
lines changed

Assets/Demo.gif

-21.2 KB
Loading

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,6 @@ To install Xcode Cleaner go to [releases](https://github.com/IrelDev/XcodeCleane
1212
<p align="center">
1313
<img src = "Assets/Demo.gif" /><br>
1414
</p>
15+
16+
## License
17+
XcodeCleaner is available under the MIT license, see the [LICENSE](LICENSE) file for more information.

XcodeCleaner.xcodeproj/project.pbxproj

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
objects = {
88

99
/* Begin PBXBuildFile section */
10+
9D5A202724BC1A7F0066303A /* ActivityIndicatorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9D5A202624BC1A7F0066303A /* ActivityIndicatorView.swift */; };
11+
9DB4448224BAEFEE00165FB9 /* FileType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9DB4448124BAEFEE00165FB9 /* FileType.swift */; };
1012
9DCE1C0B24B582D200E49E6D /* CoreDataManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9DCE1C0A24B582D200E49E6D /* CoreDataManager.swift */; };
1113
9DD3BA7024B4639400EDA308 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9DD3BA6F24B4639400EDA308 /* AppDelegate.swift */; };
1214
9DD3BA7224B4639400EDA308 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9DD3BA7124B4639400EDA308 /* ContentView.swift */; };
@@ -51,6 +53,8 @@
5153
/* End PBXBuildFile section */
5254

5355
/* Begin PBXFileReference section */
56+
9D5A202624BC1A7F0066303A /* ActivityIndicatorView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActivityIndicatorView.swift; sourceTree = "<group>"; };
57+
9DB4448124BAEFEE00165FB9 /* FileType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FileType.swift; sourceTree = "<group>"; };
5458
9DCE1C0A24B582D200E49E6D /* CoreDataManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CoreDataManager.swift; sourceTree = "<group>"; };
5559
9DD3BA6C24B4639400EDA308 /* XcodeCleaner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = XcodeCleaner.app; sourceTree = BUILT_PRODUCTS_DIR; };
5660
9DD3BA6F24B4639400EDA308 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
@@ -108,6 +112,15 @@
108112
/* End PBXFrameworksBuildPhase section */
109113

110114
/* Begin PBXGroup section */
115+
9DB4448024BAEFCE00165FB9 /* Enums */ = {
116+
isa = PBXGroup;
117+
children = (
118+
9DD3BA8F24B478B600EDA308 /* DirectoryType.swift */,
119+
9DB4448124BAEFEE00165FB9 /* FileType.swift */,
120+
);
121+
path = Enums;
122+
sourceTree = "<group>";
123+
};
111124
9DD3BA6324B4639400EDA308 = {
112125
isa = PBXGroup;
113126
children = (
@@ -130,14 +143,14 @@
130143
isa = PBXGroup;
131144
children = (
132145
9DD3BA6F24B4639400EDA308 /* AppDelegate.swift */,
133-
9DD3BA8F24B478B600EDA308 /* DirectoryType.swift */,
134146
9DD3BA8D24B478AE00EDA308 /* DirectoryManager.swift */,
135147
9DCE1C0A24B582D200E49E6D /* CoreDataManager.swift */,
136-
9DD3BA9624B478CC00EDA308 /* Views */,
137148
9DD3BA9124B478C100EDA308 /* Models */,
149+
9DD3BA9624B478CC00EDA308 /* Views */,
138150
9DD3BAA924B4795A00EDA308 /* ViewModels */,
139151
9DD3BAB224B4798200EDA308 /* Protocols */,
140152
9DD3BABB24B479B300EDA308 /* Helpers */,
153+
9DB4448024BAEFCE00165FB9 /* Enums */,
141154
9DD3BABE24B479C900EDA308 /* PieChart */,
142155
9DD3BA7624B4639700EDA308 /* Assets.xcassets */,
143156
9DD3BA7B24B4639700EDA308 /* Main.storyboard */,
@@ -170,6 +183,7 @@
170183
isa = PBXGroup;
171184
children = (
172185
9DD3BA7124B4639400EDA308 /* ContentView.swift */,
186+
9D5A202624BC1A7F0066303A /* ActivityIndicatorView.swift */,
173187
9DD3BA9924B478FD00EDA308 /* BodyViews */,
174188
9DD3BA9A24B4790200EDA308 /* FooterViews */,
175189
);
@@ -361,6 +375,7 @@
361375
9DD3BAA824B4794C00EDA308 /* ScanProgressView.swift in Sources */,
362376
9DD3BAC524B479ED00EDA308 /* PieChartSubSliceView.swift in Sources */,
363377
9DD3BA8E24B478AE00EDA308 /* DirectoryManager.swift in Sources */,
378+
9DB4448224BAEFEE00165FB9 /* FileType.swift in Sources */,
364379
9DD3BAB024B4796C00EDA308 /* ViewModel.swift in Sources */,
365380
9DD3BA9424B478C900EDA308 /* DirectoryModel.swift in Sources */,
366381
9DD3BAA224B4793900EDA308 /* FooterView.swift in Sources */,
@@ -381,6 +396,7 @@
381396
9DD3BAD224B47A1E00EDA308 /* PieChartSliceModel.swift in Sources */,
382397
9DD3BAB824B4798E00EDA308 /* PieChartViewModelProtocol.swift in Sources */,
383398
9DD3BAB124B4796C00EDA308 /* DirectoryListViewModel.swift in Sources */,
399+
9D5A202724BC1A7F0066303A /* ActivityIndicatorView.swift in Sources */,
384400
9DD3BAC024B479DF00EDA308 /* PieChartSliceFactory.swift in Sources */,
385401
9DD3BAD324B47A1E00EDA308 /* PieChartObservableItemsModel.swift in Sources */,
386402
9DD3BA7524B4639400EDA308 /* XcodeCleaner.xcdatamodeld in Sources */,
@@ -534,6 +550,7 @@
534550
"@executable_path/../Frameworks",
535551
);
536552
MACOSX_DEPLOYMENT_TARGET = 10.15;
553+
MARKETING_VERSION = 1.1;
537554
PRODUCT_BUNDLE_IDENTIFIER = com.ireldev.XcodeCleaner.XcodeCleaner;
538555
PRODUCT_NAME = "$(TARGET_NAME)";
539556
SWIFT_VERSION = 5.0;
@@ -557,6 +574,7 @@
557574
"@executable_path/../Frameworks",
558575
);
559576
MACOSX_DEPLOYMENT_TARGET = 10.15;
577+
MARKETING_VERSION = 1.1;
560578
PRODUCT_BUNDLE_IDENTIFIER = com.ireldev.XcodeCleaner.XcodeCleaner;
561579
PRODUCT_NAME = "$(TARGET_NAME)";
562580
SWIFT_VERSION = 5.0;

XcodeCleaner/DirectoryManager.swift

Lines changed: 73 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,18 @@ struct DirectoryManager {
3737
}
3838
func getArchivesPath() -> String {
3939
let xcodePath = getXcodeDefaultPath()
40-
let deviceSupportPath = "Archives/"
41-
return "\(xcodePath + deviceSupportPath)"
40+
let archivesPath = "Archives/"
41+
return "\(xcodePath + archivesPath)"
42+
}
43+
func getIOSDeviceLogsPath() -> String {
44+
let xcodePath = getXcodeDefaultPath()
45+
let iOSDeviceLogsPath = "iOS Device Logs/"
46+
return "\(xcodePath + iOSDeviceLogsPath)"
47+
}
48+
func getDocumentationCachePath() -> String {
49+
let xcodePath = getXcodeDefaultPath()
50+
let documentationCachePath = "DocumentationCache/"
51+
return "\(xcodePath + documentationCachePath)"
4252
}
4353
func getSubDirectoriesForPath(path: String) -> [String] {
4454
let fileManager = FileManager.default
@@ -57,37 +67,75 @@ struct DirectoryManager {
5767

5868
return subDirectories
5969
}
60-
func getDirectorySize(path: String, completion: @escaping () -> Void = { }) -> Int64 {
70+
func getFileType(path: String) -> FileType? {
71+
let fileManager = FileManager.default
72+
var isDirectory: ObjCBool = false
73+
74+
if fileManager.fileExists(atPath: path, isDirectory: &isDirectory) {
75+
if isDirectory.boolValue {
76+
return .directory
77+
} else {
78+
return .file
79+
}
80+
}
81+
return nil
82+
}
83+
func getSize(path: String, completion: @escaping () -> Void = { }) -> Int64 {
6184
let fileManager = FileManager.default
6285
var directorySize: Int64 = 0
6386

64-
let directories = fileManager.subpaths(atPath: path)
65-
guard directories != nil else {
66-
completion()
67-
return 0
87+
var normalizedPath: String
88+
let fileType = getFileType(path: path)
89+
90+
switch fileType {
91+
case .directory:
92+
normalizedPath = normalizePathForDirectory(path: path)
93+
case .file:
94+
normalizedPath = normalizePathForFile(path: path)
95+
case .none:
96+
return 0
6897
}
6998

70-
for directory in directories! {
99+
if fileType == .file {
71100
do {
72-
let attributes = try fileManager.attributesOfItem(atPath: path + directory)
101+
let attributes = try fileManager.attributesOfItem(atPath: normalizedPath)
73102
directorySize += attributes[FileAttributeKey.size] as! Int64
74103
} catch {
75104
print(error.localizedDescription)
76105
}
106+
} else {
107+
let directories = fileManager.subpaths(atPath: normalizedPath)
108+
109+
for directory in directories! {
110+
do {
111+
let newPath = normalizedPath + directory
112+
let attributes = try fileManager.attributesOfItem(atPath: newPath)
113+
directorySize += attributes[FileAttributeKey.size] as! Int64
114+
} catch {
115+
print(error.localizedDescription)
116+
}
117+
}
77118
}
78119
completion()
79-
80120
return directorySize
81121
}
82-
func normalizeDirectoryPath(directory: String) -> String {
83-
var newDirectoryPath = directory
122+
func normalizePathForDirectory(path: String) -> String {
123+
var newPath = path
124+
125+
if !newPath.hasSuffix("/") {
126+
newPath += "/"
127+
}
128+
return newPath
129+
}
130+
func normalizePathForFile(path: String) -> String {
131+
var newPath = path
84132

85-
if !newDirectoryPath.hasSuffix("/") {
86-
newDirectoryPath += "/"
133+
if newPath.hasSuffix("/") {
134+
newPath.removeLast()
87135
}
88-
return newDirectoryPath
136+
return newPath
89137
}
90-
func normalizeDirectoryPathForDisplay(directory: String, forType type: DirectoryType) -> String {
138+
func normalizePathForDisplay(directory: String, forType type: DirectoryType) -> String {
91139
var result = directory
92140
var prefix: String
93141

@@ -98,6 +146,10 @@ struct DirectoryManager {
98146
prefix = getDeviceSupportPath()
99147
case .archives:
100148
prefix = getArchivesPath()
149+
case .iOSDeviceLogs:
150+
prefix = getIOSDeviceLogsPath()
151+
case .documentationCache:
152+
prefix = getDocumentationCachePath()
101153
}
102154

103155
if directory.contains(prefix) {
@@ -117,9 +169,13 @@ struct DirectoryManager {
117169
directoryPath = getDeviceSupportPath()
118170
case .archives:
119171
directoryPath = getArchivesPath()
172+
case .iOSDeviceLogs:
173+
directoryPath = getIOSDeviceLogsPath()
174+
case .documentationCache:
175+
directoryPath = getDocumentationCachePath()
120176
}
121177

122-
let directoryURL = URL(fileURLWithPath: normalizeDirectoryPath(directory: directoryPath))
178+
let directoryURL = URL(fileURLWithPath: normalizePathForDirectory(path: directoryPath))
123179

124180
do {
125181
try fileManager.removeItem(at: directoryURL)

XcodeCleaner/DirectoryType.swift renamed to XcodeCleaner/Enums/DirectoryType.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,6 @@ public enum DirectoryType {
1212
case derivedData
1313
case deviceSupport
1414
case archives
15+
case iOSDeviceLogs
16+
case documentationCache
1517
}

XcodeCleaner/Enums/FileType.swift

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
//
2+
// FileType.swift
3+
// XcodeCleaner
4+
//
5+
// Created by Kirill Pustovalov on 12.07.2020.
6+
// Copyright © 2020 Kirill Pustovalov. All rights reserved.
7+
//
8+
9+
import Foundation
10+
11+
enum FileType {
12+
case file
13+
case directory
14+
}

XcodeCleaner/Helpers/BytesToStringFormatter.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
import Foundation
1010

1111
struct BytesToStringFormatter {
12-
static func format(size: Int64, allowedUnits: ByteCountFormatter.Units = [.useGB, .useMB]) -> String {
12+
static func format(size: Int64, allowedUnits: ByteCountFormatter.Units = [.useKB, .useMB, .useGB]) -> String {
1313
let byteCountFormatter = ByteCountFormatter()
1414
byteCountFormatter.allowedUnits = allowedUnits
1515

XcodeCleaner/Info.plist

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
<key>CFBundlePackageType</key>
1818
<string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>
1919
<key>CFBundleShortVersionString</key>
20-
<string>1.0</string>
20+
<string>$(MARKETING_VERSION)</string>
2121
<key>CFBundleVersion</key>
2222
<string>1</string>
2323
<key>LSApplicationCategoryType</key>

XcodeCleaner/PieChart/Views/PieChartSliceView.swift

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ struct PieChartSliceView: View {
1212
var rect: CGRect
1313

1414
let slice: PieChartSliceModel
15-
let sliceSeparatorColor: Color
1615

1716
@State var isVisible: Bool = false
1817

@@ -24,7 +23,6 @@ struct PieChartSliceView: View {
2423

2524
return Group { sliceShape
2625
.fill()
27-
.overlay(sliceShape.stroke(sliceSeparatorColor, lineWidth: 2))
2826
.foregroundColor(slice.color)
2927
.scaleEffect(isVisible ? 1: 0)
3028
.animation(Animation.easeIn)
@@ -34,7 +32,7 @@ struct PieChartSliceView: View {
3432
if self.slice.subSlices.count > 0 {
3533
GeometryReader { geometryReader in
3634
ForEach(0 ..< self.slice.subSlices.count, id: \.self) { subSliceIndex in
37-
PieChartSubSliceView(rect: geometryReader.frame(in: .local), subSlice: self.slice.subSlices[subSliceIndex], sliceSeparatorColor: self.sliceSeparatorColor)
35+
PieChartSubSliceView(rect: geometryReader.frame(in: .local), subSlice: self.slice.subSlices[subSliceIndex])
3836
.padding(0 - min(geometryReader.size.width, geometryReader.size.height) / 2)
3937
}
4038
}
@@ -45,11 +43,9 @@ struct PieChartSliceView: View {
4543

4644
struct PieSliceView_Previews: PreviewProvider {
4745
static var previews: some View {
48-
let pieSlice = PieChartSliceModel(value: .zero, color: .orange, startDegree: 50, endDegree: 130)
49-
let sliceSeparatorColor = Color.black
50-
46+
let pieSlice = PieChartSliceModel(value: .zero, color: .orange, startDegree: 50, endDegree: 130)
5147
return GeometryReader { geometryReader in
52-
PieChartSliceView(rect: geometryReader.frame(in: .local), slice: pieSlice, sliceSeparatorColor: sliceSeparatorColor)
48+
PieChartSliceView(rect: geometryReader.frame(in: .local), slice: pieSlice)
5349
}
5450
.frame(width: 150, height: 150)
5551
}

XcodeCleaner/PieChart/Views/PieChartSubSliceView.swift

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,6 @@ struct PieChartSubSliceView: View {
1212
var rect: CGRect
1313

1414
let subSlice: PieChartSubSliceModel
15-
let sliceSeparatorColor: Color
16-
1715
@State var isVisible: Bool = false
1816

1917
var body: some View {
@@ -24,7 +22,6 @@ struct PieChartSubSliceView: View {
2422

2523
return Group { sliceShape
2624
.fill()
27-
.overlay(sliceShape.stroke(sliceSeparatorColor, lineWidth: 2))
2825
.foregroundColor(subSlice.color)
2926
.scaleEffect(isVisible ? 1: 0)
3027
.animation(Animation.easeIn)
@@ -38,10 +35,9 @@ struct PieChartSubSliceView: View {
3835
struct PieChartSubSliceView_Previews: PreviewProvider {
3936
static var previews: some View {
4037
let pieSlice = PieChartSubSliceModel(value: .zero, color: .orange, startDegree: 50, endDegree: 130)
41-
let sliceSeparatorColor = Color.black
4238

4339
return GeometryReader { geometryReader in
44-
PieChartSubSliceView(rect: geometryReader.frame(in: .local), subSlice: pieSlice, sliceSeparatorColor: sliceSeparatorColor)
40+
PieChartSubSliceView(rect: geometryReader.frame(in: .local), subSlice: pieSlice)
4541
}
4642
.frame(width: 150, height: 150)
4743
}

0 commit comments

Comments
 (0)