Reading (NS)Bundle in iOS after relaunch

Sorry, I did not have a catchier title:

Prelude

Avid followers of my Twitter account know: I was looking for an easy, preferably human editable container for documents, and — being the old Mac developer I am — I went with bundles, stored in the Documents folder.

The Problem

At some point in my app, the user can choose which file to use. And then, of course, on next launch, that file should be used. Selecting the file works all nice and well, including reading from the created Bundle.

The problem occurs when the App is relaunched, and reads the absoluteString of the file from the UserDefaults. This works, and I can create a URL from it. But creating a bundle fails, and I don't get any error. This happens on iOS 15 and 16, on device and in the simulator.

Is this some permissions things? Is the url not formatted correctly? What is going on?

To Reproduce

I have created a sample App here: https://github.com/below/BundleSample

  • Launch the App, in the Simulator or on device
  • Select "Copy Bundle" (You can "Test Resource Bundle", but it does not matter)
  • Finally, select "Test Documents Bundle". You should see a picture
  • Close the app, either by stopping it in Xcode or force quit
  • Restart the App

Expected Result

You see the picture

Acutal Result

You see the "Gear" placeholder

It seems the path to the file change after a re-launch:

The prefs say

…/Containers/Data/Application/25E88AEC-9B14-48E9-A7BF-3F93C05AFCB8/Documents/Sample.quizlist

When I get the path to the documents folder after relaunch, it is

…/Containers/Data/Application/DA18292E-D744-41FF-A98B-A2085E9F4318/Documents/Sample.quizlist

I assume this is a feature, not a bug. But why? And where is it documented?

The issue is simple: Every Xcode "Run" is a reinstall

And where is it documented?

I don’t think this is documented because iOS has always worked this way. There are two ways you can approach this:

  • Store a relative path, typically relative to the home directory, that is, the root of your container

  • Store a bookmark

The latter is by far the best option. As an “old Mac developer” you can think of bookmarks as the logical successor to aliases.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Reading (NS)Bundle in iOS after relaunch
 
 
Q