215 lines
6.1 KiB
Swift
215 lines
6.1 KiB
Swift
//
|
|
// DiskManager.swift
|
|
// CapFinder
|
|
//
|
|
// Created by User on 23.04.18.
|
|
// Copyright © 2018 User. All rights reserved.
|
|
//
|
|
|
|
import Foundation
|
|
import UIKit
|
|
|
|
final class DiskManager {
|
|
|
|
enum LocalDirectory: String {
|
|
/// Folder for new images to upload
|
|
case upload = "Upload"
|
|
|
|
/// Folder for downloaded images
|
|
case images = "Images"
|
|
|
|
/// Folder for downloaded images
|
|
case thumbnails = "Thumbnails"
|
|
|
|
/// Directory for name file
|
|
case files = "Files"
|
|
|
|
private static let fm = FileManager.default
|
|
|
|
/// The url to the file sstem
|
|
var url: URL {
|
|
return URL(fileURLWithPath: self.rawValue, isDirectory: true, relativeTo: DiskManager.documentsDirectory)
|
|
}
|
|
|
|
fileprivate func create() -> Bool {
|
|
return DiskManager.create(directory: url)
|
|
}
|
|
|
|
var content: [URL]? {
|
|
do {
|
|
return try LocalDirectory.fm.contentsOfDirectory(at: url, includingPropertiesForKeys: nil, options: [])
|
|
} catch {
|
|
print("[LocalDirectory] Could not read directory \(self.rawValue): \(error)")
|
|
return nil
|
|
}
|
|
}
|
|
}
|
|
|
|
/// The folder where images and name list are stored
|
|
static let documentsDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
|
|
|
|
private static let fm = FileManager.default
|
|
|
|
// MARK: - First launch
|
|
|
|
@discardableResult static func setupOnFirstLaunch() -> Bool {
|
|
return LocalDirectory.files.create() &&
|
|
LocalDirectory.images.create() &&
|
|
LocalDirectory.thumbnails.create() &&
|
|
LocalDirectory.upload.create()
|
|
}
|
|
|
|
private static func create(directory: URL) -> Bool {
|
|
do {
|
|
if !fm.fileExists(atPath: directory.path) {
|
|
try fm.createDirectory(at: directory, withIntermediateDirectories: true, attributes: nil)
|
|
}
|
|
return true
|
|
} catch {
|
|
event("Could not create \(directory): \(error)")
|
|
return false
|
|
}
|
|
}
|
|
|
|
// MARK: - Image retrieval
|
|
|
|
/**
|
|
Check if an image exists for a cap
|
|
- parameter cap: The id of the cap
|
|
- returns: True, if an image exists
|
|
*/
|
|
static func hasImage(for cap: Int) -> Bool {
|
|
let url = localUrl(for: cap)
|
|
return fm.fileExists(atPath: url.path)
|
|
}
|
|
|
|
private static func localUrl(for cap: Int) -> URL {
|
|
return URL(fileURLWithPath: "\(cap).jpg", isDirectory: true, relativeTo: LocalDirectory.images.url)
|
|
}
|
|
|
|
private static func thumbnailUrl(for cap: Int) -> URL {
|
|
return URL(fileURLWithPath: "\(cap).jpg", isDirectory: true, relativeTo: LocalDirectory.thumbnails.url)
|
|
}
|
|
|
|
/**
|
|
Get the image for a cap.
|
|
If the image exists on disk, it is returned.
|
|
If no image exists locally, then this function returns nil.
|
|
- parameter cap: The id of the cap
|
|
- returns: The image data, or `nil`
|
|
*/
|
|
static func image(for cap: Int) -> Data? {
|
|
// If the image exists on disk, get it
|
|
let url = localUrl(for: cap)
|
|
return readData(from: url)
|
|
}
|
|
|
|
private static let mosaicURL: URL = documentsDirectory.appendingPathComponent("mosaic.png")
|
|
|
|
|
|
static var mosaicExists: Bool {
|
|
return fm.fileExists(atPath: mosaicURL.path)
|
|
}
|
|
|
|
static func saveMosaicData(_ data: Data) -> Bool {
|
|
return write(data, to: mosaicURL)
|
|
}
|
|
|
|
static var mosaicData: Data? {
|
|
return readData(from: mosaicURL)
|
|
}
|
|
|
|
/**
|
|
Get the thumbnail for a cap.
|
|
If the image exists on disk, it is returned.
|
|
If no image exists locally, then this function returns nil.
|
|
- parameter cap: The id of the cap
|
|
- returns: The image data, or `nil`
|
|
*/
|
|
static func thumbnail(for cap: Int) -> Data? {
|
|
// If the image exists on disk, get it
|
|
let url = thumbnailUrl(for: cap)
|
|
return readData(from: url)
|
|
}
|
|
|
|
private static func readData(from url: URL) -> Data? {
|
|
guard fm.fileExists(atPath: url.path) else {
|
|
return nil
|
|
}
|
|
do {
|
|
return try Data(contentsOf: url)
|
|
} catch {
|
|
self.error("Could not read data from \(url): \(error)")
|
|
return nil
|
|
}
|
|
}
|
|
|
|
/**
|
|
Save an image to the download folder
|
|
- parameter imageData: The data of the image
|
|
- parameter cap: The cap id
|
|
- returns: True, if the image was saved
|
|
*/
|
|
static func save(imageData: Data, for cap: Int) -> Bool {
|
|
let url = localUrl(for: cap)
|
|
return write(imageData, to: url)
|
|
}
|
|
|
|
/**
|
|
Save a thumbnail to the download folder
|
|
- parameter thumbnailData: The data of the image
|
|
- parameter cap: The cap id
|
|
- returns: True, if the image was saved
|
|
*/
|
|
static func save(thumbnailData: Data, for cap: Int) -> Bool {
|
|
let url = thumbnailUrl(for: cap)
|
|
return write(thumbnailData, to: url)
|
|
}
|
|
|
|
private static func write(_ data: Data, to url: URL) -> Bool {
|
|
do {
|
|
try data.write(to: url)
|
|
} catch {
|
|
self.error("Could not write data to \(url): \(error)")
|
|
return false
|
|
}
|
|
return true
|
|
}
|
|
|
|
static func removeFromUpload(url: URL) -> Bool {
|
|
guard fm.fileExists(atPath: url.path) else {
|
|
return true
|
|
}
|
|
do {
|
|
try fm.removeItem(at: url)
|
|
return true
|
|
} catch {
|
|
self.error("Could not delete file \(url.path)")
|
|
return false
|
|
}
|
|
}
|
|
|
|
static var pendingUploads: [URL]? {
|
|
return LocalDirectory.upload.content
|
|
}
|
|
|
|
static var availableImages: [Int]? {
|
|
return LocalDirectory.images.content?.compactMap {
|
|
Int($0.lastPathComponent.components(separatedBy: ".").first ?? "")
|
|
}
|
|
}
|
|
|
|
/**
|
|
Save an image to the uploads folder for later
|
|
*/
|
|
static func saveForUpload(imageData: Data, name: String) -> URL? {
|
|
let url = LocalDirectory.upload.url.appendingPathComponent(name)
|
|
return write(imageData, to: url) ? url : nil
|
|
}
|
|
}
|
|
|
|
extension DiskManager: Logger {
|
|
|
|
static let logToken = "[DiskManager]"
|
|
}
|