problem with converting NSData to NSArray - iphone

Hi
I have a problem with converting NSData to NSArray
my code is:
NSData *data = [[NSData alloc] initWithBytes:(const void *)buf length:len];
NSArray *array = [NSKeyedUnarchiver unarchiveObjectWithData:data];
can any one help me to do it.

I have no idea what is inside your byte buffer. This code works for a simple buffer of character bytes.
Try:
char buf[]="123456";
NSData *bufObj=[NSData dataWithBytes:(const void *)buf length:sizeof buf];
if(bufObj==nil)
NSLog(#"failed to create obj");
else {
NSMutableArray *marr=[NSMutableArray array];
[marr addObject:bufObj];
NSArray *arr=[NSArray arrayWithObject:bufObj];
NSLog(#"test:\n\tbufObj: %#\n\tmarr: %#\n\tarr: %#",bufObj,marr,arr);
}

Use +[NSPropertyListSerialization dataWithPropertyList:format:options:error:] to convert the data, then check if the result -isKindOfClass:[NSArray class].
It will work :)

Related

Make UIImage from ByteArray getting from .Net WebService

My problem is same as Converting byte array coming from Web service to UIImage iPhone
.Now I am storing these bytes in NSMutableArray.But the method:
NSData *data = [NSData dataWithBytes:YOUR_BYTE_ARRAY length:ARRAY_LENGTH];
takes arrayOfBytes as parameter.So can anyone tell me that how to convert this array in byte array. I searched a lot but unable to find relevant contents.
Not sure how you're getting the mutable array to begin with. If you're using NSURLConnection, the delegate will get NSData, so you needn't use a mutable array. Consider getting the data using the connection asynch block method like this ...
NSURLRequest *myRequest = // the request you've already got working to get image data
[NSURLConnection sendAsynchronousRequest:myRequest queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
if (!error) {
// image from data with no intermediate mutable array or byte array
UIImage *image = [UIImage imageWithData:data];
}
}];
Thanks for your co-operation. But it does not help me. After a long research i found my solution. I am sharing my information so that others can get right answer.
NSArray *byteArray = [[NSArray alloc]init]; //strore all data here coming from server in byte formate
unsigned c = [byteArray count];
uint8_t *bytes = malloc(sizeof(*bytes) * c);
unsigned i;
for (i = 0; i < c; i++)
{
NSString *str = [byteArray objectAtIndex:i];
int byte = [str intValue];
bytes[i] = (uint8_t)byte;
}
NSData *data = [[NSData alloc]initWithBytes:bytes length:c];
UIImage *image = [UIImage imageWithData:data];
NSLog(#"image %#",image);

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];

Why NSMutableDictionary don't want write to file?

