Convert Byte Data to image from XML Parsing - ios

I want to convert this byte data to fetch an image from it.
i have used this base64Encoding method but this does not seem to be useful.
-(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
NSString *base64StringEncoder = #"data:image/png;base64,";
base64StringEncoder = [base64StringEncoder stringByAppendingString:[[parserDataContentArray objectAtIndex:indexPath.row] exhibitorByteImageObjectClass]];
NSURL *profilePicURL = [NSURL URLWithString:base64StringEncoder];
NSData *profilePicimageData = [NSData dataWithContentsOfURL:profilePicURL];
if (profilePicimageData.length!=0) {
cell.exhibitorImage.image = [UIImage imageWithData:profilePicimageData];
}
return cell;
}
where parserDataContentArray is the mutable Array holding parsed Data.
and exhibitorByteImageObjectClass is the NSString property on which i am setting the node after checking particular tag exist.
XML Looks like
<PRODUCTION_B_IMAGE>
iVBORw0KGgoAAAANSUhEUgAAAKAAAACPCAYAAAB9NdDOAAAKQ2lDQ1BJQ0MgUHJvZmlsZQAASA2dlndUU1kTwO97L73QEkKREnoNTUoAkRJ6kV5FJSQBQgkYErBXRAVXFBVpig==
</PRODUCTION_B_IMAGE>

Please download this : NSData+Base64 files
dataWithContentsOfURL doen't actually take data from the URL but from the resource that is located at the URL. This is one of the easiest wrappers to use (decode and encode) base64 strings.
You have your NSString with base64 data in [parserDataContentArray objectAtIndex:indexPath.row] I believe. So try this :
NSData *tempData = [NSData dataFromBase64String:[parserDataContentArray objectAtIndex:indexPath.row]];
if (tempData.length!=0) {
cell.exhibitorImage.image = [UIImage tempData];
}

Related

SDWebImage is not loading images from NSDictionary

