Loading UITableView with JSON from AFNetworking 2.0 - ios

I am trying to populate a UITableView with a remote JSON file. I am able to grab the JSON in the repsonseObject but am having trouble with the TableView. I am storing the JSON in an array.
My request looks like this:
- (void)makeJSONRequest
{
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
[manager GET:#"http://www.tylacock.com/cheats.json" parameters:nil
success:^(AFHTTPRequestOperation *operation, id responseObject) {
self.jsonFromAFNetworking = [responseObject objectForKey:#"ps3"];
}
failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Error: %#", error);
}];
}
And my cellForRowAtIndexPath method looks like this:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
NSDictionary *tempDict = [self.jsonFromAFNetworking objectAtIndex:indexPath.row];
cell.textLabel.text = [tempDict objectForKey:#"name"];
return cell;
}
I have checked to make sure the data source is connected to the ViewController. I was actually able to accomplish this with AFNetworking 1.X but since the upgrade and method changes I am at a loss.

You're loading the data asynchrously, so you've got to call [self.tableView reloadData] after setting jsonFromAFNetworking.

Related

iOS - Use responseObject outside of AFNetworking

I want to display the responseObject received from the below AFNetworking call in my tableview cell. I created an NSMutableArray property in my header file (neighbourData) thinking allocating responseObject to it might work. Though as predicted, I can't seem to use the data outside of the AFNetworking method. On the other hand, placing the AFNetworking method inside of my tableview cell works, but there is a lag time in waiting for the data to display in my UIlabels. Any ideas?
ViewController.h
#property (strong, nonatomic) NSMutableArray *neighbourData;
ViewController.m
- (void)viewDidLoad {
[super viewDidLoad];
NSMutableDictionary *viewParams = [NSMutableDictionary new];
[viewParams setValue:#"u000" forKey:#"view_name"];
[DIOSView viewGet:viewParams success:^(AFHTTPRequestOperation *operation, id responseObject) {
self.neighbourData = [responseObject mutableCopy];
NSLog(#"This is the neighbourdata %#",self.neighbourData);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Failure: %#", [error localizedDescription]);
}];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *NetworkTableIdentifier = #"sidebarCell";
self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
sidebarCell *cell = (sidebarCell *)[tableView dequeueReusableCellWithIdentifier:NetworkTableIdentifier];
if (cell == nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"sidebarCell" owner:self options:nil];
cell = [nib objectAtIndex:0];
}
NSDictionary *userName = [self.neighbourData objectAtIndex:indexPath.row];
[[cell username] setText:[userName objectForKey:#"users_name"]];
NSDictionary *userBio = [self.neighbourData objectAtIndex:indexPath.row];
[[cell userDescription] setText:[userBio objectForKey:#"userbio"]];
return cell;
}
You can initialise neighbourData with the responce object or just pass its refrence to your arry and then reload the table. it will work
self.neighbourData = [NSMutableArray alloc]initWithArry: responseObject]];
[yourTableView reloadData];
OR
self.neighbourData = (NSMutableArray *)responseObject;
[yourTableView reloadData];

Update UICollectionViewCell Before Scroll?

I have a working UICollectionViewCell in UITableViewCell. I'm using HWViewPager, so the collectionview cell moves from left to right. Unfortunately, the data is not updated until the user scrolls to the left or to the right. The content that fills up the cell is fetched from json, so I figure that has something to do but I'm not sure what. I load everything in awakeFromNib.
- (void)awakeFromNib {
] videoArray = [[NSMutableArray alloc] init];
[self getDisco];
}
with getDisco being a void function.
- (void)getDisco
{
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
[manager GET:url parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {
videoArray = [NSMutableArray arrayWithArray:[responseObject valueForKey:#"releases"]];
// NSLog(#"JSON: %#", responseObject);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Error: %#", error);
}];
}
Now, where the problem is.
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
if (indexPath.item < [videoArray count]){
DiscoCell * cell = [collectionView dequeueReusableCellWithReuseIdentifier:#"CollectionCell2" forIndexPath:indexPath];
NSDictionary *shot = [videoArray objectAtIndex:[indexPath row]];
cell.label2.text = [shot objectForKey:#"title"];
return cell;
return nil;
}else{
DiscoCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:#"CollectionCell2" forIndexPath:indexPath];
cell.label2.text = [NSString stringWithFormat:#"Cell %d", indexPath.row];
return cell;
}
}
Without the if/else statements, the viewcontroller crashed completely. With it, nothing updates till the user scrolls. My question is how do I get it all to pre-load, without crashing, for the user? Please keep UICollectionViewCell is in a tableviewcell.
You should reload collectionView after finished the request:
- (void)getDisco
{
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
[manager GET:#"http://musicbrainz.org/ws/2/release/?query=arid:e0140a67-e4d1-4f13-8a01-364355bee46e%20AND%20primarytype:single&fmt=json&limit=100" parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {
videoArray = [NSMutableArray arrayWithArray:[responseObject valueForKey:#"releases"]];
// NSLog(#"JSON: %#", responseObject);
[collectionView reloadData];
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Error: %#", error);
}];
}

Displaying JSON Data from URL using AFNetworking

I want to display json data from a URL.
Everything Works the data array is accessible in only did load section. When I use it to count count it gives NULL but inside did load it works. What is the issue.
.h file
#interface ViewController : UIViewController<UITableViewDataSource,UITableViewDelegate>
{
NSDictionary *dictArray;
NSString *title;
}
.m file
#import "ViewController.h"
#import "AFNetworking.h"
#import "AFHTTPRequestOperation.h"
#interface ViewController ()
{
NSArray *data;
}
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
[manager GET:[NSString stringWithFormat:#"sampleUrl"]
parameters:nil
success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSDictionary *weather = (NSDictionary *)responseObject;
data = [weather objectForKey:#"slider"];
NSLog(#"%#",data); // Works Fine
}
failure:^(AFHTTPRequestOperation *operation, NSError *error) {
UIAlertView *av = [[UIAlertView alloc] initWithTitle:#"Error Retrieving Weather" message:[NSString stringWithFormat:#"%#", error] delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[av show];
}];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [data count]; // doesn;t work
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *cellIdentifier = #"cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
dictArray = [data objectAtIndex:indexPath.row];
cell.textLabel.text = [dictArray objectForKey:#"title"];
NSLog(#"%#",data); // Doesn;t work displays NULL
return cell;}
#end
In success block of AFNetworking manager, reload your tableView. Table is now loading before the web service gets response.
success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSDictionary *weather = (NSDictionary *)responseObject;
data = [weather objectForKey:#"slider"];
NSLog(#"%#",data); // Works Fine
[yourTableView reloadData];
}

After reloading UITableView data, indexPathForCell returns null

I have a UITableView in a ViewController which contains a custom cell.
When the view first loads, the indexPathForCell in the following code returns the indexPath without problems:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
PostCell *postCell = (PostCell *)[tableView dequeueReusableCellWithIdentifier:#"PostCell"];
if (postCell == nil) {
NSLog(#"EmptyCell Found");
}
NSDictionary *object = [postArray objectAtIndex:indexPath.row];
NSString *imageURL = [object objectForKey:#"imageURL"];
NSIndexPath *originalIndexPath = indexPath;
NSLog(#"Original IndexPath %#", originalIndexPath);
SDWebImageManager *manager = [SDWebImageManager sharedManager];
[manager downloadWithURL:[NSURL URLWithString:imageURL]
options:indexPath.row == 0 ? SDWebImageRefreshCached : 0
progress:^(NSInteger receivedSize, NSInteger expectedSize){}
completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished){
if (image) {
// This returns correctly on first load
NSIndexPath *currentIndexPath = [imageTableView indexPathForCell:postCell];
NSLog(#"Current IndexPath %#", currentIndexPath);
}
}
];
}
After refreshing the tableView, currentIndexPath is always (null).
The following is my refresh code:
- (void)refreshMainView {
AFHTTPRequestOperation *downloadPostOperation = [[AFHTTPRequestOperation alloc] initWithRequest:serviceRequest];
[downloadPostOperation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
//[tableView beginUpdates];
NSDictionary *json = [NSJSONSerialization JSONObjectWithData:urlData options:kNilOptions error:&error];
NSMutableArray *newPostArray = [json objectForKey:#"posts"];
// Replacing the old array with new array
postArray = newPostArray;
[self stopRefresh];
//[tableView endUpdates]
[imageTableView reloadData];
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
[self stopRefresh];
}];
If I just perform [tableView reloadData] without performing refreshMainView, there will not be any problem with getting the currentIndexPath.
There must be something I am overlooking, could someone please help me? Thank you!
Edit:
I have tried [postCell.postImageView setImageWithURL:[NSURL URLWithString:imageURL] placeholderImage:nil]; instead and the refreshing works, so I am suspecting that something is wrong with me getting the indexPath in the completed block, can anyone help out please? I need the completed block as I am doing some image processing.
Hi I have finally fixed it.
For people who are needing answers, just add
dispatch_async(dispatch_get_main_queue(), ^{
});
around the portion that is retrieving the indexPathForCell.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
PostCell *postCell = (PostCell *)[tableView dequeueReusableCellWithIdentifier:#"PostCell"];
if (cell == nil)
{
nib = [[NSBundle mainBundle] loadNibNamed:#"PostCell" owner:self options:nil];
}
NSIndexPath *originalIndexPath = indexPath;
NSLog(#"Original IndexPath %#", originalIndexPath);
SDWebImageManager *manager = [SDWebImageManager sharedManager];
[manager downloadWithURL:[NSURL URLWithString:imageURL]
options:indexPath.row == 0 ? SDWebImageRefreshCached : 0
progress:^(NSInteger receivedSize, NSInteger expectedSize){}
completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished){
if (image) {
// This returns correctly on first load
NSIndexPath *currentIndexPath = [imageTableView indexPathForCell:postCell];
NSLog(#"Current IndexPath %#", currentIndexPath);
}
}
];
use this it may help you

SDWebImage With Custom UITableView Cell Image

I am trying to use SDWebImage library with a custom UITableViewCell. Below is the method that is downloading the images from the web service:
- (void) downloadThumbnails:(NSURL *)finalUrl
{
SDWebImageManager *manager = [SDWebImageManager sharedManager];
[manager downloadWithURL:finalUrl
options:0
progress:nil
completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished)
{
if (image)
{
// do something with image
// THERE I HAVE TO ASSIGN the property "thumbnail" with the "image"
// So it can be used by the tableview controller class
}
}];
}
The above code is in a separate file named RSSItem. While my UITableViewController class has the following cellForRowAtIndexPath method:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"ItemsCell";
ItemsViewCell *cell = (ItemsViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
RSSItem *item = [[channel items] objectAtIndex:[indexPath row]];
cell.titleLabel.text = [item title];
cell.creatorLabel.text = [item creator];
cell.pubTimeLabel.text = [item pubTime];
cell.thumbContainer.image = [item thumbnail];
return cell;
}
Can somebody point out how can i configure the if (image) inside downloadThumbnails method? I just need to assign "image" to the property "thumbnail", how can i do that?
Looks like you have already used the right method to download images asynchronously using SDWebImage. All you need to do is to set the thumbnail property to the "image". Here is how you can do it:
- (void) downloadThumbnails:(NSURL *)finalUrl
{
SDWebImageManager *manager = [SDWebImageManager sharedManager];
[manager downloadWithURL:finalUrl
options:0
progress:nil
completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished)
{
if (image)
{
[self setThumbnail:image];
}
}];
}

Resources