i have a NSArray of twitter_timeline using this tutorial http://tutorials.veasoftware.com/2013/09/20/twitter-api-version-1-1-user-timeline-in-ios-7/
I get my timeline using this code on cellForRowAtIndexPath method:
NSdictionary *tweet=_twitter_feed[indexPath.Row];
cell.labeltext.text=tweet[#"text"];
Everything works fine, BUT i want to create another array (NSMutableArray) and insert my _twitter_feed(NSArray) into it and get the same access to twitter_feed.
Something like that:
NSMutableArray *mainarray=[[NSMutableArray alloc]init];
[mainarray addObject:_twitter_feed];
but i don't know how to get text from twitter_array from main array
NSDictionary *tweet=[[mainarray objectAtIndex:0]indexPath.row];//??????
cell.labeltext.text=tweet[#"text"];
This is doesn't work.
If the _twitter_feed is a NSArray, you can simply use [[mainarray objectAtIndex:0] objectAtIndex:indexPath.row] to get it.
Try using NSMutableDictionary: (untested)
NSMutableDictionary *mainDict= [NSMutableDictionary dictionary];
[mainDict setObject: _twitter_feed forKey:[NSString stringWithFormat:#"%#", indexPath.row]];
and retrieve like:
NSdictionary *tweet= [mainDict objectForKey:[NSString stringWithFormat:#"%#", indexPath.row]];
cell.labeltext.text=tweet[#"text"];
Consider the line that is giving you the error:
NSDictionary *tweet = [[mainarray objectAtIndex:0]indexPath.row];
Now you've added the reference stored in _twitter_feed into the your mainarray, so this line is effectively:
NSDictionary *tweet = [_twitter_feed indexPath.row];
Compare this to your working line:
NSDictionary *tweet = _twitter_feed[indexPath.row];
Those two are not the same. Maybe you meant to type:
NSDictionary *tweet = [mainarray objectAtIndex:0][indexPath.row];
You can shorten that to:
NSDictionary *tweet = mainarray[0][indexPath.row];
HTH
Related
In my application I need to build an url like :
https://www.thefootballapi/football/league1/player/stats
In order to be able to build the url, I need to access the objects in an NSDictionary, since NSDictionary is an unordered data set, I need to sort the objects alphabetically in order to build the correct url:
NSDictionary
{
category = "football";
league = " League1 " ;
section = player;
"sub_category" = "stats";
}
I have tried doing this by writing this block of code:
Accessing the objects:
NSArray *keyyy0= [self.redirect allKeys];
id aaKey0 = [keyyy0 objectAtIndex:0];
id aanObject0 = [self.redirect objectForKey:aaKey0];
NSArray *keys = [self.redirect allKeys];
id aKey = [keys objectAtIndex:1];
id anObject = [self.redirect objectForKey:aKey];
NSArray *keyyy = [self.redirect allKeys];
id aaKey = [keyyy objectAtIndex:2];
id aanObject = [self.redirect objectForKey:aaKey];
and building the full url like this :
NSString *fullurl = [NSString stringWithFormat:#"%#%#%#%#", newurl,anObject,aanObject,aanObject3 ];
This method works fine for now, however I was wondering if this is the correct way of doing this ? is there a better way of implementing this ?
For example as it's mentioned here : Joe's answer ,NSURLQueryItem is used to access objects from dictionaries and build queries from it, however when I used NSURLQueryItem the full url was built with ? and = signs.
Are there any other methods that can be used to just get all of the objects in an NSDictionary ?
When accessing values from an NSDictionary there's no guarantee what type it will be. With full type-checking, a safer and more readable way of creating your URL might be something like:
NSDictionary *redirect = #{#"category" : #"football",
#"league" : #" League1 ",
#"section" : #"player",
#"sub_category" : #"stats"};
id category = redirect[#"category"];
id league = redirect[#"league"];
id section = redirect[#"section"];
id subCategory = redirect[#"sub_category"];
if ([category isKindOfClass:[NSString class]] &&
[league isKindOfClass:[NSString class]] &&
[section isKindOfClass:[NSString class]] &&
[subCategory isKindOfClass:[NSString class]])
{
NSString *urlString = [NSString stringWithFormat:#"https://www.thefootballapi/%#/%#/%#/%#",
[((NSString*)category).lowercaseString stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]],
[((NSString*)league).lowercaseString stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]],
[((NSString*)section).lowercaseString stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]],
[((NSString*)subCategory).lowercaseString stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]];
NSLog(#"%#", urlString); // https://www.thefootballapi/football/league1/player/stats
}
This also ensures the URL is generated as you wanted (lowercase "league1" without leading/trailing whitespace) given your input JSON.
Try this code.
//Your Dictionary
NSMutableDictionary *dict = [NSMutableDictionary new];
[dict setValue:#"football" forKey:#"category"];
[dict setValue:#"League1" forKey:#"league"];
[dict setValue:#"player" forKey:#"section"];
[dict setValue:#"stats" forKey:#"sub_category"];
// Get desired URL like this
NSArray *arr = [[dict allValues] sortedArrayUsingSelector:#selector(localizedCaseInsensitiveCompare:)];
NSString *strURL = [NSString stringWithFormat:#"https://www.thefootballapi/%#/%#/%#/%#", [arr objectAtIndex:0], [arr objectAtIndex:1], [arr objectAtIndex:2], [arr objectAtIndex:3]];
NSLog(#"%#", strURL);
It will return ULR same as you want : https://www.thefootballapi/football/League1/player/stats
I have UITableViewController and it has twitter like post with like buttons. what im doing is when ever like button clicked if it is success trying to update the like count by + 1. i did the all the the above method except for the update part.
im getting Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '-[__NSCFDictionary setObject:forKey:]: mutating method sent to immutable object' Error.
Here is my code.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
FeedTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"Cell" forIndexPath:indexPath];
NSDictionary *feedList = [liveFeeds objectAtIndex:indexPath.row];
//liveFeeds is NSMutableArray
cell.likeCount.text = [feedList objectForKey:#"likes"];
cell.like.tag = indexPath.row;
[cell.like addTarget:self action:#selector(likeClicked:) forControlEvents:UIControlEventTouchUpInside];
}
-(void) likeClicked:(UIButton*)sender{
//Here im using AFNetworking and getting JSON response.
//After that im doing following to update the like
NSMutableDictionary* feedList = [liveFeeds objectAtIndex:sender.tag];
NSString *oldLike = [feedList objectForKey:#"likes"];
int newLike = [oldLike intValue] + 1;
NSString *strFromInt = [NSString stringWithFormat:#"%d",newLike];
NSLog(#"updated like %#",strFromInt); // up to this it works
[feedList setObject:strFromInt forKey:#"likes"]; // in here it get crashe
[self.tableView reloadData];
}
What i want to do is. liveFeeds Array update with that Like Count and reload the table. am i doing this wrong? or is there any easy way to do this?
Most likely [liveFeeds objectAtIndex:sender.tag] is a NSDictionary, not an NSMutableDictionary. So you cannot change its content.
Build feedlist with the content of [liveFeeds objectAtIndex:sender.tag] :
NSMutableDictionary* feedlist = [NSMutableDictionary dictionaryWithDictionary:[liveFeeds objectAtIndex:sender.tag]]
I haven't tried it yet but i guess you're trying to use a NSMutableDictionary method on a NSDictionary.
Try changing:
NSMutableDictionary* feedList = [liveFeeds objectAtIndex:sender.tag];
To:
NSDictionary* dic = [liveFeeds objectAtIndex:sender.tag];
NSMutableDictionary* feedList = [NSMutableDictionary alloc] initWithDictionary:dic]];
Simply create mutable copy of NSDictionary. Actually NSMutableDictionary* feedList = [liveFeeds objectAtIndex:sender.tag] returns NSDictionary. So to make it editable you have to create another copy which is mutable by using mutableCopy. NSMutableDictionary* feedList = [[liveFeeds objectAtIndex:sender.tag]mutableCopy]
-(void) likeClicked:(UIButton*)sender{
//Here im using AFNetworking and getting JSON response.
//After that im doing following to update the like
NSMutableDictionary* feedList = [[liveFeeds objectAtIndex:sender.tag]mutableCopy];
NSString *oldLike = [feedList objectForKey:#"likes"];
int newLike = [oldLike intValue] + 1;
NSString *strFromInt = [NSString stringWithFormat:#"%d",newLike];
NSLog(#"updated like %#",strFromInt); // up to this it works
[feedList setObject:strFromInt forKey:#"likes"]; // in here it get crashe
[self.tableView reloadData];
}
I am fairly new to Objective-C.
I have created on .plist in which all data stored in Response Dictionary.
NSString *myListPath = [[NSBundle mainBundle] pathForResource:#"OffersList" ofType:#"plist"];
dic = [NSDictionary dictionaryWithContentsOfFile:myListPath];
tableData = [dic objectForKey:#"Response"];
Now i have converted that tabledata to Dictionary.
NSDictionary *dict = [tableData objectAtIndex:indexPath.row];
cell.titleLabel.text = [dict objectForKey:#"title"];
cell.nowLabel.text = [dict objectForKey:#"price"];
cell.saveLabel.text = [dict objectForKey:#"rondel"];
Now, Problem is that it only load's first 10 data.
I am also tried to print in log but after 10th data it's values seen as NULL.
Try to make a dump of the whole dic so that you can check exactly what data it contains:
NSLog(#"Content of tableData", [dic description]);
Then double check the log content for the tableData element with the .plist content.
I'm starting objective-c development and I would like to ask the best way to implement a list of keys and values.
In Delphi there is the class TDictionary and I use it like this:
myDictionary : TDictionary<string, Integer>;
bool found = myDictionary.TryGetValue(myWord, currentValue);
if (found)
{
myDictionary.AddOrSetValue(myWord, currentValue+1);
}
else
{
myDictionary.Add(myWord,1);
}
How can I do it in objective-c? Is there equivalent functions to the above mentioned AddOrSetValue() or TryGetValue()?
Thank you.
You'd want to implement your example along these lines:
EDIT:
//NSMutableDictionary myDictionary = [[NSMutableDictionary alloc] init];
NSMutableDictionary *myDictionary = [[NSMutableDictionary alloc] init];
NSNumber *value = [myDictionary objectForKey:myWord];
if (value)
{
NSNumber *nextValue = [NSNumber numberWithInt:[value intValue] + 1];
[myDictionary setObject:nextValue forKey:myWord];
}
else
{
[myDictionary setObject:[NSNumber numberWithInt:1] forKey:myWord]
}
(Note: you can't store ints or other primitives directly in a NSMutableDictionary, hence the need to wrap them in an NSNumber object, and make sure you call [myDictionary release] when you've finished with the dictionary).
The other answers are correct, but there is more modern syntax for this now. Rather than:
[myDictionary setObject:nextValue forKey:myWord];
You can simply say:
myDictionary[myWord] = nextValue;
Similarly, to get a value, you can use myDictionary[key] to get the value (or nil).
Yep:
- (id)objectForKey:(id)key;
- (void)setObject:(id)object forKey:(id)key;
setObject:forKey: overwrites any existing object with the same key; objectForKey: returns nil if the object doesn't exist.
Edit:
Example:
- (void)doStuff {
NSMutableDictionary *dict = [NSMutableDictionary dictionary];
[dict setObject:#"Foo" forKey:#"Key_1"]; // adds #"Foo"
[dict setObject:#"Bar" forKey:#"Key_2"]; // adds #"Bar"
[dict setObject:#"Qux" forKey:#"Key_2"]; // overwrites #"Bar"!
NSString *aString = [dict objectForKey:#"Key_1"]; // #"Foo"
NSString *anotherString = [dict objectForKey:#"Key_2"]; // #"Qux"
NSString *yas = [dict objectForKey:#"Key_3"]; // nil
}
Reedit: For the specific example there exists a more compact approach:
[dict
setObject:
[NSNumber numberWithInteger:([[dict objectForKey:#"key"] integerValue] + 1)]
forKey:
#"key"
];
Crazy indentation for readability.
i have the following code and i want to use NSMutable arrays instead of NSArray
could you tell me how to load the NSMutable array, as the current method does not work.
-(void) whatever{
NSData *htmlData = [[NSString stringWithContentsOfURL:[NSURL URLWithString: #"http://www.objectgraph.com/contact.html"]] dataUsingEncoding:NSUTF8StringEncoding];
TFHpple *xpathParser = [[TFHpple alloc] initWithHTMLData:htmlData];
NSArray *titles = [xpathParser search:#"//h3"]; // get the page title - this is xpath notation
TFHppleElement *title = [titles objectAtIndex:0];
NSString *myTitles = [title content];
NSArray *articles = [xpathParser search:#"//h4"]; // get the page article - this is xpath notation
TFHppleElement *article = [articles objectAtIndex:0];
NSString *myArtical = [article content];
i have tried :
NSMutableArray *titles = [xpathParser search:#"//h3"];
but it does load the values?
You can invoke mutableCopy on an NSArray object to return to you an NSMutableArray.
Note that the callee will obtain ownership of this object since the method name contains "copy".
(Apple's memory management guide states that a method name containing the words "alloc", "new" or "copy" should by convention return an object which you own, and as such must relinquish ownership of at some point.)
Simply like this:
NSArray* someArray = [xpathParser search:#"//h3"];
NSMutableArray* mutableArray = [someArray mutableCopy];
That's quite literally, it.
Assuming [xpathparser ...] returns an NSArray, you can use:
NSMutableArray *titles = [NSMutableArray arrayWithArray:[xpathParser search:#"//h3"]];