容易持久化结构体图片和数据 - Disk

2017-07-23      1490      Swift
项目简介

Installation•Usage•Debugging•License•Contribute

Disk is a powerful and simple file management library built with Apple's Data Storage Guidelines in mind. Disk uses the newCodableprotocol 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

Andimport Diskin 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 (seeHelper 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 calledMessage...

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 + clickretrievedMessage, then Xcode will show its type asMessage?. Pretty neat, huh?

So what happened in the background? Disk first convertsmessageto JSON data and stores it as a .json file to the caches directory. Then when we retrieve themessage, Disk automatically converts the JSON data to ourCodablestruct type. If Disk runs into any problems, then it prints details about any failed operations and returnsnilinstead.

What about arrays of structs?

Thanks to the power ofCodable, 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 convertsUIImages 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 forDatawill 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 ofData

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 thedo not backupattribute (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 (usingfileExists(:in:)), and then stored the data.

Documentation

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