Creating an iPhone storage widget with Shortcuts, Toolbox Pro and Scriptable

Written on November 27, 2020

Whether you’ve got thousands of photos of yourself or loved ones or one too many apps on your iPhone. Having a widget that let’s you easily glance and see how much storage space you’ve got allows you to manage your phone’s storage easier.

In this—long—article I will show you how to set up an iPhone storage widget for your home screen.

iPhone screenshot showing two widgets

While there are a lot of steps and I’ve tried to make this article as easy as possible to follow—it might not be the most efficient set up.

Nonetheless I still wanted to share my set up in hopes that it will show you how I thought about building this widget, used some imagination and how I orchestrated various tools to bring it to life.

The apps you’ll need

Before we get started, in order to put this widget together, you’ll need a few different apps on your phone.

Those apps are:

  • Files - Files is the iCloud file browser for iOS and iPadOS
  • Shortcuts - To create an automation to get the storage information for your phone and store the data to be used for the widget
  • Toolbox Pro - Provides the custom action to get storage data from your phone
  • Scriptable - Used to create the widget using JavaScript

If you don’t have all of these, go grab them and then come on back to the article to get started.

How the widget works

In Scriptable I have two scripts set up.

The first which I call SaveStorageData is used by Shortcuts to save the storage information to a file in iCloud. This file acts as my persistent data to be used with the widget.

The other script, Phone Storage Widget is used to get the data from the file on iCloud and then to layout and create the widget on my home screen.

In Scriptable I also have an iCloud file bookmarked which is used for the two scripts above.

In Shortcuts, I have a single shortcut which uses actions from Toolbox Pro to get the storage used on my phone as well as the total storage available for the model of the phone. That information is grabbed and ran through SaveStorageData to record the formation in the iCloud file.

I also took the shortcut and passed it to an automation that runs daily in the morning. This is so once per day, the storage data will be updated for the widget.

Setting up Scriptable

To get started, we’ll work on a few steps in Scriptable first.

Setting up a bookmarked file in Scriptable

For this step, it assumes that you have a file already created in iCloud to be used to record the storage data for your phone. If you don’t then you can create a file using an app like 1Writer or if you’ve got a Mac, by placing a file into your iCloud Drive.

I like to keep all my automation files in a single place on iCloud so I’m using a folder called Automation data. The file I’ll be referencing is called, phone-storage-data.txt in the folder.

What a bookmark in Scriptable allows you to do is reference a file in iCloud without having to reference the entire path to the file. Instead you get a clean, variable-like bookmark to reference in your scripts.

  1. Tap on the gear in the top left corner in Scriptable.
  2. Scroll down and tap on the item labelled File Bookmarks
  3. Tap on the plus + symbol in the top right hand corner and when the prompt shows up, select Pick File
  4. Now navigate to the file you want to create a bookmark for in iCloud and select it by tapping on it.
  5. Once selected, you’ll be prompted by a modal to choose a name for your bookmark. One will be suggested but you can call it whatever you want. I like to use pascal-cased (or upper camel case) names without spaces so it is easier to reference in code. I chose PhoneStorageData for my bookmark name.

Once you’ve given your bookmark a name, you’ll now see it in the list of bookmarks.

Setting up a script to save storage data to a file in iCloud

Now that we’ve got our bookmark ready, we’ll set up the first script which will be used as an action to record data into the file in iCloud.

  1. If you haven’t already done so, close the settings view and tap on the plus + symbol in the top right hand corner to create a new script.

  2. Tap on the Untitled Script to give the script a new name. For scripts that I use as actions in Shortcuts, I like to give pascal-cased names like SaveStorageData. The reason is that it is easier to differentiate when selecting the script in Shortcuts.

  3. Copy and paste the code below.

// This line takes the data from the shortcut that this script is run in and passes it to a variable called `data`
const data = args.shortcutParameter

// This creates a new FileManager instance to access a file on iCloud
const fm = FileManager.iCloud()

// With the file manager's `bookmarkedPath` function we access the bookmarked file "PhoneStorageData"
const file = fm.bookmarkedPath("PhoneStorageData")

// Next we use the file manager's `writeString` function we take the file and overwrite it with the data from the shortcut
fm.writeString(file, data)

// This indicates that the script has completed
Script.complete()

Setting up a script for the widget

