Background thread running for fetching image from Facebook album - iphone

- (void)request:(FBRequest *)request didLoad:(id)result {
// NSArray *resultData = [result objectForKey:#"data"];
NSMutableArray *photos = [[NSMutableArray alloc] initWithCapacity:1];
// imageArray = [[NSMutableArray alloc] initWithCapacity:1];
NSArray *resultData = [result objectForKey:#"data"];
if ([resultData count] > 0)
{
noOfImages = 0;
for (NSUInteger i=0; i<[resultData count] ; i++)
{
[photos addObject:[resultData objectAtIndex:i]];
NSDictionary *albumPhotos = [photos objectAtIndex:i];
NSString *imageUrl = [albumPhotos objectForKey:#"picture"];
NSLog(#"ImageURL:%#",imageUrl);
NSURL *url = [NSURL URLWithString:imageUrl];
// [slideImageArray addObject:url];
NSData *data = [NSData dataWithContentsOfURL:url];
UIImage *images = [UIImage imageWithData:data];
// imageView.image = images;
[slideImageArray addObject:images];
[NSThread detachNewThreadSelector:#selector(startTheBackgroundJob:) toTarget:self withObject:images];
}
NSLog(#"ImageCount:%d",[slideImageArray count]);
if([slideImageArray count] == 1)
{
imageView.image = [slideImageArray objectAtIndex:0];
}
if([slideImageArray count]>1)
{
numTimer =0;
myTimer = [NSTimer scheduledTimerWithTimeInterval:3 target:self selector:#selector(timerRunning) userInfo:nil repeats:YES];
}
}
}
- (void)request:(FBRequest *)request didFailWithError:(NSError *)error {
NSLog(#"Err message: %#", [[error userInfo] objectForKey:#"error_msg"]);
NSLog(#"Err code: %d", [error code]);
}
- (void)startTheBackgroundJob:(UIImage *)img
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
// wait for 3 seconds before starting the thread, you don't have to do that. This is just an example how to stop the NSThread for some time
//imageView.image = img;
noOfImages++;
// [NSThread sleepForTimeInterval:3];
// [slideImageArray addObject:img];
//[NSThread sleepForTimeInterval:1];
imageView.image = img;
if(noOfImages == 1)
{
NSLog(#"noValueif:%d",noOfImages);
// imageView.image = [slideImageArray objectAtIndex:0];
[NSThread sleepForTimeInterval:1];
// imageView.image = img;
}
else if(noOfImages >1)
{
NSLog(#"noValue:%d",noOfImages);
// numTimer =0;
// myTimer = [NSTimer scheduledTimerWithTimeInterval:3 target:self selector:#selector(timerRunning) userInfo:nil repeats:YES];
// imageView.image = img;
[NSThread sleepForTimeInterval:3];
}
// [self performSelectorOnMainThread:#selector(changeImageViewImage) withObject:nil waitUntilDone:NO];
[pool release];
}
I have to run a background thread for getting image from Facebook album .i have to start a slide show with the first image collected.and i given a sleep for 3 second but it is not working.Also is there any other method for getting image from url other than the NSData *data = [NSData dataWithContentsOfURL:url]; method

Did you ever find the answer for this question?? or were u able to solve it?
And for this facebook api, are you using a personalized subclass of NSThread or using Dispatch queues?
And to answer your question if you want to fetch data in the background use performSelectorONMainThread... some facebook SDK methods require to be runned on the main thread for them to work, in my personal experience i found out that most of the data requesting is necessary to be on the mainthread using this method.
It worked for me, hopefully it works for you
:).

Related

why the images orientation is changing when loading the image from the cache?

I have an application in which i am loading the images from the image caches.`
if(![[ImageCache sharedImageCache] hasImageWithKey:imagepath])
{ cell.bannerview2.image = [UIImage imageNamed:#"no_imags.png"];
NSArray *myArray = [NSArray arrayWithObjects:cell.bannerview2,imagepath,#"no_imags.png",[NSNumber numberWithBool:NO],nil];
AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
[appDelegate performSelectorInBackground:#selector(updateImageViewInBackground:) withObject:myArray];
}
else
{
cell.bannerview2.image = [[ImageCache sharedImageCache] getImagefromCacheOrUrl:imagepath];
}
}
else
{
cell.bannerview2.image = [UIImage imageNamed:#"no_imags.png"];
}
this is how i am doing the image cache process.But the problem is when the image is larger than the required frame the image orientation is changing.this is my image updating code in the appdelegate
-(void)updateImageViewInBackground:(NSArray *)idsArray{
//NSLog(#"IN METHOD idsArray %#",idsArray);
NSString *iconurl = (NSString *)[idsArray objectAtIndex:1];
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
if([[ImageCache sharedImageCache] hasImageWithKey:iconurl]){
[self performSelectorOnMainThread:#selector(updateImageViewInForeground:) withObject:idsArray waitUntilDone:NO];
[pool release];
return;
}
if([iconurl length] > 0){
[[ImageCache sharedImageCache] saveImageToCacheOfUrl:iconurl];
}
[self performSelectorOnMainThread:#selector(updateImageViewInForeground:) withObject:idsArray waitUntilDone:NO];
[pool release];
}
-(void)updateImageViewInForeground:(NSArray *)idsArray{
UIImageView *weatherView = (UIImageView *)[idsArray objectAtIndex:0];
NSString *iconurl = (NSString *)[idsArray objectAtIndex:1];
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
weatherView.image = [[ImageCache sharedImageCache] getImagefromCacheOrUrl:iconurl];
if(weatherView.image == nil){
NSString *defaultname = (NSString *)[idsArray objectAtIndex:2];
weatherView.image = [UIImage imageNamed: defaultname];
}
BOOL resizeImgView = [(NSNumber *)[idsArray objectAtIndex:3] boolValue];
if(resizeImgView){
//NSLog(#"resizeImgView %# %#",iconurl,weatherView);
weatherView.frame = CGRectMake(weatherView.frame.origin.x, weatherView.frame.origin.y, weatherView.image.size.width, weatherView.image.size.height);
}
[pool release];
}
can anybody help me?

iPhone - NSURLConnection asynchronous download using URLs in NSArray

I have seen almost all the posts about NSURL on this site, and I am still stuck. I am using Xcode 4.5.
I am trying to download images and display them in a UIScrollView.
I want to download asynchronously download images using URLs, that get stored in an array populated using JSON. I get the URLs from a JSON grab off of my database. That works quite well and I can see the URL's being placed into the urlArray, but making the URLConnection to get the image, seems to fail.
I can't get any of the images to download, or at least they don't show up in my imageArray.
Here is my code and thank you for any help!! Let me know what else is needed
- (void)viewDidLoad
{
[super viewDidLoad];
//show network activity to user.... very useful
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
//call getJSON. getJSON does not parse, but it connects and gets the data.
[self getJSON];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void)getJSON
{
NSURL *url = [NSURL URLWithString:#"http://"My server goes here/json.php"];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
//just initialize the connection, do not
[[NSURLConnection alloc] initWithRequest:request delegate:self]; //"Ecression result unused" warning here
}
- (void)getNextImage
{
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
for (int y = 0; y < urlArray.count; y++)
{
NSString *urlString = [urlArray objectAtIndex:y];
NSLog(#"Array String is: %# ", urlString);
NSURL *arrayURL = [NSURL URLWithString:urlString];
NSURLRequest *imageRequest = [NSURLRequest requestWithURL:arrayURL];
NSData *imgData = [[NSURLConnection alloc] initWithRequest:imageRequest delegate:self]; //"Incompatible pointer types initializing ..." warning here
imageData = [UIImage imageWithData:imgData];
[imageArray addObject:imageData];
}
NSLog(#"LEAVING getNextImage");
}
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
theJsonData = [[NSMutableData alloc] init];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
[theJsonData appendData:data];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
urlArray = [[NSMutableArray alloc] init];
//This is where all the JSON Parsing is being done.
//Turn off the data indicator, because the download is complete.
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
jsonArray = [NSJSONSerialization JSONObjectWithData:theJsonData options:nil error:nil]; //"Incompatible pointer types initializing ..." warning here
//get the URL strings out of the jsonArray
for (int x = 0; x < jsonArray.count; x++)
{
NSString *urlString = [[jsonArray objectAtIndex:x] objectForKey:#"image_URL"];
NSLog(#"String is %# ", urlString);
[urlArray addObject:urlString];
}
[self getNextImage];
//display the images..... Not sure why this is in connectionDidFinishLoading.
for (int x = 0; x < imageArray.count; x++)
{
CGRect frame;
frame.origin.x = self.mainScroll.frame.size.width * x;
frame.origin.y = 0;
frame.size = self.mainScroll.frame.size;
UIImageView *nextIV = [[UIImageView alloc] initWithFrame:frame];
[nextIV setImage:imageData];
[self.mainScroll addSubview:nextIV];
//NSLog(#"Pass %d", x);
}
self.mainScroll.contentSize = CGSizeMake(self.mainScroll.frame.size.width * imageArray.count,1.0);
NSLog(#"!!!!!!leaving connection did finnish loading!!!!!");
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
//show error message to user if there is a connection error.
UIAlertView *errorView = [[UIAlertView alloc] initWithTitle:#"Error" message:#"The Download could not complete - please make sure you're connected to the internet." delegate:nil cancelButtonTitle:#"Dismiss" otherButtonTitles:nil];
[errorView show];
//turn off the network activity indicatior
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
}
you never download imageData. you assign it the request object . thats why you get the warning too. a NSURLConnection object is not a NSData object: NSData *imgData = [[NSURLConnection alloc] initWithRequest:imageRequest delegate:self]; //"Incompatible pointer types initializing ..." warning here
I would today rewrite it using the startAsyncConnection method. sec
-- there you go, untested and written in text edit but it should get you started (I reused most of your code but cut it down a lot too)
#import "RootViewController.h"
#interface RootViewController ()
#property(assign) IBOutlet UIScrollView *mainScroll;
#end
#implementation RootViewController
- (void)viewDidLoad
{
[super viewDidLoad];
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
[self getJSONAndImageData];
}
- (void)getJSONAndImageData
{
NSURL *url = [NSURL URLWithString:#"http://My server goes here/json.php"];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse*r, NSData*d, NSError*e) {
[self parseJSONAndGetImages:d];
}];
}
- (void)parseJSONAndGetImages:(NSData*)data
{
NSMutableArray *urlArray = [[NSMutableArray alloc] init];
//This is where all the JSON Parsing is being done.
//Turn off the data indicator, because the download is complete.
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
NSArray *jsonArray = (NSArray*)[NSJSONSerialization JSONObjectWithData:data options:nil error:nil]; //"Incompatible pointer types initializing ..." warning here => likely not an array then
assert([jsonArray isKindOfClass:[NSArray class]]);
//could be made in one liner with KVC
//get the URL strings out of the jsonArray
for (int x = 0; x < jsonArray.count; x++)
{
NSString *urlString = [[jsonArray objectAtIndex:x] objectForKey:#"image_URL"];
NSLog(#"String is %# ", urlString);
[urlArray addObject:urlString];
}
[self loadImageArray:urlArray handler:^(NSArray* imageArray) {
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
for (int x = 0; x < imageArray.count; x++)
{
CGRect frame;
frame.origin.x = self.mainScroll.frame.size.width * x;
frame.origin.y = 0;
frame.size = self.mainScroll.frame.size;
UIImageView *nextIV = [[UIImageView alloc] initWithFrame:frame];
[nextIV setImage:imageArray[x]];
[self.mainScroll addSubview:nextIV];
//NSLog(#"Pass %d", x);
}
self.mainScroll.contentSize = CGSizeMake(self.mainScroll.frame.size.width * imageArray.count,1.0);
}];
}
//for SIMPLICITY I do synchronous networking here!
- (void)loadImageArray:(NSArray *)urlArray handler:(void(^)())handler {
dispatch_async(dispatch_get_global_queue(0, 0), ^{
NSMutableArray *imageArray = [NSMutableArray array];
for (int y = 0; y < urlArray.count; y++)
{
NSString *urlString = [urlArray objectAtIndex:y];
NSLog(#"Array String is: %# ", urlString);
NSURL *arrayURL = [NSURL URLWithString:urlString];
NSURLRequest *imageRequest = [NSURLRequest requestWithURL:arrayURL];
NSData *imgData = [NSURLConnection sendSynchronousRequest:imageRequest returningResponse:nil error:nil];
UIImage *image = [UIImage imageWithData:imgData];
[imageArray addObject:image];
}
dispatch_async(dispatch_get_main_queue(),^ {
handler(imageArray);
});
});
}
#end

Raw image data from camera

I've been searching this forum up and down but I couldn't find what I really need. I want to get raw image data from the camera. Up till now I tried to get the data out of the imageDataSampleBuffer from that method captureStillImageAsynchronouslyFromConnection:completionHandler: and to write it to an NSData object, but that didn't work.
Maybe I'm on the wrong track or maybe I'm just doing it wrong.
What I don't want is for the image to be compressed in any way.
The easy way is to use jpegStillImageNSDataRepresentation: from AVCaptureStillImageOutput, but like I said I don't want it to be compressed.
Thanks!
This is how i do it:
1: I first open the camera using:
- (void)openCamera
{
imagePicker = [[UIImagePickerController alloc] init];
imagePicker.delegate = self;
if([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera])
{
imagePicker.sourceType = UIImagePickerControllerSourceTypeCamera;
imagePicker.mediaTypes = [NSArray arrayWithObjects:
(NSString *) kUTTypeImage,
(NSString *) kUTTypeMovie, nil];
imagePicker.allowsEditing = NO;
[self presentModalViewController:imagePicker animated:YES];
}
else {
lblError.text = NSLocalizedStringFromTable(#"noCameraFound", #"Errors", #"");
}
}
When the picture is taken this method gets called:
-(void) imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
// Save and get the path of the image
NSString *mediaType = [info objectForKey:UIImagePickerControllerMediaType];
ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
if([mediaType isEqualToString:(NSString *)kUTTypeImage])
{
// Save the image
image = [info objectForKey:#"UIImagePickerControllerOriginalImage"];
[library writeImageToSavedPhotosAlbum:[image CGImage] orientation:(ALAssetOrientation)[image imageOrientation] completionBlock:^(NSURL *assetURL, NSError *error){
if(!error) {
//Save path and location to database
NSString *pathLocation = [[NSString alloc] initWithFormat:#"%#", assetURL];
} else {
NSLog(#"CameraViewController: Error on saving image : %# {imagePickerController}", error);
}
}];
}
[imagePicker dismissModalViewControllerAnimated:YES];
}
Then with that path i get the picture from the library in FULL resolution (using the "1"):
-(void)preparePicture: (NSString *) filePathPicture{
ALAssetsLibraryAssetForURLResultBlock resultBlock = ^(ALAsset *myasset)
{
if(myasset != nil){
ALAssetRepresentation *assetRep = [myasset defaultRepresentation];
CGImageRef imageRef = [assetRep fullResolutionImage];
if (imageRef) {
NSData *imageData = UIImageJPEGRepresentation([UIImage imageWithCGImage:imageRef], 1);
}
}else {
//error
}
};
ALAssetsLibraryAccessFailureBlock failureBlock = ^(NSError *error)
{
NSString *errorString = [NSString stringWithFormat:#"can't get image, %#",[error localizedDescription]];
NSLog(#"%#", errorString);
};
if(filePathPicture && [filePathPicture length])
{
NSURL *assetUrl = [NSURL URLWithString:filePathPicture];
ALAssetsLibrary *assetslibrary = [[ALAssetsLibrary alloc] init];
[assetslibrary assetForURL:assetUrl
resultBlock:resultBlock
failureBlock:failureBlock];
}
}
Hope this helps you a bit further :-).

Memory leak Using NSData from URL

I receive Image from URL by threading .
but memory leaking in NSData.
Why? How do I fix it?
Leaking in Iphone devie not in simulator. help me!!
//viewcontroller
-(void)viewDidLoad
{
[self performSelectorInBackground:#selector(loadImageScreenshot:) withObject:args];
}
// loding image
-(void) loadImageScreenshot:(NSDictionary *) args
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
UIImage * screenshotImage=[UIImage imageWithStringURL:url];
NSDictionary *args2=[NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithInt:num], #"screenNum",
screenshotImage,#"image",
nil];
[self performSelectorOnMainThread:#selector(assignImageToScreenshotImageView:) withObject:args2 waitUntilDone:YES];
[pool release];
}
//image add
- (void) assignImageToScreenshotImageView:(NSDictionary *)arg
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
UIImage * image= [arg objectForKey:#"image"];
UIImageView *imageview=[UIImageView alloc]init];
.
.
imageview.image=image;
[self.mScreenshotSpace addSubview:imageview];
[imageview release];
[pool release];
}
//image from url
+(UIImage *)imageWithStringURL:(NSString *)strURL
{
NSURL *url =[NSURL URLWithString:strURL];
NSData * data=[[NSData alloc]initWithContentsOfURL:url options:NSDataReadingUncached error:&error];
UIImage * image=[UIImage imageWithData:data ];
[data release];
return image;
}
How do you know it is leaking? You are creating an autorelease pool in - (void) assignImageToScreenshotImageView:(NSDictionary *)arg that is never drained, that is a leak.
Otherwise the code seems fine.

AFGetImageOperation in OpenFlow

What's the correct way to implement AFGetImageOperation for OpenFlow.
AFGetImageOperation *getImageOperation = [[AFGetImageOperation alloc] initWithIndex:i viewController:self];
getImageOperation.imageURL = [NSURL URLWithString:aImage.imageURL];
[loadImagesOperationQueue addOperation:getImageOperation];
[getImageOperation release];
aImage.imageURL has the requested image URL but unsure where the retrieved image is stored?
Thanks
Images are not cached. It fetches the image again and again.
You can cache the image using following methods..
-(NSString *) md5String
{
NSString *md5 = [Utilities md5String:[imageURL absoluteString]];
return md5;
}
-(void) storeImage:(UIImage *)image AtPath:(NSString *)path
{
NSFileManager *manager = [NSFileManager defaultManager];
if([manager fileExistsAtPath:path])
{
[manager removeItemAtPath:path error:nil];
}
NSData *data = UIImagePNGRepresentation(image);
[data writeToFile:path atomically:NO];
}
//TODO: //We need to cehck the expiry date as well..
//-(UIImage *) imageFromPath:(NSString *)path Expiry:()
-(UIImage *) loadImageFromPath:(NSString *)path
{
UIImage *image = nil;
NSFileManager *manager = [NSFileManager defaultManager];
if([manager fileExistsAtPath:path])
{
image = [[[UIImage alloc] initWithContentsOfFile:path] autorelease];
}
return image;
}
-(NSString *) cachedImagePath
{
NSString *md5 = [self md5String];
NSString *cachedFilePath = [[Utilities applicationCacheDirectory] stringByAppendingPathComponent:md5];
return cachedFilePath;
}
- (void)main {
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
if (imageURL) {
UIImage *photo = nil;
NSString *cachedFilePath = [self cachedImagePath];
UIImage *image = [self loadImageFromPath:cachedFilePath];
if(image)
{
photo = image;
}
else
{
NSData *photoData = [NSData dataWithContentsOfURL:imageURL];
photo = [UIImage imageWithData:photoData];
[self storeImage:photo AtPath:cachedFilePath];
}
// Create a UIImage from the imageURL.
if (photo) {
[mainViewController performSelectorOnMainThread:#selector(imageDidLoad:)
withObject:[NSArray arrayWithObjects:photo, [NSNumber numberWithInt:photoIndex], nil]
waitUntilDone:YES];
}
} else {
// Load an image named photoIndex.jpg from our Resources.
NSString *imageName = [[NSString alloc] initWithFormat:#"place_holder_bg.png", photoIndex];
UIImage *theImage = [UIImage imageNamed:imageName];
if (theImage) {
[mainViewController performSelectorOnMainThread:#selector(imageDidLoad:)
withObject:[NSArray arrayWithObjects:theImage, [NSNumber numberWithInt:photoIndex], nil]
waitUntilDone:YES];
} else
NSLog(#"Unable to find sample image: %#", imageName);
[imageName release];
}
[pool release];
}