I use a plist file to get a list of site which are displayed in a tableview
The plist looks like this:
<array>
<dict>
<key>site</key>
<string>http://yahoo.com</string>
<key>title</key>
<string>Yahoo</string>
</dict>
<dict>
<key>site</key>
<string>http://google.com</string>
<key>title</key>
<string>Google</string>
</dict>
//...etc
</array>
</plist>
I display this without problem:
NSMutableArray *array = [[NSMutableArray alloc] initWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"TestData" ofType:@"plist"]];
[self setContentsList:array];
*The problem is when I try to search in the content and I want to get the valueforkey @"site" from the search result to use it in didSelectRowAtIndexPath: *
NSMutableArray *contentsList;
NSMutableArray *searchResults;
NSString *savedSearchTerm;
---------------------
- (void)handleSearchForTerm:(NSString *)searchTerm
{
[self setSavedSearchTerm:searchTerm];
if ([self searchResults] == nil)
{
NSMutableArray *array = [[NSMutableArray alloc] init];
[self setSearchResults:array];
[array release], array = nil;
}
[[self searchResults] removeAllObjects];
if ([[self savedSearchTerm] length] != 0)
{
for (NSString *currentString in [[self contentsList] valueForKey:@"title"])
{
if ([currentString rangeOfString:searchTerm options:NSCaseInsensitiveSearch].location != NSNotFound)
{
[[self searchResults] addObject:currentString];
// NSDictionary *dic= [[NSDictionary alloc]allKeysForObject:searchResults];
}
}
}
}
The didSelectRowAtIndexPath is used to open the site in a webView
- (void)tableView:(UITableView *)tableView
didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView deselectRowAtIndexPath:indexPath animated:YES];
NSString *arraySite = [[[self searchResults] objectAtIndex:indexPath.row] valueForKey:@"site"];
[webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:arraySite]]];
[self performSelector:@selector(showSearch:) withObject:nil afterDelay:0];
}
E开发者_如何转开发RROR I GET :
Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<NSCFString 0x6042730> valueForUndefinedKey:]: this class is not key value coding-compliant for the key site.'
The Basics
When you read the array from that plist, the array looks like the following:
(
{
"site" = "http://yahoo.com",
"title" = "Yahoo"
},
{
"site" = "http://google.com",
"title" = "Google"
},
…
)
It is an array whose elements are dictionaries, each dictionary containing two keys and their corresponding values.
When you use the KVC method -valueForKey:
on the array passing the key title
, it returns another array whose elements are the values corresponding to that key:
(
"Yahoo",
"Google",
…
)
The resulting array doesn’t hold a reference to the original array.
The Problem
In -handleSearchForTerm:
, you get an array containing only the titles from the original array. For each title, you selectively add it to the searchResults
array:
for (NSString *currentString in [[self contentsList] valueForKey:@"title"])
{
…
[[self searchResults] addObject:currentString];
}
This means that searchResults
is an array containing a list of titles which are not automatically related to the corresponding dictionaries in the contentList
array.
It seems like you want to keep the original dictionary because you’ve tried to create a dictionary:
// NSDictionary *dic= [[NSDictionary alloc]allKeysForObject:searchResults];
and, in another method, you’re trying to obtain the value corresponding to the site
key:
NSString *arraySite = [[[self searchResults] objectAtIndex:indexPath.row]
valueForKey:@"site"];
As mentioned, your searchResults
contains a list of strings representing titles. When you obtain an element from this array, it’s only a string — hence -valueForKey:@"site"
doesn’t make sense, and Cocoa warns you that a string is not key-value compliant for the key site
.
One Solution
From what I can tell, you should be storing, in your searchResults
array, the original dictionary read from the plist file. In -handleSearchForTerm:
, do the following:
for (NSDictionary *currentSite in [self contentsList])
{
NSString *title = [currentSite objectForKey:@"title"];
if ([title rangeOfString:searchTerm options:NSCaseInsensitiveSearch].location != NSNotFound)
{
[[self searchResults] addObject:currentSite];
}
}
Now every element in searchResults
is a dictionary containing both site
and title
.
In -tableView:didSelectRowAtIndexPath:
, use the dictionary to obtain the corresponding site
:
- (void)tableView:(UITableView *)tableView
didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView deselectRowAtIndexPath:indexPath animated:YES];
NSDictionary *selectedSite = [[self searchResults] objectAtIndex:indexPath.row];
NSString *siteStringURL = [selectedSite objectForKey:@"site"];
// or, if you prefer everything in a single line:
// NSString *siteStringURL = [[[self searchResults] objectAtIndex:indexPath.row] objectForKey:@"site"];
[webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:siteStringURL]]];
[self performSelector:@selector(showSearch:) withObject:nil afterDelay:0];
}
精彩评论