Demystifying iOS/iPadOS SandBox with Swift Code

Sai Balaji
Techiepedia
Published in
7 min readFeb 17, 2021

Hello everyone in this article we are going to see what is iOS Sand Box and how does it works and how developers can access their app’s sandbox and also allow the user to store data and access data from it.

In computer security, a sandbox is a security mechanism for separating running programs, usually in an effort to mitigate system failures and/or software vulnerabilities from spreading

What is a SandBox in iOS

For security purposes, an iOS app’s interactions with the file system are limited to the directories inside the app’s sandbox directory when ever a third party app is installed the operating system automatically create a Sandbox for that app.A SandBox can be seen as a container within which the app operates.

The SandBox includes several directories within them

Bundle Container

This is the app’s bundle. This directory contains the app binary and all of its resources like assets used in the app.You cannot write to this directory. To prevent tampering, the bundle directory is signed using cryptography at installation time. Writing to this directory changes the signature and prevents your app from launching. You can, however, gain read-only access to any resources stored in the apps bundle using the Swift APIs.

Data Container

It stores the data of the app for example data generated during runtime like user saving a text file, saving an image, Application caches etc.

It has some sub directory like

Documents : Use this directory to store user-generated content. The contents of this directory can be made available to the user through file sharing application like iTunes and it can also backed up using iCloud.

Library : This is the top-level directory for any files that are not user data files.

tmp : Use this directory to write temporary files that do not need to persist between launches of your app. Your app should remove files from this directory when they are no longer needed. The contents of this directory are not backed up by iTunes or iCloud.

Advantages of Sandbox

  • The sandbox protects and maintains a private environment of data and information for each app.
  • The sandbox can minimize the damage that can be done from a potential hacker by protecting the system resources from damage.
  • When an app is installed on a iOS or iPadOS device, the system creates a unique directory for it.

Examining App’s SandBox as a Developer

  • Create an empty iOS app using UIKit in Xcode.
  • Open Storyboard and add a navigation controller.
  • Add an UIImage View.

If test your app in simulator the you can easily examine the app SandBox’s Data Container.

Note This method will work only when you test your app in Simulator and not on a physical device.

  • Open up ViewController.swift and add this below line of code inside viewDidLoad()
print(NSHomeDirectory())

Now if you run the app and examine the output console you can see it prints the Sandbox’s data container path which is created when the app is installed in the simulator.

Since it is a simulator you can examine the app’s Sandbox in Mac OS.

  • Copy the path in output console and paste it in terminal

Here as you can see we are inside our app Sandbox ‘s Data Container.And it as the sub directories as mentioned before.

You can also open it using Finder by pressing Command+Shift+G and paste the path and press go.

App SandBox’s Data Container

Saving Data to SandBox Document Directory using Swift

  • Open View Controller.swift and add this following code.
 override func viewDidLoad() {
super.viewDidLoad()

title = "SandBoxDemo"

print(NSHomeDirectory())

navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .camera, target: self, action: #selector(pickImage))


navigationItem.leftBarButtonItem = UIBarButtonItem(barButtonSystemItem: .compose, target: self, action: #selector(addNote))


}

Here we add two buttons to our naviagation bar with a Camera icon and Note icon.When the button is tapped we call pickImage and addNote method which we will create.

  • Create the IBOutlet for the UIImage View and an empty String array.
    
var notes = [String]()
@IBOutlet weak var imageView: UIImageView!
  • Now create a function named saveImage() which we will use to save the image into Documents directory of App’s SandBox.
  func SaveImage(image: UIImage)
{

var path = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first! //Get the path for Document direcotry

let filename = "\(UUID().uuidString).jpg" //A random file name for our image

path.appendPathComponent(filename) //Complete path for the file along with the file name

print(path.absoluteString) //Debug print


/*Here we convert our UIImage to JPEG data
and store it inside Document direcotry of the SandBox*/
if let jpegImageData = image.jpegData(compressionQuality: 1.0)
{
do
{
try jpegImageData.write(to: path)
}
catch
{
print(error.localizedDescription)
}
}
}

As you can see the urls() method of FileManager Singleton instance returns an array of Path URL but we know that our SandBox has only one document Directory so we take the first element from the array.

  • No create a function named pickImage() which will be called when the user taps on camera button in navigation bar.In this method we allow the user to pick an image from their phone’s gallery and set it in UIImage.
 @objc
func pickImage()
{
let picker = UIImagePickerController()
picker.delegate = self
picker.allowsEditing = true //Allow user to crop the image

present(picker, animated: true, completion: nil)
}
  • Now we can set the picked image to UIImage by using a delegate method so make sure you set the delegate to self in UIImagePickerController.
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {

if let image = info[.editedImage] as? UIImage //get user picked image from info[] dictionary using .editedImage key
{
imageView.image = image// Set the image in UIImage view
SaveImage(image: image)//Also save the image to Documents Directory of Sandbox
}

dismiss(animated: true, completion: nil)//Dismiss the picker when user picks and image



}
  • Now we are going to allow the user to write some text data into a text file and store it in Sandbox in a .txt file.
  • Create a method named SaveTextFile() and add the following code in it
  func SaveTextFile()
{ //Get the path for Sandbox doucment Directory
var path = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!

let filename = "notes.txt"//Filename for our text file

path.appendPathComponent(filename)//Complete path along with file name

print(path.absoluteString)//debug print

do
{ /*Here we seprate the array elements of String array
by \n character so that we can save each note in a new line
inside the text file*/
try self.notes.joined(separator: "\n").write(to: path, atomically: false, encoding: .utf8)
}

catch
{
print(error)
}
}
  • Create a method addNote() which will be called when user taps addnote button in navigation bar.
  @objc
func addNote()
{
/*Here it diplays a pop up with a text field and we append the entered text to
notes string array and save it to Documents Directory
by calling SaveTextFile() method*/
let ac = UIAlertController(title: "Enter the note", message: nil, preferredStyle: .alert)

ac.addTextField(configurationHandler: nil)

ac.addAction(UIAlertAction(title: "Ok", style: .default, handler: { (action) in

if let enteredText = ac.textFields?.first?.text
{
self.notes.append(enteredText)
self.SaveTextFile()
}
}))

ac.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil))

present(ac, animated: true, completion: nil)
}
  • Now run the app in simulator
  • Now if you open your Documents SandBox direcotry in terminal or GUI you can see our image and a text file there
In CLI
In GUI
We can open that image to preview it
We can also preview the text file using Vim or any text editor

Allowing user’s to access SandBox document’s

However we as a developer can access the data stored in App’s SandBox only in simulator but actual user do not use simulator and they use physical device cannot access it by using above method.So now we make some small changes such that we can allow the user to see their data stored in App’s Sandbox Documents Directory using iOS/iPadOS file manager app !

  • Open info.plist and add this following keys and set the boolean values as yes

Application supports iTunes file sharing : This property allow the user to access the notes.tx file and their image files in Sandbox Documents Directory through their Mac when they connect their iPhone/iPad to their mac.

Supports opening documents in place : This property will allow the user to access the notes.txt and image file directly by using their iPad/iPhone default file manager app without need for connecting it with a Mac.

Now If you run this app either in Simulator or Physical device open the default file manager app you can see our files stored in SandBox can be accesed directly through Files app.

Here is the project repo

--

--