I have a UITableView and I am loading some articles from an RSS file with keys: title, url and image url. I am trying to display the image in the UITableViewCell using the SDWebImage library and when I "load" the image through the dictionary that is downloaded from the RSS the image is not loaded. The url of the image though is loaded successfully and printed exactly before the load. But when I copy the printed url and paste it in another string trying to load that url it works. Below is my code.
NSString *urlofimage = [[feeds objectAtIndex:indexPath.row] objectForKey: #"image"];
NSLog(#"%#", urlofimage);
NSString *urlofimage1 = #"https://www.radioevros.gr/wp-content/uploads/2017/05/1495542572-74c82f60669c9db27cad113d22379c72.jpg";
[cell.imageview sd_setImageWithURL:[NSURL URLWithString:urlofimage] placeholderImage:[UIImage imageNamed:#"radio.png"]
options:SDWebImageRefreshCached];
So, my code doesnt seem to be wrong since I was working with the same code before and it was working. In the code above, the urlofimage1 is actually a printed url from the urlofimage. And if I do this:
[cell.imageview sd_setImageWithURL:[NSURL URLWithString:urlofimage1] placeholderImage:[UIImage imageNamed:#"radio.png"]
options:SDWebImageRefreshCached];
is working, but if I do this is not.
[cell.imageview sd_setImageWithURL:[NSURL URLWithString:urlofimage] placeholderImage:[UIImage imageNamed:#"radio.png"]
options:SDWebImageRefreshCached];
This is loaded inside :
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
Any ideas? Thank you.
I would suspect that you have some invalid characters in your dictionary, like a space at the end or something similar what is hard to spot.
Try encoding your received string first, and than create your NSURL instance.
NSString *urlofimage = #"https://www.radioevros.gr/wp-content/uploads/2017/05/1495542572-74c82f60669c9db27cad113d22379c72.jpg ";
NSCharacterSet *set = [NSCharacterSet URLQueryAllowedCharacterSet];
NSString *endcodedString = [urlofimage stringByAddingPercentEncodingWithAllowedCharacters:set];
NSLog(#"%#", [NSURL URLWithString:endcodedString]);
EDIT:
The encoding highlighted, that there are invalid characters at the end of the URL. Lets get rid of them with the following code:
NSString * urlofimage = #"https://www.radioevros.gr/wp-content/uploads/2017/05/1495542572-74c82f60669c9db27cad113d22379c72.jpg ";
NSString *trimmedString = [urlofimage stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
NSLog(#"%#", [NSURL URLWithString:trimmedString]);

UIImage does not download URLs, even though it recognizes the correct amount it should download

I'm having a weird string / array problem. When I count the # of objects in the array (values taken using [string description], it returns two, the correct amount of objects. When I try and download the image, it the UIImage does not display anything.
Here's the log of the URLs, from the array photoArg (if you try and go them it will say they are invalid, as I changed a few lines)
(
"\n\"https://scontent-a.xx.fbcdn.net/hphotos-ash2/s720x720/196148_2542310658202194_959795763_n.jpg\"",
"\n\"https://fbcdn-sphotos-c-a.akamaihd.net/hphotos-ak-ash3/s720x720/576808_2239914766108450_770925407_n.jpg\"\n"
)
Here's my numberOfItemsInSection:
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
return [self.photoArg count];
}
My cellForItemAtIndexPath:
- (TBCollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"CollectionViewCell";
TBCollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:CellIdentifier forIndexPath:indexPath];
NSString *ImageURL = [self.photoArg objectAtIndex:indexPath.item];
NSData *imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:ImageURL]];
[cell.imageView setImage:[UIImage imageWithData:imageData]];
return cell;
}
My TBCollectionViewCell is just a standard UICollectionViewCell, except with a UIImageView inside of it.
I'm thinking that the reason the URLs will not download in the cellForItemAtIndexPath: method is that they are not formatted properly. if that is the case, than how should I properly format the array data?
That's because your strings aren't valid URL's. You'll want to strip out the \n\" and the \" in order for dataWithContentsOfURL: do receive valid data.
"\n\"https://scontent-a.xx.fbcdn.net/hphotos-ash2/s720x720/196148_2542310658202194_959795763_n.jpg\"",
It isn't really pretty, but this should work just find for you.
NSString *string = #"\n\"https://scontent-a.xx.fbcdn.net/hphotos-ash2/s720x720/196148_2542310658202194_959795763_n.jpg\"";
NSString *noNewLines = [string stringByReplacingOccurrencesOfString:#"\n" withString:#""];
NSString *noEscapes = [noNewLines stringByReplacingOccurrencesOfString:#"\"" withString:#""];
NSURL *validURL = [NSURL URLWithString:noEscapes];

Save and load image from SQL database

I'm trying to display an image from my Database.
This part works nicely.
I save the image in the DB like this :
UIImage *resizedImg = [Generics scaleImage:self.photo.image toResolution:self.photo.frame.size.width and:self.photo.frame.size.height];
NSData *imgData = UIImageJPEGRepresentation(resizedImg, 0.9);
NSString *stringDataImage = [NSString stringWithFormat:#"%#",imgData];
[dict setObject:stringDataImage for key#"image"];
// POST Request to save the image in DB ...
Now when I try to load the image and set it into my UIImageView I do this way :
NSData *data = [[[MyUser sharedUser] picture] dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:NO];
self.imageView = [[UIImageView alloc] initWithImage:[UIImage imageWithData:data]];
Or
NSData *data = [[[MyUser sharedUser] picture] dataUsingEncoding:NSUTF8StringEncoding allowLossyConversion:NO];
self.imageView.image = [UIImage withData:data];
But this doesn't work.
data is not equal to imgData, I think it's the encoding but I can find the good one.
And [UIImage withData:data] return nil;
Can you help me?
EDIT :
Convert and save
UIImage *resizedImg = [Generics scaleImage:self.photo.image toResolution:self.photo.frame.size.width and:self.photo.frame.size.height];
NSData *imgData = UIImageJPEGRepresentation(resizedImg, 0.9);
[dict setObject:[imgData base64EncodedStringWithOptions:NSDataBase64Encoding76CharacterLineLength] forKey:#"image"];
Load the image
NSData *data = [[NSData alloc] initWithBase64EncodedData:[[MyUser sharedUser] picture] options:kNilOptions];
NSLog(#"%#", data);
self.image.image = [UIImage imageWithData:data];
You are converting the NSData to a string and saving that to your database. Two issues:
Your choice of using the stringWithFormat construct is an inefficient string representation of your data (resulting in string representation that is roughly twice the size). You probably want to use base64 (for which the string representation is only 33% larger).
You are saving your string representation, but never converting it back to binary format after retrieving it. You could write a routine to do this, but it's better to just use established base64 formats.
If you want to save the image as a string in your database, you should use base64. Historically we would have directed you to one of the many third party libraries (see How do I do base64 encoding on iphone-sdk?) for converting from binary data to base64 string (and back), or, iOS 7 now has native base 64 encoding (and exposes the private iOS 4 method, in case you need to support earlier versions of iOS).
Thus to convert NSData to NSString base64 representation:
NSString *string;
if ([data respondsToSelector:#selector(base64EncodedStringWithOptions:)]) {
string = [data base64EncodedStringWithOptions:kNilOptions]; // iOS 7+
} else {
string = [data base64Encoding]; // pre iOS7
}
And to convert base64 string back to NSData:
NSData *data;
if ([NSData instancesRespondToSelector:#selector(initWithBase64EncodedString:options:)]) {
data = [[NSData alloc] initWithBase64EncodedString:string options:kNilOptions]; // iOS 7+
} else {
data = [[NSData alloc] initWithBase64Encoding:string]; // pre iOS7
}
If you really want to turn binary data into a string you should be using base64 encoding. Luckily for you, NSData now supports Base64 natively
So you could get your string from data with:
NSString *stringDataImage = [imgData base64EncodedStringWithOptions:NSDataBase64Encoding76CharacterLineLength];
And you could turn this back into NSData with:
NSData *imgData = [[NSData alloc] initWithBase64EncodedString:stringDataImage options:kNilOptions];

Why are characters and forward slashes being appended to my NSURL?

My images are not loading from their URLs. When I log the NSURL, it appears correct
my.website.com/images/image1.png
But when I set breakpoints, the NSURL shows up in the debugger console as
my.website.com/images/image1.png\x05\b
I have checked the json through my web browser, and it is perfectly valid. The string ends with the 'g' of "png".
I am using SDWebImage to asynchronously load images for my table cells. The URLs to be used for the pictures are coming from a php file that encodes the JSON.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
SpotsTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"SpotCell" forIndexPath:indexPath];
NSInteger row = indexPath.row;
if (self.spotDictionary)
{
NSDictionary* spot = (NSDictionary*)[self.spotDictionary objectForKey:[NSString stringWithFormat:#"%d", row]];
NSString* title = [spot objectForKey:#"Title"];
NSURL* imageURL = [NSURL URLWithString:(NSString*)[spot objectForKey:#"Image"]]; NSLog(#"%#", imageURL);
UIImage* placeholder = [UIImage imageNamed:#"placeholder.png"];
// See ~*~ below
NSURL* testURL = [NSURL URLWithString:#"http://www.hdwallpaperspot.com/wp-content/uploads/2013/08/Volvo-station-wagon-612pb.jpg"];
cell.nameLabel.text = title;
[cell.pictureView setImageWithURL:imageURL
placeholderImage:placeholder]; // SDWebImage category for UIImage
//breakpoint here
}
return cell;
}
~*~
To make sure SDWebImage was performing correctly, I grabbed an image off the net to temporarily test the library, and it performed wonderfully. I have checked the class of the "Image" object and it is _NSCFString. The (NSString*) cast was added in case my understanding of the interchangeability between NSCFString and NSString is flawed. No luck.
This is very embarrassing, but I'll share my mistake so no one gets misconcepted.
I forgot to specify the protocol (http://) in my Image JSON object.
I figured NSURL class would have some sort of default HTTP checking, but I realize that's not feasible, as there are other protocols that could be used with an NSURL.
Thanks #rmaddy for pointing out the debugger, uhm, bug.

iOS Split view controller - changing image in detailViewController

This is another of those "I'm sure there's an easy answer to this" questions, but I find myself baffled.
I'm using the split view controller from the template. I'm successfully passing a NSString to the _detailItem variable, but am unable to use it to create and load an image into an UIImageView (named "stripImage").
It works up until:
[self.stripImage setImage:[UIImage imageNamed: _detailItem]];
If I put a string literal into the same line of code (like #"image20.jpg"), it works fine.
- (void)configureView
{
// Update the user interface for the detail item.
if (self.detailItem) {
NSLog(#"_detailItem is still: %#",_detailItem);
// correctly reports the name of the imagefile (for example: "image20.jpg"
[self.stripImage setImage:[UIImage imageNamed: _detailItem]];
NSLog(#"The image being shown is: %#",self.stripImage.image);
//returns "The image being shown is: (null)"
}
}
Please help keep my head from exploding. Thanks in advance.
... and I've tried it this way:
(in my Master view controller):
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(#"Selected row %i",[indexPath row]);
NSString *imageName = [[stories objectAtIndex:[indexPath row]] objectForKey:#"link"];
NSLog(#"The image is: %#", imageName);
// These two work, oddly enough...
self.detailViewController.detailTitle.text = [[stories objectAtIndex:[indexPath row]]
objectForKey:#"title"];
self.detailViewController.detailSubtitle.text = [[stories objectAtIndex:[indexPath row]]
objectForKey:#"subtitle"];
// this one, not so much...
[self.detailViewController loadUpImageWith:imageName];
}
and in my Detail view controller:
- (void)loadUpImageWith:(NSString *)what
{
NSString *path = [[[NSBundle mainBundle] bundlePath] stringByAppendingPathComponent:[NSString
stringWithFormat:#"strips/%#", what]];
NSLog(#"The file's url is: %#",path);
UIImage *img = [UIImage imageWithContentsOfFile:path];
NSLog(#"The resultant image is: %#",img);
stripImage.image = img;
}
But here's the weird thing... If I replace the variable ("what" in this case) with a string literal:
NSString *path = [[[NSBundle mainBundle] bundlePath] stringByAppendingPathComponent:[NSString
stringWithFormat:#"strips/%#", #"grumbles300.jpg"]];
... it works, displaying that one image. But I want to be able to use a variable there!!
Help me Obiwan Kenobi! You're my only hope.
Embarrassing operator error.
I was adding a buncha images to the bundle, but it apparently kept track of the folder that contained them, which needed to be added to the file name. I thought UIImage imageNamed: would track down the images, as long as they were contained in the main bundle. Apparently not.
Perhaps this would be useful to someone who's experiencing the same sort of brain fart.
After resolving this, it was easy to do this:
- (void)loadupDetailTitle:(NSString *)title
subtitle:(NSString *)subtitle
image:(NSString *)imageName
{
NSString *path = [#"strips/" stringByAppendingPathComponent:imageName];
stripImage.image = [UIImage imageNamed:path];
detailTitle.text = title;
detailSubtitle.text = subtitle;
}

Resources