How to pass NSData as NSString and get it back? - iphone

i have a NSData object.
I want to convert it to a string, pass to a function and then reconvert back to NSData object.
But How?
I tried this method, but NSData value it's different from the original!
here my code:
// a generic class
APClass *c = [[APClass alloc] init];
c.aNumber = 123;
c.aString = #"my string";
// my data obj
NSMutableData *data = [NSMutableData data];
// archiver to store class in nsdata
NSKeyedArchiver *encoder = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data];
[encoder encodeObject:[NSNumber numberWithInt:c.aNumber] forKey:#"aNum"];
[encoder encodeObject:c.aString forKey:#"aStr"];
[encoder finishEncoding];
[encoder release];
[c release];
NSLog(#"%#", data);
NSString *d = [NSString stringWithFormat:#"%#", data];
// ---
NSString *strFromData = [NSString stringWithFormat:#"%#", d];
NSData *dataNM = [strFromData dataUsingEncoding:NSUTF8StringEncoding];
// decoder to retrieve class from nsdata
NSKeyedUnarchiver *decoder = [[NSKeyedUnarchiver alloc] initForReadingWithData:dataNM];
int number = [[decoder decodeObjectForKey:#"aNum"] intValue];
NSString *string = [decoder decodeObjectForKey:#"aStr"];
[decoder finishDecoding];
[decoder release];
NSLog(#"[Number: %d] -- [String: %#]", number, string);
How can i convert back to original NSData?
data and dataNM are different in size.
Compiler give back this error:
2012-04-02 16:33:28.269 DataTest[18008:f803] -[__NSCFData
objectForKey:]: unrecognized selector sent to instance 0x6b46c80
2012-04-02 16:33:28.270 DataTest[18008:f803] * Terminating app due
to uncaught exception 'NSInvalidArgumentException', reason:
'-[__NSCFData objectForKey:]: unrecognized selector sent to instance
0x6b46c80'
thanks.

Solved.
Using dataUsingEncoding, value of NSData it's different.
To pass data around methods or apps, etc, i've used base64 convertion.
Encode
NSString *d =
[NSString stringWithFormat:#"appdue://obj=%#",
[APBase64Converter base64forData:data]];
Decode
NSData *data = [APBase64Converter base64DataFromString:urlParams];
APBase64Converter Is a lib that encode/decode easily data and strings.
Working example and APBase64Converter lib can be downloaded from here: http://goo.gl/8YNjS
Thanks all.
I "retain" this post for helps people and me next time!

Use
NSData to NSString:
- (id)initWithData:(NSData *)data encoding:(NSStringEncoding)encoding
and
NSString to NSData:
- (NSData *)dataUsingEncoding:(NSStringEncoding)encoding
with encoding
NSUTF8StringEncoding
or
NSMacOSRomanStringEncoding (which is an 8-bit encoding).

Use Base64 class it is available in github
DatabaseResult* result = [self.database executeQuery:#"SELECT * FROM `images` WHERE image_id = ? AND imagetype = ?", self.routeId,self.imagetype];
for(EGODatabaseRow* row in result) {
NSString *strImage=[row stringForColumn:#"image_photo"];
[Base64 initialize];
NSData *data = [Base64 decode:strImage];
UIImage *image=[UIImage imageWithData:data];
}
This is how i convert String to data and then data to image.

Related

Application crashes while fetching data from NSString

I have an application in which I am converting UIImage to NSData an further NSData to Base64String using this https://github.com/nicklockwood/Base64 class....but the App crashes When I want to fetch the converted string to the other class.
It gives EXC_BAD_ACCESS error...
Is it possible that NSString can't handle such big strings or is there any other issue?
Here is my code....
image = [UIImage imageNamed:#"earring_hoops_small.jpg"];
NSData *data = UIImageJPEGRepresentation(image, 0.1f);
NSData *data2 = data;
NSLog(#"BaseString=%#",data2);
[Base64 initialize];
strEncoded = [Base64 encode:data];
NSLog(#"BaseString=%#",strEncoded);
and It gives exception while....
myString = strEncoded;

passing a UInt32 into a NSData object returns (null)

I am trying to pass a NSNumber into a UInt32, which is working.. Then I am trying to stuff that UInt32 into a NSData object.. however this is where things get abit funky...
when I try to write whats in that NSData object out to a string its returning (null).
This is what my code looks like, I think it has something to do with the way I am passing CACHE_VALUE into requestCacheData.. but I am not totally sure why.
// Use the correctly returned cache number
UInt32 CACHE_VALUE = [cacheNumber intValue];
NSLog(#"%lu", CACHE_VALUE); //gives me the correct integervalue
NSData * requestCacheData = [[NSData alloc] initWithBytes:&CACHE_VALUE length:sizeof(CACHE_VALUE)];
NSString *myString = [[NSString alloc] initWithData:requestCacheData encoding:NSUTF8StringEncoding];
NSLog(#"%#", myString); //outputs (null)
any help would be appreciated.
you can't turn the NSData to a right NSString that NSData do not contain a right string content.
in your case , your NSData just contain a binary unsigned int,
what do you suppose to get ?
NSString* str= #"a NSString";
NSData* requestCacheData =[str dataUsingEncoding:NSUTF8StringEncoding];
NSString *myString = [[NSString alloc] initWithData:requestCacheData encoding:NSUTF8StringEncoding];
NSLog(#"%#", myString);
you may get the right ouput,
but if you want to turn a UINT to NSString
just
NSString *str = [[[NSString alloc] initWithFormat:#"%u",CACHE_VALUE] autorelease];

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 ...>.)

unrecognized selector

I have a problem with the next code:
NSDictionary * imagen = [[NSDictionary alloc] initWithDictionary:[envio resultValue]];
NSString *imagenS = [imagen valueForKey:#"/Result"];
ClaseMaestra *b1 = [[ClaseMaestra alloc]init];
NSData *imagenDecode = [[NSData alloc] initWithData:[b1 base64DataFromString:imagenS]];
NSLog(#"Decode Image:");
NSLog(#"%#", imagenDecode);
//SAVE IMAGE
NSArray *sysPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES);
NSString *docDirectory = [sysPaths objectAtIndex:0];
NSString *filePath = [NSString stringWithFormat:#"%#david.png",docDirectory];
[imagenDecode writeToFile:filePath atomically:YES];
Blockquote
[envio resultValue] --> return a NSDictionary with one image in Base 64 codification.
I want decoder and save this image but in my console I have showed this message:
2011-08-23 19:19:39.750 WSStub[38501:a0f] *************************
2011-08-23 19:19:39.752 WSStub[38501:a0f] SendImage
2011-08-23 19:19:39.752 WSStub[38501:a0f] *************************
2011-08-23 19:19:39.759 WSStub[38501:a0f] -[ClaseMaestra base64DataFromString:]: unrecognized selector sent to instance 0xd00ad0
Program received signal: “EXC_BAD_ACCESS”.
ClaseMaestra interface is:
#import <Foundation/Foundation.h>
#class NSString;
#interface ClaseMaestra : NSObject
+ (NSMutableData *)base64DataFromString: (NSString *)string;
#end
I can´t understand the "unrecognized selector" error...
This is a class method and you call iton an instance of the class. You should either change it to an instance method. instead of:
+ (NSMutableData *)base64DataFromString: (NSString *)string;
Use:
- (NSMutableData *)base64DataFromString: (NSString *)string;
Or, change the call, instead of:
NSData *imagenDecode = [[NSData alloc] initWithData:[b1 base64DataFromString:imagenS]];
Use:
NSData *imagenDecode = [[NSData alloc] initWithData:[ClaseMaestra base64DataFromString:imagenS]];
What to choose depends on your needs.
base64DataFromString: is a class method (starts with a +). So instead of
ClaseMaestra *b1 = [[ClaseMaestra alloc]init];
NSData *imagenDecode = [[NSData alloc] initWithData:[b1 base64DataFromString:imagenS]];
You should do
NSData *data = [ClaseMaestra base64DataFromString:imagenS];
You are sending a class message to an instance. The receiver should be a class.
So do:
NSData *imagenDecode = [[NSData alloc] initWithData:[ClaseMaestra base64DataFromString:imagenS]];
You'll also get this error if you use the name of a private framework, eg: MPMovieView .Everyone knows you're not supposed to use those, but what I didn't know is that I was using one!
What's odd is, if you use Xibs, they load the system one and give you the same type of error (Class methods).
But if you load it in code, it shadows the system framework one. I spent a decent hour scratching my head, ensuring everything was hooked up right... it was, just needed to change how I named my custom stuff. Posting this for anyone with similar

NSString read/write to file

Im just having trouble reading and writing NSString to a dat file on the iphone.
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *saveFile = [documentsDirectory stringByAppendingPathComponent:#"Profiles.dat"];
Boolean saveFileExists = [[NSFileManager defaultManager] fileExistsAtPath:saveFile];
// NSString *saveFile = [documentsDirectory stringByAppendingPathComponent:#"Profiles.dat"];
NSMutableData *gameData;
NSKeyedUnarchiver *decoder;
NSKeyedArchiver *encoder;
//decoder = [[NSKeyedUnarchiver alloc] initForWritingWithMutableData:gameData];
myGameState *gameState = [myGameState sharedMySingleton];
if(saveFileExists) {
gameData = [NSData dataWithContentsOfFile:saveFile];
decoder = [[NSKeyedUnarchiver alloc] initForReadingWithData:gameData];
gameState.Profile1 = [decoder decodeObjectForKey:#"Name1"];
gameState.Profile2 = [decoder decodeObjectForKey:#"Name2"];
gameState.Profile3 = [decoder decodeObjectForKey:#"Name3"];
gameState.Profile4 = [decoder decodeObjectForKey:#"Name4"];
gameState.Profile5 = [decoder decodeObjectForKey:#"Name5"];
gameState.curProfile = [decoder decodeObjectForKey:#"curProfile"];
[decoder release];
}
else {
gameData = [NSMutableData data];
encoder = [[NSKeyedArchiver alloc] initForWritingWithMutableData:gameData];
gameState.Profile1 = #"Default1";
gameState.Profile2 = #"Default2";
gameState.Profile3 = #"Default3";
gameState.Profile4 = #"Default4";
gameState.Profile5 = #"Default5";
[encoder encodeObject:#"Default1" forKey:#"Name1"];
[encoder encodeObject:#"Default2" forKey:#"Name2"];
[encoder encodeObject:#"Default3" forKey:#"Name3"];
[encoder encodeObject:#"Default4" forKey:#"Name4"];
[encoder encodeObject:#"Default5" forKey:#"Name5"];
gameState.curProfile = gameState.Profile1;
[encoder encodeObject:gameState.curProfile forKey:#"curProfile"];
[encoder finishEncoding];
//[gameData writeToFile:<#(NSString *)path#> atomically:<#(BOOL)useAuxiliaryFile#>
[gameData writeToFile:saveFile atomically:YES ];
//[gameData writeToFile:saveFile atomically:NO encoding:NSStringEncodingConversionAllowLossy error:nil];
[encoder release];
}
gameState.curProfile etc are all NSString pointers. Now im very new to Objective C and just cant seem to get this working correctly. I have searched around forums and cant seem to find the correct way to do this. Literally all i want is to read a write a NSString to a dat file but it aint working as is. I have managed to write ints and bools with no problems just cant get past the text problem on my own.
any help is appreciated
thanks
g
Your code works without any problem here. I guess you have problems in other parts of codes.
By the way, if you only need to save a few entries, you don't have to do all these works yourself; just use NSUserDefaults. It automatically prepares the file to save the data, encodes the data, and decodes the data on the next launch. See this Apple document. It can be used as
[[NSUserDefaults standardUserDefaults] setString:#"boo" forKey:#"key!"];
and later the data can be read as
NSString* s=[[NSUserDefaults standardUserDefaults] stringForKey:#"key!"];
It's as easy as this! You might want to call
[[NSUserDefaults standardUserDefaults] synchronize];
to force the saving of the data to the file; usually this isn't necessary (The system does this automatically when quit, etc.)