I have a problem accessing my files in my app.
I am currently using
//Directly from TileMap example from WWDC2010
NSString *tileDirectory = [[[NSBundle mainBundle] resourcePath]
stringByAppendingPathComponent:#"Tiles"];
to access my tiles for my MKOverlay. This gives me this directory
/Users/xxxx/Library/Application Support/iPhone Simulator/4.2/Applications/9D62025C-C53B-472C-8309-xxxx/xxxx.app/Tiles
The x's is only for privacy reasons
I have my tiles in a folder called Tiles in the root of my application which is in Xcode in a group called Tiles which is in directly in the Resources group.
When I run my app, I get a simple error saying that it could not find my tiles at the generated directory (the one quote above) If I replace that piece of code and make it:
NSString *tileDirectory = #"/Users/xxxx/Documents/xxxx/Tiles";
Then my app works fine. This is obviously because it finds my tiles in its direct location on my Mac. This is fine for testing, but I need it to work on my iPhone/iPad.
This problem might be occurring due to:
The generated directory is incorrect.
The tile images aren't getting included in the builded .app file.
Either way, I have no clue of what to do to solve it.
How can I solve this problem?
[EDIT]
I changed that piece of code to:
NSString *tileDirectory = [[NSBundle mainBundle] resourcePath];
Now it works in simulator, because all files are in the apps root folder and I don't ask for it to enter another directory called "Tiles".
This runs with no error on the simulator, but when on my iPhone it gives the original error (just a different file path but also ending with /xxxx.app
How can I ensure a directory in my app file such as xxxx.app/Tiles - TileMap does this.
Since it is your files in your app bundle, I think you can use pathForResource:ofType: to get the full pathname of your file.
Here is an example:
NSString* filePath = [[NSBundle mainBundle] pathForResource:#"your_file_name"
ofType:#"the_file_extension"];
Remember that the "folders/groups" you make in xcode, those which are yellowish are not reflected as real folders in your iPhone app. They are just there to structure your XCode project. You can nest as many yellow group as you want and they still only serve the purpose of organizing code in XCode.
EDIT
Make a folder outside of XCode then drag it over, and select "Create folder references for any added folders" instead of "Create groups for any added folders" in the popup.
If your tiles are not in your bundle, either copied from the bundle or downloaded from the internet you can get the directory like this
NSString *documentdir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
NSString *tileDirectory = [documentdir stringByAppendingPathComponent:#"xxxx/Tiles"];
NSLog(#"Tile Directory: %#", tileDirectory);
You need to use the URL for the link, such as this:
NSURL *path = [[NSBundle mainBundle] URLForResource:#"imagename" withExtension:#"jpg"];
It will give you a proper URL ref.
You need to add your tiles into your resource bundle. I mean add all those files to your project make sure to copy all files to project directory option checked.
Related
In macOS apps, if you need to get the path of your app or any resources in its bundle, you can of course use the mainBundle static method of NSBundle:
NSBundle *bundle = [NSBundle mainBundle];
NSString *appPath = [bundle bundlePath];
NSString *resourceFolderPath = [bundle resourcePath];
... etc ...
However, if the user moves your app's bundle to a different location on disk while the app is running, then this method will not work. All of the above functions will still return the bundle's old paths from before the user moved it.
How can you get the current path of your bundle or the path of any resource inside of it regardless of whether the user has moved it on disk?
So far, I've tried using NSRunningApplication to get its current location like so:
NSRunningApplication *thisApp = [NSRunningApplication runningApplicationWithProcessIdentifier:getpid()];
NSLog(#"bundle URL: %#", [thisApp bundleURL]);
...but that too returns the old path of the bundle!
Moving an application that's already running typically isn't supported. If that's a scenario you really need to support then you can do the following:
When the app is first launched, get the app's current path as you would normally and then create an NSURL bookmark for that path.
Whenever you need to know the app's current path you can resolve the NSURL bookmark you created at launch. The bookmark will resolve to app's current path, even if the app has been moved.
More info on NSURL bookmarks is available here: https://developer.apple.com/library/archive/documentation/FileManagement/Conceptual/FileSystemProgrammingGuide/AccessingFilesandDirectories/AccessingFilesandDirectories.html#//apple_ref/doc/uid/TP40010672-CH3-SW10
While macOS doesn't care if you move documents around as they're open, it does care if you move applications around. This is a long-recognized issue in macOS development.
Instead of trying to fight it, app developers tend to either not care, or ask users if they want to move the application to the Applications directory at launch (since this is the most common move destination for apps). LetsMove is a project that demonstrates how you would do that.
i want to play a video, but i noticed that my files are not importing to the bundle??
so I just drag and drop the AA.mp4 file to my project,
it shows ok on the project navigator, I give it show in finder, and confirm the file exists in the project
now, when i try this
NSString *bundleRoot = [[NSBundle mainBundle] bundlePath];
NSFileManager *fm = [NSFileManager defaultManager];
NSArray *dirContents = [fm contentsOfDirectoryAtPath:bundleRoot error:nil];
NSLog(#"content of bundle ::%#", dirContents);
to see the contents of my bundle,
i see every other file, but not the one i have imported???
so what im i missing?
thanks!
Simply dropping a file into an Xcode project is not enough. You must check your app target as the one receiving the file in the dialog box, else it will not be added to the 'copy bundle phase' and as a result, not copy over to your app. Go into build phases and drag your video into the copy bundle resources phase group, then clean and run again.
Though if you can see it's name in red in the file tree, it doesn't exist.
The answer marked as correct might not be right in all situations. If you have e.g. plists, Xcode 4.5+ will for some reason NOT copy it to the application bundle, even if everything else is right. A workaround is to rename your plist to .png and then rename it back later.
I know how to read/write to local files on iOS using file handles. I can dynamically create and read/write form them.
What I'm trying to do right now is to include a file, about 200 lines long with the app bundle, which I hope to parse and extract configuration settings from. I really do not want to have to create an array of 200 numbers by hand.
How would I go about including a text file with the app, and making it accessible from my application?
Thank you!
You can include a file in the bundle by adding it to your Resources folder in Xcode and making sure that it is included in your target as well. To access a file in the bundle (e.g., a text file called info.txt), you can get the path using:
[[NSBundle mainBundle] pathForResource:#"info" ofType:#"txt"]
Then access it using the normal NSFileManager methods.
EDIT:
With this said, you can't write anything into this file inside the bundle on iOS. Instead, you can copy the file from the bundle to a file system location (say, your app's Application Support folder) on first launch, then access it there elsewhere in your app.
Why don't you create a dictionary with Property List Editor and load it like
NSString *configurationPath = [[NSBundle mainBundle] pathForResource: #"configuration" ofType: #"plist"];
NSDictionary *configuration = [NSDictionary dictionaryWithContentsOfFile: configurationPath];
So you can access its settings with
[configuration objectForKey: #"someSetting"];
If you want to write, I recommend registering that dictionary with NSUserDefaults so you could write to a copy like
[[NSUserDefaults standardUserDefaults] setObject: someSetting forKey: #"someSetting"];
I've done this before, but its not working for me now. I'm doing:
NSString* path = [[NSBundle mainBundle] pathForResource:#"test"
ofType:#"txt"];
NSString* content = [NSString stringWithContentsOfFile:path
encoding:NSUTF8StringEncoding
error:NULL];
NSLog(#"%#",path);
and it returns (null) every time when I NSLog path and content. Can anyone see what I'm doing wrong?
content will be nil (which logs as '(null)') if you pass it a path it can't open. So your only issue is that the relevant instance of NSBundle is unable to find test.txt within the resources part of your application bundle.
You should:
check the file is in your Xcode project; and, if it is,
check it's included in the 'Copy Bundle Resources' phase underneath your selected Target (in the project tree view on the left in the normal Xcode window layout) and, if it is,
look inside the generated application bundle (find your product, right click, select 'Reveal in Finder', from Finder right click on the app and select 'Show Package Contents', then look for your file in there) to make sure that it's there.
If it's copied in but the relevant instance of NSBundle can't find it then something very strange is afoot.
I'm creating a simple application with xcode and objc and I need to load an NSDictionary from a file, but I can't get the path to the file using NSBundle:
NSString *l = [[NSBundle mainBundle] pathForResource:#"LoginStatuses" ofType:#"plist"];
NSLog(#"%#", l);
When I run this code I get this:
2010-10-16 10:42:42.42 Sample[5226:a0f] (null)
And I don't know why.
I created a group called Resources and there I added the LogingStatuses.plist:
So here's the solution for this problem after I got the source:
I didn't really pay attention to the posted screenshot, but the target is of type "Command-line Tool"... and since those don't have a bundle [NSBundle mainBundle] of course returns nil. It's pretty misleading that Xcode doesn't complain that it can't execute the "Copy Bundle Resources" step, it just silently skips it.
Solution is simply to add a new target, of type "Application" so a bundle-based application is generated. Then check the Target Membership checkboxes for all sources and resources for this new target. The plist paths are correctly resolved then.
I was trying to get my iPhone app to use a default sqlite database and the darn app couldn't find it. Turned out that I had to make sure that the .sqlite file was in the bundle resource.
Select your project
Select Target
Select Build Phases tab
Open the section labelled "Copy Bundle Resources"
Drag and drop your .sqlite file into this section.
now your app will find this default sqlite database.
Is the file really included in the target (and will therefor be copied to the bundle) ? There two ways to find out/set that:
First way: right-click (or Cmd-click) on the file, select "Get Info". Then click on the "Targets" tab and make sure the file is checked for the desired target(s).
Second way: right-click (or Cmd-clock) in the project browser on the header of the file browser (it will likely read "Groups & Files"). Then select "Target Membership". Now you have checkboxes next to each file that can be member of a target (like .m files or resources). Again, make sure the checkbox next to your file is checked.
Since I have googled here, did not find the answer, but then discovered it by myself, I'll leave it here...
I had 2 files: tray.png and tray#2x.png for Retina. The files were added to "Copy Bundle Resources" automatically.
But:
[[NSBundle mainBundle] pathForResource:#"tray" ofType:#"png"];
did not return the file actually copied to the bundle! The reason was: IDE created one TIFF file tray.tiff (joint tray.png and tray#2x.png), so ... ofType:#"tiff"] helped!
My problem and solution are very similar to Dmitriy Isaev's ones. I have tried to get path for a xib file. Both calls (in Swift) pathForResource("myfile", ofType: "xib") and pathForResource("myfile.xib", ofType: nil) are failed.
The solution is to use extension "nib" instead:
pathForResource("myfile", ofType: "nib")
I encountered this issue today with a Command Line project.
Luckily, the solution is easy. Simply go to "Build Phases", click on "+" and add a new "Copy Files" phase. Choose "Resources" as Destination, and add any files you want to use.
Now you can still use [NSBundle mainBundle] and it should work!
In my case (executing XCTestCase) for some reason resources were stored in non-main Bundle. I fixed the problem by checking first which bundle test class belongs to:
[[NSBundle bundleForClass:[self class]] pathForResource:#"Config" ofType:#"plist"];
Hopefully this can help someone else as well.
Filename is case sensitive on iPad. You need use small letters.
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.
Make sure you spell your resource's file name properly. I just learned that the hard way. :)