When we use Image
views, SwiftUI knows to look in your app’s asset catalog to find the artwork, and it even automatically adjusts the artwork so it loads the correct picture for the current screen resolution – that’s the @2x and @3x stuff we looked at earlier.
For other data, such as text files, we need to do more work. This also applies if you have specific data formats such as XML or JSON – it takes the same work regardless of what file types you’re loading.
When Xcode builds your iOS app, it creates something called a “bundle”. This happens on all of Apple’s platforms, including macOS, and it allows the system to store all the files for a single app in one place – the binary code (the actual compiled Swift stuff we wrote), all the artwork, plus any extra files we need all in one place.
In the future, as your skills grow, you’ll learn how you can actually include multiple bundles in a single app, allowing you to write things like Siri extensions, iMessage apps, widgets, and more, all inside a single iOS app bundle. Although these get included with our app’s download from the App Store, these other bundles are stored separately from our main app bundle – our main iOS app code and resources.
All this matters because it’s common to want to look in a bundle for a file you placed there. This uses a new data type called URL
, which stores pretty much exactly what you think: a URL such as https://www.hackingwithswift.com. However, URLs are a bit more powerful than just storing web addresses – they can also store the locations of files, which is why they are useful here.
Let’s start writing some code. If we want to read the URL for a file in our main app bundle, we use Bundle.main.url()
. If the file exists it will be sent back to us, otherwise we’ll get back nil
, so this is an optional URL
. That means we need to unwrap it like this:
if let fileURL = Bundle.main.url(forResource: "some-file", withExtension: "txt") {
// we found the file in our bundle!
}
What’s inside the URL
doesn’t really matter, because iOS uses paths that are impossible to guess – our app lives in its own sandbox, and we shouldn’t try to read outside of it.
Once we have a URL, we can load it into a string with a special initializer: String(contentsOf:)
. We give this a file URL, and it will send back a string containing the contents of that file if it can be loaded. If it can’t be loaded it throws an error, so you need to call this using try
or try?
like this:
if let fileContents = try? String(contentsOf: fileURL) {
// we loaded the file into a string!
}
Once you have the contents of the file, you can do with it whatever you want – it’s just a regular string.
SAVE 50% All our books and bundles are half price for Black Friday, so you can take your Swift knowledge further without spending big! Get the Swift Power Pack to build your iOS career faster, get the Swift Platform Pack to builds apps for macOS, watchOS, and beyond, or get the Swift Plus Pack to learn advanced design patterns, testing skills, and more.
Link copied to your pasteboard.