Please keep in mind this is my first ios app and first experience with xcode. I have researched this but i believe my inexperience is a key factor in not being able to find it.
I am creating an app for iPhone in xcode and need help locating a file. I am currently storing an xml file in the Supporting Files of xcode. I have searched through the directories using NSDirectory trying to locate it with no success.
Any help would be appreciated.
Resources, such as an XML file, are copied into the app bundle during the build phase. You can see the list of copied files by navigating to your Project Settings, then the Build Phases tab and then expanding the Copy Bundle Resources build phase.
To find resources that are copied into the bundle you can use NSBundle to get the path to the file:
[[NSBundle mainBundle] pathForResource:#"myFile" ofType:#"xml"];
You can then use that path to load the XML file into a an NSData or NSString object before parsing it.
The directory structure inside an iOS app is largely flat, since most files are simply copied into the bundle ignoring the group structure that represents them in Xcode. It is possible to add folder references to Xcode that will be copied to the bundle verbatim, preserving their directory structure within the bundle, (look up the differences between Groups and Folder References in Xcode for more information).
Related
I have added a few .js files to an xcode project:
I am trying to load those .js files at runtime but they apparently are not available. This was seen by looking at the physical disk location of the simulator sandbox that we can find at: Bundle.main.bundlePath whose value is:
/Users/steve/Library/Developer/CoreSimulator/Devices/CC7AE0CD-4EEE-412F-8E01-E5F55F73887E/data/Containers/Bundle/Application/ECB90596-FF9F-4E40-B500-0D55DDFC0E2E/hybrid.app
Under that directory there are a few gyb files, the Info.plist, some code signature files, the storyboard .. and one .js file. That one file was added to the project earlier and I am not certain using what mechanism.
I'd be happy to see all of the .js files there - but maybe that's too much to ask? Is there a different way to get those other .js files - like reading from some Resources bundle?
Just drag any file into the Project navigator (project files structure browser) pane on the left. This file will be accessible via
let jsonFilePath = Bundle.main.path(forResource: "fileName", ofType: "js")
This is an exercise in more deeply understanding xcode project structures and Build phases. Go to the Project Properties then select the Build Phases tab. Select the Copy Bundle Resources and add the files - javascript in my case - in that section:
The files now do show up in the root directory of the simulator output sandbox directory.
I work on an ObjC framework which we provide to our clients for their own apps. It's a static library which generates .framework files (simulator and iphoneos) which we then lipo create to a fat library. For using CoreData and be compatible with iOS 7, we needed to put the .momd part in a seperate .bundle file which we provide to the client also.
Now when I create a sample Swift app with that framework and bundle, and upload it to the App Store, I get an e-mail after complaining about load commands for the .bundle:
Missing load commands - The executable at '/Payload/TestSwift.app/TheBundle.bundle/TheBundle' does not have the necessary load commands. Try rebuilding the app with the latest Xcode version. If you are using third party development tools, contact the provider.
I have no idea what it wants. Unfortunately I am the provider and contacting myself didn't help.
I have googled around and followed the few instructions available:
remove generic versioning
update to latest Xcode (mail)
upload to app store without Bitcode
put the framework in Embedded frameworks instead of Linked Frameworks and Libraries
use the framework in an ObjC app instead
But still the mail comes back with the warning, and the build is not uploaded.
Any idea how to solve this?
Important note: I'd like to avoid the XY problem, but here's more info:
we are dropping iOS7 permanently
with iOS8 it should be possible to create a dynamic .framework file which includes the CoreData directly, removing a .bundle file and easing the process for our client.
Before I dive in, is this an interesting solution? If yes, how does one properly convert a static library to a dynamic library?
Current code within the .framework for loading the .bundle:
NSBundle *bundle = [NSBundle bundleWithPath:[[NSBundle mainBundle] pathForResource:#"TheBundle" ofType:#"bundle"]];
NSString *modelPath = [bundle pathForResource:#"TheCache" ofType:#"momd"];
NSURL *modelURL = [NSURL fileURLWithPath:modelPath];
Assumed code if the TheCache schema is within the .framework:
NSBundle *bundle = [NSBundle mainBundle];
NSURL *modelURL = [bundle URLForResource:#"TheCache" withExtension:#"momd"];
Thank you.
This is a bizarre issue we just discovered too and it had to do with us building a separate Bundle from the main Static Lib. If you are also building a separate bundle;
Go to the Bundle's build target
Do a search within the Build Settings
for Versioning
Change the Versioning System from Apple Generic to None
I asked Apple through the Technical Support in Member Center.
The core issue in my case was that my Bundle behaved like an executable, because there were elements in Compile Sources.
Solution:
Select your bundle's target
Select Build Phases
If using CoreData, put YourFile.xcdatamodeld in Copy Bundle Resources (not in Compile Sources like it was in my case)
Empty all items of Compile Sources (having elements here implies that the Bundle will be considered as an executable)
Run your bundle's target
I suggest to manually delete your previous bundle in your host project prior to copying your newly generated bundle
I am currenly converting an iOS project built in another tool to xcode/swift.
I currently have an xcode swift ios project with multiple targets defined (one for each customer)
For each customer I have a folder "customerxyzassets" that I have added to "target > build phases > copy bundle resources" using the process described here Include a resource directory hierarchy into app bundle
This folder "customerxyzassets" contains subfolders with images and data files which the app is born with.
I would like to grab a path to this folder upon startup, so I can access load datafiles, images etc. from it.
However, the code I have found, e.g. NSBundle.mainBundle, seems to require speciel access to the files through the above. I would rather have raw file access to it. Am i missing something obvious?
It's not clear what you mean here by "special access" or "raw access." NSBundle just returns you paths or URLs so you can directly access the files using normal file APIs.
If you've created a directory structure, then you would generally use pathForResource(_:ofType:inDirectory:) to fetch the path to your specific file. Alternately, you can build a path using NSBundle.resourcePath and append your relative path using stringByAppendingPathComponent. The advantage of the pathForResource methods is that they handle localization for you, and this is preferred unless the resource should never be localized (which is rare).
IOS development...
I have a json data file named "Data.js" in the same directory where the code file is and is trying access it with the following code...
NSString *filePath = [[NSBundle mainBundle] pathForResource:#"Data" odType:#"js"];
but this is returning null.
Any help on this is much appreciated.
The above written answers are right. By default Data.js file will be added to the compilation phase. You can drag that to the Copy Bundle Resources phase. FYI i'am adding a reference screen shot. Go to the settings page of your target under Build phases you can find these sections. Drag the selected file to Copy Bundle Resources phase
Did you check whether Data.js has been added to copy bundle resources under build phases?
When you add JS files Xcode will add them to the compilation phase (since they're code files), instead of the Copy Bundle Resources phase. You need to go to your project settings and move it to the right phase.
I'm just new to iOS and am really confused by how files are managed.
In my project, I have set up directories, so I have in xcode:
Supporting Files
. Set 1
..pic0101N.png
..pic0102N.png
. Set 2
..pic0201N.png
..pic0202N.png
etc..
Also in the file structure where my app is (on my Desktop in a folder named FTF), I have a directory named images and a subdirectories for Set 1, Set 2, etc
When I click on an image in Xcode, the full path is listed as: /Users/MyName/Desktop/FTF/FTF/images/Set 1/pic0101N.png
My question is, how do I get a list of all the images in the Set 1 folder?
I've tried the various ways of using:
[NSBundle mainBundle] but, it all boils down to that my path seems to be:
/Users/MyName/Library/Application Support/iPhone Simulator/6.1/Applications/Axxxx1E9-19B3-XXX-XXXX-xxX5xXxX4x9/FTF.app
And that there doesn't seem to be any of my file structure in here, like the files are in there but not in any directories, they all just seem to be a bunch of files in there.
NSArray *namesArray = [[NSBundle mainBundle] pathsForResourcesOfType:#"png" inDirectory:#""];
yields a list of all the PNGS as such:
/Users/MyName/Library/Application Support/iPhone Simulator/6.1/Applications/Axxx81E9-19B3-4B4D-9FD4-XXXXX4499/FTF.app/pic0101N.png
/Users/MyName/Library/Application Support/iPhone Simulator/6.1/Applications/AXX9-19B3-4B4D-9FD4-8x9xx4499/FTF.app/pic0101P.png
I think I must have a fundamental confusion of what is going on. Could someone please help me out?
That's because Xcode is being unhelpful (and/or it assumes that the developer is dumb or something) and whenever you create a group, it's only reflected in the project structure - no corresponding folders are physically created on the filesystem.
If you want to get yourself real folders, that's also possible - refer this question.
What you are looking at is the difference between the Xcode project structure, the MAC OS X file system structure, the iOS app file system structure and what files are actually copied to the app during build.
For a start, having files in a location on Mac OS X doesn't mean they will be in any kind of similar location in the project or the app.
The iOS app is a bundle of contents (link), some of which is not editable and is set by Xcode when building the app and some of which is able to be written to (like the app documents directory). The files that are copied to the app are controlled by the build phases settings in Xcode.
The way you are using NSBundle is the correct way to find and use resources that were copied to the app during the build.