Maintaining Directory Structure when loading local files into UIWebview on iPhone - iphone

I'm noticing a minor annoyance when working with local files in a UIWebview and hoping there is a simple workaround. As a simplified example lets say in my xCode project I have a folder called "WebProject" that contains an html file and a subfolder called "images" where the images reside. The html file references the images as you'd expect: src="images/MYIMAGE.jpg" for example, which works just dandy if this where are normal webpage. When you load the html file in a UIWebview, however, this image would not show up because it seems that all of the files are just thrown into one big bundle folder (so the image link is actually: src"MyIMAGE.jpg"). Is there anyway to enforce the directory structure of these files in the main bundle, so that this sort of thing does not happen? Thanks!

Just create the structure you want in the filesystem (using finder or whatever) and import that whole tree into your project. Make sure you select "Create folder references for any added folders"
You'll notice these folders are blue instead of the normal yellow used for groups. This folder structure will exist in the bundle and so your relative references will work as you expect.
Hope that helps.

See this page and this tech note for how to add resources, and maintain directory structure. Make sure you select the radio button that says "Create folder references for any added folders." Then when you go to write your code, folder-relative paths to the bundle will resolve just as if they are sub-directories. Because they are, even in your app's resources.

Related

Classes in Swift files inside folder references not seen by Xcode 10's compiler

We have a project with nearly 1K Swift files. It just works well if everything is inside groups, but when trying to add some folder references to directories that contain Swift files, the compiler just can't see any thing defined inside these files (classes, for example). It works well for bundle and data files, but not for source code.
I also tried changing existing groups to folders using different methods (dragging, using the menu and manually browsing, etc.) and XCode stops seeing the entities declared inside these Swift folders' files. When I switch the same folder back to a group (delete -> remove reference -> add files to project...), it works again.
Please note that I opened the File Inspector, and already ensured that the target for the reference folder was checked. Also tried to uncheck it and checked again, just in case there is just-another-XCode-bug when adding files. Nothing worked.
Another experiment that I've done was consisted of moving a folder to the root directory, so the folder was not inside a group. Didn't work either.
After each try, I always cleaned the project's build folder, just in case.
Please note that the following questions did not provide anything useful tip for fixing this:
Xcode added folder in blue and related there files are not compiling
Moving Files into a Real Folder in Xcode
And of course, this another one does not make sense to me since I want folders, not groups, because I find them much easier to use and specially, to maintain, given the large amount of Swift files of this particular project: Adding Folder to Xcode Project is not Properly added
It works well for bundle and data files, but not for source code.
Yup, well, that's because those are completely different kinds of thing, and need to be treated in completely different ways.
You can't put code inside a folder reference (blue). That would simply mean "copy this code file into the body of the app", which would be silly. That's the kind of thing you would do with bundle and data files.
If the problem is to organize your code file references within the project window, you can use:
a group (yellow with a red mark in the lower corner)
or, a folder-linked group (yellow plain and simple)
In the latter case, the code file itself will also be placed in the corresponding folder on disk inside the project window, so this is also a mode of organization on disk.
NOTE But note that you must always let Xcode itself organize the contents of the project folder! You must work entirely within the Project inspector in the project window. Stay out of the Finder. Otherwise, you'll break your project.

iOS project directory organisation

