How to load image from URL in ccsprite - ios

I am showing image from URL in CCSprite. There are many images and hence i need to load image very quickly.
I have written my code which worked fine in simulator but crashed on iPad. Now i can't understand anything from the device log.
My code:
NSData *d = [NSData dataWithContentsOfURL:[NSURL URLWithString:[Data valueForKey:[NSString stringWithFormat:#"%d", idx]]]];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *filePath = [NSString stringWithFormat:#"%# %#", documentsDirectory, string];
BOOL didWrite = [d writeToFile:filePath atomically:YES];
CCSprite * facebookImage = [[CCSprite alloc] initWithFile:filePath] ;
Here I am saving my image in file and giving those content to CCSprite.
now the image from URL is fetching properly in simulator but on device this code crashes.
P.S : there are other ways too but they didn't work that well so i preferred this method over NSRequest etc.

Set a breakpoint, single-step through the code. Write probably fails because your path contains a space before the filename (format string: "%# %#"), or because string is nil.
Write failsafe code: you already have a didWrite flag, you should have an if clause that creates the sprite when write (and download) succeeded, otherwise log the error and perhaps create a placeholder sprite.

To display image from URL in CCSprite I have now changed my approach.
UIImage *uiimage2 = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:urlString]];
CCSprite * facebookImage = [[CCSprite alloc]initWithCGImage:uiimage2.CGImage key:string];
Hope this answer helps someone.

Related

Image written through WriteToFile command is missing after app rerun

I am writing an app which downloads image from my server and stores them locally for offline viewing. The codes I use to store the image locally are shown below. Apart from storing the image, I am also able to read the image from the path (which I stored separately).
However when I re-run my code from Xcode to the iPhone (without uninstalling the app from the phone), the stored image file would be missing. Is this expected? Would I face similar issue when my app has been released on App Store and when the user updates the app? Is there a way to keep the file persistent when I re-run them when I update some codes in Xcode?
NSData *imageData = UIImageJPEGRepresentation(image, 1.0);
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *imagePath =[documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:#"file.jpeg",]];
if (![imageData writeToFile:imagePath atomically:YES])
{
// Handling when there is an error
NSLog(#"Failed to store file at path %#",imagePath);
stored.text = #"";
}
else
{ // Handling when write is successful
NSLog(#"Imaged stored path is %#",imagePath);
stored.text = imagePath;
}
[imageView setImage:image];
The code to read the image is shown below:
NSString *imagePathToRead = stored.text;
NSLog(#"Retrieve image from %#",imagePathToRead);
UIImage *image = [UIImage imageWithContentsOfFile:imagePathToRead];
[imageView setImage:image];
I am posting the answer here from rmaddy which solved the issue I was facing. I am posting here so that others can benefit if they are facing similar issue.
For the storing portion:
The stored.text should never store the full path:
stored.text = imagePath;
Instead I should store #"file.jpeg" only.
For the Read portion:
I should always regenerate the full path below when I wanted to read the path instead of the code below:
NSString *imagePathToRead = stored.text;
The corrected codes are:
NSString *imagePathToRead = stored.text;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *imagePath =[documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:imagePathToRead]];
NSLog(#"Retrieve image from %#",imagePath);
UIImage *image = [UIImage imageWithContentsOfFile:imagePath];
This solved the issue and the image is able to be read even though the app is re-installed through Xcode.

Load image previously saved from the camera roll

So I have an image saved from the camera roll or camera and have a saved the directory and image name to reference back to. When I go back to where I want that image to show it won't. It's just a blank image view.
I seem like it should be straight forward and I have done my own research, but no answer seems to be working for me.
Below is the image path and the code I am using to try and show the image. What am I doing wrong here?
/Users/*****/Library/Developer/CoreSimulator/Devices/FA19C634-C029-4518-BAE1-E7CC601FB9C2/data/Containers/Data/Application/72B5C82B-A8FB-451D-A6DC-DF2C3F3ED12D/Documents/Profile Pics/CYKGXryEDj-1.jpg
self.imageView.image = [UIImage imageWithContentsOfFile:profileImg];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsPath = [paths objectAtIndex:0]; //Get the docs directory
NSString *filePath = [documentsPath stringByAppendingPathComponent:#"image.png"]; //Add the file name
NSData *pngData = [NSData dataWithContentsOfFile:filePath];
UIImage *image = [UIImage imageWithData:pngData];
I did only one time using AVFoundation framework -
I was saving images as data and showing them by using imageWithData method. hope this will help you.

Setting UIImageView image from saved screenshot working in iOS 8 but not iOS 7

I have made an app that saves a screenshot of the device to the app's Documents directory.
This UIImageView then reads in the saved screenshot image and displays it. All good so far. But wait a minute, this works absolutely fine on iOS 8, but it simply doesn't show anything on iOS 7, both simulators and devices.
So I investigated and found that iOS 8 saves the image to the following directory (Simulator on OS X):
/Users/SunburstEnzo/Library/Developer/CoreSimulator/Devices/AE8252CE-38C1-4D81-BA87-34F50E743AEC/data/Containers/Data/Application/34562F4C-5DED-4F1C-9CB6-92948B6C5F89/Documents/2014-11-26-11-12-24.png
While iOS 7 saves it to here:
/Users/SunburstEnzo/Library/Developer/CoreSimulator/Devices/CE8E7B90-F00F-441B-8E70-17E968AB7AF7/data/Applications/994CD541-2730-4E32-93CD-23B9F996C2E3/Documents/2014-11-26-11-12-51.png
I know this has something to do with it but when I reference it, it can see the image fine, it's just having a problem putting it to the screen. And I know what I've done works (on iOS 8) so the code is fine, but I need a workaround for this bug.
Also, whatever my problem is should be similar to this question's problem regarding the change over to using App Containers (NOTE: saving images is fine for me, just displaying it) -- saving image to documents directory no longer works iOS8
Tl;dr bug in iOS 7 stops saved image in Documents directory from showing, works fine on iOS 8, help me work around it
My code:
Writing screenshot to Documents directory:
UIGraphicsBeginImageContext(self.view.bounds.size);
[self.view.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *sourceImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
//UIImageWriteToSavedPhotosAlbum(sourceImage,nil, nil, nil);
NSData *pngData = UIImagePNGRepresentation(sourceImage);
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsPath = [paths objectAtIndex:0]; //Get the docs directory
NSError * error;
NSArray * directoryContents = [[NSFileManager defaultManager]
contentsOfDirectoryAtPath:documentsPath error:&error];
NSString *dateString;
NSDate *now = [NSDate date];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"yyyy-MM-dd-HH-mm-ss"];
dateString = [dateFormatter stringFromDate:now];
NSString *filePath = [documentsPath stringByAppendingPathComponent:[NSString stringWithFormat:#"%#.png",dateString]]; //Add the file name
[pngData writeToFile:filePath atomically:YES]; //Write the file
Code to read:
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsPath = [paths objectAtIndex:0]; //Get the docs directory
NSError * error;
NSArray * directoryContents = [[NSFileManager defaultManager]
contentsOfDirectoryAtPath:documentsPath error:&error];
directoryContentsPopover = [[NSFileManager defaultManager]
contentsOfDirectoryAtPath:documentsPath error:&error];
NSLog(#"Number of images: %d",directoryContents.count);
if (directoryContentsPopover.count > 0) {
self.mainImageView.image = [UIImage imageNamed:[NSString stringWithFormat:#"%#/%#",documentsPath,directoryContentsPopover[0]]];
NSLog(#"At least 1 image; Image location: %#/%#",documentsPath,directoryContentsPopover[0]);
}
****Answer by Nick Lockwood****
Replace
self.mainImageView.image = [UIImage imageNamed:[NSString stringWithFormat:#"%#/%#",documentsPath,directoryContentsPopover[0]]];
with
self.mainImageView.image = [UIImage imageWithContentsOfFile:[NSString stringWithFormat:#"%#/%#",documentsPath,directoryContentsPopover[0]]];
You are trying to load the image using [UIImage imageNamed:], but this method is only intended for images in your app bundle or XCAssets, it doesn't accept an arbitrary file path.
Use [UIImage imageWithContentsOfFile:] instead.
If the image saved on ios8 then it was also get saved in ios7,
you are not getting to correct path of documents directory ios8 and ios7 both having different path for document directory
path for ios7 document directory:/Users/**********/Library/Application Support/iPhone Simulator
try this

Saving a UIImage as a PNG, can't load image after restarting app

I am using this to save a UIImage as a PNG
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSTimeInterval timeInMiliseconds = [[NSDate date] timeIntervalSince1970];
NSString *generatedString = [NSString stringWithFormat:#"background%f.png", timeInMiliseconds];
NSString *pngPath = [documentsDirectory stringByAppendingPathComponent:generatedString];
[UIImagePNGRepresentation(customBackground) writeToFile:pngPath atomically:YES];
I am saving pngPath into a plist from above then using the string in this:
UIImage *image = [UIImage imageWithContentsOfFile:string];
as string, the string shows up right and I can see the image file at the exact location it shows.
Now the strange part is as long as I don't close the app the method works fine, but if I close and reopen the app the UIImage file just stays nil. Any thoughts?
I am an idiot...
The string saved and retrieved was missing a "/" between the Documents and file name. Added it in and it works. Now I'm curious how it ever worked when app never closed. Thanks for the help guys. :)

This used to work: Displaying image using imageWithContentsOfFile

This was working for me yesterday morning and now it doesn't. So, I suspect something else changed to cause it...but I can't find the change. I've spent hours reverting my code back almost a week and still it's not working (and I know it was working yesterday morning). So, I'm hoping that in posting this specific issue (a symptom?) some ideas will surface that I can evaluate. Thanks.
I download images as they're needed:
NSFileManager *filemgr;
filemgr = [NSFileManager defaultManager];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentDirectory = [paths objectAtIndex:0];
NSString *targetFile = [NSString stringWithFormat:#"%#/%#.%#", documentDirectory, imageName, imageType];
// only download those where an image exists
if(![imageType isEqualToString:#""])
{
// only download the file if there is not already a local copy.
if([filemgr fileExistsAtPath:targetFile] == NO)
{
NSMutableData *imageData = [[NSMutableData alloc] initWithLength:0];
[imageData appendData:data];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *thumbNailFilename = [NSString stringWithFormat:#"%#.%#", imageName, imageType];
NSString *thumbNailAppFile = [documentsDirectory stringByAppendingPathComponent:thumbNailFilename];
}
}
Then display them:
NSString *imageFullName = [NSString stringWithFormat:#"%#%#", [greetingObject valueForKey:#"gid"], [greetingObject valueForKey:#"itp"]];
NSString *fullImagePath = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0] stringByAppendingPathComponent:imageFullName];
UIImage *greetingImage = [UIImage imageWithContentsOfFile:fullImagePath];
self.greetingImage.image = greetingImage;
The variables "imageFullName" and "fullImagePath" are populated with the correct data and the image files are present on the simulator in the specified directory. Yet, "greetingImage" equals nil.
Here's what I get for "fullImagePath": /Users/Steve2/Library/Application Support/iPhone Simulator/7.1/Applications/8C9F8417-F6E2-4B38-92B3-82A88477CB7F/Documents/165.jpg
Here are the image files:
I have also tried variations using initWithContentsOfFile and dataWithContentsOfFile and get the same result. The greetingImage variable is nil.
I appreciate your ideas. I've even reinstalled Xcode in hopes that something got corrupted. No dice.
Added: One thing I just thought of... I did add the SystemConfiguration.framework to the project yesterday for an unrelated feature. It's currently at the top of the Linked Frameworks and Libraries list. I have no experience working with this. Could it be causing the problem?
Thanks.
Your code looks correct.
I would check that the images themselves are still okay. Looking at the screenshot you posted Finder isn't showing previews of the images which it should do with a valid JPEG. You say that the images are being downloaded so I suspect that they are being corrupted somehow on the way down.
EDIT:
Didn't notice that you were using initWithContentsOfFile. Since you are saving the files as NSData objects you will need to load them into memory as NSData objects and then init a UIImage with the data object, like so:
NSData *imageData = [NSData dataWithContentsOfFile:filePath];
[UIImage imageWithData:imageData];

Resources