read in did load:
NSFileManager *fileManager = [NSFileManager defaultManager];
if (![fileManager fileExistsAtPath: path]) //4
{
NSString *bundle = [[NSBundle mainBundle] pathForResource:#"data" ofType:#"plist"]; //5
[fileManager copyItemAtPath:bundle toPath: path error:&error]; //6
}
//load in text fields.
NSMutableDictionary *savedData = [[NSMutableDictionary alloc] initWithContentsOfFile: path];
nameField.text = [[savedData objectForKey:#"name"] stringValue];
locationTextField.text = [[savedData objectForKey:#"location"] stringValue];
sectorTextField.text = [[savedData objectForKey:#"sector"] stringValue];
Write on button click:
- (IBAction)writingButton:(id)sender
{
NSMutableDictionary *data = [[NSMutableDictionary alloc] initWithContentsOfFile: path];
//[data setObject:[NSNumber numberWithInt:value] forKey:#"value"];
[data setObject:[NSString stringWithString:nameField.text] forKey:#"name"];
[data setObject:[NSString stringWithString:locationTextField.text] forKey:#"location"];
[data setObject:[NSString stringWithString:sectorTextField.text] forKey:#"sector"];
}
the plist file:
The error:
2012-09-04 17:03:40.360 app[4849:c07] -[__NSCFString stringValue]:
unrecognized selector sent to instance 0x6aa38f0 2012-09-04
17:03:40.362 app[4849:c07] *** Terminating app due to uncaught
exception 'NSInvalidArgumentException', reason: '-[__NSCFString
stringValue]: unrecognized selector sent to instance 0x6aa38f0'
Any ideas? cheers.
The dictionary stores NSString objects directly - there's no need to call a (nonexistent) method called - stringValue. Simply write
nameField.text = [savedData objectForKey:#"name"];
and so on.
(Why do you think this method call would have been necessary?)
Related
how can I edit or change a value string from:
in this plist I need change or Set "NO" in Enabled Value from Item 2, I see a lot examples, but not working, or are deprecated, or don't use ARC, any idea or example code? please help guys
EDIT#1: I try this (not work)
NSString *path = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
path = [path stringByAppendingPathComponent:#"List.plist"];
NSFileManager *fileManager = [NSFileManager defaultManager];
if (![fileManager fileExistsAtPath:path]) {
NSString *sourcePath = [[NSBundle mainBundle] pathForResource:CONTENT_DEFAULT ofType:PLIST];
[fileManager copyItemAtPath:sourcePath toPath:path error:nil];
}
NSArray* newContent = [[NSArray alloc]initWithContentsOfFile:path];
NSDictionary *Dict = [[NSDictionary alloc]initWithDictionary:[newContent objectAtIndex:2]];
[Dict setValue:#"NO" forKey:#"Enabled"];
[Dict writeToFile:path atomically:YES];
NOTE: not work, it crashes send me:
*** Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<__NSDictionaryI 0x15de7ff0> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key Enabled.', or Im wrong in something?
EDIT #2 new Try
NSString *path = [[NSBundle mainBundle] pathForResource:#"List" ofType:#"plist"];
NSString *savingPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
NSArray* newContent = [[NSArray alloc]initWithContentsOfFile:path];
NSMutableDictionary *Dict = [[NSMutableDictionary alloc]initWithDictionary:[newContent objectAtIndex:2]];
[Dict setValue:#"NO" forKey:#"Enabled"];
savingPath = [savingPath stringByAppendingPathComponent:#"Modified.plist"];
[Dict writeToFile:savingPath atomically:YES];
NSLog(#"newContent:%#",newContent);
NSArray *newnew = [[NSArray alloc]initWithContentsOfFile:savingPath];
NSLog(#"newnew:%#",newnew);
NOTE: now print me a crash:
*** Terminating app due to uncaught exception 'NSRangeException', reason: '-[__NSCFArray objectAtIndex:]: index (3) beyond bounds (2)'
All you have to do is to use NSMutableDictionary instead of a regular dictionary to modify stuff. You have to always check that the object you are editing is there.
To get the right path for the plist you created in Xcode you need to use:
NSString *path = [[NSBundle mainBundle] pathForResource:#"List" ofType:#"plist"];
You might actually want to save that file into the app's document directory. So you would use the following path for saving the content:
NSString *savingPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
savingPath = [savingPath stringByAppendingPathComponent:#"Modified.plist"];
[Dict writeToFile:savingPath atomically:YES];
Well, in your case the solution would be the following (when you have Dictionary as a member of Array):
NSString *path = [[NSBundle mainBundle] pathForResource:#"List" ofType:#"plist"];
NSArray *newContent = [[NSArray alloc]initWithContentsOfFile:path];
//iterating through all members since all of them has the string "YES" which should be replaced, otherwise, you will need to create a separate dictionary for each member
for ((i = 0; i < [newContent count]; i++)){
//here you take the member (dictionary) of the array
NSDictionary *dictOfArray = [newContent objectAtIndex:i];
[dictOfArray objectForKey:#"Enabled"]=#"NO";
}
//if you update the same pList you can use the same path (otherwise use another path)
[newContent writeToFile:path atomically:YES];
So, it works now.
i'm pulling a 2 dimensional array from a remote server:
- (NSMutableArray*)qBlock{
NSURL *url = [NSURL URLWithString:#"http://wsome.php"];
NSError *error;
NSStringEncoding encoding;
NSString *response = [[NSString alloc] initWithContentsOfURL:url
usedEncoding:&encoding
error:&error];
const char *convert = [response UTF8String];
NSString *responseString = [NSString stringWithUTF8String:convert];
NSMutableArray *sample = [responseString JSONValue];
return sample;
}
and putting them into:
NSMutableArray *qnBlock1 = [self qBlock];
NSString *answer1 = [NSString stringWithFormat:[[qnBlock1 objectAtIndex:0]objectAtIndex:1]];
answer = [[NSMutableDictionary alloc]init];
[answer setObject:answer1 forKey:#"1"];
question1.text = [[qnBlock1 objectAtIndex:0] objectAtIndex:0];
label1a.text = [[qnBlock1 objectAtIndex:0]objectAtIndex:2];
label1b.text = [[qnBlock1 objectAtIndex:0]objectAtIndex:3];
label1c.text = [[qnBlock1 objectAtIndex:0]objectAtIndex:4];
label1d.text = [[qnBlock1 objectAtIndex:0]objectAtIndex:5];
I received this error during runtime
-[__NSCFDictionary objectAtIndex:]: unrecognized selector sent to instance 0x6c179502012-04-30 09:43:50.794 AppName[371:f803] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFDictionary objectAtIndex:]: unrecognized selector sent to instance 0x6c17950'
Is this due to syntax issue for 2 dimensional array?
You're not getting back a multi-dimensional array. You're getting back an array of NSDictionary objects. The error you got indicates that you're trying to send the message objectAtIndex: to an NSDictionary object, which fails since it has no such selector.
Update:
After chatting on the side, it became apparent that the following was true:
The user was using the SBJson library to parse the return value from his php web service.
The return value was either:
An NSDictionary with each key being the text representation of its (non-index-based) location in the list (#"1", #"2", etc...) and each value being an NSArray of NSString objects, or
An NSArray of NSString objects (seems to be the way a single "answer" returns)
Here's the code I supplied to let him iterate through his return value:
NSURL *url = [NSURL URLWithString:#"{his url}"];
NSError *error;
NSStringEncoding encoding;
NSString *response = [[NSString alloc] initWithContentsOfURL:url usedEncoding:&encoding error:&error];
const char *convert = [response UTF8String];
NSString *responseString = [NSString stringWithUTF8String:convert];
NSLog(#"%#", responseString);
SBJsonParser *parser = [[SBJsonParser alloc] init];
id sample = [parser objectWithString:responseString];
if ([sample isKindOfClass:[NSDictionary class]]) {
for (id item in sample) {
NSLog(#"%#", [item description]);
NSArray *subArray = [sample objectForKey:item]; // b/c I know it's an array
for (NSString *str in subArray) {
NSLog(#"item: %#", str);
}
}
} else if ([sample isKindOfClass:[NSArray class]]) {
for (NSString *str in sample) {
NSLog(#"item: %#", str);
}
}
Hope it helps, J!
I think from your error message, you're sending objectAtIndex to a dictionary. NSDictionary doesn't have such a method. You should use objectForKey instead.
I want to do a search in a tableview. But in this table view I work with a custom tableview Cell. So for the data part. I select in a view a categorie. Then in the next view I get all the products within this categorie.
I followed a tutorial and implemented all the methods.
This is my function for getting the products.
-(void) fillArrayProducts:(NSString *)cat{
NSMutableString *postString = [NSMutableString stringWithString:kGETProducts];
[postString appendString:[NSString stringWithFormat:#"?%#=%#",#"Pro_cat",cat]];
[postString setString:[postString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
NSMutableURLRequest *request= [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:postString]];
[request setHTTPMethod:#"POST"];
postConnection = [[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:YES];
NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:postString]];
NSError *error;
json = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error];
arrayProducts = [[NSMutableArray alloc] init];
copyArrayProducts = [[NSMutableArray alloc] init];
arrayProductNaam = [[NSMutableArray alloc] init];
for (int i=0; i<[json count]; i++) {
arrayProduct = [[NSMutableArray alloc] init];
[arrayProduct addObject:[json objectAtIndex:i]];
[arrayProducts addObject:arrayProduct];
[arrayProductNaam addObject:[[[arrayProducts valueForKey:#"Pro_naam"] objectAtIndex:i]objectAtIndex:0]];
[copyArrayProducts addObject:arrayProduct];
}
NSDictionary *productsDict = [NSDictionary dictionaryWithObject:arrayProductNaam forKey:#"Products"];
NSLog(#"%#",arrayProductNaam);
}
No what I'm doing. I have an array 'arrayProducts' in this array I put arrays from 'arrayProduct'. In arrayProduct you can find Pro_id,Pro_naam,Pro_prijs. But I only want to search on Pro_naam. So I fill also an array (arrayProductNaam) with only the products names.
So here is the part were I do my search.
- (void) searchTableView {
NSString *searchText = searchbar.text;
NSMutableArray *searchArray = [[NSMutableArray alloc] init];
for (NSDictionary *dictionary in arrayProductNaam)
{
NSArray *array = [dictionary objectForKey:#"Pro_naam"];
[searchArray addObjectsFromArray:array];
}
for (NSString *sTemp in searchArray)
{
NSRange titleResultsRange = [sTemp rangeOfString:searchText options:NSCaseInsensitiveSearch];
if (titleResultsRange.length > 0)
[copyArrayProducts addObject:sTemp];
}
}
I think that it's here were I getting this error.
2012-02-02 13:22:40.958 MamzelBestelling2[23727:f803] -[__NSCFString
objectForKey:]: unrecognized selector sent to instance 0x6c34780
2012-02-02 13:22:40.959 MamzelBestelling2[23727:f803] *** Terminating
app due to uncaught exception 'NSInvalidArgumentException', reason:
'-[__NSCFString objectForKey:]: unrecognized selector sent to instance
0x6c34780'
You are not filling arrayProductNaam with Dictionary. Its filled by NSString. Now, in the searchTableView function you are handling these string members as Dictionaries and hence the problem.
try to NSLog your String Array. so you can get the idea it exist or not
you are trying to get a keyValue from a string not from a dictionary.
I've an NSOpenPanel called oPanel. From it, I get the path of a folder. As I use URLs (instead of the deprecated filenames) I want to get rid of the beginning (file://localhost).
But I have the following error that I can't understand:
2011-07-29 18:01:45.587 RedimV3[12857:407] -[NSURL length]: unrecognized selector sent to instance 0x1023543d0
2011-07-29 18:01:45.588 RedimV3[12857:407] -[NSURL length]: unrecognized selector sent to instance 0x1023543d0
Here is the code:
NSArray *files = [oPanel URLs];
NSLog(#"before: %#", [files objectAtIndex:0]);
NSMutableString *temp = [[NSMutableString alloc] initWithString:[files objectAtIndex:0]];
[temp deleteCharactersInRange:NSMakeRange(0,15)];
NSLog(#"after: %#",temp);
The first NSLog works, the second doesn't.
I will be glad if you can help me, thanks.
[files objectAtIndex:0] is probably an NSURL, not an NSString. Try using [[files objectAtIndex:0] path] instead. In fact, if you use -path you won't even have to worry about the file:// part.
If you just want the file name then you would do as #jtbandes said with a minor correction to use the lastPathComponent instance method of NSString
Quick and dirty version
NSArray *files = [oPanel URLs];
NSLog(#"before %#",[files objectAtIndex:0]);
NSString *fileName = [[[files objectAtIndex:0] path] lastPathComponent];
NSLog(#"after :%#",fileName);
More readable code version
NSArray *files = [oPanel URLs];
NSURL *file = [files objectAtIndex:0];
NSLog(#"before %#",file);
NSString *localPath = [file path];
NSString *fileName = [localPath lastPathComponent];
NSLog(#"after :%#",fileName);
You need to turn the NSURL into a string...
NSURL *myURL = [files objectAtIndex:0];
NSMutableString *string = [NSMutableString stringWithString:[myURL absoluteString]];
[string deleteCharactersInRange:NSMakeRange(0,15)];
NSLog(#"after: %#", string);
- (IBAction)sendMessage:(id)sender
{
NSString* conversationFile = [#"~/" stringByAppendingPathComponent:#"conversation.txt"];
BOOL fileExists = [[NSFileManager defaultManager] fileExistsAtPath:conversationFile];
if (fileExists == FALSE)
{
[self doShellScript:#"do shell script \"cd ~/; touch conversation.txt\""];
}
NSString *conversationContent = [[NSString alloc] stringWithContentsOfFile:#"~/conversation.txt" encoding:NSUTF8StringEncoding error:NULL];
NSString *myMessage = [[messageBox stringValue]copy];
NSString *combinedContent = [NSString stringWithFormat:#"%# \r\n %#", conversationContent, myMessage];
[[[myConversationBox textStorage] mutableString] setString: combinedContent];
[combinedContent writeToFile:#"~/conversation.txt" atomically:YES encoding:NSUTF8StringEncoding error:NULL];
}
The above code presents the following error
2011-07-07 21:38:08.703
iMessages[86493:903]
-[NSPlaceholderString stringWithContentsOfFile:encoding:error:]:
unrecognized selector sent to instance
0x100111690
2011-07-07 21:38:08.704
iMessages[86493:903]
-[NSPlaceholderString stringWithContentsOfFile:encoding:error:]:
unrecognized selector sent to instance
0x100111690
stringWithContentsOfFile:encoding:error: is a class method of NSString, not an instance method, so you don't need to (shouldn't) alloc it first.
NSString *conversationContent = [NSString stringWithContentsOfFile:#"~/conversation.txt" encoding:NSUTF8StringEncoding error:NULL];
Use initWithContentsOfFile in place of stringWithContentsOfFile or remove the alloc call. So have:
NSString *conversationContent = [[NSString alloc] initWithContentsOfFile:#"~/conversation.txt" encoding:NSUTF8StringEncoding error:NULL];
or
NSString *conversationContent = [NSString stringWithContentsOfFile:#"~/conversation.txt" encoding:NSUTF8StringEncoding error:NULL];