Convert nsdictionary to nsdata - iphone

have an app that can take a picture and then upload to a server. encoding it to base 64 and pass it thru a XMLRPC to my php server.
i want to take the NSDictionary info that is returned from UIImagePickerController delegate
-(void) imagePickerController:(UIImagePickerController *)imagePicker didFinishPickingMediaWithInfo:(NSDictionary *)info
and convert it to NSData so i can encode it.
so, how can i convert NSDictionary to an NSData?

You can use an NSKeyedArchiver to serialize your NSDictionary to an NSData object. Note that all the objects in the dictionary will have to be serializable (implement NSCoding at some point in their inheritance tree) in order for this to work.
Too lazy to go through my projects to lift code, so here is some from the Internet:
Encode
NSMutableData *data = [[NSMutableData alloc] init];
NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data];
[archiver encodeObject:yourDictionary forKey:#"Some Key Value"];
[archiver finishEncoding];
[archiver release];
/** data is ready now, and you can use it **/
[data release];
Decode:
NSData *data = [[NSMutableData alloc] initWithContentsOfFile:[self dataFilePath]];
NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data];
NSDictionary *myDictionary = [[unarchiver decodeObjectForKey:#"Some Key Value"] retain];
[unarchiver finishDecoding];
[unarchiver release];
[data release];

NSDictionary -> NSData:
NSData *myData = [NSKeyedArchiver archivedDataWithRootObject:myDictionary];
NSData -> NSDictionary:
NSDictionary *myDictionary = (NSDictionary*) [NSKeyedUnarchiver unarchiveObjectWithData:myData];

I know a bit too late, but just in case someone bumps into this same issue. UIImage is not serializable, but you can serialize it using the code:
if your image is JPG:
NSData *imagenBinaria = [NSData dataWithData:UIImageJPEGRepresentation(imagen, 0.0)];
// imagen is a UIImage object
if your image is PNG:
NSData *imagenBinaria = [NSData dataWithData:UIImagePNGRepresentation(imagen)];
// imagen is a UIImage object

The NSPropertyListSerialization class give you the most control over writing and reading of property lists:
NSDictionary *dictionary = #{#"Hello" : #"World"};
NSData *data = [NSPropertyListSerialization dataWithPropertyList:dictionary
format:NSPropertyListBinaryFormat_v1_0
options:0
error:NULL];
Read:
NSData *data = ...
NSPropertyListFormat *format;
NSDictionary *dictionary = [NSPropertyListSerialization propertyListWithData:data
options:0
format:&format
error:NULL];

Three options occur to me on this, two mentioned in other answers NSKeyedArchiver and PropertyList, there is also NSJSONSerialization that gave me the most compact data in a simple test.
NSDictionary *dictionary = #{#"message":#"Message from a cool guy", #"flag":#1};
NSData *prettyJson = [NSJSONSerialization dataWithJSONObject:dictionary options:NSJSONWritingPrettyPrinted error:nil];
NSData *compactJson = [NSJSONSerialization dataWithJSONObject:dictionary options:0 error:nil];
NSData *plist = [NSPropertyListSerialization dataWithPropertyList:dictionary
format:NSPropertyListBinaryFormat_v1_0
options:0
error:NULL];
NSData *archived = [NSKeyedArchiver archivedDataWithRootObject:dictionary];`
Size results for the different approaches smallest to largest
compactJson 46 bytes
prettyJson 57 bytes
plist 91 bytes
archived 316 bytes

Related

loading Hierarchy in NSMutableData

Is there Hierarchy system in NSMutableData? If so, how do i load information in a hierarchy manner?
Example
//Create path to saving location
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSMutableData *gameData;
NSKeyedUnarchiver *decoder;
NSString *documentPath = [documentsDirectory stringByAppendingPathComponent:#"tierSave.dat"];
gameData = [NSData dataWithContentsOfFile:documentPath];
//end
//start loading
for(NSArray* firstData in gameData){
decoder = [[NSKeyedUnarchiver alloc] initForReadingWithData:gameData];
int level1 = [decoder decodeIntegerForKey:level1];
}
//end
However in for(NSArray* firstData in gameData), the compiler tells me that gameData will not respond to count because it is a NSMutableData instead of NSMutableArray etc, How do i exactly re-implement the code above?
Saving:
Create a NSArray with your multiple NSData
Use NSKeyedArchiver to make a NSData from your NSArray
Loading:
Load a NSData from file
Use NSKeyedUnarchiver to extract the NSArray
Loop your NSArray
In code:
NSData *data0 = [NSData data]; // Data 1
NSData *data1 = [NSData data]; // Data 2
/////////// SAVE
// now make a array
NSArray *array = [NSArray arrayWithObjects:data0, data1, nil];
// now archive the data
NSData *archivedData = [NSKeyedArchiver archivedDataWithRootObject:array];
// archivedData contains now a binary plist with your archived array including your NSData objects
[archivedData writeToFile:path atomically:YES];
/////// LOAD
NSData *archivedDataFromFile = [NSData dataWithContentsOfFile:path];
NSArray *newArray = [NSKeyedUnarchiver unarchiveObjectWithData:archivedDataFromFile];
NSData *dataLoaded0 = [newArray objectAtIndex:0];

How to convert NSData to NSArray (or NSObject)

I did test this code, but it cause SIGABRT error.
NSArray *array = [NSKeyedUnarchiver unarchiveObjectWithData:data]
NSData is plist data with xml format. This code works fine.
[urlData writeToFile:[self docPath] atomically:YES];
array = [[NSMutableArray alloc] initWithContentsOfFile:[self docPath]];
How can I change NSData to NSArray without file conversion?
This assumes you have populated NSString *filepath with the filepath of your saved data file.
NSPropertyListFormat format;
NSData *dataFromFile = [NSData dataWithContentsOfFile:fileNameWithPath];
NSArray *arrayFromFile = nil;
if (dataFromFile) {
arrayFromFile = [NSPropertyListSerialization propertyListFromData:dataFromFile
mutabilityOption:NSPropertyListMutableContainers
format:&format
errorDescription:NULL];
}
Hope that helps...

downloading data Json pictures

hi this is a part of my code
NSURL *jsonURL = [NSURL URLWithString:#"http://*****.php"];
NSString *donneeJson = [[NSString alloc] initWithContentsOfURL:jsonURL];
self.pseudoOnline = [donneeJson JSONValue];
NSDictionary *json2 = [pseudoOnline valueForKey: #"photo"];
NSLog(#"adresse photo%#",[pseudoOnline valueForKey: #"photo"]);
NSString *url = [[pseudoOnline valueForKey: #"photo"]objectAtIndex:0];
NSLog(#"adresse photo%#",url );
adresse photo(
"http://************/XWsmG18O27.jpg",
"http://************/Wz0ab6oIxU.jpg",
"http://***********/9yKzQrpO59.jpg",
"http://************/l2rbNeIK8a.jpg")
UIImage *image = [[UIImage alloc] initWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:url]]];
how i can download all the pictures because iam only take picture index0 !
thks
thks
ads2 is an instance of NSArray, not NSDictionary. NSArray is not a key-value collection and does not respond to valueForKey:

problem in converting NSString to NSData

I want to convert one NSString to NSData. on Using encoding am getting different value in NSData by displaying it using its description property.
I have
NSString *str=#"80369F4";
NSData *data = [str dataUsingEncoding:NSUTF8StringEncoding];
on printing [data description]; am getting some different values...
how to extract the same string from the NSData.. pl help me out on this problem.
Create a new NSString:
NSString *newString = [[[NSString alloc] initWithData: data encoding: NSUTF8StringEncoding] autorelease];
You can use NSString's initWithData:encoding: method:
NSString *str=#"80369F4";
NSData *data = [str dataUsingEncoding:NSUTF8StringEncoding];
NSString *sameString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];

Why there save and load file code works on iphone simulator but failed on device

(void) loadDataFromDisk
{
NSMutableData *data = [[NSMutableData alloc] initWithContentsOfFile:[self pathToDataFile]];
NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data];
_cells = [[unarchiver decodeObjectForKey:#"Board"] retain];
[unarchiver release];
[data release];
}
(void) saveDataToDisk
{
NSMutableData *data = [NSMutableData alloc];
NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data];
[archiver encodeObject:_cells forKey:#"Board"];
[archiver finishEncoding];
[data writeToFile:[self pathToDataFile] atomically:YES];
//[array release];
[data release];
//NSMutableData
}
(BOOL)gameDataExists
{
return [[NSFileManager defaultManager] fileExistsAtPath:[self pathToDataFile]];
}
(NSString *)pathToDataFile
{
NSString *path = [[NSBundle mainBundle] bundlePath];
return [path stringByAppendingPathComponent: GAME_DAT];
}
the code above worked on simulator but failed on device.it seems like that the file can not
be found after i exit and reload my app.
And if i implement the pathToDataFile like this:
(NSString *)pathToDataFile
{
NSArray * path = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory , NSUserDomainMask, YES);
NSString *docDir = [path objectAtIndex:0];
return [docDir stringByAppendingPathComponent:GAME_DAT];
}
the file save and reload worked on device ,but the drawRect method i implemented in my view can not be called after i called [self setNeedsDisplay].
chris
Can
The bundle path is read-only on the device but read-write on the emulator. On the device any attempts to write there will therefore fail.
Your second approach to use document directory should solve the problem.
I don't know why [self setNeedsDisplay] doesn't work for you but it's likely unrelated to this problem.
There is one error I noticed in your code:
NSMutableData *data = [NSMutableData alloc];
Should be:
NSMutableData *data = [[NSMutableData alloc] init];
You should also release the archiver at the end of the saveDataToDisk method.