Library free space detection

This commit is contained in:
Chris Li 2017-02-07 13:31:53 -05:00
parent a76b45eb4c
commit d841c3b982
5 changed files with 65 additions and 30 deletions

View File

@ -13,6 +13,7 @@ import DZNEmptyDataSet
class LibraryBooksController: CoreDataCollectionBaseController, UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout, LibraryCollectionCellDelegate, DZNEmptyDataSetSource, DZNEmptyDataSetDelegate {
private(set) var itemWidth: CGFloat = 0.0
private(set) var freeDiskSpace: Int64 = 0
var isCloudTab = true {
didSet {
title = isCloudTab ? Localized.Library.cloudTitle : Localized.Library.localTitle
@ -32,6 +33,22 @@ class LibraryBooksController: CoreDataCollectionBaseController, UICollectionView
itemWidth = (collectionViewWidth - 1 * (itemsPerRow - 1)) / itemsPerRow
}
func getAvailableDiskSpace() -> Int64 {
let docDirPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first!
let systemAttributes = try! FileManager.default.attributesOfFileSystem(forPath: docDirPath)
return (systemAttributes[FileAttributeKey.systemFreeSize] as! NSNumber).int64Value
}
func getBookSpaceStatus(fileSize: Int64) -> SpaceStatus {
if (0.8 * Double(freeDiskSpace)) > Double(fileSize) {
return .enough
} else if freeDiskSpace < fileSize{
return .notEnough
} else {
return .caution
}
}
// MARK: - Override
override func viewDidLoad() {
@ -39,7 +56,10 @@ class LibraryBooksController: CoreDataCollectionBaseController, UICollectionView
configureBarButtons()
configureCollectionViewLayout()
if isCloudTab { configureRefreshControl() }
if isCloudTab {
freeDiskSpace = getAvailableDiskSpace()
configureRefreshControl()
}
}
override func viewWillAppear(_ animated: Bool) {
@ -172,6 +192,7 @@ class LibraryBooksController: CoreDataCollectionBaseController, UICollectionView
].flatMap({$0}).joined(separator: " ")
cell.descriptionLabel.text = book.desc
cell.hasPicLabel.isHidden = !book.hasPic
cell.spaceStatus = getBookSpaceStatus(fileSize: book.fileSize)
return cell
}
@ -194,7 +215,7 @@ class LibraryBooksController: CoreDataCollectionBaseController, UICollectionView
guard let indexPath = collectionView.indexPath(for: cell) else {return}
let book = fetchedResultController.object(at: indexPath)
let procedure = AlertProcedure.Library.more(context: self, book: book)
let procedure = AlertProcedure.Library.more(context: self, book: book, spaceStatus: cell.spaceStatus)
procedure.alert.modalPresentationStyle = .popover
procedure.alert.popoverPresentationController?.sourceView = cell.moreButton
procedure.alert.popoverPresentationController?.sourceRect = cell.moreButton.bounds

View File

@ -154,6 +154,31 @@ class LibraryCollectionCell: UICollectionViewCell {
delegate?.didTapMoreButton(cell: self)
}
var spaceStatus: SpaceStatus = .enough {
didSet {
switch spaceStatus {
case .enough:
titleLabel.textColor = UIColor.black
subtitleLabel.textColor = UIColor.black
descriptionLabel.textColor = UIColor.black
hasPicLabel.textColor = UIColor.orange
hasPicLabel.layer.borderColor = UIColor.orange.cgColor
case .caution:
titleLabel.textColor = UIColor.orange
subtitleLabel.textColor = UIColor.orange
descriptionLabel.textColor = UIColor.orange
hasPicLabel.textColor = UIColor.orange
hasPicLabel.layer.borderColor = UIColor.orange.cgColor
case .notEnough:
titleLabel.textColor = UIColor.gray
subtitleLabel.textColor = UIColor.gray
descriptionLabel.textColor = UIColor.gray
hasPicLabel.textColor = UIColor.gray
hasPicLabel.layer.borderColor = UIColor.gray.cgColor
}
}
}
weak var delegate: LibraryCollectionCellDelegate?
@IBOutlet weak var imageView: UIImageView!
@IBOutlet weak var titleLabel: UILabel!
@ -163,6 +188,11 @@ class LibraryCollectionCell: UICollectionViewCell {
@IBOutlet weak var moreButton: UIButton!
}
enum SpaceStatus {
case enough, caution, notEnough
}
protocol LibraryCollectionCellDelegate: class {
func didTapMoreButton(cell: LibraryCollectionCell)
}

View File

@ -60,13 +60,3 @@ extension Bundle {
return (Bundle.main.object(forInfoDictionaryKey: kCFBundleVersionKey as String) as? String) ?? "Unknown"
}
}
extension UIDevice {
class var availableDiskSpace: (freeSize: Int64, totalSize: Int64)? {
let docDirPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first!
guard let systemAttributes = try? FileManager.default.attributesOfFileSystem(forPath: docDirPath),
let freeSize = (systemAttributes[FileAttributeKey.systemFreeSize] as? NSNumber)?.int64Value,
let totalSize = (systemAttributes[FileAttributeKey.systemSize] as? NSNumber)?.int64Value else {return nil}
return (freeSize, totalSize)
}
}

View File

@ -228,17 +228,6 @@ class Book: NSManagedObject {
stateRaw = Int16(newValue.rawValue)
}
}
var spaceState: BookSpaceState {
guard let freeSpaceInBytes = UIDevice.availableDiskSpace?.freeSize else {return .enough}
if (0.8 * Double(freeSpaceInBytes)) > Double(fileSize) {
return .enough
} else if freeSpaceInBytes < fileSize{
return .notEnough
} else {
return .caution
}
}
}
enum BookState: Int, CustomStringConvertible {
@ -253,8 +242,3 @@ enum BookState: Int, CustomStringConvertible {
}
}
}
enum BookSpaceState: Int {
case enough, caution, notEnough
}

View File

@ -114,11 +114,20 @@ extension AlertProcedure {
return alert
}
static func more(context: UIViewController, book: Book) -> AlertProcedure {
static func more(context: UIViewController, book: Book, spaceStatus: SpaceStatus) -> AlertProcedure {
assert(Thread.isMainThread)
let alert = AlertProcedure(presentAlertFrom: context, withPreferredStyle: .actionSheet, waitForDismissal: true)
alert.title = book.title
alert.message = book.desc
alert.message = {
switch spaceStatus {
case .enough:
return book.desc
case .caution:
return "Caution: This book will take up more than 80% of the free space on your device!"
case .notEnough:
return "You cannot start downloading, because your device does not have enough free space for this book."
}
}()
if book.state == .cloud {
alert.add(actionWithTitle: Localized.Library.download, style: .default) { _ in
Network.shared.start(bookID: book.id)
@ -137,6 +146,7 @@ extension AlertProcedure {
}
alert.add(actionWithTitle: Localized.Common.cancel, style: .cancel) { _ in alert.finish() }
alert.actions.first?.isEnabled = spaceStatus != .notEnough
return alert
}