Just a quick question/opinion about how you arrange Xcode 4 directory for each of your iOS app you create.
Personally, I still add a directory called /Resources which contains sub-directories like /Fonts, /Images, /Icons, etc. I use the option "Copy items to destination group's folder (if needed)". If I need to add a new ressource, I simply add it to the right directory in finder.app in my project directory (i.e if it's an image, I add it to MyProject/Resources/Images/Foo.png) and then I simply go on my group "Images" in Xcode and add the file from there.
I once tried to use "Folder references" option to keep Xcode and Finder in sync, but IB was not able to get the images...
Also, is your Icon.png and Default.png at the root of your project? (i.e with the .xcodeproj file?) When you use Xcode 4 (in project info > summary) they add them there... Wondered if you keep them there, Cause personally I always prefer having all my images in a sample directory!
And what about photoshop files or any other files relative to your project, do you put them in the root directory too (again with the .xcodeproj file) ?
I suggest keeping all your .m and .h and .xib files in a single folder because it simplifies localizing strings when you run ibtool to extract all the NSLocalizedString references, and it also makes it easier to move files around int the virtual folder structure within Xcode when you refactor your project.
Keep third party libraries or frameworks in a separate folder to avoid mixing them up with your own code.
Within Xcode itself, I organise these class files into separate virtual folders called Views, Controllers, Model and Nibs (and Libraries for 3rd party stuff). If it's a large project I break it into folders for each component and then break those into views, controllers, etc, but again that's only virtual folders, not physical ones.
Keeping resources in a separate physical folder is a good idea just to make it easier to browse them on disk. It may make sense to split these into images, sounds, xml, etc. Within Xcode you may want to break these down into virtual subfolders by component or category (interface, content, etc) but I wouldn't suggest doing that on disk as it makes it harder to refactor your folder structure as your project grows.
It's a really good idea to keep all your images in the same folder because it avoids you accidentally giving two images the same name. Xcode won't warn you if you import two images with the same name from different places, but when it builds the app you'll end up with just one or the other, chosen at random.
You don't have to keep Default.png and Icon.png in the root (or even call them Default.png and Icon.png) but sometimes Xcode gets confused if standard files aren't where it expects.
And yeah, whatever you do, don't try to use the blue folder references when you import images otherwise you can't access them from within your code with imageNamed: or within Interface Builder. Use the yellow virtual folder references instead. Basically blue folders get copied into the app bundle as actual folders when the app is built, whereas the yellow folders are ignored and their contents go directly into the root of the app bundle. To access content in blue folders, you'll need to include the blue folder names in the path when you load them, e.g.
NSString *path = [[NSBundle mainBundle] pathForResource:#"image" ofType:#"png" inDirectory:#"nameOfBlueFolderInXcode"];
UIImage *image = [UIImage imageWithContentsOfFile:path];
I've been thinking about this a lot lately; here's the structure I decided to go with:
ProjectName
ProjectName/Assets
ProjectName/Assets/Images
ProjectName/Frameworks
ProjectName/Logic
ProjectName/Logic/Models
ProjectName/Presentation
ProjectName/Presentation/ViewControllers
ProjectName/Presentation/Views
I think this gives a good structure for growth and provides a reasonable home for most anything. Of course, add additional subfolders (e.g. Assets/Fonts) as needed. For my full rationale for the structure check out this blog post.
I do keep things like Icon.png and Default.png at the root of the project as Xcode seems finicky about it, but otherwise things are neatly organized. I keep my corresponding .m, .h, and .xib files together, but I split up the view controllers logically into subfolders by feature (e.g. Initial, Settings).

Way to shrink Resources folder?

I have 100 pictures in my Resources folder and they can really be annoying when trying to find some other resource. Is there a way I could "create another resource folder" to put the 100 pictures in?
Or do I just have to deal with scrolling and scrolling when trying to find another resource?
You can put files wherever you want in your project-- Resources is just a default folder that gets created for you. You could create a sibling folder to Resources, or a subfolder inside of it.
You can do this in two ways: One by right clicking on the project and creating a new group for the images. This will create the logical folder, but won't actually create a subdirectory on disk. If you want the layout on disk also, create the folder on the command line or with Finder and then drag it into Xcode.
I totally agree with #quixoto ans,
one thing more you can categories your folders according to any visible form.And use proper hierarchy for folders.because when you having number of folder and files then this necessary to make hierarchy also naming conventions are necessary for quick understanding and quick search. (e.g. Make images folder for images and in this folder sub folders, for backgrond image,button images,tab images etc.).so it helps you in quick search.

Problem removing and re-adding an image file into my iOS4 app bundle

My problem is something that should be so simple it is mind boggling. When I change the look (in PhotoShop) of an image file that is being stored in my app bundle. My method for replacing the old image in the bundle with the new one is this:
1) remove the old image from the app bundle (choosing to also move to trash)
2) drag the new image into my file hierarchy in xcode (choosing to copy to app directory)
when I do this, the app cannot find the image no matter what I do. The new images have the same name as the old images but none of the image loading methods (imageNamed, imageWithContentsOfFile, nibs) work. (Although I believe nibs also load with imageNamed, i'm not sure).
Is there something that I am missing here? I feel like it should be a relatively simple process but I am having all kinds of trouble. I also make sure to delete the app off of the target device and clean all targets before rebuilding and running after changing the image files just in case.
Any help would be appreciated.
Thanks
Your problem is probably that the image is not copied to the target. In xcode groups & file pane, fine the node for targets, expand your app target and you'll see Copy Bundle resources expand it and you'll see all the files copied to the default resource bundle when you deploy your app to the sim/device. Only the resources found there will be available to your app. If you don't see your image there you can just drag it there and everything will work.
Now, in order to understand why this might happened we need to look at the different options for adding files to xcode.
When you're adding a file to xcode you are presented with a dialog that includes a few interesting and sometimes overlooked option.
The first - Should the file be copied to the project folder, or should it just point to the file original location. The safest way will be to always copy the files to the project's path. However for images (such in your case) I do it differently. I maintain a separate graphics folder for every app, I save images there (both sources, and final png). When I add an image I do not copy it to the project folder, rather xcode just points to its location. That way I can just edit the image in photoshop, do a rebuild, and the updated image will show up on the phone. Whats important to understand that the directory structure of files you include in the project have almost no meaning, files that appear in the Copy Bundle Resources for the target will always be copied to a single (and flat) bundle/"directory" on the phone. The only exception for this is if you actually add directories to xcode (Personally I recommend against it).
The second option when adding files, is to which targets to add the file. This is the list with checkboxes on the bottom, if when you added the image, your app target wasn't checked the file won't be included in the target Copy bundle resource, and won't be available for the phone.
A few caveats - When using references to files in other location, that location is relative to the project's path, so it's a good idea to keep all the files in directories below the project's root directory. That way you can still copy the entire project to a different location and it will still work.
Great advice above: I thought I would add more for future searches on this topic:
I was adding and removing images to the project just like above:
Remove the old image from the app bundle (choosing to also move to trash).
Drag the new image into my file hierarchy in xcode (choosing to copy to app directory).
However when I tried to drag the new image with the same name to my file hierarchy in xcode I was getting an error that this was not allowed.
Turns out when I was removing the old image Xcode was removing it from the project file hierarchy but the actual file wasnt being removed from the project's root directory.
I solved my problem by removing the image from the project's root directory and added the image again!
Do you put your images in a custom sub-folder? If you just drag in images into the Xcode project tree, if you copy them, the images will be copied to the root of the project directory, instead of the "Images" or other folder you might have set up.
Note that you can right-click on the image in your bundle, select "Get Info..." and reset its location, if it has been moved or copied to a folder you didn't expect.

iPhone Interface Builder - Moved resources to sub-directory, now IB can't see them!

I had a bunch of images in my Xcode project. They were originally added without choosing "Create Folder References for any added folders". So I removed the references and re-added as per these instructions Include a resource directory hierarchy into app bundle
Unfortunately, Interface Builder will not display any of the images inside that directory. On the project tree the directory comes up with a blue icon and all the files are there!
The file names show in the IB Inspector (i.e. under the 'Image' property), but I get missing image icons for everything located in that directory.
Any ideas how to get the images showing again?
Problem solved! Turns out that blue folder references are fine, but IB will not read them!
For anyone else who cares to know, if you have the following:
/iphone-project-dir/images/pic.png
Once you've added them in a blue folder in Xcode (as detailed in link above), you can refer to them in IB as follows:
images/pic.png
In the XIB's XML it will look something like this
<string key="NSResourceName">images/pic.png</string>
Simple! The only drawback is Interface Builder's WYSIWYG preview does not process these paths!
I found the answer here http://www.iphonedevsdk.com/forum/iphone-sdk-development/6457-xcode-folder-directories.html
If you like to have your images structured in your SCM and under XCode but really doesn't mind that all images will be placed in one directory once building the final .ipa package, here is what you need to do:
Create a directory called e.g. "Images" in your root folder
Place all your images into this folder
Add a new group from within XCode and call this "Images" too
Right-click this group and choose "Add Files to ..."
Select all your files and uncheck "Copy items into destination group's folder" because they are already in there
Make sure to select your right targets
From Interface Builder you are now able to pick your images without prefixing it with the folder name and you will see a preview of your images within Interface Builder.
Gives me both my IB preview and a neat folder structure when designing my app.
Copy Images folder to your project folder.
Add this folder to project. In "Choose options for adding these files" dialog, you must check "Create groups".
"Copy items if needed" you can leave checked.
Make sure to select your right targets
Finish