// // FreeSpaceViewController.swift // Free Space // // Created by Kyle Howells on 04/05/2022. // import UIKit class FreeSpaceViewController: UIViewController { let byteFormatter:ByteCountFormatter = { let formatter = ByteCountFormatter() formatter.allowedUnits = .useAll formatter.countStyle = .file formatter.includesUnit = true formatter.isAdaptive = true return formatter }() private let textView:UITextView = { let textView = UITextView() textView.backgroundColor = UIColor.white textView.textColor = UIColor.black textView.font = UIFont.systemFont(ofSize: 14, weight: .medium) textView.isEditable = false textView.contentInsetAdjustmentBehavior = .never return textView }() // MARK: - View Setup let settingsTitleLabel:UILabel = { let l = UILabel() l.font = UIFont.systemFont(ofSize: 16, weight: .medium) l.text = "Settings App (Important Files)" return l }() let settingsStorageBar:KHFileStorageView = KHFileStorageView() let realTitleLabel:UILabel = { let l = UILabel() l.font = UIFont.systemFont(ofSize: 16, weight: .medium) l.text = "Real Storage Usage" return l }() let realStorageBar:KHFileStorageView = KHFileStorageView() override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view. // formatter.string(fromByteCount: 123456789000) // '123.46 GB' // formatter.string(fromByteCount: 0) // 'Zero KB' // self.byteFormatter self.view.addSubview(self.textView) self.view.addSubview(self.settingsStorageBar) self.view.addSubview(self.settingsTitleLabel) self.view.addSubview(self.realStorageBar) self.view.addSubview(self.realTitleLabel) var text = "\n" text += "Total Space: \( self.byteFormatter.string(fromByteCount: Int64(getTotalSpace() ?? 0))) \n" text += "Total Real Free Space: \( self.byteFormatter.string(fromByteCount: Int64(getRealFreeSpace() ?? 0))) \n" text += "Total Important Free Space: \( self.byteFormatter.string(fromByteCount: getImportantFreeSpace() ?? 0)) \n" text += "Total Opportunistic Free Space: \( self.byteFormatter.string(fromByteCount: getOpportunisticFreeSpace() ?? 0)) \n" self.textView.text = text guard let _totalSpace = getTotalSpace() else { return } guard let _freeSpace = getRealFreeSpace() else { return } guard let importantFreeSpace = getImportantFreeSpace() else { return } //guard let opportunisticFreeSpace = getOpportunisticFreeSpace() else { return } let totalSpace = Int64(_totalSpace) let freeSpace = Int64(_freeSpace) self.settingsStorageBar.totalSpace = totalSpace self.settingsStorageBar.usedSpace = (totalSpace - importantFreeSpace) self.realStorageBar.totalSpace = totalSpace self.realStorageBar.usedSpace = (totalSpace - freeSpace) } // MARK: - Layout override func viewDidLayoutSubviews() { super.viewDidLayoutSubviews() let size = self.view.bounds.size //let safeArea = self.view.safeAreaInsets let width = size.width * 0.9 // - Settings self.settingsTitleLabel.frame = { var frame = CGRect() frame.size.height = self.settingsTitleLabel.intrinsicContentSize.height frame.size.width = width frame.origin.x = (size.width - frame.width) * 0.5 frame.origin.y = (size.height * 0.3) return frame }() self.settingsStorageBar.frame = { var frame = CGRect() frame.size.height = self.settingsStorageBar.intrinsicContentSize.height frame.size.width = width frame.origin.x = (size.width - frame.width) * 0.5 frame.origin.y = self.settingsTitleLabel.frame.maxY + 10 return frame }() // - Real self.realTitleLabel.frame = { var frame = CGRect() frame.size.height = self.settingsTitleLabel.intrinsicContentSize.height frame.size.width = width frame.origin.x = (size.width - frame.width) * 0.5 frame.origin.y = self.settingsStorageBar.frame.maxY + 40 return frame }() self.realStorageBar.frame = { var frame = CGRect() frame.size.width = width frame.size.height = self.realStorageBar.intrinsicContentSize.height frame.origin.x = (size.width - frame.width) * 0.5 frame.origin.y = self.realTitleLabel.frame.maxY + 10 return frame }() self.textView.frame = { var frame = CGRect() frame.origin.y = self.realStorageBar.frame.maxY + 30 frame.size.height = size.height - frame.origin.y frame.size.width = width frame.origin.x = (size.width - frame.width) * 0.5 return frame }() } } // MARK: - Get Free Space func getTotalSpace() -> Int? { let fileURL = URL(fileURLWithPath: NSHomeDirectory() as String) do { let values = try fileURL.resourceValues(forKeys: [.volumeTotalCapacityKey]) if let capacity = values.volumeTotalCapacity { print("Total capacity: \(capacity)") return capacity } else { print("Capacity is unavailable") } } catch { print("Error retrieving capacity: \(error.localizedDescription)") } return nil } func getRealFreeSpace() -> Int? { let fileURL = URL(fileURLWithPath: NSHomeDirectory() as String) do { let values = try fileURL.resourceValues(forKeys: [.volumeAvailableCapacityKey]) if let capacity = values.volumeAvailableCapacity { print("Available capacity: \(capacity)") return capacity } else { print("Capacity is unavailable") } } catch { print("Error retrieving capacity: \(error.localizedDescription)") } return nil } func getImportantFreeSpace() -> Int64? { let fileURL = URL(fileURLWithPath: NSHomeDirectory() as String) do { let values = try fileURL.resourceValues(forKeys: [.volumeAvailableCapacityForImportantUsageKey]) if let capacity: Int64 = values.volumeAvailableCapacityForImportantUsage { print("Available capacity for important usage: \(capacity)") return capacity } else { print("Capacity is unavailable") } } catch { print("Error retrieving capacity: \(error.localizedDescription)") } return nil } func getOpportunisticFreeSpace() -> Int64? { let fileURL = URL(fileURLWithPath: NSHomeDirectory() as String) do { let values = try fileURL.resourceValues(forKeys: [.volumeAvailableCapacityForOpportunisticUsageKey]) if let capacity: Int64 = values.volumeAvailableCapacityForOpportunisticUsage { print("Available capacity for important usage: \(capacity)") return capacity } else { print("Capacity is unavailable") } } catch { print("Error retrieving capacity: \(error.localizedDescription)") } return nil }