Displaying JSON Data from URL using AFNetworking - ios

I want to display json data from a URL.
Everything Works the data array is accessible in only did load section. When I use it to count count it gives NULL but inside did load it works. What is the issue.
.h file
#interface ViewController : UIViewController<UITableViewDataSource,UITableViewDelegate>
{
NSDictionary *dictArray;
NSString *title;
}
.m file
#import "ViewController.h"
#import "AFNetworking.h"
#import "AFHTTPRequestOperation.h"
#interface ViewController ()
{
NSArray *data;
}
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
[manager GET:[NSString stringWithFormat:#"sampleUrl"]
parameters:nil
success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSDictionary *weather = (NSDictionary *)responseObject;
data = [weather objectForKey:#"slider"];
NSLog(#"%#",data); // Works Fine
}
failure:^(AFHTTPRequestOperation *operation, NSError *error) {
UIAlertView *av = [[UIAlertView alloc] initWithTitle:#"Error Retrieving Weather" message:[NSString stringWithFormat:#"%#", error] delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[av show];
}];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [data count]; // doesn;t work
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *cellIdentifier = #"cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
dictArray = [data objectAtIndex:indexPath.row];
cell.textLabel.text = [dictArray objectForKey:#"title"];
NSLog(#"%#",data); // Doesn;t work displays NULL
return cell;}
#end

In success block of AFNetworking manager, reload your tableView. Table is now loading before the web service gets response.
success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSDictionary *weather = (NSDictionary *)responseObject;
data = [weather objectForKey:#"slider"];
NSLog(#"%#",data); // Works Fine
[yourTableView reloadData];
}

Related

Getting a json file from a website into UITableview with Objective C

I'm attempting to get a json file from a website into UITableview with Objective C.
As I'm not an advanced coder please excuse my crude coding tecniques.
I have a .json file uploaded to my webspace. The File is formatted as so:
"JSONDATA":[
{
"name": "ABC",
"details": "DEF"
},
{
"name": "UVW",
"details": "XYZ"
}
]
my .h looks like:
#interface ViewController : UIViewController <UITableViewDataSource, UITableViewDelegate>
{
IBOutlet UITableView *myTableView;
}
#property (strong, nonatomic) IBOutlet UITableView *myTableView;
#end
the .m code
#import "ViewController.h"
#interface ViewController ()
{
NSMutableArray *arrName;
NSMutableArray *arrDetails;
NSString *responseString;
}
#end
#implementation ViewController
#synthesize myTableView;
- (void)viewDidLoad {
[super viewDidLoad];
NSLog(#"ViewDidLoad");
[self fetchData];
[myTableView reloadData];
}
-(void)fetchData
{
NSLog(#"GetJsonResponse Fired");
NSURL *URL = [NSURL URLWithString:#"http://myWebsite.com/json/myJsonFile.json"];
NSURLRequest *request = [NSURLRequest requestWithURL:URL];
NSLog(#"URLRequest = %#",request);
/////////////////////////////////////////////////////////////////// Nothing Below Here Fires/////////////////////////////////////////////////
// [[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler:ourBlock];
[[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler:^(NSData *data,NSURLResponse *response,NSError *error)
{
// Block Body
NSLog(#"response = %#",response);
NSLog(#"block Body");
NSDictionary *jsonDict = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error];
NSLog(#"GetJsonDict%#",jsonDict);
NSArray *arr = jsonDict[#"JSONFILE"];
NSLog(#"jasoDict = %#",arr);
self->arrName = [[NSMutableArray alloc]init];
self->arrDetails = [[NSMutableArray alloc]init];
//arrValue = [[NSMutableArray alloc]init];
for(int i=0;i<[arr count];i++)
{
NSString *strName = [arr[i]objectForKey:#"NAME"];
NSString *strCode = [arr[i]objectForKey:#"CODE"];
// NSString *strValue = [arr[i]objectForKey:#"VALUE"];
NSLog(#"The strName is - %#",strName);
NSLog(#"The strCode is - %#", strCode);
// NSLog(#"The strValue is - %#", strValue);
[self->arrName addObject:strName];
[self->arrDetails addObject:strCode];
// [arrValue addObject:strValue];
NSLog(#"The arrName is - %#",self->arrName);
NSLog(#"The arrDetails is - %#", self->arrDetails);
// NSLog(#"The arrValue is - %#", arrValue);
}
}];
}
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return arrName.count;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *strCell = #"Cell";
// UITableViewCell *cell = [UITableView dequeueReusableCellWithIdentifier:strCell];
UITableViewCell *cell = [myTableView dequeueReusableCellWithIdentifier:strCell forIndexPath:indexPath];
if(cell==nil)
{
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:strCell];
}
cell.textLabel.text = arrName[indexPath.row];
cell.detailTextLabel.text = arrDetails[indexPath.row];
return cell;
}
#end
I can't seem to put all the pieces together and get any data through to parse.
The NSLog is telling me:
2020-03-09 14:13:42.605558-0500 jsonFromWeb[27389:1317924] ViewDidLoad
2020-03-09 14:13:42.605802-0500 jsonFromWeb[27389:1317924] GetJsonResponse Fired
2020-03-09 14:13:42.606118-0500 jsonFromWeb[27389:1317924] URLRequest = <NSURLRequest: 0x6000001f8cc0> { URL: http://mywebsite.com/json/myJsonFile.json }
Where is this thing derailing? I can't get any data out of the URLResponse.
Thanks so much.
You have to resume the data task and you have to reload the table view inside the completion block on the main thread
[[[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler:^(NSData *data,NSURLResponse *response,NSError *error) {
...
}
dispatch_async(dispatch_get_main_queue(), ^{
[myTableView reloadData];
});
}] resume];

How to get value from Model > NSDictionary and parse to another view controller?

I have a ViewController A and retrieve JSON data in ViewDidLoad by using following method:-
[self.manager GET:#"http://api.sampleWebsite.com/api/xx" parameters:nil progress:nil success:^(NSURLSessionDataTask *task, id responseObject) {
json_product = responseObject;
self.aryProducts=[NSMutableArray array];
for (NSDictionary *subDic in json_product) {
ProductItem_Model *model=[[ProductItem_Model alloc]initWithDic:subDic];
[self.aryProducts addObject:model];
}
[self.collectionView reloadData];
}
failure:^(NSURLSessionDataTask *operation, NSError *error) {
}];
}
Model.h
#import <Foundation/Foundation.h>
#import "JSONModel.h"
#interface ProductItem_Model : JSONModel
#property (nonatomic,strong) NSString <Optional>*name;
- (instancetype)initWithDic:(NSDictionary *)dicProductItem;
#end
It will working fine and return result in Model.m
- (instancetype)initWithDic:(NSDictionary *)dicProductItem{
NSError *error = nil;
self = [self initWithDictionary:dicProductItem error:&error];
NSLog(#"CORRECT RESULT WILL RETURN HERE%#",dicProductItem);
return self;
}
In my ViewController B, how can I pass in NSDictionary list from Model as mentioned above? Here is my sample code:-
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
UICollectionViewCell *gridcell = nil;
ProductItem_Model *model = [[ProductItem_Model alloc]init];
NSDictionary *subDic;
NSLog(#"HOW CAN I PASS IN THE NSDICTIONARY LIST HERE - %#",[model initWithDic:[subDic objectForKey:#"name"]]);

Passing JSON data on uiviewTable ios (objective c)

There are similar questions but i could not find any solution which fits for me.
I have got all the data from the link as JSON but i am unable to understand that how can i show that data on uitableview. It is to be shown on homepage. it has title, info. for now i only need title and info to be shown on homepage.
NSURL *url = [NSURL URLWithString:#"http://mantis.vu.edu.pk/fundme/public/api/v1/ideas"];
NSURLRequest *urlRequest = [NSURLRequest requestWithURL:url];
AFJSONRequestOperation *jsonOperation = [AFJSONRequestOperation JSONRequestOperationWithRequest:urlRequest success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON)
{
NSDictionary *responseDict = (NSDictionary *)JSON;
ideasArrayList = [[NSMutableArray alloc] init];
for (NSDictionary *innerObject in [responseDict objectForKey:#"data"])
{
[ideasArrayList addObject:innerObject];
if (ideasArrayList.count > 0) {
NSDictionary *userObject = [ideasArrayList objectAtIndex:0];
NSLog(#"Object and first index of array is %#",userObject);
}
failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, id JSON)
{
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"Oops something went wrong."
message:[error localizedDescription]
delegate:nil
cancelButtonTitle:#"Ok"
otherButtonTitles:nil];
[alertView show];
}];
[jsonOperation start];
i am using AFNetworking library.
if you call your code in ViewController, at first you need add a dispatch_async block for move your data to main thread and reload tableview
-(void)getDataFromApi {
NSURL *url = [NSURL URLWithString:#"http://mantis.vu.edu.pk/fundme/public/api/v1/ideas"];
NSURLRequest *urlRequest = [NSURLRequest requestWithURL:url];
AFJSONRequestOperation *jsonOperation = [AFJSONRequestOperation JSONRequestOperationWithRequest:urlRequest success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON)
{
NSDictionary *responseDict = (NSDictionary *)JSON;
ideasArrayList = [[NSMutableArray alloc] init];
for (NSDictionary *innerObject in [responseDict objectForKey:#"data"])
{
[ideasArrayList addObject:innerObject];
if (ideasArrayList.count > 0) {
NSDictionary *userObject = [ideasArrayList objectAtIndex:0];
NSLog(#"Object and first index of array is %#",userObject);
dispatch_async(dispatch_get_main_queue(), ^{
self.ideasArrayList = ideasArrayList;
[self.tableView reloadData];
});
}
failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, id JSON)
{
dispatch_async(dispatch_get_main_queue(), ^{
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"Oops something went wrong."
message:[error localizedDescription] delegate:nil cancelButtonTitle:#"Ok" otherButtonTitles:nil];
[alertView show];
});
}];
[jsonOperation start];
}
In viewDidLoad method
- (void)viewDidLoad{
self.tableView.dataSource = self;
}
And implement UITableViewDatasource protocol methods
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return self.ideasArrayList.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (!cell) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
//configure the cell here or create custom subclass
}
NSDictionary *innerObject = self.ideasArrayList[indexPath.row];
cell.textLabel.text = innerObject[#"title"];
return cell;
}
You need to store the values you need to display in tableview in an array. So retrieve those values from your output JSON and store them in an array. Then in the data source methods of table view follow the usual.For e.g.- In the numberOfRowsInSection return yourArray.count. I hope you get the point.
I hope you get the point. Store values in array and then make the table fetch from that array.
I think it's help for you.
First you want to add the .m file.
#import "ViewController.h"
#import "tblcellTableViewCell.h"
#interface ViewController ()<UITableViewDelegate,UITableViewDataSource>
{
NSMutableArray *arrJSONDATA;
}
#property (weak, nonatomic) IBOutlet UITableView *tbl;
#end
and add the below code the viewDidLoad.
arrJSONDATA = [[NSMutableArray alloc] init];
NSURL *url = [NSURL URLWithString:#"http://mantis.vu.edu.pk/fundme/public/api/v1/ideas"];
NSData *data = [NSData dataWithContentsOfURL:url];
NSError *err;
NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&err];
NSDictionary *dicData = [dic valueForKey:#"data"];
for (NSDictionary *dic1 in dicData) {
NSMutableArray *arr = [[NSMutableArray alloc] init];
[arr addObject:[dic1 objectForKey:#"idea_title"]];
[arr addObject:[dic1 objectForKey:#"idea_info"]];
[arrJSONDATA addObject:arr];
}
NSLog(#"%#",[arrJSONDATA description]);
[_tbl reloadData];
Label Outlet Create for title and info.
#import <UIKit/UIKit.h>
#interface tblcellTableViewCell : UITableViewCell
#property (weak, nonatomic) IBOutlet UILabel *lblTitle;
#property (weak, nonatomic) IBOutlet UILabel *lblInfo;
#end
Then Create the tableView Delegate Method.
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return [arrJSONDATA count];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return 1;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
tblcellTableViewCell *cells = [tableView dequeueReusableCellWithIdentifier:#"cell" forIndexPath:indexPath];
NSMutableArray *arr = [[NSMutableArray alloc] init];
arr = [arrJSONDATA objectAtIndex:indexPath.section];
cells.lblTitle.text = [arr objectAtIndex:0];
cells.lblInfo.text = [arr objectAtIndex:1];
return cells;
}
[Check the Screenshot.]

Data not populating on TableView

I am fetching data from the website and loading on the tableViewController. Tableviewcontroller is inside the tabbarcontroller. Whenever I clickked on tabbar, tableview data does not populated. However once I click other viewcontrollers and then click again on tableviewcontroller, then data populated.
#import "GetBookViewController.h"
#import "AFNetworking.h"
#interface GetBookViewController ()
#end
#implementation GetBookViewController
#synthesize booksArray;
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
}
-(void)viewWillAppear:(BOOL)animated
{
[self loadData];
}
-(void)viewDidAppear:(BOOL)animated
{
[self.tableView reloadData];
}
-(void) loadData
{
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
[manager POST:#"http://XXXXXX.com/coursera/books.php" parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"JSON: %#", responseObject);
if ([[responseObject valueForKey:#"status"] isEqualToString:#"success"]) {
int count = [[responseObject valueForKey:#"total"] integerValue];
NSMutableArray *array = [[NSMutableArray alloc] initWithCapacity:count];
for (int i = 1; i <= count; i++) {
NSString *obj = [NSString stringWithFormat:#"%i", i];
[array addObject:[responseObject objectForKey:obj]];
}
booksArray = array;
for (id obj in booksArray) {
NSLog(#"%#", [obj valueForKey:#"title"]);
}
}
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Error: %#", error);
}];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
}
#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 [booksArray count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
UILabel* label = (UILabel*)[cell viewWithTag:100];
NSString *title = [[booksArray objectAtIndex:indexPath.item] valueForKey:#"title"];
label.text = title;
return cell;
}
You aren't doing anything once you receive a response from the network and populate your array?
What you need to do is notify the table view that it needs to query its data source again to refresh its values. Simply calling reloadData on your table view once you have your array would to the trick:
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
[manager POST:#"http://ilyasuyanik.com/coursera/books.php" parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"JSON: %#", responseObject);
if ([[responseObject valueForKey:#"status"] isEqualToString:#"success"]) {
int count = [[responseObject valueForKey:#"total"] integerValue];
NSMutableArray *array = [[NSMutableArray alloc] initWithCapacity:count];
for (int i = 1; i <= count; i++) {
NSString *obj = [NSString stringWithFormat:#"%i", i];
[array addObject:[responseObject objectForKey:obj]];
}
dispatch_async(dispatch_get_main_queue,^{
booksArray = array;
for (id obj in booksArray) {
NSLog(#"%#", [obj valueForKey:#"title"]);
}
//now you can update your table view
[self.tableView reloadData];
});
}
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Error: %#", error);
}];

Making Profile Photos show up using Twitter API 1.1

We're working on an iOS 7 Twitter client. I haven't worked with the the Twitter API much and what I did was before 1.1.
Could somebody please help us get the profile photos loading on our application's Timeline?
Our code is below.
Here is our .h file:
#import <UIKit/UIKit.h>
#import <Accounts/Accounts.h>
#import <Social/Social.h>
#import <Twitter/Twitter.h>
#interface FirstViewController : UIViewController <UITableViewDataSource , UITableViewDelegate> {
UIRefreshControl *myRefreshControl;
}
#property (nonatomic) IBOutlet UITableView *timelineTableView;
#property (nonatomic) NSArray *timelineArray;
#end
and here is our .m for the application's timeline.
#interface FirstViewController ()
#end
#implementation FirstViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
[self getTimeline];
myRefreshControl = [[UIRefreshControl alloc]init];
myRefreshControl.tintColor = [UIColor blackColor];
[myRefreshControl setAttributedTitle:[[NSAttributedString alloc]initWithString:#"Pull to Refresh"]];
[myRefreshControl addTarget:self action:#selector(refreshTimeline) forControlEvents: UIControlEventValueChanged];
[self.timelineTableView addSubview:myRefreshControl];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
-(void)getTimeline
{
ACAccountStore *account = [[ACAccountStore alloc] init];
ACAccountType *accountType = [account
accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierTwitter];
[account requestAccessToAccountsWithType:accountType
options:nil completion:^(BOOL granted, NSError *error)
{
if (granted == YES)
{
NSArray *arrayOfAccounts = [account
accountsWithAccountType:accountType];
if ([arrayOfAccounts count] > 0)
{
ACAccount *twitterAccount = [arrayOfAccounts lastObject];
NSURL *requestURL = [NSURL URLWithString:#"http://api.twitter.com/1/statuses/home_timeline.json"];
NSMutableDictionary *parameters =
[[NSMutableDictionary alloc] init];
[parameters setObject:#"200" forKey:#"count"];
[parameters setObject:#"1" forKey:#"include_entities"];
SLRequest *postRequest = [SLRequest
requestForServiceType:SLServiceTypeTwitter
requestMethod:SLRequestMethodGET
URL:requestURL parameters:parameters];
postRequest.account = twitterAccount;
[postRequest performRequestWithHandler:
^(NSData *responseData, NSHTTPURLResponse
*urlResponse, NSError *error)
{
self.timelineArray = [NSJSONSerialization
JSONObjectWithData:responseData
options:NSJSONReadingMutableLeaves
error:&error];
if (self.timelineArray.count != 0) {
dispatch_async(dispatch_get_main_queue(), ^{
[self.timelineTableView reloadData];
});
}
}];
}
} else {
}
}];
}
-(void)refreshTimeline
{
[self getTimeline];
[self.timelineTableView reloadData];
}
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [self.timelineArray count];
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (!cell) {
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
}
NSDictionary *tweet = self.timelineArray[[indexPath row]];
cell.textLabel.text = [[tweet objectForKey:#"user"]objectForKey:#"name"];
cell.detailTextLabel.text = [tweet objectForKey:#"text"];
cell.imageView.image = [UIImage imageWithData:[NSData dataWithContentsOfURL: [[tweet objectForKey:#"user"]objectForKey:#"profile_image_url"]]];
return cell;
}
#end
The response of :
http://api.twitter.com/1/statuses/home_timeline.json
will return home feeds. It contains a user key in it , you have to access that and get the profile image by profile_image_url.
Handling response in array of dictionaries will solve your problem and each dictionary will have the user key which contains profile_image_url.
Your call to the api is referencing version 1. I would suggest reviewing the info at https://dev.twitter.com/docs/api/1.1/get/statuses/home_timeline and examining the response format.
You can drill down the response to arrive at the 'user' object and get the profile image from there.

Resources