how to data fetch using json parsing in ios - iphone

I am beginner of iPhone developer. I want to display data from server I have used below source code..
-(void)loadData:(id)sender
{
self.requestdata=[NSMutableData data];
NSURLRequest *request=[NSURLRequest requestWithURL:[NSURL URLWithString:kLatestKivaLoansURL]];
[[NSURLConnection alloc]initWithRequest:request delegate:self];
}
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
[requestdata setLength:0];
}
-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
[requestdata appendData:data];
}
-(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
[connection release];
self.requestdata=nil;
}
#pragma mark-
#pragma process loan data
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
[connection release];
NSString *responsedata=[[NSString alloc]initWithData:requestdata encoding:NSUTF8StringEncoding];
self.requestdata=nil;
NSDictionary *respDict = [[responsedata JSONValue]objectForKey:#"nodes"];
NSLog(#"Response Dict:%#",respDict);
NSMutableArray *arraY = [[NSMutableArray alloc]init];
arraY = [respDict mutableCopy];
NSLog(#"My array:%#",arraY);
NSString *mystr = [[[arraY objectAtIndex:0]valueForKey:#"node"]valueForKey:#"field_company_name_value"];
NSLog(#"Mystrname:%#",mystr);
NSArray *latestLoans=[(NSDictionary *)[responsedata JSONValue]objectForKey:#"responseData"];
NSLog(#"latest_dictionary:%#",latestLoans);
DisplayViewController *disp=[[DisplayViewController alloc]init];
for (int i = 0; i< [[latestLoans valueForKey:#"entries"] count] ; i++) {
// Search *aSearches = [[Search alloc] init];
NSDictionary *tempDict = [[latestLoans valueForKey:#"entries"] objectAtIndex:i];
// disp.link=[tempDict valueForKey:#"link"];
/*link = [tempDict valueForKey:#"link"];
aSearches.title = [tempDict valueForKey:#"title"];
aSearches.description = [tempDict valueForKey:#"contentSnippet"];
[appDelegate.search addObject:aSearches];*/
[appDelegate.disparray addObject:tempDict];
}
NSLog(#"DisplayArray:%#",appDelegate.disparray);
[self.view addSubview:disp.view];
/* DisplayViewController *disp=[[DisplayViewController alloc]initWithNibName:#"DisplayViewController" bundle:nil];
[self.navigationController pushViewController:disp animated:YES];*/
}
Please give any suggestion or source code which is apply in my code

Take a look at AFNetworking. It will do the job for you.
There is a specific method to handle JSON operations through the class AFJSONRequestOperation
Hope it helps.

http://www.touch-code-magazine.com/how-to-fetch-and-parse-json-by-using-data-models/
http://blog.zachwaugh.com/post/309924609/how-to-use-json-in-cocoaobjective-c
http://www.raywenderlich.com/5492/working-with-json-in-ios-5
http://json.org/
This is great tutorial for beginner, pls read this tutorial.

Related

Asynchronous NSURLConnection getting failed with auto mistypecasting of class instance

I am creating a single instance of a chase class which has a dictionary as a property.
As I add elements to dictionary, I can see the change in the count of dictionary keys.
But when I am accessing, it's firing a crash with message like given below:
[__NSCFString connection:didReceiveData:];
[__NSCFArray reqmap]; etc..
Basically, I am mapping request url with NSData instance, so that the response could be mapped and appended properly, asynchronously.
Code:
-(id)init
{
self = [super init];
if (self)
{
self.cacheDict = [[NSMutableDictionary alloc] initWithCapacity:20];
self.reqmap = [[NSMutableDictionary alloc] initWithCapacity:20];
}
return self;
}
+ (CommunityImageCache*)getSharedCommunityImageCache
{
if (sharedCommunityImageCacheInstance == nil) {
sharedCommunityImageCacheInstance = [[super allocWithZone:NULL] init];
}
return sharedCommunityImageCacheInstance;
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
NSString* keyurl = [[[connection currentRequest] URL] absoluteString];
//crash point >>>>
NSMutableData* tempdata = (NSMutableData*)[self.reqmap objectForKey:keyurl];
[tempdata appendData:data];
}
- (void)connectionDidFinishLoading:(NSURLConnection*)theConnection
{
NSString* keyurl = [[[theConnection currentRequest] URL] absoluteString];
NSMutableData* tempdata = [self.reqmap objectForKey:keyurl];
UIImage* img = [UIImage imageWithData:tempdata];
[self.cacheDict setObject:img forKey:[#"image:\\\\public\\" stringByAppendingString:keyurl]];
[self.reqmap removeObjectForKey:keyurl];
}
-(UIImage *)getImageFromUrl:(NSString *)url
{
UIImage* image = nil;
image = [self.cacheDict objectForKey:url];
if (!image)
{
image = [UIImage imageNamed:#"defaultProfile.png"];
//dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
NSString* localUrl = [NSString stringWithString:url];
NSString* finurl = [localUrl substringFromIndex:[#"image:\\\\public\\" length]];
UIImage* img = nil;
NSURLRequest* request = [NSURLRequest requestWithURL:[NSURL URLWithString:finurl]
cachePolicy:NSURLRequestUseProtocolCachePolicy
timeoutInterval:60.0];
NSMutableData* data = [[NSMutableData alloc] init];
NSURLConnection* connect = [[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:YES];
NSString* keyurl = [[[connect currentRequest] URL] absoluteString];
[self.reqmap setObject:data forKey:keyurl];
}
}
Needed badly, Thanks in advance.
Well, reqmap is suppose to contain NSMutableData objects, right ?
They need instantiation, something like :
[self.reqmap setValue:[[NSMutableData alloc] init] forKey:#"TheKey"];
You should also implement
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
when you're using NSURLConnection. I don't see it in your code above. Then you should alloc/reset the data in this function.
What is the actual error you are seeing? It sounds like either reqmap isn't an NSDictionary (though it is in your code above), or the object you're retrieving isn't a NSMutableData.
In total, implement:
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
- (void)connectionDidFinishLoading:(NSURLConnection *)connection

UIActivityIndicatorView freeze

i have this function which call a function to check CMS for info. but the UIActivityIndicatorView freeze till the check is completed. not sure why.
EDIT: one thing funny, i commented out the performselector. the UIActivityIndicatorView still freezed. until i tapped my back button then it started to spin....
i'm using storyboard, iOS 5
-(void)showLoading
{
[activity startAnimating];
//loading is a label to show "File Loading"
loading.alpha =1;
//is a label to show a 0.3 alpha of the label
blackOverlay.hidden =0;
[self performSelector:#selector(updateFromInternet:) withObject:#"a" afterDelay:2];
//[self updateFromInternet:#"a"];
}
-(void)updateFromInternet:(NSString *)urlStr
{
NSString *URLString = #"http://sites.google.com/site/iphonesdktutorials/xml/Books.xml";
NSURL *updateDataURL = [NSURL URLWithString:URLString];
NSMutableURLRequest *WPXMLFetchRequest = [NSMutableURLRequest requestWithURL:updateDataURL];
self.receivedData = [NSMutableData data];
self.updateConnection = [NSURLConnection connectionWithRequest:WPXMLFetchRequest delegate:self];
NSLog(#"Checking update at : %#", updateDataURL);
//[self.updateConnection cancel];
}
-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
////NSlog(#"Receiving data");
[self.receivedData appendData:data];
}
-(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
////NSlog(#"Failed to receive data");
self.receivedData = nil;
}
-(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
////NSlog(#"Received response from data");
[self.receivedData setLength:0];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
NSString *data=[[NSString alloc]initWithData:self.receivedData encoding:NSUTF8StringEncoding];
NSLog(#"data %#",data);
NSError *parseError = nil;
//NSDictionary *xmlDict = [XMLReader dictionaryForXMLData:self.receivedData error:&parseError];
self.receivedDict = [XMLReader dictionaryForXMLData:self.receivedData error:&parseError];
[self showDataOnScrollView];
}
You should delay the "heavy" function a bit and let the Activity Indicator fire.
try adding a 2.0 and not 2 to your delay (I would use a much smaller value - say 0.3)
[self performSelector:#selector(updateFromInternet:) withObject:#"a" afterDelay:0.3];
if this does not solve's your problem you should look (or post) the code related to the extra stuff you have in your code like : loading.alpha =1; and blackOverlay.hidden =0; which I assume are elements added to the Activity Indicator

iPhone App: Yelp Api integration problem

in My iPhone App I want to integrate Yelp API
for that I download Yelp example from GitHub
I tried to Add All library files ,both Frameworks for Yelp and Github into my project
but still I am not able to reference the files which are in framework"s Header.
like:GHAsyncTestCase and it is giving message can not find interface declaration "GHAsyncTestCase" superClass of AOuthTest
What could be wrong ?
please help me to integrate it and if possible explain me all required steps to integrate it into my project.
Thanks
you have do additional settin in xcode
YAJL Framework Installing in XCode 4 (iOS)
* In Build Phases, make sure its listed in Link Binary With Libraries, along with:
o CoreGraphics.framework
o Foundation.framework
o UIKit.framework
* In Build Settings:
o Under Framework Search Paths make sure the (parent) directory to YAJLiOS.framework is listed.
o Under Other Linker Flags in your target, add -ObjC and -all_load
* Import with #import <YAJL/YAJL.h>.
EDITED
you can create custom class or write the below code in any class but i suggest you to create custom class as follows :
in .h file say test.h
#import <Foundation/Foundation.h>
#import "OAuthConsumer.h"
#import <GHUnit/GHUnit.h>
#import <YAJL/YAJL.h>
#interface test : NSObject
{
NSMutableData *responseData;
NSDictionary *JSON1 ;
}
- (NSMutableDictionary *) getData ;
#end
now in test.m file
#import "test.h"
#import "OAuthConsumer.h"
#implementation test
- (void)test:(NSString *)urlString
{
NSURL *URL = [NSURL URLWithString:#"http://api.yelp.com/v2/search?term=restaurants&location=new%20york"];
OAConsumer *consumer = [[[OAConsumer alloc] initWithKey:#"yourKey" secret:#"yourKey"] autorelease];
OAToken *token = [[[OAToken alloc] initWithKey:#"yourKey-" secret:#"yourKey-Bc"] autorelease];
id<OASignatureProviding, NSObject> provider = [[[OAHMAC_SHA1SignatureProvider alloc] init] autorelease];
NSString *realm = nil;
OAMutableURLRequest *request = [[OAMutableURLRequest alloc] initWithURL:URL
consumer:consumer
token:token
realm:realm
signatureProvider:provider];
[request prepare];
responseData = [[NSMutableData alloc] init];
//[self prepare];
NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
//[self waitForStatus:kGHUnitWaitStatusSuccess timeout:10.0];
//NSDictionary *JSON = [responseData yajl_JSON];
//GHTestLog(#"JSON: %#", [JSON yajl_JSONStringWithOptions:YAJLGenOptionsBeautify indentString:#" "]);
//NSLog(#"%#",[JSON valueForKey:#"region"]);
[connection release];
[request release];
}
- (void) setString
{
//NSMutableString *JSON = [[NSMutableString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];
//NSLog(#"JSON Data Parsing:--->%#",JSON);
JSON1 = [responseData yajl_JSON];
NSArray *arry = [JSON1 valueForKey:#"businesses"];
for (int i = 0; i < [arry count]; i ++)
{
NSLog(#"Res Name : %#",[[arry objectAtIndex:i] valueForKey:#"name"]);
}
NSDictionary *temp = [arry objectAtIndex:0];
}
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
[responseData setLength:0];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
[responseData appendData:data];
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
NSLog(#"Error: %#, %#", [error localizedDescription], [error localizedFailureReason]);
//[self notify:kGHUnitWaitStatusFailure forSelector:#selector(test)];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
[self setString];
//[self notify:kGHUnitWaitStatusSuccess forSelector:#selector(test)];
}
- (NSDictionary *) getData
{
return JSON1 ;
}
- (void)tearDown
{
[responseData release];
responseData = nil;
}
#end
I hope it help. Its working for me ....

l[20]ve: invalid chunk type?

I don't know why I'm getting this error. I'm also getting an EXC_BAD_ACCESS issue from the following code. Any ideas why?
Running breakpoints on the didRecieveResponse and didRecieveData and didFinishLoading shows the first two get run and mid way through recieving data the program crashes.
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
// starts... :)
plistContentsData = [NSMutableData data]; //NSMutableData - inst in head
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
[plistContentsData appendData:data];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
mellowListings = [[NSArray alloc] initWithData:plistContentsData]; //NSArray - inst in head
NSLog(#"%#",mellowListings);
CLLocationCoordinate2D newLocation;
int counter = 0;
for(NSDictionary *tempDict in mellowListings){
NSLog(#"%f",([[tempDict objectForKey:#"lat"] floatValue]));
NSLog(#"%f",([[tempDict objectForKey:#"long"] floatValue]));
newLocation.latitude = ([[tempDict objectForKey:#"lat"] floatValue]);
newLocation.longitude = ([[tempDict objectForKey:#"long"] floatValue]);
TCPlaceMarker *placemark = [[TCPlaceMarker alloc] initWithCoordinate:newLocation];
placemark.title = [tempDict objectForKey:#"name"];
placemark.subtitle = [tempDict objectForKey:#"address1"];
placemark.source = [[tempDict objectForKey:#"source"] lowercaseString];
placemark.tag = counter;
[mapView addAnnotation:placemark];
counter++;
}
}
plistContentsData = [NSMutableData data];
You create an autoreleased NSMutableData object and it may become invalid right after you exit didReceiveResponse method. You need to retain plistContentsData to fix that error.

Adding a new row in a UITableView

HI Everyone,
It is my first post here and this is my problem:
I am trying to get some data from a REST API call and show then in a UITableView.
This s what I am doing:
in the viewDidLoad: 1) here I initialize my array of things to show in the Table (that is empty at the beginning) 2) the table is loaded (with 0 rows) and 3) then the HTTP async call is issued.
Done this I do my stuff with the HTTP Response and when ready I call the reloadData on my table. Here the strange happens.
numberOfRowsInSelection returns me the correct number of rows
but
tableView:cellForRowAtIndexPath:indexPath for the indexPath.row always returns me zero!
so no new row is added to the table.
- (void)doJSONRequest{
responseData = [[NSMutableData data] retain];
NSString *addr = [[NSString alloc] initWithFormat:#"http://localhost:8080/blabla/v1/items?count=10"];
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:addr]];
[[NSURLConnection alloc] initWithRequest:request delegate:self];
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
[addr release];
}
- (void)doJSONRequestWithURL:(NSString *)url{
responseData = [[NSMutableData data] retain];
NSString *addr = [[NSString alloc] initWithFormat:url];
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:addr]];
[[NSURLConnection alloc] initWithRequest:request delegate:self];
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
[addr release];
}
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
//NSLog(#"[%#] connection:didReceiveResponse %#",[self class], response);
[responseData setLength:0];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
//NSLog(#"[%#] connection:didReceiveData %#",[self class], data);
[responseData appendData:data];
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
NSLog(#"[%#]",[NSString stringWithFormat:#"Connection failed: %#", [error description]]);
UIAlertView *alert = [[UIAlertView alloc] init];
[alert setTitle:#"NETWORK ERROR!"];
[alert setMessage:#"App will close"];
[alert setDelegate:self];
[alert addButtonWithTitle:#"Close"];
[alert show];
[alert release];
[alert show];
[alert release];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
//NSLog(#"[%#] connectionDidFinishLoading %#",[self class], connection);
[connection release];
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
NSString *responseString = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];
[responseData release];
NSDictionary *res = [NSDictionary dictionaryWithDictionary:[responseString JSONValue]];
NSDictionary *tmp = [res valueForKey:#"reviews"];
tmp = [tmp valueForKey:#"reviews"];
NSEnumerator *e = [tmp objectEnumerator];
NSDictionary *tmp_review;
int i=0;
while (tmp_review = [e nextObject]) {
//NSLog(#"tmp_review %#", tmp_review);
//NSLog(#"count %d", i++);
MyObject r = [... doing my staff...]
[reviews addObject: r];
[r release];
};
[reviewListTableView reloadData];
[responseString release];
}
- (void)viewDidLoad {
//- (void)initUI {
//review is the array where I put my data
//it is empty at the beginning
reviews = [[NSMutableArray alloc] initWithObjects:nil];
[super viewDidLoad];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [reviews count]
}
Sounds like you may not have properly implemented numberOfSectionsInTableView:. You should log indexPath.section in tableView:cellForRowAtIndexPath:indexPath to see what section value you are passing. You will have multiple indexPath.row values of zero because there is a zero row for each section.
add new object in the array and [mytableview reloadData];
Implement following data source return number of section to be present in the table view.
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView;
In tableView:cellForRowAtIndexPath:indexPath check section number and do your operation.
Note: If you don't need sections you can remove it.