Best way of retrieving image from the server - ios

I am newbiee to the backend. I have been working on an app collaborating with a newbiee backend developer. I am working on an application where a user sells/buys a product. I could able to send product the image which taken from the device camera and send it via POST method to database.
Taken image is stored in the database. The question that I have is as follows:
In order to get back this image to the app what method needs to be used? Is it better to get data chunk or image URL in JSON?

I would recommend getting the image URL and then using the following code to load the image:
dispatch_async(dispatch_get_global_queue(0,0), ^{
NSData * data = [[NSData alloc] initWithContentsOfURL:url];
if (data == nil) {
NSLog(#"Uh oh! Couldn't retrieve the image");
return;
}
dispatch_async(dispatch_get_main_queue(), ^{
UIImage *image = [UIImage imageWithData:data];
//do something with the image such as:
UIImageView *myImageView.image = image;
});
});

Related

How to get thumbnail image from parse, objective c

I want to get thumbnail image or blank image first while app is loading image data from parse database. After finish loading, the image view will display the image I load from parse.
So far, I have following codes
PFFile *thumbnail = object1[#"PostFiles"];
NSData *imageData = [thumbnail getData];
UIImage *image = [UIImage imageWithData: imageData];
I use PFtableviewcontroller. when I scroll down, my code will load image, the controller can't move smoothly.
The issue is that you are running a synchronous call for a task that could take a varying amount of time. Try getting the NSData using InBackgroundWithBlock:
image = nil; //prevent images from being shown erroneously
[thumbnail getDataInBackgroundWithBlock:^(NSData *data, NSError *error) {
if (data && !error) {
image = [UIImage imageWithData:data];
} else {
//maybe set a default image here if there is none?
}
}];

How Do I save the user's image fetched from fbprofilepictureview using the Facebook SDK

So I'm implementing the Facebook login button in an iOS app I'm currently working on, I'm trying to save the user's profile picture that's accessed using this line;
self.profilePicture.profileID = user.id;
I haven't had any luck storing that image for use elsewhere in the app. I have tried a number of methods including this approach
imageUrl=[NSString stringWithFormat:#"https://graph.facebook.com/%#/picture?redirect=true", user.username];
Any help is welcome!
You need to use user.objectID and not user.username.
You can also use my drop-in replacement for FBProfilePictureView, DBFBProfilePictureView. This exposes the imageView as a readonly property. Using that, your code would be something like this...
self.profilePicture.completionHandler = ^(DBFBProfilePictureView* view, NSError* error){
if(error) {
view.showEmptyImage = YES;
NSLog(#"Loading profile picture failed with error: %#", error);
} else {
UIImage *image = view.imageView.image;
NSData *imageData = UIImagePNGRepresentation(image);
[imageData writeToFile:filename atomically:NO];
}
};

How do I preload images from an array of urls in iOS?

I have a music app that I want to preload album arts for. Right now, when you hit next song it loads the album art from a URL but it would be nice if it was already preloaded and in memory. I've tried a few things but nothing seems to really work. Does anyone know of a technique that where I can preload images in iOS and then look for that image later and if its not there, then download it?
Edit with some more detail...
When I go to play a 'station' on my app, I make a request to a server that returns JSON for the playlist. Inside of this JSON is each song as well as data including the album art URL. When a user goes to play a 'station' I would like to preload images for either the next album art URL in the stack or all album art URLs in the entire playlist.
Anyways, I've tried loading the next album art URL in a UIImage in the background as like a temporaryAlbumArt and then when the next song is played simply do albumArt = temporaryAlbumArt and then repeat the process setting the next songs album art to temp and so on..
I've tried something like this:
if (temporaryAlbumArt) {
albumArt = temporaryAlbumArt
} else {
albumArt = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:firstAlbumArtURL]]];
}
temporaryAlbumArt = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:nextAlbumArtURL]]];
I guess my question is, what is the best method of:
loading an image or multiple images from a URL(s) into memory
using those images later on without any lag time
You can use this "must have" tool APSmartStorage. It supports everything you need.
This library does what you need: JMImageCache
Loop through your URLs, download them through JMImageCache and when you need to show an image the library will fetch the stored image if it's finished downloading.
//You can do this when you get the array of urls to download the images in the background
for(NSURL *url in urls) {
[[JMImageCache sharedCache] imageForURL:url];
}
//and then when you need an image:
[imageView setImageWithURL:url placeholder:[UIImage imageNamed:#"placeholder.png"]];
I'm not for sure what you are asking but if you know what the next song is going to be couldn't you just down load it in a background thread then have it ready for display when the next song starts?
If you want the app to store all the downloaded images locally you may eventually run into space issues but its do able. You could use the downloaded image then store it in the caches directory (not document dir or Apple will get mad!). When a song comes just do a quick check for the image and if its not local download it. Songs take a few minutes so there should be time to do all this in the background.
#define GET_QUEUE dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)
// while song is playing...
dispatch_async(GET_QUEUE, ^{
// On a separate thread look for the image locally in the cache and then
// download it if necessary
});
I'm not sure if this answers your question or not...
Ok so here is a bit more code - basically it lets me ask hopefully helpful questions in context.
// Inside some loop/method that plays songs...
if (temporaryAlbumArt)
albumArt = temporaryAlbumArt
else
albumArt = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:firstAlbumArtURL]]];
// If this keeps executing then perhaps temporaryAlbumArt is getting released somehow?
// Are you persisting it correctly through each iteration/method call?
// show art...
// start music
// Call art update
dispatch_async(GET_QUEUE, ^{
temporaryAlbumArt = nil; // In case the data hasn't been obtained yet on the next iteration???
temporaryAlbumArt = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:nextAlbumArtURL]]];
// This works ok then? Can you make sure this is completing correctly before the next iteration/method call?
});
Sorry I can't be of more help.
I have written this code to download data from server and save that data into document directory so that next time if anybody hit the same url,it is fetched from document directory without any server hit.
-(void)downloadImageForProductsFromArray:(NSArray *)inventoryArr {
BOOL isAllDataDownloaded = YES;
MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:self.view animated:YES];
hud.labelText = #"Data Sync...";
[[NSOperationQueue mainQueue] addObserver:self forKeyPath:#"operations" options:0 context:nil];
for (int i = 0; i < inventoryArr.count; i++) {
NSString *productUrlStr = [inventoryArr objectAtIndex:i];
NSData *dirData = [CommonUtils fetchImageDataFromDirectoryWithImageName: productUrlStr];/*****Check whether Image data is already downloaded and saved in document directory*****/
if (!dirData) {
isAllDataDownloaded = NO;
NSBlockOperation *downloadImgOpr = [[NSBlockOperation alloc] init];
downloadImgOpr.queuePriority = NSOperationQueuePriorityVeryHigh;
downloadImgOpr.qualityOfService = NSQualityOfServiceUserInitiated;
[downloadImgOpr addExecutionBlock:^{
NSData *imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString: productUrlStr]];
if (imageData) {
/*****Save Image Data in Document Directory*****/
}
}];
}
}
if (isAllDataDownloaded) {
[MBProgressHUD hideAllHUDsForView:self.view animated:YES];
}}
- (void) observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object
change:(NSDictionary *)change context:(void *)context{
if (object == [NSOperationQueue mainQueue] && [keyPath isEqualToString:#"operations"]) {
if ([[NSOperationQueue mainQueue].operations count] == 0) {
// Do something here when your queue has completed
[MBProgressHUD hideAllHUDsForView:self.view animated:YES];
NSLog(#"queue has completed");
}
}
else {
[super observeValueForKeyPath:keyPath ofObject:object
change:change context:context];
}
}
In This code i have all the url strings in the inventory array.In for loop i have made several operations and added those operations into the queue(I have used main queue for holding UI and syncing data.Choose your queue appropriately).Also I have added the KVO to the queue for keypath value "operations" so that if count of operations is 0,we can do the useful operation.

Save image into library directly from APNS

i want to save image into photo library of iphone sdk. my image is coming from one url and that url is coming from APNS. basically i want save image directly into iphone lib without opening app when user will click on that URL which is coming as Push notification. right now i am doing this as follows but i dont want to show that image i just want to save.
-(void) sshowansimage:(NSString *) strImageURL
{
NSURL *imageURL = [NSURL URLWithString:strImageURL];
NSLog(#"coming URL is %#", strImageURL);
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
NSData *imageData = [NSData dataWithContentsOfFile:strImageURL];
[self performSelectorOnMainThread:#selector(showImage:) withObject:imageData waitUntilDone:YES];
});
}
-(void)showImage:(NSData*)imageAsData
{
NSLog(#"IN image view mthhod data is %d",imageAsData.length);
ansinage.image = [UIImage imageWithData:imageAsData];
}
you can use your image as NSData and store it to albums with following.first you need to convert your NSData in to image object and then do following.
UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil);
Use below code for store image directly to Photo Album
UIImage *image=[UIImage imageWithData: imageData];
UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil);

Slow loading the images from URL in UITAbleView.

I'm loading the images from URL in UITableView. But it's very slow when loading an view. Here's an example,
UIImage *image = nil;
image = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:#"http://calcuttans.com/palki/wp-content/uploads/2009/02/kidscover-small.png"]]];
In Table view, UIButton i'm setting the background image.
Please Can you provide the sample.
FYI : I'm used the LazzyTable sample program but it's not much helpful. Can you suggest any other samples.
Load image asynchronously
NSURL* url = [NSURL URLWithString:#"http://calcuttans.com/palki/wp-content/uploads/2009/02/kidscover-small.png"];
NSURLRequest* request = [NSURLRequest requestWithURL:url];
[NSURLConnection sendAsynchronousRequest:request
queue:[NSOperationQueue mainQueue]
completionHandler:^(NSURLResponse * response,
NSData * data,
NSError * error) {
if (!error){
NSImage* image = [[NSImage alloc] initWithData:data];
// do whatever you want with image
}
}];
There are some open source libraries available for this:
HJCache
SDWebImage
These libraries download image in a asynchronous manner and cache it for further use.
Try to implement AFNetworking. It uses async requests to download the image, you are currently blocking your view with every download.
You can then use an AFImageRequestOperation to download your image.
if you load the image all download from the internet every time , it must be very slow.
I think you shuold exist your download image to the filePath , and when you will load the image , you can check whether the image has been downloaded before , if not ,then download. if it has been downloaded , you can use imageWithContentsOfFile: method to load the image
//Make use of dispatch queue for faster processing of data. add this in viewDidLoad
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
NSData * data=[NSData dataWithContentsOfURL:[NSURL URLWithString:imageUrl]];
[self performSelectorOnMainThread:#selector(setImage:) withObject:data waitUntilDone:YES];
});
//once data is got set the image and reload tableview
-(void)setImage:(NSData *)responseData
{
image = [UIImage imageWithData:responseData];
[tableView reloadData];
}
maybe you can use asihttprequest to lazy load images. use ASINetworkQueues
You've to use NSOperationQueue to make your tableview efficient.
Check this icodeblog tutorial and raywenderlich tutorial
Have a look at this tutorial. It helped me a lot. When I was using it I was quite new to iOS in general and it was helpful not only with respect to loading images from the web.
http://www.markj.net/iphone-asynchronous-table-image/
With AFNetworking it is more easy.
//AFNetworking
#import "UIImageView+AFNetworking.h"
[cell.iboImageView setImageWithURL:[NSURL URLWithString:server.imagen] placeholderImage:[UIImage imageNamed:#"qhacer_logo.png"]];

Resources