Now that you’ve created the script which will save the data to an iCloud file, we’ll now want to create a scrip that not only reads the file, but then uses it to create the widget that’ll sit on your home screen.

  1. Tap on the plus + symbol in the top right hand corner to create a new script.

  2. Tap on the Untitled Script to give the script a new name. Unlike my scripts for using as actions in Shortcuts, I just name these with regular titles like, Phone Storage Widget.

  3. Copy and paste the code below.

// Various variables used throughout the code
const width = 120
const height = 32
const bg = "#3d3b30"
const baseColor = "#242305"
const fillColor = "#e7e247"

// Only runs if it is in the context of a widget
if (config.runsInWidget) {
  const widget = createWidget()
  Script.setWidget(widget)
  Script.complete()
}

// Function to get data from iCloud
function getData () {
  const fm = FileManager.iCloud()
  const file = fm.bookmarkedPath("PhoneStorageData")
  
  // Using the file manager's `readString` function, I grab data from 
  // the file and split it by the space character. This is because the
  // data is saved in the file as a single string made up of two 
  // floating point numbers separated by a single space. 
  // The resulting array is returned by the function.
  return fm.readString(file).split(" ")
}

// Function to create the widget
function createWidget() {
  // Create a new `ListWidget`
  const w = new ListWidget()
  
  // Call the `getData` function and assign it to variable `storageData`
  const storageData = getData()
  
  // Take the first value stored in the array which is the number for 
  // the storage amount used on the phone.
  const used = Number(storageData[0])
  
  // Take the second value stored in the array which is the total number 
  // of stoage on the phone.
  const total = Math.round(Number(storageData[1]))
  
  // Grab the memorychip symbol in Apple's SF Symbol
  const playSymbol = SFSymbol.named("memorychip")
  
  // Turn that into an image to be used in the widget
  const playImage = w.addImage(playSymbol.image)
  
  // Give the image a tint, size and alignment
  playImage.tintColor = Color.white()
  playImage.imageSize = new Size(12, 12)
  playImage.rightAlignImage()
  
  // Add spacing between the image and the next element
  w.addSpacer()
  
  // Create a progress bar using the total and used storage space data
  const progressBar = w.addImage(createProgress(total, used)) 
  
  // Set the width and height based on the variables at the top of 
  // the script
  progressBar.imageSize = new Size(width, height)
  progressBar.centerAlignImage()
  
  // Add 6 units of spacing between the progress bar and the next element
  w.addSpacer(6)
  
  // Add a stack to the widget
  const s = w.addStack()
  
  // Add a text to indicate the storage amount used in GB to the stack
  const usedGB = s.addText(used + " GB")
  usedGB.font = Font.semiboldSystemFont(10)
  
  // Add equal amounts of spacing between the two elements in the stack
  s.addSpacer()
  
  // Add a text to indicate the total storage amount available in GB 
  // to the stack
  const totalGB = s.addText(total + " GB")
  totalGB.font = Font.semiboldSystemFont(10)
  
  w.addSpacer()
  
  // Calculate the percentage used and add a text to the widget
  const percentage = (used/total * 100).toFixed(2)
  const percentageText = w.addText(percentage + "%")
  percentageText.font = Font.boldSystemFont(20)
  percentageText.centerAlignText()
  
  // Add a label underneath the percentage text above
  const usedLabel = w.addText("Used")
  usedLabel.centerAlignText()
  usedLabel.font = Font.semiboldSystemFont(10)
  
  w.addSpacer()
  
  // Add one last text label to indicate the phone's storage
  const label = w.addText("My iPhone's storage")
  label.font = Font.semiboldSystemFont(10)
  label.centerAlignText()
  
  // Set the background color of the widget
  w.backgroundColor = new Color(bg)

  return w
}

// Function was borrowed from the Time Progress script available in 
// the Scriptable Gallery https://scriptable.app/gallery/time-progress
function createProgress(total, used){
  const context = new DrawContext()
  
  context.size = new Size(width, height)
  context.opaque = false
  context.respectScreenScale = true
  context.setFillColor(new Color(baseColor))
  
  const base = new Path()
  base.addRoundedRect(new Rect(0, 0, width, height), 16, 24)
  context.addPath(base)
  context.fillPath()
  context.setFillColor(new Color(fillColor))
  
  const fill = new Path()
  fill.addRoundedRect(new Rect(0, 0, width * used/total, height), 16, 24)
  context.addPath(fill)
  context.fillPath()
  
  return context.getImage()
}

