UIImage not writing to or appearing on Desktop - debugging

For whatever reason, I'm not having the UIImage appear on my desktop. I'm using this code as a means of debugging. However, I'm pretty sure that I am receiving an image since the UIImage in the debugger is not null.
UIImage *imgageProfile = [UIImage imageWithData:
[NSData dataWithContentsOfURL:
[NSURL URLWithString: sUrlPic]]];
// Use this code to debug images
NSURL *aLocalURL = [NSURL URLWithString:#"file:///Users/snuffles753/Desktop/"];
NSData *imageData = UIImagePNGRepresentation(imgageProfile);
[imageData writeToURL:aLocalURL atomically:YES];

-[NSData writeToURL:…] takes a URL that includes the name of the file you'd like created. It will `not take the URL of a folder, and automatically create a file inside of that. So your current code is attempting to overwrite an existing directory, which then fails.
Instead, specify the filename explicitly:
NSURL *aLocalURL = [NSURL URLWithString:#"file:///Users/snuffles753/Desktop/debug.png"];

Related

Can't access local resource with NSURL. Strange

My iOS app wants to play a local audio file. So, in xCode, I’ve added a file "audio.m4a" to my project. It resides on the top level of the file tree, but
NSURL *audioFileURL = [[NSBundle mainBundle]
URLForResource:#"audio"
withExtension:#"m4a"];
returns nil. There must be a stupid oversight. What am I doing wrong?
NSBundle *mainBundle = [NSBundle mainBundle];
NSString *myFile = [mainBundle pathForResource: #"audio" ofType: #"m4a"];
NSURL *audioFileURL = [NSURL URLWithString:myFile];
and check whether that file present in Build Phases" -> "copy bundle Resources"
Swift
Since neither answer is complete, and the solution is disseminated in the comments, let me offer a Swift alternative. and a step-by-step response.
The original Objective-C code is correct:
NSURL *audioFileURL = [[NSBundle mainBundle]
URLForResource:#"audio"
withExtension:#"m4a"];
Swift
let audioFileURL = NSBundle.mainBundle().URLForResource(
"audio",
withExtension: "m4a")
Target Membership
This was probably an oversight when originally adding the resource to the project. You must select adequate targets when adding these files:
Regardless of the language, ensure that your file is Project > Build Phases > Copy Bundle Resources. You need not to do that by hand. Instead, use the File Inspector. Select your resource (on the left panel) and verify it's target membership (on the right panel):
/* Use this code to play an audio file */
NSString *soundFilePath = [[NSBundle mainBundle] pathForResource:#"test" ofType:#"m4a"];
NSURL *soundFileURL = [NSURL fileURLWithPath:soundFilePath];
AVAudioPlayer *player = [[AVAudioPlayer alloc] initWithContentsOfURL:soundFileURL error:nil];
player.numberOfLoops = -1; //Infinite
[player play];

Loading retina images from a subdirectory

I'm using NSDrawNinePartImage() to draw a stretchable control. Since this of course requires nine separate images to draw the parts (plus some extras that are drawn over that), I have a directory full of files like top-left.png and top-left#2x.png. I include this directory in my app bundle as a folder reference.
Unfortunately, the usual image-loading APIs like -[NSImage imageNamed:] and -[NSBundle imageForResource:] don't seem to support subdirectories, even if you put a slash in the name. Instead, I'm loading the images with this method:
- (NSImage*)popoverImage:(NSString*)name {
NSURL * url = [[NSBundle bundleForClass:self.class] URLForResource:name withExtension:#"png" subdirectory:#"popover"];
return [[NSImage alloc] initWithContentsOfURL:url];
}
This works fine for normal displays, but it ignores the 2x images for retina displays. How can I get it to load the retina images as well? Is there a better way than loading the two reps separately and combining them by hand? I'd rather not use TIFFs as my source files for these resources, because I use Acorn as my image editor and last time I checked, it doesn't really understand compound image formats like that very well.
The simple answer is to use TIFF's, your concern is misplaced. In Xcode set the project preference "Combine High Resolution Artwork" and continue to produce your two PNG's with Acorn as you do now. During build Xcode will combine those two PNG's into a single TIFF and store that in your bundle.
I ended up biting the bullet and combining the images manually at runtime. I did so by adding this method in a category on NSImage, and then using it in place of -initWithContentsOfURL::
- (id)initRetinaImageWithContentsOfURL:(NSURL *)url {
if((self = [self initWithContentsOfURL:url])) {
NSURL * baseURL = url.URLByDeletingLastPathComponent;
NSString * baseName = url.lastPathComponent.stringByDeletingPathExtension;
NSString * extension = url.lastPathComponent.pathExtension;
NSString * retinaBaseName = [NSString stringWithFormat:#"%##2x", baseName];
NSURL * retinaURL = [baseURL URLByAppendingPathComponent:[retinaBaseName stringByAppendingPathExtension:extension]];
if([retinaURL checkResourceIsReachableAndReturnError:NULL]) {
NSData * data = [[NSData alloc] initWithContentsOfURL:retinaURL];
NSBitmapImageRep * rep = [[NSBitmapImageRep alloc] initWithData:data];
rep.size = self.size;
[self addRepresentation:rep];
}
}
return self;
}
This is what I do:
NSArray *paths = [NSBundle.mainBundle pathsForResourcesOfType: #"icns" inDirectory: #"Collections/1"];
for (NSString *path in paths) {
NSString *fileName = [[path lastPathComponent] stringByDeletingPathExtension];
NSImage *image = [[NSImage alloc] initWithContentsOfFile: path];
image.name = fileName;
[iconCollectionController addObject: #{#"icon": image}];
}
but as CRD already pointed out you need to combine your artwork (either as tiff or icns files). But it frees you from manually selecting an image resolution (which also requires you to listen to backing store changes).

What’s the correct way to create an NSURL from an NSString?

I’ve got an NSString that stores the path to a saved file:
NSString *filePath = [NSString stringWithFormat:
#"%#/someFolder/%#",
NSHomeDirectory(),
[NSString stringWithFormat:#"%#",[self.fileName stringByAppendingPathExtension:#"txt"]]];
And it’s OK — when I log it, I get:
/Users/username/someFolder/fileName.txt
So my next step is to make an NSURL object from this NSString. I did this:
NSURL *pathURL = [NSURL URLWithString:[NSString stringWithFormat:#"%#", filePath]];
NSLog(#"URL = %#", pathURL);
but the response is:
URL = (null)
What’s wrong here? How can I do this correctly?
A path is not a valid URL by itself. You have to use this:
NSURL *pathURL = [NSURL fileURLWithPath:filePath];
And read the documentation. (And don’t overuse / abuse format strings.)

how to play an audio file which is not in the main bundle?

this is my code to play mp3 file from the directory of the application, and for some reason it's not working. lease find out what's wrong with this code !
-(IBAction)PlayLesson:(id)sender;
{
NSString *folderAndFile = #"/Users/alaaalfadhel/Library/Application Support/iPhone Simulator/5.1/Applications/1021CF5B-F664-4123-B9CB-529217225B74/Documents/file.mp3";
NSString *audioFilePath = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0] stringByAppendingPathComponent:folderAndFile];
NSURL *url = [NSURL fileURLWithPath:audioFilePath];
ofType:#"mp3"]];
AVAudioPlayer *click = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:nil];
[click play];
}
Since the NSSearchPathForDirectoriesInDomains supplies everything up to the Documents directory, you don't need to give it a folder/file combination but just the file.
You really want your URL to be /Users/alaaalfadhel/Library/Application Support/iPhone Simulator/5.1/Applications/5515AFBA-1E7D-4B06-A62E-F6FDFD7DD7C7/Documents/file.m‌​p3 instead of the one displayed in your log. This is necessary because the long hex value will change any time you remove the app from the simulator and then launch it again.

NSImage returns 0x0 when there is space in the file name

I used the codes below to load image
NSURL *url=[NSURL URLWithString:[NSString stringWithFormat:#"file://home/%#", filename]];
NSImage *image = [[[NSImage alloc] initWithContentsOfURL:url] autorelease];
but I found that if there is a space in the filename, such as
#"a b.jpg"
image returns 0x0
Welcome any comment
When creating URLs pointing to file system paths, one should use +fileURLWithPath: or -initFileURLWithPath:. Replace:
NSURL *url=[NSURL URLWithString:[NSString stringWithFormat:#"file://home/%#", filename]];
with:
NSURL *url=[NSURL fileURLWithPath:[NSString stringWithFormat:#"/home/%#", filename]];
And, in general, one should use -[NSString stringByAppendingPathComponent] when composing strings that represent paths. This method takes care of placing a solidus / when appropriate:
NSString *fullPath = [[#"/home" stringByAppendingPathComponent:filename] autorelease];
NSURL *url = [NSURL fileURLWithPath:fullPath];

Resources