Making TableView Pull from 1 of 2 NSURLRequests - objective-c

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.

Related

Cannot call method in objective c

I'm having difficulty understanding how to call a method. Here's the code:
- (void)beachJSON
{
// Build the string to call Beach API
NSString *urlString = [NSString stringWithFormat:#"http://nrw-bwq-dev-api.azurewebsites.net/api/Pull"];
// Create NSURL string from formatted string
NSURL *url = [NSURL URLWithString:urlString];
// Setup and start async download
NSURLRequest *request = [[NSURLRequest alloc] initWithURL: url];
NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
[connection release];
[request release];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
// Store incoming data into a string
NSString *jsonString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
results = [jsonString JSONValue];
}
- (NSArray *)getBeachList {
[self beachJSON];
return results;
}
I call getBeachList from another class to populate 'results', beachJSON is called fine but I need to call
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
Within
- (NSArray *)getBeachList
i.e. right here
- (NSArray *)getBeachList {
[self beachJSON];
//This is where I want to call it to populate results before it is returned
return results;
}
Calling getBeachList will call beachJSON but the connection method will be skipped over leaving 'results' nil
If i try simply putting
[self connection:(NSURLConnection *)connection didReceiveData:(NSData *)data]
I get a expected expression error on that line.
I'm pretty new to objective c so any help would be great.
You don't need to call this method.
It's a delegate method of NSURLConnection.
What you need is to set a delegate for connection and method will be called by connection when it downloads any data.
You should not call connection:didReceiveData: by yourself. This is an event which is only supposed to be fired by the NSURLConnection instance. As far as I can see the only thing you are missing is the start call, which actually makes the NSURLConnection perform the request.
Try this:
NSURLRequest *request = [[NSURLRequest alloc] initWithURL: url];
NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
[connection start];
Then you should see that your NSURLConnection instance will call your implementation of connection:didReceiveData:.
If you want to be sure that your data is fully loaded you should be using this event instead:
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
The connection:didReceiveData: will be called multiple times if your data size is large enough. Every time the NSURLConnection receives data it will invoke connection:didReceiveData:. connectionDidFinishLoading: will only be called once when all your data is ready.

Downloading images and captions with JSON in xcode

I have googled this numerous times, with lots of different phrasing, but nothing seems to have exactly what I am after.
What I want to do is to download images and captions into a NSArray with JSON. I do not want to save these images, only display them in a UICollectionView. It would be much easier to be able to download multiple images using the same URL, not just 1 image per URL.
Since I am a fairly newbie programmer, I only know how to use NSURLRequest. This is some of my code:
NSString *getDataURL = [[NSString stringWithFormat:#"URL and a couple of perams", var, var2] stringByReplacingOccurencesOfString:#" " withString:#"%20"];
NSURLRequest *req = [NSURLRequest requestWithURL:[NSURL URLWithString:getDataURL]];
[[NSURLConnection alloc] initWithRequest:req delegate:self];
And then a bit later on in the connectionDidFinishLoading: method:
NSArray *dataArray = [NSJSONSerialization JSONObjectWithData:data options:nil error:nil]; // variable 'data' is an NSMutableData declared in .h
Please advise on what to do, or even if it's possible!
Thanks in advance!
You can do it this way:
-(void) loadImageAtURL:(NSString*)url {
NSURL *requestURL = [[NSURL alloc] initWithString:url];
NSURLRequest *request = [[NSURLRequest alloc] initWithURL:requestURL cachePolicy:nil timeoutInterval:45.0];
connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
imageData = [[[NSMutableData alloc] init] retain];
}
And handle response in NSURL delegate methods like:
- (void)connection:(NSURLConnection *)connection
didReceiveData:(NSData *)data {
[imageData appendData:data];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)aConnection {
// RELEASE THE CONNECTION
[connection release];
// CREATE NEW UIIMAGE FROM THE DATA
UIImage *image = [[[UIImage alloc] initWithData:imageData] retain];
[imageData release];
[yourImageView setImage:image];
[image release];
}
- (void)connection:(NSURLConnection *)connection
didFailWithError:(NSError *)error {
// Handle error
}
Hope these methods will give you direction how to carry out things. You make the JSON handling as per your API response in didReceiveData:(NSData *)data and use that data later in connectionDidFinishLoading:
I'm not sure I understand exactly what you are trying to ask but if your goal is to get a list of images/captions using JSON give AFNetworking a try
https://github.com/AFNetworking/AFNetworking

iOS Read Json from web and display to tableView

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.

NSURLConnection is returning null when XML is expected

I have a basecamp account which I'm trying to access via its XML API.
I have created a NSURL Request with proper header fields.
NSURL* projectsUrl = [NSURL URLWithString:[self.accountURL stringByAppendingString:#"/projects.xml"]];
NSMutableURLRequest* projectsRequest = [NSMutableURLRequest requestWithURL:projectsUrl];
[projectsRequest setValue:#"application/xml" forHTTPHeaderField:#"Content-Type"];
[projectsRequest setValue:#"application/xml" forHTTPHeaderField:#"Accept"];
I create a connection and start it.
NSURLConnection* connection = [[NSURLConnection alloc] initWithRequest:projectsRequest delegate:self];
[connection start];
[connection autorelease];
Basecamp uses HTTP basic authentication. So I use a NSCredential object to handle it as below.
-(void) connection:(NSURLConnection*)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge*)authenticationChallenge
{
if ([authenticationChallenge previousFailureCount] <=2 ) {
NSURLCredential* basecampCredentials;
basecampCredentials = [NSURLCredential credentialWithUser:[self username]
password:[self password]
persistence:NSURLCredentialPersistenceNone];
[[authenticationChallenge sender] useCredential:basecampCredentials forAuthenticationChallenge:authenticationChallenge];
}else {
[[authenticationChallenge sender] cancelAuthenticationChallenge:authenticationChallenge];
}
}
And when I receive data from connection i handle it with these delegates.
-(void) connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
[[self responseData] appendData: data];
NSLog(#"I received %#", [self responseData]);
}
-(void) connectionDidFinishLoading:(NSURLConnection*)connection
{
NSLog(#"I FINALLY received %#", [self responseData]);
NSXMLParser* parser = [[NSXMLParser alloc] initWithData:[self responseData]];
[parser setDelegate:self];
BOOL success = [parser parse];
if (success) {
NSLog(#"XML parse success");
}else {
NSLog(#"XML parse ERROR");
}
[parser autorelease];
}
The problem is even after using right urls, authentication credentials and header fields I get null data in responseData whereas when I try to access the same url with curl I get proper xml response from the basecamp server. I'm new to objective C. Please explain and tell me what else should I set to get this right.
Before starting connection ([connection start];) you should initialise property responseData, for example, self.responseData = [[NSMutableData alloc] init];.
In method - (void)connection:(NSURLConnection *)conn didReceiveResponse:(NSURLResponse *)response you should set the length of that data to zero : [self.responseData setLength:0];
Are you sure you set [self responseData]?
Try the same URL with an ASIHTTPRequest and see if it works.

What is asynchronous image downloading and how can I download too many images?

I have too many images to be download from net into iPhone? How can I build an application using asynchronous image downloading?.
Most common and simple way is to use NSURLConnection with asynchronous request. Create connection with request set delegate, and it starts load data in background calling delegate methods when receive next chunk of data, finish load or fail. when first object is loaded, start next and so on.
Here is slightly simplified working code:
- (id)init...{
//...
requestData = [[NSMutableData alloc] initWithCapacity:1000000];
myImages = [[NSMutableArray alloc] initWithCapacity:100];
myImagesAddresses = [[NSMutableArray alloc] initWithCapacity:100];
[myImagesAddresses addObject:#"http://mysite.com/image1"];
[myImagesAddresses addObject:#"http://mysite.com/image2"];
//...
[self loadNextImage];
//...
}
-(void)loadNextImage{
if ([myImagesAddresses count]){
NSURL * imageURL = [NSURL URLWithString:[myImagesAddresses lastObject]];
NSURLRequest * myRequest = [NSURLRequest requestWithURL:imageURL];
[[NSURLConnection alloc] initWithRequest:myRequest delegate:self];
NSLog(#"start load URL:%#", imageURL);
}
else{
NSLog(#"No more images to load");
// all images are ready to use!
}
}
// connection delegate methods
- (void)connection:(NSURLConnection*)connection didReceiveData:(NSData*)data{
NSLog(#"more data...");
[requestData appendData:data];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)inConnection{
[myImages addObject:[UIImage imageWithData:[NSData dataWithData:requestData]]];
[inConnection release];
inConnection = nil;
NSLog(#"Image from:%# loaded",[myImagesAddresses lastObject]);
[myImagesAddresses removeLastObject];
[self loadNextImage];
}
- (void)connection:(NSURLConnection *) inConnection didFailWithError:(NSError *)error{
[inConnection release];
inConnection = nil;
NSLog(#"Image from:%# not loaded",[myImagesAddresses lastObject]);
[myImagesAddresses removeLastObject];
[self loadNextImage];
}