Iam having a hard time accessing another top-level JSON object within my application.
The plan is to load data from Instagram (which works), but not to count the top-level I want.
The JSON document can be found here (http://pastebin.com/0Z4vBjRn) Basically it has three top-level objects: pagination, meta and data (where I want the data bit).
This is my code for now:
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
// Viser "spinner" for å symbolisere nettverkstrafikk.
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
// URL til JSON filen
NSURL *newsUrl = [NSURL URLWithString:#"https://api.instagram.com/v1/tags/beer/media/recent?client_id=client_key"];
//URL Requestobjekt for å kontrollere tilkobling
NSURLRequest *newsRequest = [NSURLRequest requestWithURL:newsUrl];
[[NSURLConnection alloc]initWithRequest:newsRequest delegate:self];
}
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response{
[rawImages setLength:0];
rawImages = [[NSMutableData alloc] init];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{
[rawImages appendData:data];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
images = [[NSArray alloc]init]; // Updated
images = [NSJSONSerialization JSONObjectWithData:rawImages options:0 error:0];
[self.collectionView reloadData];
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
UIAlertView *errorView = [[UIAlertView alloc]initWithTitle:#"Feil" message:#"Det har oppstått en feil ved nedlastingen av data. Dobbeltsjekk at du er koblet til internett" delegate:nil cancelButtonTitle:#"Fortsett" otherButtonTitles:nil];
[errorView show];
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
}
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView {
return 1;
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
return [images count];
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
UICollectionViewCelle *cell = (UICollectionViewCelle *)[collectionView dequeueReusableCellWithReuseIdentifier:#"cell" forIndexPath:indexPath];
cell.imageView.image = [UIImage imageNamed:#"eksempel.jpg"];
return cell;
}
Obviously the count part won't work (it only returns three). But how could I make it count all the objects within the "data" object?
All help are highly appreciated! I've done my Googling but I can't seem to find exactly what Iam looking.
Related
I trying to search a particular name in an array, It is working well, But I want to cancel search by touching in other place in tableview, How to do that.
I trying to search a particular name in an array, It is working well, But I want to cancel search by touching in other place in tableview, How to do that.
- (void)viewDidLoad {
[super viewDidLoad];
// arr1=[[NSMutableArray alloc]initWithObjects:#"Raj",#"Ramu",#"Abdul",#"Kavitha",#"Abi",#"Abinesh",#"Gobi",#"Giri",#"Gayathri",#"Ramesh",#"Thiru",#"Sri",#"Siva",#"Senthil",#"Kumar",#"Rajkumar",#"Raman",#"Karthik",#"Kanna",#"Kamal",#"Ramya",#"Somu",#"Sankar",#"Murali",#"Muthu",#"Murugan",#"Nandha",#"Kamal", nil];
// NSLog(#"%#",arr1);
NSURL *url=[NSURL URLWithString:#"http://192.168.1.92/Abdul/Json/Json5.txt"];
NSURLRequest *req=[NSURLRequest requestWithURL:url];
conn=[NSURLConnection connectionWithRequest:req delegate:self];
if(conn)
{
webdata =[[NSMutableData alloc]init];
NSLog(#"Connection Success");
}
//[tabvw reloadData];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
-(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{
NSLog(#"%#",#"Fail");
}
-(void)connectionDidFinishLoading:(NSURLConnection *)connection {
jsonarr=[NSJSONSerialization JSONObjectWithData:webdata options:0 error:nil];
if (jsonarr> 0)
{
[tabvw reloadData];
}
}
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
return 1;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if (isfiltered)
{
return [filterarr count];
}
else
{
return [jsonarr count];
}
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
UITableViewCell *cell=[tableView dequeueReusableCellWithIdentifier:#"myid"];
if (cell==nil)
{
cell=[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"myid"];
}
if (isfiltered ) {
dic =[filterarr objectAtIndex:indexPath.row];
cell.textLabel.text=[dic objectForKey:#"Name"];
}
else
{
dic =[jsonarr objectAtIndex:indexPath.row];
cell.textLabel.text=[dic objectForKey:#"Name"];
}
return cell;
}
-(void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText{
NSPredicate *pred =[NSPredicate predicateWithFormat:#"Name contains[c]%#",searchText];
filterarr = [jsonarr filteredArrayUsingPredicate:pred];
NSLog(#"%#",filterarr);
isfiltered=YES;
[tabvw reloadData];
}
-(void)searchBarSearchButtonClicked:(UISearchBar *)searchBar{
[sbar resignFirstResponder];
}
let's try this and check output,
ViewDidLoad
UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(refreshData:)];
tapGesture.delegate = self;
[self.view addGestureRecognizer:tapGesture];
#pragma mark Gesture delegate
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
if (touch.view == self.view)
return YES;
return NO;
}
- (IBAction)refreshData:(id)sender
{
isfiltered=NO;
[tabvw reloadData];
}
Iam having a hard time updating my tableview with new results when the user slides to update (UIRefreshControl). The controller works properly, but the data never gets updated. I've tried to wipe the raw-data variable, and my NSArray that holds all the data, but it doesn't seem to work. Iam new to iPhone programming, so forgive me is this is a dumb question.
If I managed to fixed it, wouldn't it be wrong to remove all the data I've already pulled? Is there a simple way to append changes, considering most of my users will be using 3G/Edge connections. Here's my implementation class for the TableViewController:
#import "Nyhetsfane.h"
#interface Nyhetsfane ()
#end
#implementation Nyhetsfane
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Uncomment the following line to preserve selection between presentations.
// self.clearsSelectionOnViewWillAppear = NO;
// Kaller på slide to update.
[self updateTable];
UIRefreshControl *refreshControl = [[UIRefreshControl alloc] init];
[refreshControl addTarget:self action:#selector(updateTable) forControlEvents:UIControlEventValueChanged];
[refreshControl setAttributedTitle:[[NSAttributedString alloc] initWithString:#"Dra for å oppdatere"]];
self.refreshControl = refreshControl;
}
- (void)updateTable{
// Viser "spinner" for å symbolisere nettverkstrafikk.
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
// URL til JSON filen
NSURL *newsUrl = [NSURL URLWithString:#"http://localhost:7192/fadderapp/events.json"];
//URL Requestobjekt for å kontrollere tilkobling
NSURLRequest *newsRequest = [NSURLRequest requestWithURL:newsUrl];
[[NSURLConnection alloc]initWithRequest:newsRequest delegate:self];
[self.tableView reloadData];
[self.refreshControl endRefreshing];
}
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response{
[newsRawData setLength:0];
newsRawData = [[NSMutableData alloc] init];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{
[newsRawData appendData:data];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
newsCases = [NSJSONSerialization JSONObjectWithData:newsRawData options:0 error:0];
[self.tableView reloadData];
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
UIAlertView *errorView = [[UIAlertView alloc]initWithTitle:#"Feil" message:#"Det har oppstått en feil ved nedlastingen av data. Dobbeltsjekk at du er koblet til internett" delegate:nil cancelButtonTitle:#"Fortsett" otherButtonTitles:nil];
[errorView show];
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - Table view data source
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
return [newsCases count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"cell"];
if(cell == nil){
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:#"cell"];
}
cell.textLabel.text = [[newsCases objectAtIndex:indexPath.row]objectForKey:#"navn"];
return cell;
}
...
For all it's worth, here's my JSON feed:
[
{"navn": "Registration", "tidspunkt": "Monday 15:05", "beskrivelse": "Demo!"},
{"navn": "Party!", "tidspunkt": "Monday 19:30", "beskrivelse": "Demo"}
]
Try with this code
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
newCases = [NSArray array];
newsCases = [NSJSONSerialization JSONObjectWithData:newsRawData options:0 error:0];
[self.tableView reloadData];
}
The proper way to update a table view is to call
[self.tableView reloadData];
It should call all its datasource methods again automatically.
I am trying to parse a Json file into the Table view and I am getting this error
[__NSCFDictionary objectAtIndex:]: unrecognized selector sent to instance
and the app is crashing. Please help me, I am new to iOS development.
My Code
#implementation ViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
self.title = #"Feeds";
[super viewDidLoad];
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
NSURL *url = [NSURL URLWithString:#"http://little-people.blogspot.com/feeds/posts /default?alt=json"];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
[[NSURLConnection alloc] initWithRequest:request delegate:self];
}
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
data = [[NSMutableData alloc] init];
NSLog(#"Data Data , %#", data);
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)theData
{
[data appendData:theData];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
feed = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
NSLog(#"Data , %#", feed);
[mainTableView reloadData];
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
UIAlertView *errorView = [[UIAlertView alloc] initWithTitle:#"Error" message:#"The download could not complete - please make sure you're connected to either 3G or Wi-Fi." delegate:nil cancelButtonTitle:#"Dismiss" otherButtonTitles:nil];
[errorView show];
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
}
- (int)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (int)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [feed count];
NSLog(#"Data Data , %#", feed);
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"MainCell"];
if(cell == nil){
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:#"MainCell"];
}
if (([feed count] - 1) >=indexPath.row) {
cell.textLabel.text = [[feed objectAtIndex:indexPath.row] objectForKey:#"feed"];
cell.detailTextLabel.text = [[feed objectAtIndex:indexPath.row] objectForKey:#"title"];
}
return cell;
}
The problem is that feed is not a NSArray, but a NSDictionary.
Looking at the JSON, you likely want to access this array: [feed objectForKey:#"entry"]
The top level object in your feed is a JSON object, not a JSON array. So the deserialisation gives you an NSDictionary, not an NSArray.
I'm trying to do a request but it works only in the first time....
Here is my code:
NSArray *infos = [rows objectAtIndex:indexPath.row];
NSString *thumbPath = thePath;
NSURLRequest *thumbRequest = [NSURLRequest requestWithURL:[NSURL URLWithString:thumbPath]cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:10];
self->thumbConnection = [[NSURLConnection alloc] initWithRequest:thumbRequest
delegate:self
startImmediately:YES];
self->thumbData = [[NSMutableData alloc]init];
when receive Response
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
if (self->thumbData == nil) {
self->thumbData = [[NSMutableData alloc]init];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
self.thumbImage.image = [UIImage imageWithData:self->thumbData];
self.thumbActivityView.hidden = YES;
self->thumbData = nil;
}
when didFinishDownloading:
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
self.thumbImage.image = [UIImage imageWithData:self->thumbData];
self.thumbActivityView.hidden = YES;
[self->thumbData release];
self->thumbData = nil;
}
when timeout or other erros method:
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
[self->thumbData release];
self->thumbData = nil;
self.thumbActivityView.hidden = YES;
[thumbConnection release];
self->thumbConnection = nil;
}
Don't allocate it again if it's non-nil. Better still allocate it in your object's init method and release it in your object's dealloc method
I'm trying to show a custom MBProgressHUD while downloading a list of URLs with SDWebImagePrefetcher using NSURLConnection methods.
SDWebImagePrefetcher has a method that, when called, shows in console the progress of the images download.
Now, i would like to show that NSLog progress in the custom MBProgressHUD and I would like the HUD to stay on screen until the process is done, but I don't know how to do it and plus, when my NSURLConnection methods are called, it shows the initial HUD (Connnecting), then quickly jumps to "Complete", even if the images still needs to be downloaded.
Here's my code:
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
HUD.mode = MBProgressHUDModeDeterminate;
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
HUD.labelText = #"Loading";
HUD.detailsLabelText = #"Downloading contents..."; //here, i would like to show the progress of the download, but it seems to jump this part
HUD.dimBackground = YES;
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
//arr = array which holds a plist
NSMutableArray *array = [[[NSMutableArray alloc]init]autorelease];
for (NSDictionary *dict in arr) {
for (NSDictionary *val in [dict valueForKey:STR_ROWS]) {
[array addObject:[val objectForKey:#"image"]];
}
}
[prefetcher prefetchURLs:array];
HUD.customView = [[[UIImageView alloc] initWithImage:[UIImage imageNamed:#"checkmark.png"]] autorelease];
HUD.mode = MBProgressHUDModeCustomView;
HUD.labelText = NSLocalizedString(#"Completed",#"Completed!");
HUD.detailsLabelText = nil;
HUD.dimBackground = YES;
[HUD hide:YES afterDelay:2];
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
[HUD hide:YES];
UIAlertView *alertView = [[[UIAlertView alloc] initWithTitle:#"Connection Failed message:[NSString stringWithFormat:#"Connection to the remote server failed with error:\n %#\n Try again in a while"),[error localizedDescription]] delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil] autorelease];
[alertView show];
}
I tried to look into the examples, but didn't find out how to do what i want to do.
EDIT
HUD Setup:
-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex{
if (buttonIndex == 0){
[alertView dismissWithClickedButtonIndex:0 animated:YES];
}
else{
NetworkStatus internetStatus = [internetReachable currentReachabilityStatus];
switch (internetStatus) {
case NotReachable:
{
//not reachable
break;
}
case (ReachableViaWWAN):
{
//reachable but not with the needed mode
break;
}
case (ReachableViaWiFi):{
HUD = [[MBProgressHUD showHUDAddedTo:self.navigationController.view animated:YES]retain];
HUD.delegate = self;
HUD.dimBackground = YES;
HUD.labelText = #"Connecting...";
NSURL *URL = [NSURL URLWithString:#"http://mywebsite.com/myPlist.plist"];
NSURLRequest *request = [NSURLRequest requestWithURL:URL];
NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
[connection start];
[connection release];
break;
}
default:
break;
}
}
}
Any ideas?
In connection:didReceiveResponse: you must record how large the download is,
for example in self.responseSize. Then, in connection:didReceiveData: you
must append the data you just got to the data you previously got, and update the progress:
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
HUD.mode = MBProgressHUDModeDeterminate;
HUD.labelText = #"Loading";
HUD.detailsLabelText = #"Downloading contents...";
HUD.dimBackground = YES;
// Define responseSize somewhere...
responseSize = [response expectedContentLength];
myData = [NSMutableData data];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
[myData appendData:data];
HUD.progress = (float)myData.length / responseSize;
}