ios - ASIHTTPREQUEST populating uitableview with json data - ios

I've been reading for hours and I can't figure out why my table won't reload itself with the updated data, here is the request I am making in block form:
ASIHTTPRequest *_request= [ASIHTTPRequest requestWithURL:url];
__weak ASIHTTPRequest *request = _request;
request.requestMethod = #"POST";
[request addRequestHeader:#"Content-Type" value:#"application/json"];
[request setDelegate:self];
[request setCompletionBlock:^{
NSString *responseString = [request responseString];
NSData *responseData = [request responseData];
NSLog(#"Response: %#", responseString);
NSError* error;
json = [NSJSONSerialization JSONObjectWithData:responseData options:kNilOptions error:&error];
NSLog(#"request finished");
[CommMTable reloadData];
}];
[request setFailedBlock:^{
NSError *error = [request error];
NSLog(#"Error: %#", error.localizedDescription);
}];
[request startAsynchronous];
It gets the json object successfully as it is printed in my console but the table doesn't update!
here is my table pragma section
(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
return 1;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [self.json count];
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *cellIdentifier=#"Cell";
UITableViewCell *cell=[tableView dequeueReusableCellWithIdentifier:cellIdentifier];
NSDictionary *tempDictionary= [self.json objectAtIndex:indexPath.row];
if(cell==nil) {
cell = [[UITableViewCell alloc] initWithStyle: UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
}
cell.accessoryType=UITableViewCellAccessoryDetailDisclosureButton;
cell.textLabel.text = [tempDictionary objectForKey:#"title"];
return cell;
}
any help is appreciated, this is really frustrating :(

Have you checked whether json array has been updated or not? And you have used json array as property(self.json) in pragma sections not in inside blocks.

json = [NSJSONSerialization JSONObjectWithData:responseData options:kNilOptions error:&error];
On doing this, the json array will be available only in the scope of setCompletionBlock.
Since you have synthesized json array, you need to assign it like
self.json = [NSJSONSerialization JSONObjectWithData:responseData options:kNilOptions error:&error];
If this was also not worked, just check whether the format of json was correct and you are parsing the json properly in cellForRowAtIndexPath.

I found the problem, I was doing everything correctly (json format and stuff were properly set). The problem was that for some reason the table got disconnected from it's delegate and datasource, for the people who had a similar problem try this solution.
In the xib file just ctrl + drag the tableview to the File Owner and connect it to the delegate and datasource.
or you can do it with just code if you don't like the interface builder with the following lines
[myTableView setDataSource:self];
[myTableView setDelegate:self];
or
self.tableView.delegate = self.tableDelegate;
self.tableView.datasource = self.tableDelegate;
both either/or should work.

Related

How to count two arrays in a single label in UITableViewCell? Objective-C

I want to create a message conversation screen.I have two arrays, first is web_array and the second is local_array. First, I have one UITableViewCell in one UILabel, and one UITextField, and one UIButton. In the textfield, write any text and it will print on UITableViewCell label. TextField text is stored in a one array (local_array). (application run time local_array is empty).
And second array (web_array), web_array is stored in a web service get data, I want to web_array count on UITableViewCell label after local_array count in same label.
web_array data counting is over after just down local_array data counting start.
My english is very bad and i can't explain proper. seriously i'm so tired please help me and guide.
ViewController
#import "Chat_ViewController.h"
#import "chatview_Cell.h"
#interface Chat_ViewController () <UITableViewDataSource,UITableViewDelegate>
{
NSArray*web_array;
NSMutableArray*Local_array;
}
#end
#implementation Chat_ViewController
- (void)viewDidLoad {
[super viewDidLoad];
Local_array=[[NSMutableArray alloc]init];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:#"MYURL"]];
//create the Method "GET" or "POST"
[request setHTTPMethod:#"POST"];
//Pass The String to server(YOU SHOULD GIVE YOUR PARAMETERS INSTEAD OF MY PARAMETERS)
NSString *userUpdate =[NSString stringWithFormat:#"senderid=%#&recid=%#&",_chat_myuid.text,_chat_uid.text, nil];
//Check The Value what we passed
NSLog(#"the data Details is =%#", userUpdate);
//Convert the String to Data
NSData *data1 = [userUpdate dataUsingEncoding:NSUTF8StringEncoding];
//Apply the data to the body
[request setHTTPBody:data1];
//Create the response and Error
NSError *err;
NSURLResponse *response;
NSData *responseData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&err];
NSDictionary *json = [NSJSONSerialization JSONObjectWithData:responseData options:kNilOptions error:&err];
NSString *resSrt = [[NSString alloc]initWithData:responseData encoding:NSASCIIStringEncoding];
//This is for Response
NSLog(#"got response==%#", resSrt);
NSArray *results = [json objectForKey:#"status"];
web_array = [results valueForKey:#"message"];
NSLog(#"your message %#",web_array);
//This is for Response
NSLog(#"got response==%#", resSrt);
if(resSrt)
{
NSLog(#"got response");
}
else
{
NSLog(#"faield to connect");
}
}
- (IBAction)send:(id)sender
{
NSString *textNameToAdd = self.mymsg.text; //mymsg is UITextField outlet
[Local_array addObject:textNameToAdd];
[self.table_view reloadData];
}
//TABLEVIEWCELL Code
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if ([Local_array count] > 0 && web_array.count>0)
{
return [Local_array count];
}
else
return 1;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
chatview_Cell *cell = [tableView dequeueReusableCellWithIdentifier:#"ht"];
if (cell==nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"Cell" owner:self options:nil];
cell = [nib objectAtIndex:0];
}
if (Local_array.count > 0 && web_array.count>0)
{
cell.other_msg.text=[NSString stringWithFormat:#"%#",[Local_array objectAtIndex:indexPath.row]];
}
cell.other_msg.text=[NSString stringWithFormat:#"%#",[web_array objectAtIndex:indexPath.row]];
return cell;
}

JSON data show on first cell

I am Developing An IOS App.On Button Click Show JSON Data In Tableview..But The Data Show ON Only First Cell Not On Other Cells..I Can Check The Data Through NSLog That Are Correct..But In Tableview Show In First Cells And Some Time App Crash And Error Data Parameters Are Nil..Warning Show on This Line
`"Incompatible Pointer Assigning To 'NSDictionary'
To
NSArray "[str = [BBServerJson sendPostRequest:json toUrl:url];]`
Any Help Or Advice Is Greatly Appreciated. Thanks In Advance.
//Button Click
BBAuthorViewController *BBAuthor =[[UIStoryboard storyboardWithName:#"Main" bundle:nil]instantiateViewControllerWithIdentifier:#"BBAuthor"];
BBAuthor.authorDetail=_adDetailsObj.authorDetail;
[self.navigationController pushViewController:BBAuthor animated:YES];
//Json
+(NSDictionary *)sendPostRequest:(NSDictionary *)params toUrl:(NSString *)urlString
{
NSMutableString *paramString =
[NSMutableString stringWithString:#""];
NSArray *keys = [params allKeys];
for (NSString *key in keys) {
[paramString appendFormat:#"%#=%#&",key,
[params valueForKey:key]];
}
NSString *postString = #"";
if ([paramString length] > 0)
postString = [paramString substringToIndex:
[paramString length]-1];
NSMutableURLRequest *request =[NSMutableURLRequest
requestWithURL:[NSURL URLWithString:urlString]];
[request setHTTPMethod:#"POST"];
[request setHTTPBody:[postString
dataUsingEncoding:NSUTF8StringEncoding]];
NSURLResponse *res;
NSError *error;
NSData *resp = [NSURLConnection sendSynchronousRequest:request
returningResponse:&res error:
&error];
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)res;
int statusCode;
statusCode = [httpResponse statusCode];
NSDictionary *jsonArray = [NSJSONSerialization JSONObjectWithData:resp options:NSJSONReadingMutableContainers error:&error];
return jsonArray;
}
NSString *url = #"https://boatbrat.com/wp-app-handler-boatsales.php";
NSMutableDictionary *json = [[NSMutableDictionary alloc]init];
[json setObject:#"AuthorListing" forKey:#"method"];
[json setObject:_authorDetail forKey:#"author"];
str = [BBServerJson sendPostRequest:json toUrl:url];
//Tableview
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return str.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
cell=[tableView dequeueReusableCellWithIdentifier:#"cell"];
NSArray *array = [str objectForKey:#"results"];
NSDictionary *dic= [array objectAtIndex:indexPath.row];
cell.textLabel.text = [dic objectForKey:#"author_name"];
return cell;
}
I think you are returning wrong row count in numberOfRowsInSection: method.
Change the return statement to,
return [[str objectForKey:#"results"] count];

How to populate UITableView with JSON data?

I'm struggling to figure out what i am doing wrong. I am basically trying to populate the my UITableView with json data. In the console I can see the results but just don't know why the data is not displayed in the tableview. I have looked at similar questions and answers but none is a solution to my problem.
Advice or help please;
#pragma mark - Private method implementation
-(void)loadData{
// Form the query.
#try {
NSString *get =[[NSString alloc] initWithFormat:#""];
NSString *getRegions = [NSString stringWithFormat:#"JSON URL HERE",self.sessionId, self.companyId];
NSURL *url=[NSURL URLWithString:getRegions];
NSLog(#"Get regions: %#", url);
NSData *postData = [get dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
NSString *postLength = [NSString stringWithFormat:#"%lu", (unsigned long)[postData length]];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
[request setURL:url];
[request setHTTPMethod:#"GET"];
[request setValue:postLength forHTTPHeaderField:#"Content-Length"];
[request setValue:#"application/json" forHTTPHeaderField:#"Accept"];
[request setHTTPBody:postData];
//[NSURLRequest setAllowsAnyHTTPSCertificate:YES forHost:[url host]];
NSError *error = [[NSError alloc] init];
NSHTTPURLResponse *response = nil;
NSData *urlData=[NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
NSLog(#"Reponse code: %ld", (long)[response statusCode]);
if ([response statusCode] >= 200 && [response statusCode] < 300)
{
NSString *responseData = [[NSString alloc]initWithData:urlData encoding:NSUTF8StringEncoding];
NSLog(#"Response ==> %#", responseData);
#try{
NSError *error = nil;
regionsJson = [[NSMutableArray alloc]init];
//[jsonData removeAllObjects];
regionsJson = [NSJSONSerialization JSONObjectWithData:urlData options:NSJSONReadingMutableContainers|NSJSONReadingMutableLeaves error:&error];
NSArray *tblArray = [NSArray arrayWithObject:regionsJson];
}
#catch (NSException *e){
NSLog(#"Try catch block: %#", e);
}
#finally{
// [self.tblRegion reloadData];
NSLog(#"finally");
}
structureJson =[regionsJson valueForKey:#"structure"];
companyJson =[structureJson valueForKey:#"company"];
_barBtnCompanyName.title = [companyJson valueForKey:#"company_name"];
NSLog(#"Get company name: %#", [companyJson valueForKey:#"company_name"]);
for (int i =0 ; i < regionsJson.count; i++){
regionsJson = [companyJson objectForKey:#"regions"];
NSString *regionName = [NSString stringWithFormat:#"%#", [regionsJson valueForKey:#"region_name"]];
NSLog(#"Region name: %#",regionName);
// [regionsJson addObject:regionName];
NSString *alarmCount = [NSString stringWithFormat:#"%#", [regionsJson valueForKey:#"alarm_cnt"]];
NSLog(#"Alarm count: %#", alarmCount);
// [regionsJson addObject:alarmCount];
}
}
}
#catch (NSException * e) {
NSLog(#"Exception: %#", e);
}
// Reload the table view.
[self.tblRegion reloadData];
}
#pragma mark - UITableView method implementation
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
return 1;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
NSLog(#"Number of rows: %lu", (unsigned long)regionsJson.count);
return [regionsJson count];
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *CellIdentifier = #"CellRegions";
// Dequeue the cell.
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
}
// Set the loaded data to the appropriate cell labels.
cell.textLabel.text = [[regionsJson objectAtIndex:indexPath.row] objectForKey:#"region_name"];
cell.detailTextLabel.text = [[regionsJson objectAtIndex:indexPath.row] objectForKey:#"alarm_cnt"];
[cell setAccessoryType: UITableViewCellAccessoryDisclosureIndicator];
NSLog(#"Table cell: %#", cell);
return cell;
}
My code is just fine, i did a stupid omission of this declaration.
-(void)viewDidLoad{
[super viewDidLoad];
// Do any additional setup after loading the view.
self.tblRegion.delegate = self;
self.tblRegion.dataSource = self;
[self loadData];
}

Error applying dictionary to table view in IOS

I'm very new to developing in Objective C and am trying to figure out why I'm getting an error with my NSDictionary when trying to apply it to a table view. I'm getting the error "Expected method to read array element not found on object of type 'NSDictionary*". Does anyone know what that means, or how I would go about fixing it? I've included the model where I'm having the issue.
UPDATED:
The statement getting flagged is:
NSDictionary *conversation = self.data[indexPath.row];
Thanks!
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
ConversationTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"conversationCell" forIndexPath:indexPath];
// Get data from array at position of the row
NSDictionary *conversation = self.data[indexPath.row];
// Apply the data to each row
cell.conversationRecipients.text = [conversation valueForKey:#"recipients"];
cell.conversationPreview.text = [conversation valueForKey:#"last_message"];
cell.conversationTime.text = [conversation valueForKey:#"last_thread_post_short"];
//Set conversation thumbnail
[cell.conversationThumbnail sd_setImageWithURL:[conversation valueForKey:#"sender_avatar"]];
return cell;
}
Here's where I'm setting self.data:
// Successful Login
// Create the URL from a string.
NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:#"URLISHERE"]];
NSMutableURLRequest *request=[NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:60];
[request setHTTPMethod:#"GET"];
[request addValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
// Prepare for the response back from the server
NSHTTPURLResponse *response = nil;
NSError *error = nil;
// Send a synchronous request to the server (i.e. sit and wait for the response)
NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
NSError *serializeError;
id json = [NSJSONSerialization JSONObjectWithData:data options:0 error:&serializeError];
// Get response
self.data = json;
NSLog(#"%#", self.data);
// Reload data after Get
[self.tableView reloadData];
self.data needs to be of type NSArray not NSDictionary then it will work.

Issue reloading cellForRowAtIndexPath - Objective C

I am having an issue reloading my tableView when calling from an outside class to start a method and reload the tableView
More specifically:
Here is the call from the outside class:
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [collectionView cellForItemAtIndexPath:indexPath];
NSInteger tag = cell.tag;
impact* myScript = [[impact alloc] init];
[myScript startProcess:tag];
}
**From here** it moves to the `impact` class and loads the `startProcess` method:
- (void)startProcess:(NSInteger)number {
NSInteger testing = number;
cellID = testing;
// MAKE REQuEST TO SERVER
[self makeRequests];
dispatch_async(dispatch_get_main_queue(), ^{
[self.tableView reloadData];
});
}
This is the makeRequests method it calls:
-(void)makeRequests
{
/* GRAB USERNAME TO BE SENT OVER FOR NOTIFICATIONS */
NSArray *get = [[SSKeychain allAccounts] init];
//NSLog(#"get%#", get);
NSString *username = [get[0] objectForKey:#"acct"];
//if(cellID != 0)
//{
NSDictionary *dictionary = #{#"function": #"populateNotfications", #"username" : username};
NSError *error = nil;
NSData *data = [NSJSONSerialization dataWithJSONObject:dictionary options:0 error:&error];
NSString *string = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
if (error)
NSLog(#"%s: JSON encode error: %#", __FUNCTION__, error);
NSURL *url = [NSURL URLWithString:#"test.com/dev/iphone/test.php"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
[request setHTTPMethod:#"POST"];
NSString *params = [NSString stringWithFormat:#"json=%#",
[string stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
NSData *paramsData = [params dataUsingEncoding:NSUTF8StringEncoding];
[request addValue:#"8bit" forHTTPHeaderField:#"Content-Transfer-Encoding"];
[request addValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"Content-Type"];
[request addValue:[NSString stringWithFormat:#"%lu", (unsigned long)[paramsData length]] forHTTPHeaderField:#"Content-Length"];
[request setHTTPBody:paramsData];
// issue the request
NSURLResponse *response = nil;
NSData *returnData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
if (error)
NSLog(#"%s: NSURLConnection error: %#", __FUNCTION__, error);
// GRAB STATUS OBJECT
NSDictionary* json = [NSJSONSerialization
JSONObjectWithData:returnData //1
options:kNilOptions
error:&error];
self.impactsGrabed = [json objectForKey:#"requested_data"];
//}
}
Now from here it will run my tableView methods as shown below:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [self.impactsGrabed count];
}
- (double) tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 75;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"timelineCell";
impactTimelineCell *cell = (impactTimelineCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
cell = [[impactTimelineCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
[cell setSelectionStyle:UITableViewCellSelectionStyleNone];
[cell initTimelineCell];
cell.statusLabel.text = [self.impactsGrabed[indexPath.row] objectForKey:#"message"];
cell.timestampLabel.text = [self.impactsGrabed[indexPath.row] objectForKey:#"time_post"];
return cell;
}
I have logged every method and every method works until I hit cellForRowAtIndexPath where nothing happens than. Nothing is returning void. Now heres the thing:
When calling the function startProcess from another class that starts the whole process of loading the tableView cells it does not work. If I call the startProcess method inside the viewDidLoad in that file on initiation the tableView cells load properly.
So for example:
If I place [self startProcess:1]; within the viewDidLoad it works perfect! If I call [myScript startProcess:tag]; from the other class, it wont work properly.
What do you guys think the issue is?
Since all your controller are already instantiated and on screen, you don't need to instantiate one (and indeed you shouldn't since that creates a new instance that's not on screen).
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [collectionView cellForItemAtIndexPath:indexPath];
NSInteger tag = cell.tag;
impact* myScript = self.parentViewController.childViewControllers[1]; // if my script is one of the child view controllers, then this is how you need to access it -- the number might be 0,1 or 2 depending on which one is the impact controller
[myScript startProcess:tag];
}
You can also do this in prepareForSegue -- when your controller is instantiated, all the embedded child controllers will also be, and you can get a reference to them from the destinationViewController property of the segue.
Because this controller is already on screen, it's ok to call reloadData where you do in startProcess.

Resources