NSKeyedUnarchiver unarchiveObjectWithFile cause crash - iphone

I try to use codes
-(bool)checIfWorksOnJailbreak;
{
NSString *s = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:#"Info.plist"];
NSLog(#"%#",s);
if([[NSFileManager defaultManager] fileExistsAtPath:s]) {
NSDictionary *plistDictionary = (NSDictionary*)[NSKeyedUnarchiver unarchiveObjectWithFile:s];
NSString *valueString = [plistDictionary objectForKey:#"SigerIdentity"];
if([valueString isEqualToString:#"Apple OS Application Signing"])
return true;
else
return false;
}
return false;
}
it always cause error
*** Terminating app due to uncaught exception 'NSInvalidArgumentException',
reason: '*** -[NSKeyedUnarchiver initForReadingWithData:]:
incomprehensible archive version (-1)'
at line
NSDictionary *plistDictionary = (NSDictionary*)[NSKeyedUnarchiver unarchiveObjectWithFile:s];
Welcome any comment

NSKeyedUnarchiver (and NSKeyedArchiver) are not for encoding and decoding plists. Instead, they are used to serialize and deserialize objects that implement the NSCoding protocol. To read your plist data into a dictionary, you instead should use:
NSDictionary *plistDictionary = [NSDictionary dictionaryWithContentsOfFile:s];

Related

Read/Write plist on iPhone iOS 5

I am studying iPhone development and facing a problem with a reading/writing plist file. I followed an example from a iPhone development book but keep getting an error message when running.
The error message says : 2012-04-26 00:21:09.759 FileHandling[5915:207] -[__NSCFDictionary addObject:]: unrecognized selector sent to instance 0x685ac40
Here is the example code (it seems fine to me...though):
NSString *plistFileName = [[self documentPath] stringByAppendingPathComponent: #"Apps.plist"];
NSLog(#"Where is the file? => %#", plistFileName);
if ([[NSFileManager defaultManager] fileExistsAtPath:plistFileName]) {
NSDictionary *dict = [[NSDictionary alloc] initWithContentsOfFile:plistFileName];
for (NSString *category in dict) {
NSLog(#"%#", category);
NSLog(#"=========");
NSArray *titles = [dict valueForKey:category];
for (NSString *title in titles) {
NSLog(#"%#", title);
}
}
} else {
NSString *plistPath = [[NSBundle mainBundle] pathForResource:#"Apps" ofType: #"plist"];
NSLog(#"%#", plistPath);
NSDictionary *dict = [[NSDictionary alloc] initWithContentsOfFile: plistPath];
NSLog(#"Let's take a look : %#", dict);
NSMutableDictionary *copyOfDict = [dict mutableCopy];
NSLog(#"Let's look at the mutable dictationary : %#", copyOfDict);
NSArray *categoriesArray = [[copyOfDict allKeys] sortedArrayUsingSelector: #selector(compare:)];
for (NSString *cateogry in categoriesArray) {
NSArray *titles = [dict valueForKey: cateogry];
NSMutableArray *mutableTitles = [titles mutableCopy];
[mutableTitles addObject: #"New App Title"];
[copyOfDict setObject: mutableTitles forKey:cateogry];
}
NSString *fileName = [[self documentPath] stringByAppendingPathComponent: #"Apps.plist"];
[copyOfDict writeToFile: fileName atomically:YES];
}
According to the error message, the problem is occurring in the call to addObject: on an __NSCFDictionary. This means that, at runtime, a dictionary received a message to add an object.
However, in this code snippet, addObject: is apparently being sent to an NSMutableArray. This probably means that each object titles you're retrieving from dict in the last for-loop is not an array, but in fact another dictionary, that your code is simply referring to as an array.
Indeed, your code does seem well-formed, so check the well-formedness of your source plist; open it up in a plain text editor. Also, you use a ton of logging, so confirm this way: in the output, dictionaries (including the root entry) are denoted by {curly = braces}, where arrays are denoted by (round parentheses).

Reading value from JSON - help writing the logic

I have the JSON in the format of
{"index":"0","name":"jemmy","age":"2"}
I need to extract the values stored and save it; I have done the following, but it doesn't work
Terminating app due to uncaught exception
'NSInvalidArgumentException', reason: '-[NSCFString objectForKey:]:
unrecognized selector sent to instance 0x6671a10'
my code
NSDictionary *dictionary = [request responseHeaders];
SBJsonParser *parser = [SBJsonParser new];
id content = [responseString JSONValue];
NSDictionary *dealDictionary = content;
NSArray *array = [dealDictionary allKeys];
for (NSString *str in array)
{
NSDictionary *childDictionary = [dealDictionary objectForKey:str];
NSLog(#"%# ",[childDictionary objectForKey:#"name"]);
}
You may not understand how to use SBJSON, maybe a quick read through the documentation would be useful. First, you need to actually use the parser that you create:
SBJsonParser *parser = [SBJsonParser new];
NSDictionary *content = [parser objectWithString:[request responseString]];
Secondly, you can traverse your dictionary slightly easier as such:
NSEnumerator *enum = [content keyEnumerator];
id key;
while (key = [enum nextObject]) {
NSLog(#"key %# and object %#",key,[content objectForKey:key]);
}

NSPropertyListSerialization after parsing an XML

I need to know if I am in the right track here. I am parsing an XML-RPC in iPhone (using the eczarny framework) and I am getting an array with objects. I create an NSData and store an object. After that I am trying to deserialize it but get en error.
Code:
NSArray *result = [response object];
NSData *data = [result objectAtIndex:0];
NSLog(#"Data %#",data);
NSDictionary * message = nil;
NSString * error = nil;
message = [NSPropertyListSerialization propertyListFromData:data mutabilityOption:NSPropertyListMutableContainers format:nil errorDescription:&error];
The nslog:
Data {
DESCRIPTION = "Standardverkn";
FLAGS = 0;
NAME = "Fenster OG3";
RECEIVER = "IEQ007:3";
SENDER = "IEQ0043:1";
}
The error:
-[__NSCFDictionary length]: unrecognized selector sent to instance 0x6e4bd50
What am I doing wrong?
[result objectAtIndex:0] is already an NSDictionary. You don't need to deserialize it. You can just directly use it as the message.
(If it is an NSData, the NSLog will show something like <12345678 9abcdef0 ...>.)

Problems with passing of data from NSDictionary to NSMutableDictionary

I'm trying to access a webservice using the json framework.
Code:
NSDictionary *allData;
NSMutableDictionary *displayData;
NSString *string = [[NSString alloc] initWithFormat:#"http://localhost/Gangbucks.svc/GetDealList"];
NSURL *jsonURL = [NSURL URLWithString:string];
NSString *jsonData = [[NSString alloc] initWithContentsOfURL:jsonURL];
self.allData = [jsonData JSONValue];
NSLog(#"allData value is1:%#", self.allData);
self.displayData = [[NSMutableDictionary alloc] initWithDictionary:self.allData];
NSLog(#"displayData value is2:%#", self.displayData);
allData works fine but I got an error on the displayData
2011-12-13 14:59:23.875 IPhone[352:207] -[__NSArrayM getObjects:andKeys:]: unrecognized selector sent to instance 0x59e1c20
2011-12-13 14:59:23.878 IPhone[352:207] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSArrayM getObjects:andKeys:]: unrecognized selector sent to instance 0x59e1c20'
*** Call stack at first throw:
Is it possible to pass data from NSDictionary to NSMutableDictionary ?
allData is apparently an NSArray, not an NSDictionary. You should go back and look at your JSON. The top-level there is probably an array.

Unrecognized Selector Error when writing dictionary values to file in iOS

I'm reading an array of ALAsset objects (delcared as NSMutableArray *assets; in the header file). I'm trying to follow this example in order to print the contents of an ALAssets dictionary to file to be retrieved later. Note that I can properly write the dictionary key to file (commented out), but not the value.
Here is my code which runs at the end of the viewDidLoad() method:
// Create path to Documents
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
if ([paths count] > 0) {
NSString *dictPath = [[paths objectAtIndex:0] stringByAppendingPathComponent:#"dict.out"];
NSDictionary *aDict = [[assets objectAtIndex:0] valueForProperty:ALAssetPropertyURLs];
for (id key in aDict) {
NSLog(#"key: %#, value: %#", key, [aDict valueForKey:key]);
//[key writeToFile:dictPath atomically:YES]; <- THIS LINE WORKS
[[aDict valueForKey:key] writeToFile:dictPath atomically:YES];
}
}
else
NSLog(#"nope"); // The program doesn't get here.
The log looks like this:
2011-11-17 23:44:41.340 PhotoApp[542:12803] key: public.jpeg,
value: assets-library://asset/asset.JPG?id=1000000001&ext=JPG
2011-11-17 23:44:41.361 PhotoApp[542:12803] -[NSURL
writeToFile:atomically:]: unrecognized selector sent to instance
0x6455650
2011-11-17 23:44:41.370 PhotoApp[542:12803] *
Terminating app due to uncaught exception
'NSInvalidArgumentException', reason: '-[NSURL
writeToFile:atomically:]: unrecognized selector sent to instance
0x6455650'
Edit: Not sure whether it matters, but the project is targeted for iPad, and is running on the simulator.
The problem is
[[aDict valueForKey:key] writeToFile:dictPath atomically:YES]; line.
as in key: public.jpeg, value: assets-library://asset/asset.JPG?id=1000000001&ext=JPG
you get the
key as public.jpeg and value as
asassets-library://asset/asset.JPG?id=1000000001&ext=JPG
which is a NSURL object so when you use.
[[aDict valueForKey:key] writeToFile:dictPath atomically:YES];
code then [aDict valueForKey:key] return NSURL object which does not recognizes writeToFile: method.
The method writeToFile:atomically: is available only for NSDictionary and NSArray. Actually you have NSURLs objects in the aDict dictionary. Even for NSString, that has been deprecated actually.
Since you are obtaining the URLs, get the NSURL's absoluteString (which returns NSString) from them and write them to file using writeToFile:atomically:encoding:error:
Otherwise you can write the aDict (NSDictionary) object itself to a file.