iOS Read Json from web and display to tableView - objective-c

What I am trying to do is read a json file on the web (I know the connection to this aspect is working) and then get some file contents to display on my tableView.
I was able to do this fine in another example but I'm not sure what the problem is now.
JSON File:
{
"entry":
[
{"Current Date":"Tuesday June 22 2011","Time Period":"00:00 - 06:45,"},
{"Current Date":"Tuesday June 23 2011","Time Period":"00:00 - 07:22"}
]
}
Button that fetches the JSON file from the web:
- (IBAction)getJsonButton:(id)sender {
[array removeAllObjects];
NSURL *url = [NSURL URLWithString:#"https://LinkToWhereJSONfileIsLocated/"];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
connection = [NSURLConnection connectionWithRequest:request delegate:self];
if(connection)
{
webData = [[NSMutableData alloc]init];
}
}
Here's where I think I'm having my problem (must be my logic or syntax):
-(void)connectionDidFinishLoading:(NSURLConnection *)connection
{
NSDictionary *allDataDictionary = [NSJSONSerialization JSONObjectWithData:webData options:0 error:nil];
NSArray *arrayOfEntry = [allDataDictionary objectForKey:#"entry"];
for (NSDictionary *diction in arrayOfEntry) {
NSString *currDate = [diction objectForKey:#"Current Date"];
[array addObject:currDate];
}
[[self myTableView]reloadData];
}

This is a quick guess, try calling reloadData method on main thread.

Related

How to make a POST request with an array in body data

I'm trying to do this with Objective-C but i think is the same body data but a don't know how it has to be.
I found the way to do this:
POST request
head: </*Your route*/>
body:
p=aString&p=bString&p=cString&p=dString
And then in the server you get:
body : {
p : [{
"aString",
"bString",
"cString",
"dString"
}]
}
Thanks for the support :)
One way (not sure the best way) is to encode the array in the POST data by sending the # of elements as a POST data field. For example
NSArray *array = #[#"hi", #"there"];
NSMutableString *postData = [NSMutableString stringWithFormat:#"array_length=%d", array.count];
for (int i=0; i<array.count; ++i)
[postData appendFormat:#"&array_%d=%#", i, array[i]];
// ...
The decoder, then, takes array_length and iterates over i = [0 .. array_length-1] to repopulate the array with array_0, array_1, ....
Here are two methods I used in an old project. You'll need to set the NSURLConnectionDelegate and implement the required methods.
// Check if the URLString is a valid data object
- (void) formatURLString: (NSString *) target forData:(NSArray *) data
{
if ([NSJSONSerialization isValidJSONObject:data])
{
NSError *error;
NSData *JSONdata = [NSJSONSerialization dataWithJSONObject:data options:kNilOptions error:&error];
// *** POST ***//
[self post:target withJSON:JSONdata];
} else
{
NSLog(#"Invalid JSON object. JSON object: %#", data);
}
}
- (void) post: (NSString *) target withJSON: (NSData *) jsonData
{
// Inform user network activity is taking place
[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES];
NSMutableURLRequest *urlRequest =
[[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:target]];
[urlRequest setHTTPMethod:#"POST"];
[urlRequest addValue:#"postValues" forHTTPHeaderField:#"METHOD"];
[urlRequest setHTTPBody:jsonData];
NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:urlRequest
delegate:self];
if (!connection) { NSLog(#"Connection Failed"); }
}

Making TableView Pull from 1 of 2 NSURLRequests

I am having trouble telling my table view which NSURLRequest it should target. I can get a basic table view to load with a single query, but am trying to make it pull the json string from a different URL if certain segmented controls are active.
These first three lines of code work by themselves
NSString *urlA1 = [NSString stringWithFormat:#"http://www.website.com/json_books.php?
item_id=%#",itemId];
NSURL *urlA2 = [NSURL URLWithString:urlA1];
NSURLRequest *requestA = [NSURLRequest requestWithURL:urlA2];
[[NSURLConnection alloc] initWithRequest:requestA delegate:self];
However, if I include the following three lines after the first three, the tableview loads the json from the first NSURLRequest, then immediately flickers and shows content from the string below:
NSString *urlB1 = [NSString stringWithFormat:#"http://www.website.com/json_movies.php?
item_id=%#",itemId];
NSURL *urlB2 = [NSURL URLWithString:urlB1];
NSURLRequest *requestB = [NSURLRequest requestWithURL:urlB2];
[[NSURLConnection alloc] initWithRequest:requestB delegate:self];
I am pulling the result into the table view with these lines of code:
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse
*)response
{
data = [[NSMutableData alloc] init];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)theData
{
[data appendData:theData];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
items = [NSJSONSerialization JSONObjectWithData:data options:nil error:nil];
[mainTableView reloadData];
}
Does anyone know why I am unable to specify which NSURLRequest I would like the tableview to target? Thank you!
Do you Want to Show Data from Both The URL ?
if yes then You have to take NSMUtableArray and initialize the Array in ViewDidload before Firing the Request. And You have to Add the Objects into the Array from Each URL.
Example:
[DataArray addObject:#"Yourdata"];
[Yourtable reloadData];
If You need to Separate the data as per Segmented Control then Save Your data in Separate Array.
MyfirstArray= #"Data from URL 1";
MySecondArray= #"Data from URL 2";
-(IBAction)SegmentChange:(Id)sender
{
if(segmented.selectedSegmentIndex==0)
{
items=MyfirstArray;
[mytable reloadData];
}
else
{
items=MysecondtArray;
[mytable reloadData];
}
}
Also You can take Switch statement.

Objective C NSURLConnection dosen't get response data

I am creating this application, it communicates with a PHP script on my web-server.
Last night it was working perfectly. But today two of the connections does not get response.
I've tried the NSURL link in my browser, it works fine. Also one of the connections work, but as i said two connections does not work?
- (void) getVitsTitelByID:(int)id {
NSString *url = [NSString stringWithFormat:#"http://webserver.com /ivitserdk.php?function=gettitelbyid&id=%d", id];
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:url] cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:1.0];
connectionTitelByID = [[NSURLConnection alloc] initWithRequest:request delegate:self];
}
connectionDidReciveData:
if(connection == connectionTitelByID){
responseTitel = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
}
connectionDidFinishLoading:
if(connection == connectionTitelByID){
titelLabel.text = responseTitel;
}
I've tried and debugging it.
responseTitel seems to be (null).
Help would be apriceated :)
didReceiveData may be called N (several) times. save the data to a mutably data buffer (queue it up) and in didFinish read it into a string
mock code:
- (void) getVitsTitelByID:(int)identifier {
NSString *url = [NSString stringWithFormat:#"http://webserver.com/ivitserdk.php?function=gettitelbyid&id=%d", identifier];
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:url] cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:1.0];
connectionTitelByID = [[NSURLConnection alloc] initWithRequest:request delegate:self];
dataForConnectionTitelByID = [NSMutableData data];
[connectionTitelByID start];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
if(!data.length) return;
if(connection == connectionTitelByID)
[dataForConnectionTitelByID appendData:data];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
if(connection == connectionTitelByID) {
id str = [[NSString alloc] initWithData:dataForConnectionTitelByID encoding:NSUTF8StringEncoding];
NSLog(#"%#",str);
dataForConnectionTitelByID = nil;
connectionTitelByID = nil;
}
}

Slow Multiple URL retreival in iOS code

I want to access a URL and retrieve data from this URL, based on the data retrieved I want to retrieve data from another URL
I tried accessing multiple URL in the following way:
- (void) showClassRoom:(NSString *)theMessage{
NSString *queryURL =[NSString stringWithFormat:#"http://nobert.cloudfoundry.com/CalOfEvents/tos"];
NSURL *url = [NSURL URLWithString: queryURL];
NSURLRequest *req = [NSURLRequest requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60.0];
NSError *error;
NSURLResponse *response;
NSData *returnData = [NSURLConnection sendSynchronousRequest:req returningResponse:&response error:&error];
if(returnData){
NSString *strResult = [[NSString alloc] initWithBytes:[returnData bytes] length:[returnData length] encoding:NSUTF8StringEncoding];
NSDictionary *result = [strResult JSONValue];
for(id theKey in result){
for(id hello in theKey){
NSLog(#"The key:%#, The value:%#",hello,[theKey objectForKey:hello]);
}
}
if(TRUE){//based on some condition secondShowClassRoom is called
[self secondShowClassRoom];
}
}
}
- (void) secondShowClassRoom{
NSString *queryURL =[NSString stringWithFormat:#"http://nobert.cloudfoundry.com/CalOfEvents/to"];
NSURL *url = [NSURL URLWithString: queryURL];
NSURLRequest *req = [NSURLRequest requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60.0];
NSError *error;
NSURLResponse *response;
NSData *returnData = [NSURLConnection sendSynchronousRequest:req returningResponse:&response error:&error];
if(returnData){
NSString *strResult = [[NSString alloc] initWithBytes:[returnData bytes] length:[returnData length] encoding:NSUTF8StringEncoding];
NSDictionary *result = [strResult JSONValue];
for(id theKey in result){
for(id hello in theKey){
NSLog(#"The key:%#, The value:%#",hello,[theKey objectForKey:hello]);
}
}
}
}
This retrieves the data VERY SLOWLY and my app requires very fast access as I am developing an application on Augmented Reality
There is another method that is faster however I am not able to access multiple URLs:
- (void) showClassRoom:(NSString *)theMessage{
NSString *queryURL =[NSString stringWithFormat:#"http://nobert.cloudfoundry.com/CalOfEvents/to"];
NSURL *url = [NSURL URLWithString: queryURL];
NSMutableURLRequest *req = [NSMutableURLRequest requestWithURL:url];
conn = [[NSURLConnection alloc] initWithRequest:req delegate:self];
if (conn) {
webData = [[NSMutableData data] retain];
}
classRoomControl.hidden = NO;
labControl.hidden = YES;
placementControl.hidden = YES;
}
-(void) connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *) response{
[webData setLength: 0]; }
-(void) connection:(NSURLConnection *)connection didReceiveData:(NSData *) data {
[webData appendData:data];
}
-(void) connection:(NSURLConnection *)connection didFailWithError:(NSError *) error {
[conn release];
[webData release];
}
-(void) connectionDidFinishLoading:(NSURLConnection *) connection {
[conn release];
NSLog(#"DONE. Received Bytes: %d", [webData length]);
NSString *strResult = [[NSString alloc] initWithBytes:[webData mutableBytes] length:[webData length] encoding:NSUTF8StringEncoding];
NSDictionary *result = [strResult JSONValue];
for(id theKey in result){
for(id hello in theKey){
NSLog(#"The key:%#, The value:%#",h,hello);
}
}
[strResult release];
[webData release];
}
Please Help me with this.Any help would be appreciated..
You are right on track preferring the asynchronous model for network communication (since synchronous communication will block your UI unless you handle it in a separate thread).
The correct way to chain multiple asynchronous network request is doing one request after another in the callbacks (i.e., in connectionDidFinishLoading; when one request is done, you send the next one).
One more suggestion is not using NSURlRequest/NSURLConnection for that, since they make thinks unnecessarily complex, and try with a framework like AFNetworking.

iOS Get Connection

This is my first time on this site and I am very new to coding so I was wondering if somebody could help me out.
I want to set a get request from my iphone app to my website and get the information echoed back from the website to my phone.
I have gotten this far but do not know where to go from here. Any help would be much appreciated, thanks!
- (void)myData:(id)sender
{
NSString *DataToBeSent;
sender = [sender stringByReplacingOccurrencesOfString:#"," withString:#"%20"];
[receivedData release];
receivedData = [[NSMutableData alloc] init];
DataToBeSent = [[NSString alloc] initWithFormat:#"http://194.128.xx.xxx/doCalc/getInfo.php?Data=%#",sender];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:dataToBeSent] cachePolicy:NSURLRequestReloadIgnoringLocalAndRemoteCacheData timeoutInterval:10];
[request setHTTPMethod: #"GET"];
NSError *requestError;
NSURLResponse *urlResponse = nil;
NSData *response1 = [NSURLConnection sendSynchronousRequest:request returningResponse:&urlResponse error:&requestError];
[dataToBeSent release];
}
OLD WAY
- (void)myData:(id)sender
{
NSString *dataToBeSent;
sender = [sender stringByReplacingOccurrencesOfString:#"," withString:#"%20"];
[receivedData release];
receivedData= [[NSMutableData alloc] init];
dataToBeSent= [[NSString alloc] initWithFormat:#"http://194.128.xx.xxx/doCalc/getInfo.php?Data=%#",sender];
NSURLRequest *theRequest=[NSURLRequest requestWithURL:[NSURL URLWithString:dataToBeSent]];
Theconn= [[NSURLConnection alloc]initWithRequest:theRequest delegate:self];
NSLog (#"test1 %#", theRequest);
NSLog (#"test2 %#", Theconn);
[dataToBeSent release];
}
Then the following methods are called and I get my data BUT if I sent another request after my first one but different data on the same connection, it would always give me the same result which shouldn't happen
- (void) connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
/* appends the new data to the received data */
[receivedData appendData:data];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)conn
{
NSString *stringData= [[NSString alloc]
initWithData:receivedData encoding:NSUTF8StringEncoding];
NSLog(#"Got data? %#", stringData);
[self displayAlertCode:stringData];
[stringData release];
// Do unbelievably cool stuff here //
}
Assuming your data loaded properly you can convert the data into a string and do whatever you want with it.
NSData *response1 = [NSURLConnection sendSynchronousRequest:request returningResponse:&urlResponse error:&requestError];
//Make sure to set the correct encoding
NSString* responseString = [[NSString alloc] initWithData:response1 encoding:NSASCIIStringEncoding];
If your server returns JSON there are 3rd party libraries that can parse the string into collections like NSArray and NSDictionary. If your server returns XML then NSXMLParser could be something you can use.
EDIT
I've changed your code to manage the memory a little differently.
.h
#property (nonatomic,retain) NSMutableData * receivedData;
#property (nonatomic,retain) NSURLConnection * Theconn;
.m
#synthesize receivedData;
#synthesize Theconn;
//A bunch of cool stuff
- (void)myData:(id)sender
{
//If you already have a connection running stop the existing one
if(self.Theconn != nil){
[self.Theconn cancel];
}
sender = [sender stringByReplacingOccurrencesOfString:#"," withString:#"%20"];
//This will release your old receivedData and give you a new one
self.receivedData = [[[NSMutableData alloc] init] autorelease];
NSString *dataToBeSent = [NSString stringWithFormat:#"http://194.128.xx.xxx/doCalc/getInfo.php? Data=%#",sender];
NSURLRequest *theRequest= [NSURLRequest requestWithURL:[NSURL URLWithString:dataToBeSent]];
//This will release your old NSURLConnection and give you a new one
self.Theconn = [NSURLConnection connectionWithRequest:theRequest delegate:self];
NSLog (#"test1 %#", theRequest);
NSLog (#"test2 %#", Theconn);
}
//...
//Your delegate methods
//...
- (void) dealloc{
[receivedData release];
[Theconn release];
[super dealloc];
}