Skip to content

JamesLinus/Disk

 
 

Repository files navigation

Disk

Platform: iOS 10+ Language: Swift 4 CocoaPods compatible License: MIT

InstallationUsageDebuggingLicenseContribute

Disk is a powerful and simple file management library built with Apple's Data Storage Guidelines in mind. Disk uses the new Codable protocol introduced in Swift 4 to its utmost advantage and gives you the power to persist JSON data without ever having to worry about encoding/decoding. Disk also helps you store images and other data types to disk with as little as one line of code.

Compatibility

Disk requires iOS 10+ and is compatible with Swift 4 projects. Therefore you must use Xcode 9 when working with Disk.

Installation

platform :ios, '10.0'
target 'ProjectName' do
use_frameworks!

    pod 'Disk'

end
  • Or embed the Disk framework into your project

And import Disk in the files you'd like to use it.

Usage

Disk currently supports file management of the following types:

  • Codable
  • [Codable]
  • UIImage
  • [UIImage]
  • Data
  • [Data]

These are generally the only types you'll ever need to deal with when persisting data on iOS.

Disk follows Apple's iOS Data Storage Guidelines and therefore allows you to store files in three primary directories:

Documents Directory .documents

"Only documents and other data that is user-generated, or that cannot otherwise be recreated by your application, should be stored in the <Application_Home>/Documents directory and will be automatically backed up by iCloud."

Caches Directory .caches

"Data that can be downloaded again or regenerated should be stored in the <Application_Home>/Library/Caches directory. Examples of files you should put in the Caches directory include database cache files and downloadable content, such as that used by magazine, newspaper, and map applications.

Use this directory to write any application-specific support files that you want to persist between launches of the application or during application updates. Your application is generally responsible for adding and removing these files (see Helper Methods). It should also be able to re-create these files as needed because iTunes removes them during a full restoration of the device. In iOS 2.2 and later, the contents of this directory are not backed up by iTunes.

Note that the system may delete the Caches/ directory to free up disk space, so your app must be able to re-create or download these files as needed."

Temporary Directory .temporary

"Data that is used only temporarily should be stored in the <Application_Home>/tmp directory. Although these files are not backed up to iCloud, remember to delete those files when you are done with them so that they do not continue to consume space on the user’s device."

Using Disk is easy.

Structs (must conform to Codable)

Let's say have a data model called Message...

struct Message: Codable {
    let title: String
    let body: String
}

... and we want to persist a message to disk...

let message = Message(title: "Hello", body: "How are you?")
Disk.store(message, to: .caches, as: "message")

... we might then want to retrieve this message from the caches directory...

let retrievedMessage = Disk.retrieve("message", from: .caches, as: Message.self)

If you Alt + click retrievedMessage, then Xcode will show its type as Message?. Pretty neat, huh? example

So what happened in the background? Disk first converts message to JSON data and stores it as a .json file to the caches directory. Then when we retrieve the message, Disk automatically converts the JSON data to our Codable struct type. If Disk runs into any problems, then it prints details about any failed operations and returns nil instead.

What about arrays of structs?

Thanks to the power of Codable, storing and retrieving arrays of structs is just as easy the code above.

var messages = [Message]()
for i in 0..<5 {
    messages.append(Message(title: "\(i)", body: "..."))
}
Disk.store(messages, to: .caches, as: "many-messages")
let retrievedMessages = Disk.retrieve("many-messages", from: .caches, as: [Message].self)

Images

Disk automatically converts UIImages to .png or .jpg files.

let image = UIImage(named: "nature.png")
Disk.store(image, to: .documents, as: "nature")
let retrievedImage = Disk.retrieve("nature", from: .documents, as: UIImage.self)

Array of images

Multiple images are saved to a single directory with the given name. Each image is then named 1.png, 2.png, 3.png, etc.

var images = [UIImages]()
// ...
Disk.store(images, to: .documents, as: "album")
let retrievedImages = Disk.retrieve("album", from: .documents, as: [UIImage].self)

Data

If you're trying to save data like .mp4 video data for example, then Disk's methods for Data will help you work with the file system to persist large files.

let videoData = Data(contentsOf: videoURL, options: [])
Disk.store(videoData, to: .documents, as: "anime")
let retrievedData = Disk.retrieve("anime", from: .documents, as: Data.self)

Array of Data

var data = [Data]()
// ...
Disk.store(data, to: .documents, as: "videos")
let retrievedVideos = Disk.retrieve("videos", from: .documents, as: [Data].self)

Helper Methods

  • Clear an entire directory
Disk.clear(.caches)
  • Remove a certain file from a directory
Disk.remove("videos", from: .documents)
  • Check if file exists with specified name at a directory
if Disk.fileExists("videos", in: .documents) {
    // ...
}
  • Move a file to another directory
Disk.move("images", in: .documents, to: .caches)
  • Rename a file
Disk.rename("currentName", in: .documents, to: "newName")
  • Mark a file with the do not backup attribute (this keeps the file on disk even in low storage situations, but prevents it from being backed up by iCloud or iTunes.)
Disk.doNotBackup("message", in: .caches)

All files saved to the user's home directory are backed up by default.

Disk.backup("message", in: .caches)

You should generally never use the .doNotBackup(:in:) and .backup(:in:) methods unless you're absolutely positive you want to persist data no matter what state the user's device is in.

Debugging

Disk is forgiving, meaning that it will handle most rookie mistakes on its own. However if you make a mistake that Disk thinks is worth telling you, it will print details of the operation to the console instead of crashing the project at runtime. This should help you better manage your data and change your persistence game plan.

Let's say, for example, that you try to write data to a location on the file system where data already exists:

❗️💾 Disk: File with name "message" already exists in Documents Directory. Removing and replacing with contents of new data...

In this case, Disk took care of everything for you. You should have first checked if a file exists in the location you wanted to store data to (using fileExists(:in:)), and then stored the data.

Documentation

Alt + click on any of Disk's methods for detailed documentation. documentation

License

Disk uses the MIT license. Please file an issue if you have any questions or if you'd like to share how you're using Disk.

Contribute

Disk is in its infancy, but v0.0.8 provides the barebones of the simplest way to persist data in iOS. Please feel free to send pull requests of any features you think would add to Disk and its philosophy.

Questions?

Contact me by email hello@saoudmr.com, or by twitter @sdrzn. Please create an issue if you come across a bug or would like a feature to be added.

About

Delightful framework for iOS to easily persist structs, images, and data.

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages

  • Swift 97.4%
  • Ruby 1.8%
  • Objective-C 0.8%