- (void)viewDidLoad
{
[super viewDidLoad];
if ([[NSFileManager defaultManager] fileExistsAtPath:pathString])
{
infoDict = [[NSMutableDictionary alloc] initWithContentsOfFile:pathString];
}
else
{
infoDict = [[NSMutableDictionary alloc]initWithObjects:[NSArray arrayWithObjects:#"BeginFrame",#"EndFrame", nil] forKeys:[NSArray arrayWithObjects:[NSNumber numberWithBool:YES],[NSNumber numberWithBool:YES], nil]];
if ([infoDict writeToFile:pathString atomically:YES])
{
NSLog(#"Created");
}
else
{
NSLog(#"Is not created");
NSLog(#"Path %#",pathString);
}
}
This is my code. I check if file is created, if not - I create a NSMutableDictionary and I write it to file at path, but writeToFile method returns NO. Where is problem? If I create this file with NSFileManager it works, but doesn't when I want to write a dictionary.
writeToFile:atomically only works if the dictionary you call it on is a valid property list object (see docs).
For a NSDictionary to be a valid property list object, among other things, its keys must be strings, but in your example the keys are NSNumber instances.
You can not control the content you are going to write sometimes. For example, you can't avoid a null value when you are going to write a JSON object that is gotten from a server.
NSData is compatible with these "invalid" values, so converting NSArray or NSDictionary to NSData is an ideal way in these cases.
write:
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:jsonObject];
[data writeToFile:path atomically:YES];
read:
NSData *data = [NSData dataWithContentsOfFile:path];
NSDictionary *jsonObject = [NSKeyedUnarchiver unarchiveObjectWithData:data];

NSString encoding for accents displays crazy characters

I am downloading data (text) from a server.
I have tried with both:NSISOLatin1StringEncoding and NSASCIIStringEncoding
But I keep seeing things like: {"estado":"M\u00e9xico"}
Noting that it should read México and not M\u00e9xico (with an accent over the e).
Looking online I figured that \u00e9 is in fact é link.
But the NSString is not able to interpret this and instead prints weird things on my UILabels:
I would really really appreciate your help on this.
Alsso, if you are itnerested, you can download the data from here: http://www.miorden.com/demo/iphone/estadoJSON.php
NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:#"http://www.miorden.com/demo/iphone/estadoJSON.php"]];
NSString *string = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding];
NSLog(#"Downloaded: %#", string);
string = [NSString stringWithContentsOfURL:[NSURL URLWithString:#"http://www.miorden.com/demo/iphone/estadoJSON.php"] encoding:NSISOLatin1StringEncoding error:nil];
NSLog(#"Downloaded: %#", string);
I have been literally trying for days and it is killing me!
Thank you so much!
That appears to be unicode, try NSUTF8StringEncoding.
The data is in JSON format, so you'll need to JSON decode it too.
For example using this: https://github.com/TouchCode/TouchJSON
NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:#"http://www.miorden.com/demo/iphone/estadoJSON.php"]];
NSError *error;
NSArray *array = [[CJSONDeserializer deserializer] deserializeAsArray:data error:&error];
NSLog(#"Test: %#", [[array objectAtIndex:11] valueForKey:#"estado"]);
outputs
2011-08-11 09:35:45.742 enctest[63236:407] Test: México

How to convert NSArray to NSData?

Can anyone tell me how to convert an NSArray to an NSData? I have an NSArray. I need to send it to an NSInputStream. In order to do that I need to convert the NSArray to an NSData.
Please help me, I'm stuck here.
Use NSKeyedArchiver (which is the last sentence of the post Garrett links):
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:array];
Note that all the objects in array must conform to the NSCoding protocol. If these are custom objects, then that means you need to read up on Encoding and Decoding Objects.
Note that this will create a fairly hard-to-read property list format, but can handle a very wide range of objects. If you have a very simple array (strings for instance), you may want to use NSPropertyListSerialization, which creates a bit simpler property list:
NSString *error;
NSData *data = [NSPropertyListSerialization dataFromPropertyList:array format:NSPropertyListBinaryFormat_v1_0 errorDescription:&error];
There's also an XML format constant you can pass if you'd rather it be readable on the wire.
On a somewhat related note, here's how you would convert the NSData back to an NSArray:
NSArray *array = [NSKeyedUnarchiver unarchiveObjectWithData:data]
I used this code.
NSError *error;
NSMutableData *jsonData = [[NSJSONSerialization dataWithJSONObject:yourDemoArray
options:0 // Pass 0 if you don't care about the readability of the generated string
error:&error] copy];
Swift :
let data = NSKeyedArchiver.archivedData(withRootObject: jsonArray)
print(data)
You can do this-
NSArray *array= [NSArray array];
NSData *dataArray = [NSKeyedArchiver archivedDataWithRootObject:array];
In iOS 9+ use this please:
NSArray *array = [[NSArray alloc] init];
NSData *data = [NSPropertyListSerialization dataWithPropertyList:array format:NSPropertyListBinaryFormat_v1_0 options:0 error:nil];
The older version of this was deprecated in iOS 8.
Swift 5
let data = try! NSKeyedArchiver.archivedData(withRootObject: array, requiringSecureCoding: true)