Parsing JSON url pictures to iOS not working - ios

I'm trying to parse a json-file containing links to images. This is my code:
#import "Pictures.h"
#import "DEMONavigationController.h"
#import "PicturesObject.h"
#interface Pictures ()
{
NSInteger refreshIndex;
NSArray *images;
NSMutableArray *jsonIs;
NSArray *items;
IBOutlet UIImageView *imagesinsta;
}
#end
#implementation Pictures
- (void)viewDidLoad
{
[super viewDidLoad];
self.title = #"Pictures";
self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:#"Menu"
style:UIBarButtonItemStylePlain
target:(DEMONavigationController *)self.navigationController
action:#selector(showMenu)];
// ***************** FETCHING DATA ******************* //
NSURL *URL = [NSURL URLWithString:[NSString stringWithFormat:#"link-to-json.php?image=Image"]];
NSData *data= [NSData dataWithContentsOfURL:URL];
if (data == nil) {
return;
}
NSError* error;
items = [NSJSONSerialization JSONObjectWithData:data
options:kNilOptions
error:&error];
NSLog(#"Json : %#",jsonIs);
if (jsonIs != nil) {
NSMutableDictionary* aDict = jsonIs[0];
NSString *item_media = [aDict objectForKey:#"link"];
}
// ***************** FETCHING DATA ******************* //
}
#pragma mark - Table view data source
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *simpleTableIdentifier = #"PicturesObject";
PicturesObject *cell = (PicturesObject *)[tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"PicturesObject" owner:self options:nil];
cell = [nib objectAtIndex:0];
}
// The element in the array is going to be a dictionary. I JUST KNOW THIS. The key for the tweet is "text".
NSDictionary *item = [items objectAtIndex:indexPath.row];
NSString *item_media = [item objectForKey:#"link"];
return cell;
}
- (void)issueLoadRequest
{
// Dispatch this block asynchronosly. The block gets JSON data from the specified URL and performs the proper selector when done.
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSData* data = [NSData dataWithContentsOfURL:[NSURL URLWithString:#"link-to-json.php?image=Image"]];
[self performSelectorOnMainThread:#selector(receiveData:) withObject:data waitUntilDone:YES];
});
}
- (void)receiveData:(NSData *)data {
// When we have the data, we serialize it into native cocoa objects. (The outermost element from twitter is
// going to be an array. I JUST KNOW THIS. Reload the tableview once we have the data.
self.tweets = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
[self.myTableView reloadData];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return self.tweets.count;
}
#end
This is how my custom PicturesObject table view look like:
But when I launch my app I only get a screen like this:

Json Data is similar to Dictionary and not an array. Instead of using
NSArray items
use
NSDictionary items
and then extract the the relevant data from dictionary.

Related

reloadData is stacking ontop of old data

I understand that I need to change the data in the data source before calling reloadData. My problem is that I'm not sure how this is done and why my getData method doesn't overwrite the current cells. Is it necessary to use subviews for this? Or is there a way to reset the cells when refresh is called to just create a new set of data?
#property (nonatomic,strong) NSMutableArray *objectHolderArray;
#end
#implementation MartaViewController
- (void)viewDidLoad
{
[super viewDidLoad];
[self getData];
//to add the UIRefreshControl to UIView
UIRefreshControl *refreshControl = [[UIRefreshControl alloc] init];
refreshControl.attributedTitle = [[NSAttributedString alloc] initWithString:#"Please Wait..."];
[refreshControl addTarget:self action:#selector(refresh:) forControlEvents:UIControlEventValueChanged];
}
- (void)getData
{
NSURL *blogURL = [NSURL URLWithString:JSON_URL];
NSData *jsonData = [NSData dataWithContentsOfURL:blogURL];
NSError *error = nil;
NSDictionary *dataDictionary = [NSJSONSerialization
JSONObjectWithData:jsonData options:0 error:&error];
for (NSDictionary *bpDictionary in dataDictionary) {
Object *currenHotel = [[Object alloc]Station:[bpDictionary objectForKey:#"station"] Status:[bpDictionary objectForKey:#"status"]];
[self.objectHolderArray addObject:currenHotel];
}
}
- (IBAction)refresh:(UIRefreshControl *)sender {
[self getData];
[self.tableView reloadData];
[sender endRefreshing];
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:
(NSInteger)section
{
return [self.objectHolderArray count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:
(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
MartaViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier
forIndexPath:indexPath];
Object *currentHotel = [self.objectHolderArray
objectAtIndex:indexPath.row];
cell.lblStation.text = currentHotel.station;
cell.lblStatus.text = currentHotel.status;
return cell;
}
-(NSMutableArray *)objectHolderArray{
if(!_objectHolderArray) _objectHolderArray = [[NSMutableArray alloc]init];
return _objectHolderArray;
}
#end
Because you are adding objects to self.objectHolderArray instead of overwriting in getData method. Try this
- (void)getData
{
NSURL *blogURL = [NSURL URLWithString:JSON_URL];
NSData *jsonData = [NSData dataWithContentsOfURL:blogURL];
NSError *error = nil;
NSDictionary *dataDictionary = [NSJSONSerialization
JSONObjectWithData:jsonData options:0 error:&error];
[self.objectHolderArray removeAllObjects];
for (NSDictionary *bpDictionary in dataDictionary) {
Object *currenHotel = [[Object alloc]Station:[bpDictionary objectForKey:#"station"] Status:[bpDictionary objectForKey:#"status"]];
[self.objectHolderArray addObject:currenHotel];
}
}
First initialize the array in viewDidLoad self.objectArray = [NSMutlabelArray alloc] init] and when you are refreshing the table view remove all objects from object array using [self.orderArray removeAllObject] the copy new content in new array.

Sending data from Google Places API to tableview

How send data to tableview in iOS with objective-C? I am trying to solve my problem very long time but result is not correct. My tableview is still empty. What I'm doing wrong? Below is my implementation file.
import "PlacesViewController.h"
#implementation PlacesViewController
#synthesize places;
- (void)viewDidLoad
{
[super viewDidLoad];
// Set this view controller object as the delegate and data source for the table view
self.listTableView.delegate = self;
self.listTableView.dataSource = self;
}
-(void)queryGooglePlaces
{
//Build the url string to send to Google
NSString *url = [NSString stringWithFormat:#"https://maps.googleapis.com/maps/api/place/nearbysearch/json?location=51.503186,-0.126446&radius=5000&types=food#|restaurant|bar&keyword=vegetarian&key=myOwnKEY"];
url = [url stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSLog(#"%#", url);
//Formulate the string as a URL object.
NSURL *googleRequestURL=[NSURL URLWithString:url];
// Retrieve the results of the URL.
dispatch_async(kBgQueue, ^{
NSData* data = [NSData dataWithContentsOfURL: googleRequestURL];
dispatch_sync(dispatch_get_main_queue(), ^{
[self fetchedData:data];
});
});
}
-(void)fetchedData:(NSData *)responseData {
//parse out the json data
NSError* error;
NSDictionary* json = [NSJSONSerialization
JSONObjectWithData:responseData
options:kNilOptions
error:&error];
//The results from Google will be an array obtained from the NSDictionary object with the key "results".
self.places = [json objectForKey:#"results"];
//Write out the data to the console.
NSLog(#"Google Data: %#", json);
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
return [self.places count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
NSDictionary *tempDictionary= [self.places objectAtIndex:indexPath.row];
cell.textLabel.text = [tempDictionary objectForKey:#"name"];
return cell;
}
#end
Whenever you update the datasource, you need to call [self.tableView reloadData]
So it should be like this
-(void)fetchedData:(NSData *)responseData {
//parse out the json data
NSError* error;
NSDictionary* json = [NSJSONSerialization
JSONObjectWithData:responseData
options:kNilOptions
error:&error];
//The results from Google will be an array obtained from the NSDictionary object with the key "results".
self.places = [json objectForKey:#"results"];
// NOTE - ADDED RELOAD
[self.tableView reloadData];
//Write out the data to the console.
NSLog(#"Google Data: %#", json);
}
For more information about reloadData see the answer
After you update the data source you should reload the table view.
self.places = [json objectForKey:#"results"];
[self.tableView reloadData];

tableView unable to display data parsed from the web in json format

I created an api using kimono and here is my code.
#import "PlayerRankingsTableViewController.h"
#import "RankingsTableViewCell.h"
#define kBgQueue dispatch_get_global_queue (DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)
#define kPlayerRankingsURL [NSURL URLWithString:#"https://www.kimonolabs.com/api/bg6tcuuq?apikey=xgp4nU6xA9UcBWSe0MIHcBVbAWz5v4wR"]
#interface PlayerRankingsTableViewController () {
}
#property (nonatomic, strong) NSArray *playerRankings;
#end
#implementation PlayerRankingsTableViewController
- (void)viewDidLoad {
[super viewDidLoad];
dispatch_async(kBgQueue, ^{
NSData *data = [NSData dataWithContentsOfURL:
kPlayerRankingsURL];
[self performSelectorOnMainThread: #selector(initializePlayerRankingsArray:)
withObject:data waitUntilDone:YES];
});
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be rexrcreated.
}
- (NSArray *)initializePlayerRankingsArray:(NSData *)responseData {
NSError* error;
NSDictionary *json = [NSJSONSerialization
JSONObjectWithData:responseData
options:kNilOptions
error:&error];
NSArray *myPlayerRankings = [[json objectForKey:#"results"]objectForKey:#"collection1"];
self.playerRankings = myPlayerRankings;
NSLog(#"%#", self.playerRankings);
return self.playerRankings;
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [self.playerRankings count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
RankingsTableViewCell *cell = (RankingsTableViewCell *)[tableView dequeueReusableCellWithIdentifier:#"cell"];
if (cell == nil) {
cell = (RankingsTableViewCell *)[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"cell"];
}
NSDictionary *rankings = [self.playerRankings objectAtIndex: indexPath.row];
NSString *rank = [rankings objectForKey:#"rank"];
NSString *name = [rankings objectForKey:#"name"];
NSString *points = [rankings objectForKey:#"points"];
[cell.playerRank setText:rank];
cell.playerName.text = name;
cell.playerPoints.text = points;
return cell;
}
#end
I think there is nothing wrong with data parsing process, because the console displays my data parsed from the web correctly.
However, when I ran the app, I saw nothing but a empty table.
Again, I think this might be something simple and new to programming.
Thank you in advance, and sorry for being such a burden.
In initializePlayerRankingsArray: you shouldn't be returning the array because nothing it there to receive it. You have already set self.playerRankings, so that is enough.
What is missing from this method is [self.tableView reloadData]; (which should be the last line after self.playerRankings is set).

How to customize the position in Table View cell iOS

Hi everyone I would like to ask I want to show JSON data and customize the position for image and text in Table View.
how can I do like that? please advice me.
You can take a look at the Image Url.
for image 1 it is the result as I've parsing from JSON.
Image 1
for image 2 it is my goal.
Image 2
ViewController.h
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController <UITableViewDataSource,UITableViewDelegate>
#property (retain, nonatomic) IBOutlet UITableView *myTableView;
#end
ViewController.m
#import "ViewController.h"
#interface ViewController ()
{
NSMutableArray *myObject;
// A dictionary object
NSDictionary *dict;
// Define keys
NSString *galleryid;
NSString *name;
NSString *titlename;
NSString *thumbnail;
}
#end
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
// Define keys
galleryid = #"GalleryID";
name = #"Name";
titlename = #"TitleName";
thumbnail = #"Thumbnail";
// Create array to hold dictionaries
myObject = [[NSMutableArray alloc] init];
NSData *jsonData = [NSData dataWithContentsOfURL:
[NSURL URLWithString:#"MY_JSON_URL"]];
id jsonObjects = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingMutableContainers error:nil];
// values in foreach loop
for (NSDictionary *dataDict in jsonObjects) {
NSString *strGalleryID = [dataDict objectForKey:#"GalleryID"];
NSString *strName = [dataDict objectForKey:#"Name"];
NSString *strTitleName = [dataDict objectForKey:#"TitleName"];
NSString *strThumbnail = [dataDict objectForKey:#"Thumbnail"];
dict = [NSDictionary dictionaryWithObjectsAndKeys:
strGalleryID, galleryid,
strName, name,
strTitleName, titlename,
strThumbnail, thumbnail,
nil];
[myObject addObject:dict];
}
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return myObject.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
// Use the default cell style.
cell = [[[UITableViewCell alloc] initWithStyle : UITableViewCellStyleSubtitle
reuseIdentifier : CellIdentifier] autorelease];
}
NSDictionary *tmpDict = [myObject objectAtIndex:indexPath.row];
NSURL *url = [NSURL URLWithString:[tmpDict objectForKey:thumbnail]];
NSData *data = [NSData dataWithContentsOfURL:url];
UIImage *img = [[UIImage alloc] initWithData:data];
cell.imageView.image = img;
cell.textLabel.text = [tmpDict objectForKey:name];
cell.detailTextLabel.text= [tmpDict objectForKey:titlename];
//[tmpDict objectForKey:memberid]
//[tmpDict objectForKey:name]
//[tmpDict objectForKey:titlename]
//[tmpDict objectForKey:thumbnail]
return cell;
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void)dealloc {
[_myTableView release];
[super dealloc];
}
#end
It will be easy if creating custom TableviewCell (subclass to UITableViewCell) to display the array of objects you have, than using UITableViewCell to display as you desired.
Create custom UITableviewCell with xib or with storyboard and create properties as you needed and give the position and styling for the cell elements.
Bind data for the cells in your cellForRowAtIndexPath method.
For more information, refer: this and this for more info

Parsing JSON link in Objective C error

I'm trying to parse a JSON file containing urls to images.
My code:
NSURL *URL = [NSURL URLWithString:[NSString stringWithFormat:#"http://my-site/pictureparse.php?name=Name"]];
NSData *data= [NSData dataWithContentsOfURL:URL];
if (data == nil) {
return;
}
NSError* error;
NSMutableDictionary *jsonIs = [NSJSONSerialization
JSONObjectWithData:data
options:kNilOptions
error:&error];
NSLog(#"Json : %#",jsonIs);
if (jsonIs != nil) {
NSString *item_media = [jsonIs objectForKey:#"link"];
where "link" is the link to the image in the JSON-file.
The JSON structure looks like this:
[
{
"link": "http://link-to-image.com/picture.jpg",
"title": "Title",
"published": "0:01 PM 24/10"
},
{
"link": "http://link-to-image.com/picture.jpg",
"title": "Title",
"published": "0:01 PM 24/10"
},
{
"link": "http://link-to-image.com/picture.jpg",
"title": "Title",
"published": "0:01 PM 24/10"
},
{
"link": "http://link-to-image.com/picture.jpg",
"title": "Title",
"published": "0:08 PM 23/10"
}
]
When I launch the app I see in NSLog that it parses the objects, but I get the error:
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFArray objectForKey:]: unrecognized selector sent to instance 0x16e81ed0
How can I take these parsed objects/links and display them in a feed, like Instagram?
I have tried with the following code, but it doesn't work...
#import "PicturesViewController.h"
#import "DemoViewController.h"
#import "SecondViewController.h"
#import "AppDelegate.h"
#import "RNBlurModalView.h"
#import "PictureJSON.h"
#import "HMSegmentedControl.h"
#interface PicturesViewController ()
{
NSInteger refreshIndex;
NSArray *images;
}
#end
#implementation PicturesViewController
- (void)viewDidLoad
{
HMSegmentedControl *segmentedControl = [[HMSegmentedControl alloc] initWithSectionTitles:#[#"Instagram", #"Hashtags", #"Facebook"]];
[segmentedControl setFrame:CGRectMake(10, 10, 300, 60)];
[segmentedControl addTarget:self action:#selector(segmentedControlChangedValue:) forControlEvents:UIControlEventValueChanged];
[self.view addSubview:segmentedControl];
[super viewDidLoad];
self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:#"Menu" style:UIBarButtonItemStyleBordered target:self action:#selector(showMenu)];
UIPanGestureRecognizer *gestureRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:#selector(swipeHandler:)];
[self.view addGestureRecognizer:gestureRecognizer];
[self issueLoadRequest];
}
- (void)swipeHandler:(UIPanGestureRecognizer *)sender
{
[[self sideMenu] showFromPanGesture:sender];
}
- (void)segmentedControlChangedValue:(HMSegmentedControl *)segmentedControl1 {
[self issueLoadRequest];
}
- (void)segmentedControlSelectedIndexChanged:(id)sender
{
[self issueLoadRequest];
}
#pragma mark -
#pragma mark Button actions
- (void)showMenu
{
[[self sideMenu] show];
}
#pragma mark - Table view data source
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *simpleTableIdentifier = #"PictureJSON";
PictureJSON *cell = (PictureJSON *)[tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"PictureJSON" owner:self options:nil];
cell = [nib objectAtIndex:0];
}
// The element in the array is going to be a dictionary. I JUST KNOW THIS. The key for the tweet is "text".
NSDictionary *tweet = [self.tweets objectAtIndex:indexPath.row];
NSLog(#"%#", [cell class]);
UIImageView *instaImage = [[UIImageView alloc] init];
instaImage.image = [tweet objectForKey:#"link"];
cell.titleLabel.text = [tweet objectForKey:#"title"];
cell.timeLabel.text = [tweet objectForKey:#"published"];
return cell;
}
- (void)issueLoadRequest
{
// Dispatch this block asynchronosly. The block gets JSON data from the specified URL and performs the proper selector when done.
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSData* data = [NSData dataWithContentsOfURL:[NSURL URLWithString:#"http://my-site.com/picutreparse.php?name=Name"]];
[self performSelectorOnMainThread:#selector(receiveData:) withObject:data waitUntilDone:YES];
});
}
- (void)receiveData:(NSData *)data {
// When we have the data, we serialize it into native cocoa objects. (The outermost element from twitter is
// going to be an array. I JUST KNOW THIS. Reload the tableview once we have the data.
self.tweets = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
[self.myTableView reloadData];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return self.tweets.count;
}
#end
I would really appreciate a solution!
The problem is that the object you get from your parsing is a NSArray and not a NSDictionary.
Edit your code to this one:
#interface PicturesViewController ()
{
// ...
NSArray *items;
}
At the point where you get the data:
items = [NSJSONSerialization JSONObjectWithData:data
options:kNilOptions
error:&error];
Finally:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
// ...
NSDictionary *item = [items objectAtIndex:indexPath.row];
NSString *item_media = [item objectForKey:#"link"];
// ...
}
What is wrong you make NSMutableDictionary
NSMutableArray *jsonIs = [NSJSONSerialization
JSONObjectWithData:data
options:kNilOptions
error:&error];
NSLog(#"Json : %#",jsonIs);
if (jsonIs != nil) {
NSMutableDictionary* aDict = jsonIs[0];
NSString *item_media = [aDict objectForKey:#"link"];
}
your main JSON is an array because of "[...]" in this array you got dictionaries : "{..}"
edit for tableView question:
make the NSMutableArray *jsonIs to global
#implementation PicturesViewController{
NSMutableArray *jsonIs
}
then in tableview delegate:
NSString *item_media = [jsonIs[indexPath.row] objectForKey:#"link"];

Resources