0

I'm trying to figure out how to store text information in a MacOS app, in the bundle. But when I try to run the application it can't find the file.

Here's what I'm doing:

  1. Create a brand new Xcode project using the command line app template, called BundleExperiment in the directory random_code_projects

  2. From the command line added a text file in the root directory of the created repository (~\random_code_projects\BundleExperiment) called "hello.txt" containing "hello cruel world" in what I assume is either ascii or utf-8. (echo "hello cruel world" > hello.txt)

So the contents of my top-level BundleExperiment are:


BundleExperiment
|
|- - main.swift

BundleExperiment.xcodeproj
|
|- - a bunch of Xcode generated stuff like project.pbxproj

hello.txt 

  1. In xcode 10.2.1, on macOS 10.14.4, in the project navigator, highlighted the "BundleExperiment" folder then used the menu commands File --> Add Files to "BundleExperiment", navigated up to hello.txt and added it, with the following options selected:

    • copy items if needed
    • create folder references (NOT create groups)
    • add to targets (with BundleExperiment checked)
  2. Then the contents of my main.swift file are as follows:


import Foundation

let urlPath = Bundle.main.url(forResource: "hello", withExtension: "txt")!

let hello = try! String(contentsOf: urlPath)

print(hello)

  1. I build and run by clicking the little play symbol.

And it throws:

Fatal error: Unexpectedly found nil while unwrapping an Optional value
2019-05-05 22:38:23.456979-0500 BundleExperiment[5030:6734193] Fatal error: Unexpectedly found nil while unwrapping an Optional value

What am I doing wrong? I assume that I haven't yet gotten the thing into the bundle, like, there's some random sub-sub-sub-sub menu item with some totally meaningless name like "finagle the squirtle" that means "no, I really wanted to put the thing in the bundle".

rmaddy
  • 314,917
  • 42
  • 532
  • 579
Paul Gowder
  • 2,409
  • 1
  • 21
  • 36
  • Command line apps don't have bundles. "hello.txt" won't be part of the final compiled executable. You need a full Cocoa/macOS app to get a bundle. – rmaddy May 06 '19 at 03:52
  • aaah. Thanks. So, for the use case "I'm trying to test some API calls by putting configuration information (API credentials) in a text file, and I don't want to hard-code the absolute path to that file, but I do want to be able to incrementally test the code" how do I do that? Like, create a dummy UI just to get a bundle? Or just create a "mycreds.swift" with a struct with the credentials in it?! – Paul Gowder May 06 '19 at 03:56
  • There is a way to do this for a Command-Line app. Instead of using "Copy Bundle Resources" use "Copy Files". For "Destination" select "Resources". This will copy the file to the app bundle and the Bundle.main can find it. – Robert Schmid Mar 31 '22 at 16:25

0 Answers0