objectatindex outside of loop? - objective-c

This is a question hard to ask but I'm going to give it a shot anyways. I'm trying to retrieving the contents of an NSDictionary outside of the UITableCell loop. Right now, when I do retrieve its content via:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
everything works fine. But outside of that loop, in a void function of its own, the number retrieved is 0.
- (void)getVideoList{
NSString *ensdsds = #"z9yDgV3ONSU";
for (int i=0; i< [self.youtubePaginator.results count]; i++){
NSDictionary *photoshoots = [self.youtubePaginator.results objectAtIndex:i];
NSString * videoId = photoshoots[#"videoID"];
NSLog(#"Newly %#: ", videoId);
NSString *urlStrings = [NSString stringWithFormat:#"https://www.googleapis.com/youtube/v3/videos?part=id%%2C+snippet%%2C+contentDetails%%2C+statistics&id=%#&key=78587868", videoId];
NSLog(#"Arries %#", urlStrings);
NSURL *urlstats = [NSURL URLWithString:urlStrings];
NSURLRequest *requeststats = [NSURLRequest requestWithURL:urlstats];
AFHTTPRequestOperation *operationtwo = [[AFHTTPRequestOperation alloc] initWithRequest:requeststats];
operationtwo.responseSerializer = [AFJSONResponseSerializer serializer];
[operationtwo setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operationtwo, id responseObjected)
{
NSDictionary *itemed = [responseObjected objectForKey:#"items"];
for (NSDictionary *itemest in itemed )
{
YouTubeVideo *youTubeVideo = [[YouTubeVideo alloc] init];
NSDictionary* stats = [itemest objectForKey:#"statistics"];
youTubeVideo.likesCount = [stats objectForKey:#"likeCount"];
youTubeVideo.viewsCount = [stats objectForKey:#"viewCount"];
NSDictionary* channelInfo = [itemest objectForKey:#"snippet"];
youTubeVideo.channelInfo = [channelInfo objectForKey:#"channelId"];
youTubeVideo.videoUploader = [channelInfo objectForKey:#"channelTitle"];
NSLog(#"True To: %#", youTubeVideo.videoUploader);
[self.thunder addObject:youTubeVideo];
}} failure:^(AFHTTPRequestOperation *operation, NSError *error)
{
NSLog(#"Error loading %#", error);
}];
[operationtwo start]; }
}
The above code returns nothing. How do I incorporate NSIndexPath in the void function and still be able to call [self getVideoList]; in viewDidLoad.
Hope that makes sense? :/

You can get the imageURL in getVideoList by passing NSIndexPath as a parameter , you just need to create a global NSString object if you want to access it globally or you can return extracted imageURL as a return value.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString * imageURL = [self getVideoList:indexPath];
// Write your code to perform operation with the image URL.
}
Here is the getVideoList method
- (NSString *)getVideoList:(NSIndexPath *)indexPath{
NSDictionary *photoshoots = [self.youtubePaginator.results objectAtIndex:indexPath.Row];
NSString * imageURL = photoshoots[#"avatar_url"];
NSLog(#"Newly %#: ", imageURL);
NSLog(#"To find us: [%d]:%#",i,self.youtubePaginator.results[i]);
return imageURL;
}
You can update the code as per your requirement.

Related

Array reduplication not working

Xcode problem. I have a nsmutablearray that is pulling json objects. Example Company: Name, state, address, phone number, etc.
I am pulling the info just fine. And I want to display 1 of each state in a table view. It works fine but shows multibles of the same state. But I only want to show 1 of each state. I am using some code but it does not return any states. I have seen a lot of examples and this should work but it returns nothing. If I skip this code below it does show all states. i have also tried a for loop. And tried array to NSSet. Nothing is working. Any Ideas???
My problem is with this code...
//Create states only array...remove duplicate states here
NSArray *statesArray = [companies valueForKeyPath:#"#distinctUnionOfObjects.state"];
return statesArray;
Here is my whole code. Please help been struggling with this for a week.
#interface StatesTableViewController ()
#property (nonatomic) NSString *name;
#property (nonatomic) NSString *state;
#end
#implementation StatesTableViewController
NSArray *companies;
NSArray *statesArray;
- (void)viewDidLoad {
[super viewDidLoad];
NSString *address = #"http://www.companiesFeed";
NSURL *url = [[NSURL alloc] initWithString:address];
//laod the data on a background queue..
//if we were connecting to a an online url then we need it
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
companies = [self readCompanies:url];//, statesSet = [self readCompanies:url];
//now that we have the data, reload the table data on the main ui thread
[self.tableView performSelectorOnMainThread:#selector(reloadData) withObject:nil waitUntilDone:YES];
});
}
//new code
- (NSArray *)readCompanies:(NSURL *)url {
//create a nsurlrequest with the given Url
NSURLRequest *request = [NSURLRequest requestWithURL:url cachePolicy:
NSURLRequestReloadIgnoringLocalAndRemoteCacheData timeoutInterval:30.0];
//get the data
NSURLResponse *response;
NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:nil];
//now create a nsdictionary from the json data
NSDictionary *jsonDictionary = [NSJSONSerialization JSONObjectWithData:data
options:0 error:nil];
//create a new array to hold the comanies
NSMutableArray *companies = [[NSMutableArray alloc] init];
//get an array of dictionaries with the key "company"
NSArray *array = [jsonDictionary objectForKey:#"companies"];
//iterate throught the array of dictionaries
for (NSDictionary *dict in array) {
//create a new company object with information in the dictionary
Company *company = [[Company alloc] initWithJSONDictionary:dict];
//add the Company object to the array
[companies addObject:company ];
}
//Create states only array...remove duplicate states here
NSArray *statesArray = [companies valueForKeyPath:#"#distinctUnionOfObjects.state"];
return statesArray;
//return companies;
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark -table view controller methods
//change uniqueValue errors to companies
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger) section {
//return[companies count];
return [statesArray count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *cellID = #"CellIDState";
UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:cellID];
if (cell == nil){
//single line on table view
//cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:cellID];
// dual line on table view
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellID];
}
//edit single state
//Company *company = [companies objectAtIndex:indexPath.row];
Company *company = [statesArray objectAtIndex:indexPath.row];
//cell.textLabel.text = company.company_id;
cell.textLabel.text = company.state;
cell.detailTextLabel.text = [NSString stringWithFormat:#"%#",company.companyName];
//adds cheveron to tableviewl
[cell setAccessoryType: UITableViewCellAccessoryDisclosureIndicator];
return cell;
}
#pragma mark - navigation
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
}
#end
I was able to get the unique list of states by using a predicate and a block to check a set for existing states. Like so:
NSMutableArray *statesArray = [NSMutableArray array];
[companies filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(id evaluatedObject, NSDictionary *bindings) {
Company *dict = (Company *)evaluatedObject;
BOOL seen = [statesArray containsObject:dict];
if (!seen) {
[statesArray addObject:dict];
}
return !seen;
}]];
NSLog(#"unique states: %#", statesArray);
Where the companies array looks like this:
{[{
"company_id": "22",
"entityformSubmissionID": "22",
"companyName": "house of waffles",
"companySlogan": " where your home is!",
"address1": "123 here",
"address2": "thre",
"city": "everywhere",
"state": "CA",
"zipCode": "94531",
"phoneNumber": "777-777-7777",
"email": "test#test.com",
"additionalCompanyInfo": "all additional company info is going here",
"sales": "There are no sales!",
"rentalTerms": "Terms is dont break our stuff jerks!",
"companyLogo": "/16x16icon.png"
}]

Unable to parse JSON to UITableView

Currently I'm trying to parse responseObject to populate my table view, but I've been having some problem with parsing the array in the responseObject. I want to populate my cell with values from responseObject[#"test"].
Request operation:
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
[manager POST:[kBaseURL stringByAppendingString:#"directori/member_list"]parameters:params
success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"RESPONSE: %#", responseObject);
if ([responseObject[#"status_reason"] isEqualToString:#"Success"]) {
self.allMembers = responseObject[#"test"];
NSLog(#"MEMBERS: %#", self.allMembers);
} else {
// handle error
}
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"ERROR: %#", error);
}];
As you can see below, test is an array of objects.
Sample responseObject:
RESPONSE: {
test = (
{
img = "http://test.com/assets_api/images/no_image.png";
location = "test location";
name = "test user";
position = "test";
}
);
"audit_no" = "";
"status_code" = 200;
"status_reason" = Success;
}
And here's is my table view data source.
Table View Data Source
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"DirectoryCell";
DirectoryViewCell *cell = (DirectoryViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell==nil) {
cell = [[DirectoryViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
NSDictionary *member = [self.allMembers objectAtIndex:indexPath.row];
NSLog(#"MEMBER: %#", member);
return cell;
}
allMembers is of type NSArray while member is of type NSDictionary.
When I try to log the value of member it returns null. Where did it go wrong?
You Should try this
NSDictionary *member = [[self.allMembers objectAtIndex:indexPath.row]objectAtIndex:0];

Multilevel JSON Dictionary - can't extract key into new dictionary

I've been stuck on a problem for a few days now. I have searched the internet and found many answers, but nothing that seems to work - I may not grasp how to modify my own code.
I have a JSON connection which I make a dictionary. This all works very well when I dont have a multilevel dictionary, but as soon as I have:
{
"Table": [
{
"MENUID": 1072.0,
"MENUDESC": "HOME ",
"PARENTMENUID": null,
"NAVIGATETO": "content.aspx?item=1072&pid=0",
"NAVIGATETO2": "default.aspx?item=1072&pid=0",
"PROTECTED": null,
"parentmenuid2": null
},
{
"MENUID": 1073.0,
"MENUDESC": "PRODUCTS & SERVICES",
"PARENTMENUID": null,
"NAVIGATETO": "#",
"NAVIGATETO2": "default.aspx?item=1073&pid=0",
"PROTECTED": null,
"parentmenuid2": null
}
]
}
I adapt my code as follows:
- (void)fetchTweets
{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSData* data = [NSData dataWithContentsOfURL:
[NSURL URLWithString: #"http://adhoc.nyxtek.co.za/spfjsonws/default2.aspx"]];
NSError* error;
menuItems = [NSJSONSerialization JSONObjectWithData:data
options:kNilOptions
error:&error];
NSArray * allKeys = [menuItems allKeys];
NSLog(#"Count : %d", [allKeys count]);
dispatch_async(dispatch_get_main_queue(), ^{
[self.tableView reloadData];
});
});
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return menuItems.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"TweetCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
NSDictionary *tweet = (NSDictionary *)[menuItems objectForKey:#"Table"];
NSArray * allKeys = [tweet allKeys];
NSLog(#"Count : %d", [allKeys count]);
//NSDictionary *tweet = [tweets objectAtIndex:indexPath.row];
NSString *text = [tweet objectForKey:#"MENUDESC"];
NSString *name = [tweet objectForKey:#"MENUID"];
cell.textLabel.text = text;
cell.detailTextLabel.text = [NSString stringWithFormat:#"by %#", name];
return cell;
}
Specifically this line of code is not working:
NSDictionary *tweet = (NSDictionary *)[menuItems objectForKey:#"Table"];
My first count of the outer dictionary is 1 which is correct, but my second count of the new above dictionary is 0 which is wrong.
I have applied much of this from researching previous questions as I understand the importance of research, but I still cant seem to find a specific fault.
Any assistance would be appreciated.
Table is an array (of dictionaries):
"Table": [
...
]
So the code should be:
NSArray *tweet = (NSArray *)[menuItems objectForKey:#"Table"];

NSCache to store images for UITableView

I have a view controller with a table view. in each cell of the table view, i have an image which is fetched from the net - but many of them have the same image. so, what i'm doing currently is storing the fetched images in a NSCache object. it happens this way:
- (void)fetchAvatarForUser:(NSString *)uid completion:(void (^)(BOOL))compBlock
{
if (!imageCache) {
imageCache = [[NSCache alloc] init];
}
if (!avatarsFetched) {
avatarsFetched = [[NSMutableArray alloc] initWithCapacity:0];
}
if ([avatarsFetched indexOfObject:uid] != NSNotFound) {
// its already being fetched
} else {
[avatarsFetched addObject:uid];
NSString *key = [NSString stringWithFormat:#"user%#",uid];
NSString *path = [NSString stringWithFormat:#"users/%#/avatar",uid];
[crudClient getPath:path parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"%#",[operation.response allHeaderFields]);
UIImage *resImage = [UIImage imageWithData:[operation responseData]];
[imageCache setObject:resImage forKey:key];
compBlock(YES);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Got error: %#", error);
compBlock(NO);
}];
}
}
- (UIImage *)getAvatarForUser:(NSString *)uid
{
NSString *key = [NSString stringWithFormat:#"user%#",uid];
NSLog(#"Image cache has: %#",[imageCache objectForKey:key]);
return [imageCache objectForKey:key];
}
imageCache is an instance variable, and also avatarsFetched, crudClient is an AFHTTPClient object.
and, in the table view:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
PostCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[PostCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
Post *curPost = [displayedPosts objectAtIndex:indexPath.section];
cell.nickname.text = [curPost nickname];
UIImage *avatarImage = [self.delegateRef.hangiesCommunicator getAvatarForUser:curPost.userID];
if (avatarImage) {
cell.avatar.image = avatarImage;
NSLog(#"Its not null");
} else {
cell.avatar.image = [UIImage imageNamed:#"20x20-user-black"];
}
}
self.delegateRef.hangiesCommunicator returns the object (which is a retained property of the app delegate) with the imageCache as an instance variable, and the two methods at the top.
When i scroll, i see the #"Its not null" in the console, yet i don't see the fetched image but the default 20x20-user-black image. does anybody have an idea, why is this happening? what am i doing wrong?
thanks!
Your code is missing some things. I can't see where you ever call the fetchAvatarForUser:completion: method on your hangiesCommunicator and your tableView:cellForRowAtIndexPath: method is not returning the cell, so I don't think the code you posted will compile cleanly.

Read plist data into a NSArray but get null

I got same warning here “local declaration hides instance variable” warning
but I got more problems...
Here is my code
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
NSURLRequest *theRequest=[NSURLRequest requestWithURL:[NSURL URLWithString:#"http://www.someaddress.php"]
cachePolicy:NSURLRequestUseProtocolCachePolicy
timeoutInterval:60.0];
// create the connection with the request
// and start loading the data
NSURLConnection *theConnection=[[NSURLConnection alloc] initWithRequest:theRequest delegate:self];
NSLog(#"\n\nCONNECTION: %#", theConnection);
NSData *returnData = [NSURLConnection sendSynchronousRequest:theRequest returningResponse:nil error:nil];
NSString *listFile = [[NSString alloc] initWithData:returnData encoding:NSASCIIStringEncoding];
NSMutableArray *plist = [[NSMutableArray alloc] init];
plist = [listFile propertyList];
NSLog( #"\n 1111 plist is \n%#", plist );
//I can get a plist format data here,But nothing in 2222
NSLog(#"Now you see me tableView Row Count");
NSLog(#"TOTAL PLIST ROW COUNT IS = %i", [plist count]);
// Return the number of rows in the section.
return [plist count];
}
and I got Warning here"Local declaration of 'plist' hides instance variable"
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"LightCell";
LightCell0 *cell =(LightCell0 *) [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[LightCell0 alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease];
}
// Set up the cell…
NSLog(#"Now you see me Load Data %i", indexPath.row);
[cell setSelectionStyle:UITableViewCellSelectionStyleNone];
//I try to get list data here But RETURN NULL
NSLog( #"\n 2222 plist is \n %#", plist);
switch (indexPath.row) {
case 0:
if ([plist valueForKey:#"nodeStatus"] == 0){
cell.lightImageView.image = [UIImage imageNamed:#"lightOff.png"];
NSLog(#"value for key Node Status : %#" ,[self.plists Valuefokey:#"nodeStatus"]);
//also return NULL !!
}
else if([self valueForKey:#"nodeStatus"] == 1){
cell.lightImageView.image = [UIImage imageNamed:#"lightOn.png"];
}
break;
case 1:
cell.lightLocation.text =[plist valueForKey:#"nodeName"] ;
if ([plist valueForKey:#"nodeStatus"] == 0){
cell.lightImageView.image = [UIImage imageNamed:#"lightOff.png"];
}
else if([plist valueForKey:#"nodeStatus"] == 1){
cell.lightImageView.image = [UIImage imageNamed:#"lightOn.png"];
};
break;
default:
break;
}
return cell;
}
This is the tow items I create in a plist
{
category = Light;
nodeID = 1;
nodeName = "Living Room";
nodeStatus = 0;
nodeTrigger = 0;
nodeType = "light_sw";
},
{
category = Light;
nodeID = 2;
nodeName = Kitchen;
nodeStatus = 0;
nodeTrigger = 0;
nodeType = "light_sw";
}
So that's my question ,Why can't I pass "plist" from
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
...
}
to
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
...
}
and I use NSMutableArray *plist = [[NSMutableArray alloc] init];
But still appear "Local declaration of 'plist' hides instance variable"
???
hope someone can figure out this problem
Best Regards !
and I got Warning here"Local declaration of 'plist' hides instance variable"
Well, then, you should fix that.
The warning is telling you that you've declared two variables named plist: One local to this instance method, and the other an instance variable. The local variable, having a narrower scope, hides the instance variable, so that when you refer to plist in the method, you are referring to the local variable. This means that you cannot access anything stored in the instance variable by another method, nor store anything in it for another method to retrieve.
The solution is either to kill off or to rename the local variable. If the latter is what you want, use Xcode's “Edit All in Scope” feature.
Also:
NSMutableArray *plist = [[NSMutableArray alloc] init];
plist = [listFile propertyList];
Creating the array on the first of those lines is redundant, because you immediately replace your pointer to that array with the pointer to another array, returned by propertyList. Thus, you never use and you leak the first array. You should at least cut out the creation of the first array, and you should probably cut out the entire first line (thereby cutting out both the first array and the local variable).
Here is the code I fix the warning ,the program can build without any warning
it also can display the result after reading the plist in tableview
1.Load the plist:
- (void)viewDidLoad {
NSURLRequest *theRequest=[NSURLRequest requestWithURL:[NSURL URLWithString:#"http://www. someaddress.php"]
cachePolicy:NSURLRequestUseProtocolCachePolicy
timeoutInterval:60.0];
NSURLConnection *theConnection=[[NSURLConnection alloc] initWithRequest:theRequest delegate:self];
NSData *returnData = [NSURLConnection sendSynchronousRequest:theRequest returningResponse:nil error:nil];
NSString *listFile = [[NSString alloc] initWithData:returnData encoding:NSASCIIStringEncoding];
plist = [listFile propertyList];
}
2.return the number to rows
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [plist count];
}
3.read the plist data to show result in cells
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"LightCell0";
LightCell0 *cell =(LightCell0 *) [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[LightCell0 alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease];
}
// Set up the cell…
[cell setSelectionStyle:UITableViewCellSelectionStyleNone];
int i;
for (i=0; i<[plist count]; i++) {
//Get nodeName
if(indexPath.row == i)
{
cell.lightLocation.text = [[[plist objectAtIndex:i] valueForKey: #"nodeName"]description];
//Get Light Status to show the image
if ([[[plist objectAtIndex:i] valueForKey: #"nodeStatus"] intValue] == 0){
cell.lightImageView.image = [UIImage imageNamed:#"lightOff.png"];
}
else if([[[plist objectAtIndex:i] valueForKey: #"nodeStatus"] intValue] == 1){
cell.lightImageView.image = [UIImage imageNamed:#"lightOn.png"];
cell.lightSwitch.on=YES;
}
}
}
return cell;
}
It can get the right data ,and display the correct result in the tableview cells
BUTTTTTTT
If you scroll up the tableview,it's ok,when you on the top it will scroll down Automatically
When you "scroll down" the tableview,program crash ???
WHY ??? did I write anything wrong ???
plist = [listFile propertyList];=====>self.plist = [listFile propertyList];
THAT IS CORRECT