So I have this method to download an image from imgur.com as shown below:
- (void)getImageForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSURL *url=[NSURL URLWithString:[NSString stringWithFormat:#"i.imgur.com/%#.jpg",
[self.IDArray objectAtIndex:indexPath.row]]];
NSData * imageData = [[NSData alloc] initWithContentsOfURL:url];
self.imageTest = [UIImage imageWithData: imageData];
}
and then log the size of the data with this:
NSLog(#"%lx", (unsigned long)imageData.length);
but the size of the image in the log says
0
previously I use this asynchronous method:
- (void)getImageForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSURL *url=[NSURL URLWithString:[NSString stringWithFormat:#"i.imgur.com/%#.jpg",
[self.IDArray objectAtIndex:indexPath.row]]];
NSURLRequest *urlRequest = [NSURLRequest requestWithURL:url];
[NSURLConnection sendAsynchronousRequest:urlRequest
queue:[NSOperationQueue currentQueue]
completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
UIImage *imageMain = [UIImage imageWithData:data];
self.imageTest = [[UIImage alloc] init];
self.imageTest = [self imageWithImage:imageMain forRowAtIndexPath:indexPath];
}];
self.imageTest = [UIImage imageWithData: imageData];
}
but the log also says 0
yes the url exist. I have log it in another another method it is: i.imgur.com/EXtwoxT you can see for yourself
What did I do wrong? how do I check that the image has been downloaded properly?
EDIT :
for those who says it's the URL you can see my actual log below. you can copy&paste the URL in your browser to see if it exist (it does)
- (void)getImageForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSURL *url=[NSURL URLWithString:[NSString stringWithFormat:#"i.imgur.com/%#.jpg",
[self.IDArray objectAtIndex:indexPath.row]]];
NSLog(#"i.imgur.com/%#.jpg", [self.IDArray objectAtIndex:indexPath.row]);
//Asynchronous handler
// NSURLRequest *urlRequest = [NSURLRequest requestWithURL:url];
// [NSURLConnection sendAsynchronousRequest:urlRequest
// queue:[NSOperationQueue currentQueue]
// completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
// UIImage *imageMain = [UIImage imageWithData:data];
// self.imageTest = [[UIImage alloc] init];
// self.imageTest = [self imageWithImage:imageMain forRowAtIndexPath:indexPath];
// NSLog(#"%lx", (unsigned long)imageData.length);
// }];
//Synchronous handler
NSData * imageData = [[NSData alloc] initWithContentsOfURL:url];
self.imageTest = [UIImage imageWithData: imageData];
NSLog(#"%lx", (unsigned long)imageData.length);
}
2015-01-06 07:44:26.564 Huckleberry[12733:361944] i.imgur.com/EXtwoxT.jpg
2015-01-06 07:44:26.600 Huckleberry[12733:361944] 0
First off, your code is missing a protocol for the URL -- NSURL can handle different protocols and doesn't just default to http. Prefix http:// to your URL and see if that gets you some data.
Secondly, that URL isn't actually the URL of the image -- I believe that URL will return the whole HTML imgur page, which is most likely not what you want (since you're trying to create a UIImage with the data).
Instead, try looking into the Imgur API (https://api.imgur.com) -- there's even a link on that page to an example Obj-C library (https://github.com/geoffmacd/ImgurSession)
Related
I'm messing with some API stuff and tried the following:
#define searchWebService #"https://api.flickr.com/services/rest/?method=flickr.photos.search&api_key=b667841296224aab0371a6f4a4546662&format=json&per_page=20&page=1"
// Construct url string for search
NSString *urlString = [NSString stringWithFormat:#"%#&text=%#&nojsoncallback=1", searchWebService, keyword];
//NSString *formattedURLString = [urlString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
// Create url via formatted string
NSURL *url = [NSURL URLWithString:urlString];
// Get all data from the return of the url
NSData *photoData = [NSData dataWithContentsOfURL:url];
// Place all data into a dictionary
NSDictionary *allData = [NSJSONSerialization JSONObjectWithData:photoData options:kNilOptions error:nil];
Here is the URL that is built:
https://api.flickr.com/services/rest/?method=flickr.photos.search&api_key=b667841296224aab0371a6f4a4546662&format=json&per_page=20&page=1&text=ball&nojsoncallback=1
When I plug this URL into a web browser I get formatted JSON but when I try to plug that into:NSData *photoData = [NSData dataWithContentsOfURL:url];
I get 'data parameter is nil'.
Any ideas what I'm doing wrong?
UPDATE:
I'm now using:
// Construct url string for search
NSString *urlString = [NSString stringWithFormat:#"%#&text=%#&nojsoncallback=1", searchWebService, keyword];
NSString *formattedURLString = [urlString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSURLRequest *theRequest = [NSURLRequest requestWithURL:[NSURL URLWithString:urlString]];
[NSURLConnection sendAsynchronousRequest:theRequest queue:nil completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
NSLog(#"BOOM %s %#", __func__, response);
if(!connectionError){
}
else{
NSLog(#"%s %#", __func__, connectionError.localizedDescription);
}
but neither of the logs ever show in the console.
UPDATE: TEST PROJECT
I've created a brand new project and put the following code in the viewDidLoad method:
NSString *urlString = [NSString stringWithFormat:#"%#", webServiceGetGlobalScores];
NSString *formattedURLString = [urlString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSURLRequest *theRequest = [NSURLRequest requestWithURL:[NSURL URLWithString:formattedURLString]];
NSLog(#"theRequest: %#", theRequest);
[NSURLConnection sendAsynchronousRequest:theRequest queue:nil completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
NSLog(#"BOOM %s %#", __func__, response);
if(!connectionError){
}
else{
NSLog(#"%s %#", __func__, connectionError.localizedDescription);
}
}];
And this is the defined #define webServiceGetGlobalScores #"http://www.appguys.biz/JSON/iTapperJSON.php?key=weBeTappin&method=getGlobalScores"
But still the sendAsynchronousRequest does not log anything.
UPDATE 3
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
// Construct url string for search
NSString *urlString = [NSString stringWithFormat:#"%#", webServiceGetGlobalScores];
NSURL *url = [NSURL URLWithString:urlString];
NSURLRequest *urlRequest = [NSURLRequest requestWithURL:url];
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
NSLog(#"urlRequest: %#", urlRequest);
[NSURLConnection sendAsynchronousRequest:urlRequest queue:queue completionHandler:^(NSURLResponse *response, NSData *data, NSError *error)
{NSLog(#"BOOM %s %#", __func__, response);
NSLog(#"ERROR: %#", error);
if ([data length] > 0 && error == nil){
NSLog(#"BOOM");
}
}];
}
Try using + dataWithContentsOfURL:options:error: instead, which gives you an NSError object. Plus, notice that that the docs say:
Do not use this synchronous method to request network-based URLs. For
network-based URLs, this method can block the current thread for tens
of seconds on a slow network, resulting in a poor user experience, and
in iOS, may cause your app to be terminated.
Instead, for non-file URLs, consider using the
dataTaskWithURL:completionHandler: method of the NSSession class. See
URL Loading System Programming Guide for details.
You can use this code for downloading data,
NSString *urlString = //your whatever URL
NSURLRequest *theRequest = [NSURLRequest requestWithURL:[NSURL URLWithString:urlString]];
[NSURLConnection sendAsynchronousRequest:theRequest queue:nil completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
NSLog(#"%s %#", __func__, response);
if(!connectionError){
//Parse your JSON data
}
else{
NSLog(#"%s %#", __func__, connectionError.localizedDescription);
}
}];
Edited
Other way works!!! o_O see following
Now i surprised why following code working instead of above.
NSString *urlString = #"https://api.flickr.com/services/rest/?method=flickr.photos.search&api_key=b667841296224aab0371a6f4a4546662&format=json&per_page=20&page=1&text=ball&nojsoncallback=1";
NSString *formattedURLString = [urlString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSError *theErr;
NSData *thd = [NSData dataWithContentsOfURL:[NSURL URLWithString:formattedURLString] options:0 error:&theErr];
if(theErr){
NSLog(#"%#", theErr.localizedDescription);
}
else{
NSLog(#"%#", [[NSString alloc] initWithData:thd encoding:NSUTF8StringEncoding]);
}
3rd Way,
Newer iOS simulator version > 6.x having some issue. Reset your simulator and check it out your code.
For reference go NSURLConnection GET request returns -1005, "the network connection was lost"
So I have this method to download an image from imgur.com as shown below:
- (void)getImageForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSURL *url=[NSURL URLWithString:[NSString stringWithFormat:#"i.imgur.com/%#.jpg",
[self.IDArray objectAtIndex:indexPath.row]]];
NSData * imageData = [[NSData alloc] initWithContentsOfURL:url];
self.imageTest = [UIImage imageWithData: imageData];
}
and then log the size of the data with this:
NSLog(#"%lx", (unsigned long)imageData.length);
but the size of the image in the log says
0
previously I use this asynchronous method:
- (void)getImageForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSURL *url=[NSURL URLWithString:[NSString stringWithFormat:#"i.imgur.com/%#.jpg",
[self.IDArray objectAtIndex:indexPath.row]]];
NSURLRequest *urlRequest = [NSURLRequest requestWithURL:url];
[NSURLConnection sendAsynchronousRequest:urlRequest
queue:[NSOperationQueue currentQueue]
completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
UIImage *imageMain = [UIImage imageWithData:data];
self.imageTest = [[UIImage alloc] init];
self.imageTest = [self imageWithImage:imageMain forRowAtIndexPath:indexPath];
}];
self.imageTest = [UIImage imageWithData: imageData];
}
but the log also says 0
yes the url exist. I have log it in another another method it is: i.imgur.com/EXtwoxT
What did I do wrong? how do I check that the image has been downloaded properly?
I've been working with AFHTTPRequestOperationManager calling my service that return an image and my code looked like this:
NSString *baseURLString = #"http://get_image/";
#try {
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
[manager GET:baseURLString
parameters:nil
success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSString *imageStr = responseObject[0];
if([imageStr isKindOfClass:[NSNull class]]==NO)
{
NSData *imageData = [NSData dataWithBase64EncodedString:imageStr];
UIImage *image = [UIImage imageWithData:imageData];
self.myImage = (image==nil)? [UIImage imageNamed:#"noPhoto"]: image;
}
}
failure:^(AFHTTPRequestOperation *operation, NSError *error) {
self.myImage = [UIImage imageNamed:#"noPhoto"];
}];
}
#catch (NSException *exception) {
NSLog(#"exception %#", exception);
}
since AFHTTPRequestOperationManager is async and I need a sync call how can I complete this code to produce my image:
NSString *baseURLString = #"http://get_image/";
NSURLResponse *response;
NSError *error;
NSURLRequest *urlRequest = [NSURLRequest requestWithURL:[NSURL URLWithString:p_baseURLString] cachePolicy:NSURLRequestReturnCacheDataElseLoad timeoutInterval:30];
// Make synchronous request
NSData *imageRequest = [NSURLConnection sendSynchronousRequest:urlRequest returningResponse:&response error:&error];
???
UIImage *image = [UIImage imageWithData:imageData];
self.displayedApartment.exteriorImage = (image==nil)? [UIImage imageNamed:#"noPhoto"]: image;
This is what I've tried in place of ??? all resulted in image=nil
using the imageRequest data as is
converting the imageRequest to base64 with [[NSData alloc] initWithBase64EncodedData:imageRequest options:0];
converting it to string and back to NSData
NSData NSString *imageStr = [NSString stringWithUTF8String:[imageRequest bytes]];
NSData *imageData = [NSData dataWithBase64EncodedString:imageStr];
If I'm reading your code correctly, I think your variable names might be causing some trouble. Try replacing the following line:
NSData *imageRequest = [NSURLConnection sendSynchronousRequest:urlRequest returningResponse:&response error:&error];
with
NSData *imageData = [NSURLConnection sendSynchronousRequest:urlRequest returningResponse:&response error:&error];
and then see what UIImage *image = [UIImage imageWithData:imageData]; gives you. Unless there has been an error in the request, I can't see a reason why image wouldn't be properly instantiated unless it didn't represent an image object.
Why not just display the image using the AFNetworking function setImageWithURL, it takes the URL of an image and sets the UIImageView to that image. Its a much simpler way of doing things if you only need to display it.
It looks something like this:
[imageView setImageWithURL:[NSURL URLWithString:p_baseURLString]];
In the header file you'll have something like this:
#property (weak, nonatomic) IBOutlet UIImageView *imageView;
Its much faster as well.
I'm writing an application in Objective C and Cocoa for Mac OS X that loads GIFs from an external source and displays them on screen. The user searches for a term, GIFs are downloaded and placed into NSImageViews, and then those views are displayed in a scroll view.
Earlier, the GIFs were animated as expected. I then tried to use an NSThread to do the loading of the GIFs and adding to the scroll view separate from the main thread. Here is the method that is called in the thread:
- (void)threading:(id)obj
{
NSURL *url = [NSURL URLWithString: #"URL HERE"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
[request setURL:url];
[request setHTTPMethod:#"GET"];
[request setValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
NSError *error;
NSURLResponse *response;
NSDictionary *data = [NSJSONSerialization JSONObjectWithData:[NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error] options:NSJSONReadingMutableLeaves error:nil];
NSArray *gifs = [data objectForKey:#"data"];
for (int i = 0; i < 1; i++) { // try to load 1 gif
NSString *currentGifURL = #"whatever";
NSImageView *imgView = [[NSImageView alloc] initWithFrame:CGRectMake(10, 1820-100*i, 150, 120)];
// I tried using these 2 lines, still didn't work
//[imgView setAnimates:YES]; [imgView setImageScaling:NSScaleNone];
NSURL *imageURL = [NSURL URLWithString:currentGifURL];
NSData *imageData = [NSData dataWithContentsOfURL:imageURL];
NSImage *image = [[NSImage alloc] initWithData:imageData];
imgView.image = image;
[_scrollView.documentView addSubview:imgView];
}
[_progressIndicator stopAnimation:self];
}
I later call
[NSThread detachNewThreadSelector:#selector(threading:) toTarget:self withObject:nil];
To create the thread. The images appear on screen, but only the first frame is displayed—they're not animated. Literally replacing the thread initialization with the code from inside the thread renders the same view, except the GIFs are animated. Is there something about threads that would prevent the GIFs from animating?
Thanks!
NSImageView is not threadsafe. use - (void)performSelectorOnMainThread:(SEL)aSelector withObject:(id)arg waitUntilDone:(BOOL)wait
- (void)threading:(id)obj
{
NSURL *url = [NSURL URLWithString: #"URL HERE"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
[request setURL:url];
[request setHTTPMethod:#"GET"];
[request setValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
NSError *error;
NSURLResponse *response;
NSDictionary *data = [NSJSONSerialization JSONObjectWithData:[NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error] options:NSJSONReadingMutableLeaves error:nil];
NSArray *gifs = [data objectForKey:#"data"];
for (int i = 0; i < 1; i++) { // try to load 1 gif
NSString *currentGifURL = #"whatever";
// I tried using these 2 lines, still didn't work
//[imgView setAnimates:YES]; [imgView setImageScaling:NSScaleNone];
NSURL *imageURL = [NSURL URLWithString:currentGifURL];
NSData *imageData = [NSData dataWithContentsOfURL:imageURL];
NSImage *image = [[NSImage alloc] initWithData:imageData];
[self performSelectorOnMainThread:#selector(LoadImageView:) withObject:image waitUntilDone:NO];
}
[_progressIndicator stopAnimation:self];
}
-(void)LoadImageView : (NSImage *)image
{
NSImageView *imgView = [[NSImageView alloc] initWithFrame:CGRectMake(10, 1820-100*i, 150, 120)];
imgView.image = image;
[_scrollView.documentView addSubview:imgView];
}
How can i add local image.png to cell if image not load from url?
- (UITableViewCell*)tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *CellIdentifier = #"Cell";
DetailCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
NSURL* url = [NSURL URLWithString:[arrayOfImages objectAtIndex:indexPath.row]];
NSURLRequest* request = [NSURLRequest requestWithURL:url];
[NSURLConnection sendAsynchronousRequest:request
queue:[NSOperationQueue mainQueue]
completionHandler:^(NSURLResponse * response,
NSData * imagedata,
NSError * error) {
if (!error){
UIImage* image = [[UIImage alloc] initWithData:imagedata];
cell.flowerImage.image = image;
}
}];
return cell;
}
arrayOfImages - array of url strings that i've parsed from json.
You can check the image against nil to verify the image url.
[NSURLConnection sendAsynchronousRequest:request
queue:[NSOperationQueue mainQueue]
completionHandler:^(NSURLResponse * response,
NSData * imagedata,
NSError * error) {
if (!error){
UIImage* image = [[UIImage alloc] initWithData:imagedata];
if(!image) {
cell.flowerImage.image = [UIImage imageNamed:#"localImage"]; //local bundle image.
} else
cell.flowerImage.image = image;
} else {
cell.flowerImage.image = [UIImage imageNamed:#"localImage"];//local bundle image.
}
}];