Now that we’ve got our two scripts set up in Scriptable, we’ll next head over to Shortcuts to set up our shortcut to get the storage data and save it to the file on iCloud to be used in the widget.

Setting up a shortcut in Shortcuts to get storage data

  1. The first action is to get the amount of storage used.

    Icon for Toolbox Pro
    Toolbox Pro
    Get used space in GB
    include units in output
    Show When Run
  2. Next you’ll want to take the output from the action above and assign it to a variable. I’ve named this variable remaining.

    Variables
    Set variable Remaining to Device Storage
  3. Now you’ll want to get the total storage available for your device.

    Icon for Toolbox Pro
    Toolbox Pro
    Get total capacity in GB
    include units in output
    Show When Run
  4. Again, you’ll want to assign this to a variable. I named mine, Total.

    Variables
    Set variable Total to Device Storage
  5. In the next action, we’ll take the two variables defined above and create a single string. This is what is used to record the bookmarked files in Scriptable.

    Text
    RemainingTotal
  6. The final step is to take the text and pass it along to Scriptable to run the script that saves the string to the bookmarked file in Scriptable.

    Icon for Scriptable
    Scriptable
    Run SaveStorageData with Text
    Run In App
    Show When Run

Set up automation to grab storage data daily

Currently the only way that the storage data is kept up to date is by manually running the shortcut.

You could of course add a Shortcuts widget to your home screen to make it easier to access and run, or you could have the shortcut run automatically daily.

  1. In Shortcuts, tap on the Automation tab
  2. Tap the plus + button on the top right to create a new automation.
  3. On the next screen, you’ll want to select Create Personal Automation as you’ll want this running on your device.
  4. Next you’ll want to select your trigger for the shortcut. I’ve chosen the, Time of Day trigger and I have it set up to run Daily at 30 minutes before Sunrise. This way I get the most current storage snap shot as I’m getting out of bed in the morning.
  5. Next you’ll want to select Add Action and tap the Shortcuts actions.
  6. Select, Run Shortcut
  7. When you’re given the new Shortcuts action, you’ll want to tap the Shortcut label after Run in the action.
  8. Select the new shortcut you’ve created to grab the storage data.
  9. Tap next and you’ll be given a screen to review your new automation. Since I want this automation to run before I get up, I disable the option Ask Before Running.
  10. When you disable the option in step 9—above—a modal will show up asking you to make sure you want it to run without asking you, you can confirm your decision by tapping Don’t Ask.
  11. When you’re done tap Done and you’ll see your new automation in your list of personal automations.

Your first run

At this point, you’ve got all the pieces set up to now run your widget.

  1. To do this, you’ll want to run the new shortcut you’ve created. This will add the first storage data to your file on iCloud.

  2. Next, you’ll want to add the new widget on your home screen.

    You do this by entering the edit home screen mode. To enter the mode, you’ll want to long press anywhere on your home screen and you’ll icons change on your home screen to indicate you’re in the mode.

    You’ll also see a plus + symbol on the top left. This is the button to add a new widget to your home screen.

  3. Scroll down on the widgets screen and select Scriptable. Doing so will give you a screen that gives you the option to add a new Scriptable widget.

  4. Select the small widget and then tap the + Add Widget button to add the new widget on your home screen.

  5. Once you’re back on your home screen, tap on the new widget and this will give you a menu to configure your new widget.

    The first option labelled Script allows you to select the script that has to widget data and layout. Go ahead and select the script, Phone storage widget.

    The second option is labelled When Interacting which tells scriptable what to do when you tap on the widget itself. I’ve selected Run Script. This is so that it’ll get the latest data and update the widget when I do.

  6. Once you’re done configuring your widget, tap anywhere outside of the configuration menu and you’ll be returned to your home screen. You should now see your new widget with your phone’s storage data.

Congrats on your new widget!

Daily your new widget will be updated with the latest storage information from your phone and I hope this leads to making it easier to choose how to manage your storage.

I also hope you learned a ton about how some imagination and apps on your iPhone opens up a whole playground to make your phone do some neat things for you.

If you have any questions about this article, feel free to reach out to me on Twitter @michaelsoolee.

Stay in touch

Thanks for reading this article. I'd love to stay in touch and share more tips on programming and side projects with you. Sign up and I'll send you my articles straight to your email, you'll also get a free copy of the light themed version of my Git cheat sheet.
Git cheat sheet preview image