I have following code for loading image from url in xml parsing endElement method :
food.image=strVal;
NSData *data=[[NSData alloc]initWithContentsOfURL:[NSURL URLWithString:strVal]];
UIImage *image=[[UIImage alloc]initWithData:data];
food.myImage=image;
Although I am using this loaded images at the end of application,my application has to wait till all image get loaded. I supposed to use cache here but i am confused how to use the cache in this application. Is there any other way?
Try this code this will not create load on your main thread:-
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0);
dispatch_async(queue, ^{
NSData *data=[[NSData alloc]initWithContentsOfURL:[NSURL URLWithString:yourURL]];
UIImage *image=[[UIImage alloc]initWithData:data];
dispatch_sync(dispatch_get_main_queue(), ^{
[yourImageView setImage:image];
});
});
Related
I am using this code for displaying the image from URL to UIImageview
UIImageView *myview=[[UIImageView alloc]init];
myview.frame = CGRectMake(50, 50, 320, 480);
NSURL *imgURL=[[NSURL alloc]initWithString:#"http://soccerlens.com/files/2011/03/chelsea-1112-home.png"];
NSData *imgdata=[[NSData alloc]initWithContentsOfURL:imgURL];
UIImage *image=[[UIImage alloc]initWithData:imgdata];
myview.image=image;
[self.view addSubview:myview];
But the problem is that its taking too long time to display the image in imageview.
Please help me...
Is there any method to fast the process...
Instead of dispatch_async, Use SDWebImage for caching the images.
This is best I have seen...
The problem of dispatch_async is that if you lost focus from image, it will load again. However SDWebImage, Caches the image and it wont reload again.
The answers given to me on my own question Understanding the behaviour of [NSData dataWithContentsOfURL:URL] inside the GCD block does makes sense.So be sure that if you use [NSData dataWithContentsOfURL:URL] inside the GCD(as many developers do these days) is not a great idea to download the files/images.So i am leaning towards the below approach(you can either use NSOperationQueue).
Load your images using [NSURLConnection sendAsynchronousRequest:queue:completionHandler: then use NSCache to prevent downloading the same image again and again.
As suggested by many developers go for SDWebimage and it does include the above strategy to download the images files .You can load as many images you want and the same URL won't be downloaded several times as per the author of the code
EDIT:
Example on [NSURLConnection sendAsynchronousRequest:queue:completionHandler:
NSURL *url = [NSURL URLWithString:#"your_URL"];
NSURLRequest *myUrlRequest = [NSURLRequest requestWithURL:url];
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
[NSURLConnection sendAsynchronousRequest:myUrlRequest queue:queue completionHandler:^(NSURLResponse *response, NSData *data, NSError *error)
{
if ([data length] > 0 && error == nil)
//doSomething With The data
else if (error != nil && error.code == ERROR_CODE_TIMEOUT)
//time out error
else if (error != nil)
//download error
}];
Use Dispatch queue to load image from URL.
dispatch_async(dispatch_get_main_queue(), ^{
});
Or add a placeholder image till your image gets load from URL.
Once in a while when loading image like this:
dispatch_async(dispatch_get_global_queue(0, 0), ^
{
NSData *data = [[NSData alloc] initWithContentsOfURL:someImgUrl.jpg];
if (data == nil)
{
NSLog( #"data is nil with img url:%#" ,imgUrl);
return;
}
dispatch_async(dispatch_get_main_queue(), ^
{
img.image = [UIImage imageWithData:data];
});
});
my data is nil.
I used fiddler to sniff that, and saw that everytime it happened no request is shown in fiddler!
The only times it NEVER happens are
When I don't use SignalR client in my app.
Downloading the image synchronically:
NSData * imageData = [[NSData alloc] initWithContentsOfURL:someImgUrl.jpg ];
img.image = [UIImage imageWithData: imageData];
The way I initialize SignalR is this:
NSString *listenurl = [NSString stringWithFormat:#"%#/%#", SERVICE_URL, #"/echo"];
mConnection = [SRConnection connectionWithURL:listenurl];
[mConnection setDelegate:self];
[mConnection start:[[SRLongPollingTransport alloc] init]];
Anyone else use signalR client in ios and exprience this behaviour?
It seems that problem only happens when SignalR listens with the same domain name to the server where you try to load images from.
So the (lame) solution so far that I found is buy a second domain and listen to that one.
Don't know why it happens though...
I have the following code and it does not work. Is there something working behind it.
[operationQueue addOperationWithBlock:^{
imageData = [NSData dataWithContentsOfURL:imageURL];
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
UIImage *image = nil;
if(imageData){
UIImage *image = [UIImage imageWithData:imageData];
cell.imageView.image = image;
}
}];
}];
Even I create a subclass of NSOperation and then alloc init it, it does not work the way I think it to. I always have to invoke start to the NSOperation subclass to run but I suppose sending start message to NSOperation runs it in the main thread rather than running in the background thread.
I want to add an alternative solution using GCD :
backgroundQueue = dispatch_queue_create("com.razeware.imagegrabber.bgqueue", NULL);
dispatch_async(backgroundQueue, ^{
/* put the codes which makes UI unresponsive like reading from network*/
imageData = [NSData dataWithContentsOfURL:imageURL];
..... ;
dispatch_async(dispatch_get_main_queue(),^{
/* do the UI related work on main thread */
UIImage *image = [UIImage imageWithData:imageData];
cell.imageView.image = image;
......; });
});
dispatch_release(backgroundQueue);
Let me know whether this one helped you ;)
Reference
I have an app which requires downloading image asynchronously in base64 encoded string(server is returning the image in Base64 encoded format),I am using the AsyncImage view,but it seems that AsyncImageView library only accepts the url to download asynchronously.
Anyone having any idea how to go about this,if i will download all images at once an then i can pass that encoded string to
[self.imageView loadImageFromURL:[NSURL URLWithString:[EncodedString]]];
but this dosesn't make sense as all the image will be downloaded still in UIThread.
Please help.
Thanks..!!
You should look into Cocoa Helpers - it has SimpleHTTPLoader for async loading and ImageViewCached which does exactly what you need. You create not imageView, but ImageViewCached and just set URL for it. It does the rest for you.
But if you want to do it your way:
I don't guarantee that the code below is correct, but the whole idea is (i took it from working code and rewrote it to correspond your task. I used cocoa helpers for base64 decoding. You may use your own methods.
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul);
dispatch_async(queue, ^{
NSString *query = [NSString stringWithFormat:#"site.example/image.jpg"];
NSString *data = [[[NSString alloc] initWithContentsOfURL:[NSURL URLWithString:query] encoding:NSUTF8StringEncoding error:nil] autorelease];
theImage = [UIImage imageWithData:(rfc::from_base64(data))]
dispatch_sync(dispatch_get_main_queue(), ^{
self.imageview.image = theImage;}
});
});
P.S. for base64-encoded images you'd have to modify ImageViewCached for it to load and decode images.
I kinda want a CMS feature in my iPhone app. I want to load text and an image from the internet and apply them to a UIImageView, UIButton, and UITextView. However I am getting an error. Currently the code works fine with the loading of the image. I had the text code in the viewDidAppear code however the user wasn't able to interact with the screen until the text loaded so I moved it to the loadInfo method with the Image, however it didn't like this and gave me a Bad Access error. And printed the following in the console:
2011-05-08 21:26:13.770 Fraction Calculator Lite[2184:6b03] bool _WebTryThreadLock(bool), 0x62338d0: Tried to obtain the web lock from a thread other than the main thread or the web thread. This may be a result of calling to UIKit from a secondary thread. Crashing now...
Anyone know what might be my issue?
Thanks!
This is my code:
- (void)viewDidAppear:(BOOL)animated {
[self performSelectorInBackground:#selector(loadInfo) withObject:nil];
}
-(void) loadInfo {
NSAutoreleasePool *arPool = [[NSAutoreleasePool alloc] init];
NSError *error;
NSString *internetTest = [NSString stringWithContentsOfURL:[NSURL URLWithString:#"http://lindahlstudios.com/cms/internettest.txt"] encoding:NSUTF8StringEncoding error:&error];
if ([internetTest isEqualToString: #"Internet Connection Complete"]) {
UIImage *img1 = [[UIImage alloc] initWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:#"http://lindahlstudios.com/cms/adimage.png"]]];
[image1 setImage:img1];
[img1 release];
NSString *string = [NSString stringWithContentsOfURL:[NSURL URLWithString:#"http://lindahlstudios.com/cms/adtext.txt"] encoding:NSUTF8StringEncoding error:&error];
NSString *string2 = [NSString stringWithContentsOfURL:[NSURL URLWithString:#"http://lindahlstudios.com/cms/price.txt"] encoding:NSUTF8StringEncoding error:&error];
[adText setText:string]; //Thread 8: Program received signal: "EXC_BAD_ACCESS"
[price setTitle:string2 forState:UIControlStateNormal];
}
[arPool release];
}
You cannot invoke UIKit operations on background thread. I would suggest you get the data on background thread and then update it in the main thread.
Use blocks for ease in coding,
Once you retrieve NSData in background thread, simple assign it to the UIImage etc in the main thread via blocks,
//get NSData from URL
dispatch_async(dispatch_get_main_queue(), ^{
//set assignments for UIImage here.
});