Store Image from JSON into Custom Class iOS - ios

I'm building an RSS reader app, following tutorials and what not.
So far I've built a custom class named blogPost, which stores the post name and post author, with a designated initializer based on the name.
I'm attempting to pull the thumbnail image of the post in my for loop, and display it in the cell where I'm currently showing the title and author attributes.
I successfully pulled the image URL and parsed it from JSON but can't seem to store the image in a UIImage.
//Custom header for BlogPost
#interface BlogPost : NSObject
#property (nonatomic, strong) NSString *title;
#property (nonatomic, strong) NSString *author;
#property (nonatomic, strong) UIImage *image;
// Designated Initializer
- (id) initWithTitle:(NSString *)title;
+ (id) blogPostWithTitle:(NSString *)tile;
#end
And here's the tableViewController
[super viewDidLoad];
NSURL *blogUrl = [NSURL URLWithString:#"http://www.wheninmanila.com/api/get_recent_summary/"];
NSData *jsonData = [NSData dataWithContentsOfURL:blogUrl];
NSError *error = nil;
NSDictionary *dataDictionary = [NSJSONSerialization JSONObjectWithData:jsonData options:0 error:&error];
self.blogPosts = [NSMutableArray array];
NSArray *blogPostsArray = [dataDictionary objectForKey:#"posts"];
for (NSDictionary *bpDictionary in blogPostsArray) {
BlogPost *blogPost = [BlogPost blogPostWithTitle:[bpDictionary objectForKey:#"title"]];
blogPost.author = [bpDictionary objectForKey:#"author"];
NSURL *thumbURL = [bpDictionary objectForKey:#"thumbnail"];
NSData *thumbData = [NSData dataWithContentsOfURL:thumbURL];
blogPost.image = [[UIImage alloc] initWithData:thumbData];
[self.blogPosts addObject:blogPost];
}

Change this line:
NSURL *thumbURL = [bpDictionary objectForKey:#"thumbnail"];
To this:
NSURL *thumbURL = [NSURL urlWithString:[bpDictionary objectForKey:#"thumbnail"]];
The values in your dictionary will be NSStrings, which are not the same thing as NSURL's.

You are using NSURL instead of a NSString and NSString does not respond to selector isFileURL (thats why you get the exception). I assume your thumbnail is a string so you should get it as NSString and than convert it to NSURL as follows :
NSString *thumbAsString = [bpDictionary objectForKey:#"thumbnail"];
NSURL *thumbURL = [NSURL URLWithString:thumbAsString];

Related

Store the image into cache for avoiding frequent loading from url in tableview

NSURL *url =[NSURL URLWithString:
#"http://api.kivaws.org/v1/loans/search.json?status=fundraising"];
Serialisation part is done below
(void)connectionDidFinishLoading{
NSDictionary *allDict = [NSJSONSerialization JSONObjectWithData:webData options:0 error:nil];
NSArray *loans = [allDict objectForKey:#"loans"];
countryArray = [[NSMutableArray alloc] init];
for (NSDictionary *diction in loans) {
Country *countryObj = [[Country alloc]init];
NSString *sector = [diction objectForKey:#"sector"];
countryObj.sector = sector;
NSDictionary *imageID = [diction objectForKey:#"image"];
NSString *img = [imageID objectForKey:#"id"];
countryObj.idValue=img;
NSString *activity = [diction objectForKey:#"activity"];
countryObj.activity = activity;
NSString *name = [diction objectForKey:#"name"];
countryObj.name = name;
NSDictionary *con = [diction objectForKey:#"location"];
NSString *world = [con objectForKey:#"country"];
countryObj.country= world;
NSString *towname = [con objectForKey:#"town"];
countryObj.down=towname;
[countryArray addObject:countryObj];
}
}
This contains both images and data. I need to store the image into cache.
Please use SDWebImage it contains everything you need. I am using this library for 2 years already.
Follow that tutorial which contains how to cache images inside a UIImageView with a simple one line of code and also a class that prefetches all the images in background, just create an NSArray with all the images you want to prefetch.
Hope that helps!

Passing data through modal segue: [__NSArrayI length]: unrecognized selector sent to instance

I'm trying to pass dogData from my ViewController to PetViewController (through a modal segue). That said, for some reason when I attempt to pass the dogData (NSMutableArray), I get this error:
[__NSArrayI length]: unrecognized selector sent to instance
Any idea why this might be? See code below (hope this is enough info, tried to trim it).
ViewController.h
#property (strong, nonatomic) NSMutableArray *dogData;
ViewController.m
NSMutableDictionary *viewParamsDogs = [NSMutableDictionary new];
[viewParamsDogs setValue:#"mydogs" forKey:#"view_name"];
[DIOSView viewGet:viewParamsDogs success:^(AFHTTPRequestOperation *operation, id responseObject) {
self.dogData = [responseObject mutableCopy];
NSLog(#"This is the dog photo data %#", self.dogData);
[operation responseString];
NSDictionary *dic = [responseObject valueForKey: #"field_pet_photo_path"];
NSArray *arr = [dic valueForKey: #"und"];
NSDictionary *dic2= [arr objectAtIndex : 0];
NSString *path = [NSString stringWithFormat:#"%#", [dic2 valueForKey: #"safe_value"]];
NSMutableCharacterSet *characterSetToTrim = [NSMutableCharacterSet characterSetWithCharactersInString:#"()\""];
[characterSetToTrim formUnionWithCharacterSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
path = [path stringByTrimmingCharactersInSet:characterSetToTrim];
if([path length]>0) {
NSURL *url = [NSURL URLWithString:path];
NSData *data = [NSData dataWithContentsOfURL:url];
UIImage *image = [UIImage imageWithData:data];
self.dogimageView.image = image;
} else {
NSString *ImageURL = #"http://url.ca/paw.png";
NSData *imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:ImageURL]];
self.dogimageView.image = [UIImage imageWithData:imageData];
}
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Failure: %#", [error localizedDescription]);
}];
- (IBAction)openPetProfile:(id)sender {
PetViewController *petProfile = [[PetViewController alloc] init];
petProfile.petSubDetail = self.dogData;
[self presentViewController:petProfile animated:YES completion:nil];
}
PetViewController.h
#property (nonatomic, copy) NSMutableArray *petSubDetail;
#property (weak, nonatomic) IBOutlet UILabel *petName;
PetViewController.m
- (void)viewDidLoad {
[super viewDidLoad];
self.petName.text = [self.petSubDetail valueForKey:#"petname"];
}
Data output:
"field_petname" = {
und = (
{
format = "<null>";
"safe_value" = Pebbles;
value = Pebbles;
}
);
};
Your code should be like,
NSdictionary *dict = [self.petSubDetail objectForKey:#"field_petname"];
NSArray *arr = [dict objectForKey:#"und"];
NSdictionary *dict1 = [arr objectAtIndex : 0];
self.petName.text = [dict1 valueForKey:#"value"];
where you need " in key use \"
hope this will help :)

JSON Image View Showing Object at same Index

I have a UIImageView in side a UIView, which displays an object #"photos" in a JSON Array as such: http://topmobiletrends.com/wp-content/uploads/2013/10/screen568x568-14.jpeg
My NSLog tells me that all the objects have been parsed correctly. But the UIImageViews inside UIViews show the same image, I believe it is the first object [0]. I need to have the views show each image for all of the objects for the #"photos" key.
Here is my code for my ViewController.m:
. . .
#interface ViewController ()
{
NSInteger index;
}
//#property (nonatomic, weak)NSURL *imageURL;
#end
#implementation ViewController
#synthesize menuButton;
#synthesize myImage;
#synthesize priceLabel;
-(void)viewDidLoad{
[super viewDidLoad];
NSURL *bburl = [NSURL URLWithString:#"http://www.suchandsuch.com/api/sites"];
NSData *jsonData = [NSData dataWithContentsOfURL:bburl];
NSURLSession *session = [NSURLSession sharedSession];
NSURLRequest *request = [[NSURLRequest alloc]initWithURL:bburl];
NSURLSessionDownloadTask *task = [session downloadTaskWithURL:bburl completionHandler:^(NSURL *location, NSURLResponse *response, NSError *error){
NSLog(#"%#", response);
NSData *data = [[NSData alloc]initWithContentsOfURL:location];
NSDictionary *dataDictionary = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error];
NSString *imageURLString = [[[dataDictionary objectForKey:#"sites"] objectAtIndex:index] objectForKey:#"photo"];
NSURL *imageURL = [NSURL URLWithString:[imageURLString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
NSLog(#"sites : %#", imageURLString);
NSArray *sitesArray = [dataDictionary objectForKey:#"sites"];
NSMutableArray *photos = [[NSMutableArray alloc]initWithArray:sitesArray];
for (NSDictionary *item in sitesArray) {
MyObject *current = [MyObject alloc];
current.name = [item objectForKey:#"name"];
current.url = [item objectForKey:#"url"];
current.price = [item objectForKey:#"price"];
current.photo = [item objectForKey:#"photo"];
[photos addObject:current];
NSLog(#"%#", current.photo);
}
for (MyObject *photo in photos)
{
dispatch_async(dispatch_get_main_queue(),^{
UIView *dView = [[UIView alloc]initWithFrame:CGRectMake(30,30,258,229)];
UIImage *image = [UIImage imageWithData:data];
UIImageView *imageView = [[UIImageView alloc] initWithImage:image];
imageView.image = [UIImage imageWithData:[NSData dataWithContentsOfURL:imageURL]];
imageView.frame = CGRectMake(30, 30, 258, 229);
//Get image from url
[self.imageView setImageWithURL:imageURL];
//[self.myImage addSubview:imageView];
[dView addSubview:imageView];
[self.view addSubview:dView];
// priceLabel.text = [[[dataDictionary objectForKey:#"sites"] objectAtIndex:index] objectForKey:#"price"];
});
}
}];
[task resume];
}
There are a few issues with the code.
You are adding both NSURL and name string to the photos array but when reading you are expecting all of them to be photos.
I would recommend create a data structure called Photo which contains
#interface PhotoClass :NSObject
#property (nonatomic, strong) NSString *name;
#property (nonatomic, strong) NSURL *url;
#property (nonatomic, strong) NSString *price
#property (nonatomic, strong) NSString *photo;
#end
That way you can do the following when parsing your data.
PhotoClass *current = [PhotoClass alloc];
current.name = [item objectForKey:#"name"];
current.url = [item objectForKey:#"url"];
current.price = [item objectForKey:#"price"];
current.photo = [item objectForKey:#"photo"];
// Add to array
[photos addObject:current];
And then when you are ready to display use the url from each PhotoClass object.
The next issue in your code is with the image view setup. First of all You will need to create as many ImageViews. each one needs to be offset to the other can be visible behind that image. Plus the image view seems to be getting set in many diff ways. Is that just a typo? :
for (PhotoClass *photo in photos)
{
dispatch_async(dispatch_get_main_queue(),^{
UIView *dView = [[UIView alloc]initWithFrame:CGRectMake(50,50,258,229)];
// The frame of each of the frames needs to be offset a little ..
// so you need to figure out how to calculate that for each image.
UIImageView *imageView = [[UIImageView alloc] initWithFrame:frame];
imageView.image = [UIImage imageWithData:[NSData dataWithContentsOfURL:photo.url]];
[dView addSubview:imageView];
[self.view addSubview:dView];
....
}];
}
At the end of the loop you should have as many image views in view as objects in photos.
Disclaimer - code not compiled and typed directly into stackoverflow browser

how to pass a NSString from NSObject to UIViewcontrller?

I understand this is a very basic question, but as a beginner who already google a bunch of resources I just couldn't make it. I would like to pass a NSString from a NSObject to UIViewController. I know if want to pass a value to another class I need to make it public. I have a method in DataConnection.m
- (void)jsonParse{
NSString* path = #"http://phdprototype.tk/getResultData.php";
NSURL* url = [NSURL URLWithString:path];
NSString* jsonString = [[NSString alloc]initWithContentsOfURL:url encoding:NSUTF8StringEncoding error:nil];
NSData* jsonData = [jsonString dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary* dic = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingMutableLeaves error:nil];
NSDictionary* resultDic = [dic objectForKey:#"maxid"];
NSString* recData = [resultDic objectForKey:#"recommendData"];
NSString* rData = [resultDic objectForKey:#"room"];
NSString* lData = [resultDic objectForKey:#"level"];
NSLog(#"recommendData = %#, room = %#, level = %#",recData,rData,lData);
self->_room = rData;
self->_level = lData;
self->_recommendID = recData;
}
what I want to do is to pass the value of recData to another UIViewController. So I have made a code in 'h:
#property (nonatomic) NSString *recommendID;
in my UIViewController I have this code:
[self.delegate NextScreen: self ndx: recData];
I would like pass value to reData. Anyone tell me how to do that?? sorry for my programme knowledge!
~~~ update~~~
I have put the codes like this:
DataConnection *data = [[DataConnection alloc] init];
[data jsonParse];
[self.delegate NextScreen: self ndx: [data.recommendID]];
but i got expected identifier??
"mmmmmm~i have try some code like DataConnection *data =
[DataConnection jsonParse]; but i got error of no known class method
for selector of "jsonParse" ps: i have put
- (void)jsonParse; in DataConnection.h –"
Above mentioned way is wrong way of calling a method. you can call it this way:
DataConnection *data = [[DataConnection alloc] init];
[data jsonParse];
But, as per your question,
"what I want to do is to pass the value of recData to another
UIViewController. So I have made a code in 'h:"
Change the return type of jsonParse to NSDictionary and return the resultDic which you wish to transfer.
- (NSDictionary *)jsonParse{
NSString* path = #"http://phdprototype.tk/getResultData.php";
NSURL* url = [NSURL URLWithString:path];
NSString* jsonString = [[NSString alloc]initWithContentsOfURL:url encoding:NSUTF8StringEncoding error:nil];
NSData* jsonData = [jsonString dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary* dic = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingMutableLeaves error:nil];
NSDictionary* resultDic = [dic objectForKey:#"maxid"];
/* NSString* recData = [resultDic objectForKey:#"recommendData"];
NSString* rData = [resultDic objectForKey:#"room"];
NSString* lData = [resultDic objectForKey:#"level"];
NSLog(#"recommendData = %#, room = %#, level = %#",recData,rData,lData);
self->_room = rData;
self->_level = lData;
self->_recommendID = recData;*/
return resultDic;
}
In your view controller,
#property (nonatomic,retain) NSDictionary *resultDict;
#synthesize resultDict;
DataConnection *data = [[DataConnection alloc] init];
self.resultDict = (NSDictionary *)[data jsonParse];
_recommendID = [resultDic objectForKey:#"recommendData"];
_room = [resultDic objectForKey:#"room"];
_level = [resultDic objectForKey:#"level"];
now recommendID will have the recData value.
have you included
#synthesize recommendID;
in the DataConnection.m file?
I did consider adding this as a comment, but i dont have enough reputation for commenting.

Converting UIImage to NSData and NSData to NSString for posting images to a server

I have two UIImageViews. I want to post two images to server through the script. Before that I have to convert these images to data and data to string but I don't know how to convert the images from UIImageView to NSData and NSData to NSString.I have referred all the codes but it does not work. I would also like to know as to where should I declare the conversion coding (image to data and data to image) in my code?
This is what I have implemented
.h part
#import <UIKit/UIKit.h>
#import "GlobalAccessClass.h"
#import <QuartzCore/QuartzCore.h>
#interface AskQuestionHome : UIViewController<UITextViewDelegate,UITextFieldDelegate,UIImagePickerControllerDelegate,UIActionSheetDelegate>
{
}
#property (strong, nonatomic) IBOutlet UIImageView *imgSecondImg;
#property (strong, nonatomic) IBOutlet UIImageView *imgFirstImg;
#property (strong, nonatomic) IBOutlet UITextView *txtviewAsk;
-(IBAction)postbutton:(id)sender;
#property (nonatomic,retain) NSString *datestr;
#property(nonatomic,retain) NSData *imageData;
#property(nonatomic,retain) NSString *postLength;
#end
.m part
-(void)post
{
NSMutableURLRequest *mutableurlrequest = [[NSMutableURLRequest alloc]initWithURL:[NSURL URLWithString:#"http://www.alvinchuastudios.com/aNSWERED/insert_question.php"]];
// create the Method "POST" For POSTING the QUESTIION with IMAGES
[mutableurlrequest setHTTPMethod:#"POST"];
NSLog(#"the email is:%#",manage.transformEmail);
NSLog(#"the cat is:%#",manage.transformCategories);
NSLog(#"the text is:%#",textviewText.text);
// NSLog(#"the firstimage is:%ld",(long)imgFirstImg.tag);
// NSLog(#"the secondimage is:%ld",(long)imgSecondImg.tag);
// NSlog(#"the status is:%d",1);
NSLog(#"the user is:%#",manage.transformName);
NSLog(#"the user registered is:%#",datestr);
//passing the string to the server
NSString *qususerUpdate =[NSString stringWithFormat:#"email_id=%#&cat=%#&q_text=%#&q_image1=%ld&q_image2=%ld&q_status=1&last_upd_by=%#&last_upd_timestamp=%#",manage.transformEmail,manage.transformCategories,textviewText.text,(long)imgFirstImg.tag,(long)imgSecondImg.tag,manage.transformName,datestr,Nil];
//check the value that what we passed
NSLog(#"the data Details is =%#", qususerUpdate);
//Convert the String to Data
NSData *data1 =[qususerUpdate dataUsingEncoding:NSUTF8StringEncoding];
//Apply the data to the body
[mutableurlrequest setHTTPBody:data1];
//Create the response and Error
NSError *err;
NSURLResponse *response;
NSData *responseData =[NSURLConnection sendSynchronousRequest:mutableurlrequest returningResponse:&response error:&err];
NSString *resStr =[[NSString alloc]initWithData:responseData encoding:NSASCIIStringEncoding];
//This is for Response
NSLog(#"got response==%#", resStr); }
I think Ashu's answer will return a null. try this
NSData *dataImage = [[NSData alloc] init];
dataImage = UIImagePNGRepresentation(image);
NSString *stringImage = [dataImage base64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength];
// From image to data
NSData *imgData = [NSData dataWithData:UIImagePNGRepresentation(yourImage)];
// From data to string
NSString *string = [[NSString alloc] initWithData:imgData encoding:NSUTF8StringEncoding];
After Long time I post my answer here.
Option 1 : Image to server and Image from Server
When we send image to server(UIImage-NSData-NSString), we need to use below coding
NSData *postData = UIImageJPEGRepresentation(myImage, 1.0);
NSString *strEncoded = [postData base64EncodedStringWithOptions:0];
When we get the image from server(NSString-NSData-UIImage),we need to use below coding
NSData *getData = [[NSData alloc] initWithBase64EncodedString:strEncodedFromServer options:0];
UIImage *image = [UIImage imageWithData:getData];
Option 2 : Simple String Encode,Decode Conversion
NSString *strName = #"iOS";
NSData *dataEncoded = [strName dataUsingEncoding:NSUTF8StringEncoding];
NSString *base64EncodedString = [dataEncoded base64EncodedStringWithOptions:0];
NSLog(#"The Encoded String is - %#", base64EncodedString);
NSData *dataDecoded = [[NSData alloc] initWithBase64EncodedString:base64EncodedString options:0];
NSString *strDecoded = [[NSString alloc] initWithData:dataDecoded encoding:NSUTF8StringEncoding];
NSLog(#"The DeCoded String is - %#", strDecoded);
Output Screenshot is
Option 3 : When we need to encode and decode the dictionary
NSDictionary *dictEncoded = #{
#"OS":#"iOS",
#"Mobile":#"iPhone",
#"Version":#"iOS10"
};
NSData *dataDictEncode = [NSJSONSerialization dataWithJSONObject:dictEncoded options:(NSJSONWritingOptions) 0 error:nil];
NSString *strBase64Encode = [dataDictEncode base64EncodedStringWithOptions:0];
NSLog(#"The encoded dictionary is - %#", strBase64Encode);
NSData *dataDictDecode = [[NSData alloc] initWithBase64EncodedString:strBase64Encode options:0];
NSDictionary *dictDecoded = [NSJSONSerialization JSONObjectWithData:dataDictDecode options:NSJSONReadingMutableContainers error:nil];
NSLog(#"The decoded dictionary is - %#", dictDecoded);
Output result is
the answer is right ,and converting NSString to Data to Uiimage in ios is below:
UIImage* image=nil;
NSString* path =[NSString stringWithFormat: #"%#",#"http://wx.qlogo.cn/mmopen/q9UTH59ty0K1PRvIQkyydYMia4xN3gib2m2FGh0tiaMZrPS9t4yPJFKedOt5gDFUvM6GusdNGWOJVEqGcSsZjdQGKYm9gr60hibd/0"];
NSURL* url = [NSURL URLWithString:[path stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];//网络图片url
NSData* data = [NSData dataWithContentsOfURL:url];//获取网咯图片数据
if(data!=nil)
{
image = [[UIImage alloc] initWithData:data];//根据图片数据流构造image
}
NSData *dataImage = [[NSData alloc] init];
dataImage = UIImagePNGRepresentation(image);
NSString *stringImage = [dataImage base64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength];
imgstr = stringImage;
NSData *data = [[NSData alloc] initWithBase64EncodedString:imgstr options:NSDataBase64DecodingIgnoreUnknownCharacters];
UIImageView *img1 = [[UIImageView alloc] initWithFrame:CGRectMake(0, 300, 200, 200)];
img1.image =[[UIImage alloc] initWithData:data];//根据图片数据流构造image
[self.view addSubview:img1];
You can use the following library for pre- ios 7 :
https://github.com/l4u/NSData-Base64/blob/master/NSData%2BBase64.h
(or)
If your app is for ios 7 and above , apple has added the category NSData + Base64 which is inbuilt in ios 7 SDK
For Base64 encoding with swift 3
func createImageString(image: UIImage) -> String? {
if let dataImage = UIImagePNGRepresentation(image) {
return dataImage.base64EncodedString(options: .lineLength64Characters)
}
return nil
}

Resources