Swiftpack.co - Package - nodes-vapor/storage

Storage 🗄

Swift Version Vapor Version Circle CI codebeat badge codecov Readme Score GitHub license

A package to ease the use of multiple storage and CDN services.

Table of Contents

📦 Installation

Add Storage to the package dependencies (in your Package.swift file):

dependencies: [
    .package(url: "https://github.com/nodes-vapor/storage.git", from: "1.0.0")

as well as to your target (e.g. "App"):

targets: [
        name: "App",
        dependencies: [... "Storage" ...]

Getting started 🚀

Storage makes it easy to start uploading and downloading files. Just register a network driver and get going.

Upload a file 🌐

There are a few different interfaces for uploading a file, the simplest being the following:

    bytes: [UInt8],
    fileName: String?,
    fileExtension: String?,
    mime: String?,
    folder: String,
    on container: Container 
) throws -> String

The aforementioned function will attempt to upload the file using your selected driver and template and will return a String representing the location of the file.

If you want to upload an image named profile.png your call site would look like:

try Storage.upload(
    bytes: bytes,
    fileName: "profile.png",
    on: req

Base64 and data URI 📡

Is your file a base64 or data URI? No problem!

Storage.upload(base64: "SGVsbG8sIFdvcmxkIQ==", fileName: "base64.txt", on: req)
Storage.upload(dataURI: "data:,Hello%2C%20World!", fileName: "data-uri.txt", on: req)

Remote resources

Download an asset from a URL and then reupload it to your storage server.

Storage.upload(url: "http://mysite.com/myimage.png", fileName: "profile.png", on: req)

Download a file ✅

To download a file that was previously uploaded you simply use the generated path.

// download image as `Foundation.Data`
let data = try Storage.get("/images/profile.png", on: req)

Get CDN path

In order to use the CDN path convenience, you'll have to set the CDN base url on Storage, e.g. in your configure.swift file:

Storage.cdnBaseURL = "https://cdn.vapor.cloud"

Here is how you generate the CDN path to a given asset.

let cdnPath = try Storage.getCDNPath(for: path)

If your CDN path is more involved than cdnUrl + path, you can build out Storage's optional completionhandler to override the default functionality.

Storage.cdnPathBuilder = { baseURL, path in
    let joinedPath = (baseURL + path)
    return joinedPath.replacingOccurrences(of: "/images/original/", with: "/image/")

Delete a file ❌

Deleting a file can be done as follows.

try Storage.delete("/images/profile.png")

Configuration ⚙

Storage has a variety of configurable options.

Network driver 🔨

The network driver is the module responsible for interacting with your 3rd party service. The default, and currently the only, driver is s3.

import Storage

let driver = try S3Driver(
    bucket: "bucket", 
    accessKey: "access",
    secretKey: "secret"

services.register(driver, as: NetworkDriver.self)

bucket, accessKeyand secretKey are required by the S3 driver, while template, host and region are optional. region will default to eu-west-1 and host will default to s3.amazonaws.com.

Upload path 🛣

A times, you may need to upload files to a different scheme than /file.ext. You can achieve this by passing in the pathTemplate parameter when creating the S3Driver. If the parameter is omitted it will default to /#file.

The following template will upload profile.png from the folder images to /myapp/images/profile.png

let driver = try S3Driver(
    bucket: "mybucket",
    accessKey: "myaccesskey",
    secretKey: "mysecretkey",
    pathTemplate: "/myapp/#folder/#file"

Aliases are special keys in your template that will be replaced with dynamic information at the time of upload.

Note: if you use an alias and the information wasn't provided at the file upload's callsite, Storage will throw a missingX/malformedX error.

#file: The file's name and extension.

File: "test.png"
Returns: test.png

#fileName: The file's name.

File: "test.png"
Returns: test

#fileExtension: The file's extension.

File: "test.png"
Returns: png

#folder: The provided folder.

File: "uploads/test.png"
Returns: uploads

#mime: The file's content type.

File: "test.png"
Returns: image/png

#mimeFolder: A folder generated according to the file's mime.

This alias will check the file's mime and if it's an image, it will return images/original else it will return data

File: "test.png"
Returns: images/original

#day: The current day.

File: "test.png"
Date: 12/12/2012
Returns: 12

#month: The current month.

File: "test.png"
Date: 12/12/2012
Returns: 12

#year: The current year.

File: "test.png"
Date: 12/12/2012
Returns: 2012

#timestamp: The time of upload.

File: "test.png"
Time: 17:05:00
Returns: 17:05:00

#uuid: A generated UUID.

File: "test.png"
Returns: 123e4567-e89b-12d3-a456-426655440000

🏆 Credits

This package is developed and maintained by the Vapor team at Nodes.

📄 License

This package is open-sourced software licensed under the MIT license


Stars: 60


Used By

Total: 0


Version 1.0.1 - 2020-03-23 07:17:42


  • Support for deleting files (closes https://github.com/nodes-vapor/storage/issues/47). Remember that CDNs will still cache your files even if you delete them on S3.

Version 1.0.0 Beta 7 - 2019-12-30 13:15:21


  • Fixes a problem with the authorization header (that only appears over the years), due to wrong date format.

Version 1.0.0 Beta 6 - 2019-05-07 11:13:57


  • Fixed Swift 5 compiler warnings related to redundant access modifiers

Version 1.0.0 Beta 5 - 2019-04-23 10:09:06


  • Upload errors are no longer ignored, instead they're forwarded to provide a better description of the error.
  • Content type is now passed along when uploading, using the S3 provider


  • ACL settings can now be customised when uploading to S3

Version 1.0.0 Beta 4 - 2019-03-11 08:33:54


  • Add eu-west-2 and eu-west-3 Regions and allow the use of custom Regions by specifying a region code: Region(code: "my-custom-region"). Thanks @iGranDav !

Version 1.0.0 Beta 3 - 2019-01-02 10:26:15


  • amzDate now has the correct year format (changed YYYY to yyyy). Thanks to @chili-ios

Version 1.0.0 Beta 2 - 2018-11-07 07:12:08


  • Small introduction to how to set the cdnBaseURL.


  • cdnBaseURL on Storage is now opened up to be able to be set.

Version 1.0.0 Beta 1 - 2018-11-06 14:31:20


  • Vapor 3!

Version 0.4.0 - 2017-05-18 15:14:26

  • Vapor 2 released 🎉

Version 0.3.8 - 2017-05-15 13:19:55

  • Fixed default template location (thanks a2)

Version 0.3.7 - 2017-02-10 18:43:09

  • CAPS file extensions now work

0.3.6 - 2017-02-06 19:54:33


  • Properly loads mime for files with the extension jpg

0.3.5 - 2017-02-02 21:39:17


  • support for upload(formData: Field)

0.3.4 - 2017-01-28 21:38:59

  • Changed argument name for getCDNUrl optional overload

0.3.3 - 2017-01-28 21:29:41

  • getCDNPath overload for optionals

0.3.2 - 2017-01-08 22:35:00

Updated AWS module name.

0.3.1 - 2017-01-04 22:16:39

Updates to Alias.

0.3.0 - 2017-01-03 01:21:03

More aliases and better path/file handling.

0.2.2 - 2017-01-02 18:25:52

Updated for new Data URI API.

0.2.1 - 2016-12-22 22:46:50


  • Updated documentation


  • Multipart overload.

0.2.0 - 2016-12-22 06:07:15

Data URIs

0.1.0 - 2016-12-20 06:08:48

The first beta release!