Oganization of Folders in XCode - ios

I'm using physical folders to organise my files in XCode, as I have multiple files with the same name. Eg: /skin1/navbar.jpg and /skin2/navbar.jpg.
Every time I add a new file, I can't drag it into the folder, it seems like once I ad the folder as a group in XCode, it gets locked somehow and I can't change it. When I try to initialize a UIImage with this method, it turns out to be nil.
Using this image as an example:
To create a UIImage I'm using this:
NSString *skinBasePath = [AppearanceUtils skinBasePath]; // Returns /Users/echilon/Library/Application Support/iPhone Simulator/5.1/Applications/E6C7ECF4-B36A-4092-97BC-CDE2D0A526C2/ReadMeAStory.app/ReadMeAStory/images/skin/wood/
NSString *bgImagePath = [skinBasePath stringByAppendingPathComponent:#"button_181_43.png"],
*bgImagePathPressed = [skinBasePath stringByAppendingPathComponent:#"button_181_43_pressed.png"];
UIImage *bgImage = [UIImage imageWithContentsOfFile:bgImagePath]
Everything looks fine in the debugger until I actually create the image, which comes back as null.
The full path to the image in the debugger is /Users/echilon/Library/Application Support/iPhone Simulator/5.1/Applications/E6C7ECF4-B36A-4092-97BC-CDE2D0A526C2/ReadMeAStory.app/ReadMeAStory/images/skin/wood/button_181_43.png.
What am I missing?

"images" is just a Group and not a Folder, so .../ReadMeAStory.app/ReadMeAStory/images/ don't exist.
What are you doing in [AppearanceUtils skinBasePath]?
Maybe this will help:
NSString *path=[[NSBundle mainBundle] pathForResource:#"button_181_43" ofType:#"png" inDirectory:#"skin/wood"];

Related

NSbundle pathforresource not finding file

I have images.xcassets listed ounder copy bundle resources, and I did try to just state the file name by itself: MSB_big_icon , before trying to add the path within images.xcassets.
Can anybody tell me what I'm doing wrong?
NSString *path = [[NSBundle mainBundle]pathForResource:#"/Raymio_android_images/MSB_big_icon.imageset/MSB_big_icon" ofType:#"png"];
NSLog(#"path: %#", path);
MSBIcon *tilecon = [MSBIcon iconWithUIImage:[UIImage imageWithContentsOfFile:path] error:&error];
David Ansermot is right that xcassets is a much better approach and strongly preferred. If you can't use that (running on older versions of iOS for instance), still put everything in one directory and use imageNamed:. This has significant caching benefits over hand-loading the file.
An asset catalog (xcassets) is a (relatively) new, unified way of managing image resources. The images are no longer accessible as separate files on the disk. Instead, imageNamed: consults the asset catalog and fetches the correct asset.
Prior to asset catalogs (and still, for non-images), assets were stored in localized directories. All of your unlocalized assets would be put into a directory called Resources (no matter where those files might appear to be in your source tree, and no matter how those files might be arranged in your Xcode folders). Localized files would be stored in directories like English.lproj or French.lproj. When you make NSBundle calls to load MyImage, it looks at each localized directory in the order the user has configured, and if it cannot find it in any of those directories, it looks in Resources.
Now it is possible to store full directories as "a resource" by marking them as directory references in Xcode. In that case, the whole directory would be copied into Resources or the appropriate localized directory. In order to find files inside such a directory you can use the ...inDirectory: version of the NSBundle methods.
So most of the time, you want to just use imageNamed:, which is going to fetch things out of the asset catalog if available, and then search localized directories, and then look in Resources. If you need to find a non-image, or if for some reason you want the real path to the file, you can compute it like this:
NSString *path = [[NSBundle mainBundle] pathForResource:#"MSB_big_icon" ofType:#"png"];
And if that resource were in a directory tree (because it was a directory reference in Xcode), you can access it like this:
NSString *path = [[NSBundle mainBundle] pathForResource:#"MSB_big_icon"
ofType:#"png"
inDirectory:#"Raymio_android_images/MSB_big_icon.imageset"];
Here's a code exemple from one of my apps :
NSString *appKey = #"Applications__GENERIC";
NSString *path = [[NSBundle mainBundle] pathForResource:appKey ofType:#"plist"];
appData = [NSDictionary dictionaryWithContentsOfFile:path];
The "Applications__GENERIC.plist" is stored like this :
Other solutions :
Use the images.xcassets.
Then in your code to load an image, use the code :
UIImage *image = [UIImage imageNamed:#"MyImageWithoutExtension"];
Don't put any path or extension, only the image's name
Try using this:
NSString *path = [[NSBundle mainBundle] pathForResource:#"MSB_big_icon" ofType:#"png" inDirectory:#"Raymio_android_images/MSB_big_icon.imageset"];
What you can also do to debug is to print out
[[NSBundle mainBundle] bundleURL]
Then navigate to that folder and see if the folder structure corresponds to the path you use.
I just struggled with this today, hope it works out for you too.

Loading UIImage from Directory no longer working

For the past 5 or 6 months i have been saving images to a Photos folder in which i created within the documents directory on the users device. The photos would then be loaded into an imageView when the user entered a specific screen, until recently this has been working perfectly.
Now the images no longer show in the image view and when using the URL to print out the image width and height, the values are zero even though the URL has not changed.
I am using the following code to display the image within the image view.
outputImageView = [[UIImageView alloc] init];
[outputImageView setFrame:originalImageViewSize];
outputImageView.image = [UIImage imageWithData:[NSData dataWithContentsOfFile:photoURL]];
NSLog(#"width %f, height %f", outputImageView.image.size.width, outputImageView.image.size.height);
the photoURL is as follows: /Users/fernandosantos/Library/Developer/CoreSimulator/Devices/6F3FCE2A-F7F9-4F77-B66D-3DA2A25BE166/data/Containers/Data/Application/C3867EFA-6AA8-4B71-A856-DCF7F83DEFF0/Documents/AUDIBURY/Photos/COMMTRCIAL-CSRSignature--2014-10-13 10-49-16.jpg
Thanks
In iOS8 the application documents directory dynamically changes its name on every running. You have to use the following method from Appdelegate in order to get the current documents directory path:
// Returns the URL to the application's Documents directory.
- (NSURL *)applicationDocumentsDirectory
{
return [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
}
You should only save the relative path of the file, not the full path. This method also works on iOS7.
You can use the iOS simulator and check that the full path actually doesn't exist.
Thanks to everyone that replied with a suggestion.
I combined what everyone had suggested and came up with this solution which works for me.
//get the documents directory, in iOS 8 this is now dynamic everytime you run the app.
NSString *documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
//Create the CurrentPhotoURL by using the current documents directory and the appending the photo name which
//was created when saving the image originally.
NSString *currentPhotoURL = [[documentsDirectory stringByAppendingString:#"/"] stringByAppendingString:photoName];
Since i had created a new a folder within the documents directory called Photos, the photoName variable holds the name of the Photos folder followed by the name of the image when it was originally saved.
I then append the photoName variable to the current documents directory to get the full directory path for that photo.
This may not be the best solution but its what i came up with and it works.
If anyone else needs further information then please contact me.

Image retrieve from folder with folder name in iOS

I have all my images in folder name ImageMe and I like to retrieve image with this name like
[UIImage imageNamed:#"ImageMe/bulk-female.jpg"];
how I get this approach, because I rereiving path name from data base, and in that format it's coming.
If you do not want to modify these images, just create folder name "Resource" under supporting files and save ImageMe folder with your images there. Then use below code to get path of image folder.
NSString *theResourcePath = [NSBundle mainBundle] resourcePath];
NSString *theFilePath = [theResourcePath stringByAppendingPathComponent:#"ImageMe/bulk-female.jpg"];
If you have the images in the main bundle you can get them with
[UIImage imageNamed:#"theNameOfTheImage_WithOutDirecotry"];.
You have to specify only the image name not the directory. This is because when the application is packed in .ipa only the images are copied (the images that are in the Copy Bundle Resources) not the directories.
If you want to pack the images in to one folder you have to create a new bundle but you can not use imageNamed you have to use initWithContentsOfFile:(NSString *)path
Here are some docs UIImage, NSBundle, Bundle Programming Guide
If your all images are present in bundle then you can directly get that images from name.
like this
[UIImage imageNamed:#"1.jpg"];
[UIImage imageNamed:#"2.jpg"]
[UIImage imageNamed:#"3.jpg"]
directly get the images using their names.
And if you want to laod that images to particular folder of bundle.
NSString *Path = [NSBundle mainBundle] resourcePath];
NSString *FilePath = [Path stringByAppendingPathComponent:#"ImageMe/bulk-female.jpg"];
try this one this might be helpful to you.
Add your images in a floder & than add that folder to your project like this
after adding the folder to your project, you can access your images with the following code.
NSString *bundlePath = [NSBundle mainBundle] bundlePath];
NSString *imagePath = [bundlePath stringByAppendingPathComponent:#"ImageFolder/imagename.jpg"];
Hope this will solve your problem

Can a plist file be too big?

I'm working on a reference app that loads a plist file that can be searched.
The plist file is about 6kb with about 600 entries.
I have been working with the simulator and all works ok, however when I load it onto a device none of the data is there. Just an empty table.
I think the file may be too big because I can load a plist with 20 entries and it loads fine on the device.
If the file was too large wouldn't the whole app just crash?
Does anyone have any suggestions?
This is how I load my plist file
NSString* myFile = [[NSBundle mainBundle] pathForResource:#"myPlistFile" ofType:#"plist"];
array = [[NSMutableArray alloc] initWithContentsOfFile:myFile];
What it sounds like to me is that either your plist isn't even getting copied at all onto the device, or you're using case-sensitive file naming.
First see if the file exists at all:
NSString *myFilePath = [[NSBundle mainBundle] pathForResource:#"myPlistFile" ofType:#"plist"];
BOOL exists = [[NSFileManager defaultManager] fileExistsAtPath:myFilePath];
Check that boolean (using the debugger or by logging, either way). If the file exists, then I suspect that you're using a wrong case when trying to access the filename. Filenames are case-sensitive on iOS devices, unlike the Simulator. For example, lets say your plist was named myAwesomeStuff.plist. If you tried to access myawesomestuff.plist on the Simulator, it would work just fine. Not so on the device. Make sure you are using the correct case on your file names.

NSBundle mainBundle pathForResource (maybe not the same problem)

Problem : [NSBundle mainBundle] pathForResource returns null (0x0)
I read a lot of posts on this topic, here is what I found:
Make sure the file you are trying to get a path to, is in the project. To check, look in the project file list for the file, if it is not there, drag and drop it in.
Check that the file your trying to load is being copied to the app. To do this, click on project under project files (blue bar with project name in it->Click on the target->Click on Build Phases->Click to expand the "copy Bundle Resources", and make sure your file is in it. If it is not, click the plus, and add it.
Make sure the case matches exactly. (aka - The simulator will work/the app will not problem) Make sure the case matches exactly, otherwise it will return nothing. To fix this, just rename it in the project, or use the right case in the source.
Project may be missing the media framework. To fix this click on your project menu -> click on the target -> click to expand "Link Binary With Libraries". Now select MediaPlayer.framework and build the code.
If all else fails, clean the project, and try again.
All this is checked/fixed, but not working. I had this working fine, and then I changed the video that I am showing in the app. Since i changed the file, it stopped working.
NSString *path = [[NSBundle mainBundle] pathForResource:#"multiplying" ofType:#"m4v"];
Q: why is it null? The file is case matched/typed correctly and is about 10 megs. (is the file too large?) Works fine in the simulator, and I can get the path to an image, a line above this one, with no error.
You say it's working in simulator and not working on device?
May be you should try to copy the file at first launch to one of the application sandbox folders and access it like this:
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *pathForTheFile= [documentsDirectory stringByAppendingPathComponent: #"multiplying.m4v"];

Resources