converting NSMutableData to NSMutableDictionary? - iphone

i am accumulating data from NSMutableDictionary to NSMutabledata like
NSMutableData *data = [receivedData objectForKey:#"tag1"];
and also
data = [receivedData objectForKey:#"tag2"];
after this one , how can i get data for #"tag2" only from NSMutableData?
NSMutableData tag2Data = [Data forKey:#"tag2"];
is not working?

I'm unsure exactly what you are trying to do here, but it doesn't look like you are using the proper class. If you check the class reference from Apple there is a link to a great code example of getting a string out of an NSMutableData object, but the only way to access the data inside it is using getBytes.

Related

Convert NSMutableData to NSData in Swift

I have a method which is returning NSMutableData. I need to pass this NSMutableData to another method but that method is expecting only NSData. I am trying to find any method/solution to convert NSMutableData to NSdata. But still no luck.
In Objective C, it can be done like this
NSData *immutableData = [NSData dataWithData:mutableData];
I am not sure how it can be done in Swift?Can someone help me in this?
Simply pass the NSMutableData to any method that expects NSData. Since it's a subclass, it will work fine.
But if you really want to do the conversion, simply do (Swift 3):
let data = someNSMutableDataVariable.copy() as! NSData
or
let data = NSData(data: someNSMutableDataVariable as Data)
It may make sense to update your code to use Data instead of NSMutableData or NSData. Just like using String instead of NSString and NSMutableString.

How to convert UIImage to JSON file in iPhone?

I have been using NSJSONSerialization class for converting fields of my object to JSON. Sadly only NSString, NSNumber, NSArray, NSDictionary, or NSNull types are supported.
As my object has one additional field, that is UIImage, I am at loss as to how to deal with it. I am sure many people have encountered this common problem, so what is best method to approach this?
You can encode UIImage data by base64, and add it to json object.
To get data from UIImage, you can use UIImagePNGRepresentation and UIImageJPEGRepresentation.
The code like this,
NSData *imageData = UIImagePNGRepresentation(image);
NSString *base64encodedStr = base64encode(imageData);
[dict setObject:base64encodedStr forKey:#"myImage"];
//then covert dict to json object.
To restore UIImage data, just parse json object and decode the data by base64.
Hope this can help you.
You could convert your images data to a string and then write that string.
NSData *imageData = UIPNGRepresentation(image);
NSString *imageString = [[NSString alloc] initWithData:imageData encoding:NSUTF8StringEncoding];
//I don't know how to use NSJSONSerialization
//[NSJSONSerialization serializeString:imageString];
NSString *base64encodedStr = [imageData base64Encoding];

iPhone, NSURLConnection > didReceiveData:(NSData *)data, How to check result data

I use url connection (http).
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
NSString *filePath; /* .../link.plist */
[data writeToFile:filePath atomically:YES];
}
After connection, I check result file (link.plist)
- (void)checkLinkResult {
NSString *filePath; //link.plist
NSString *result = [[NSString alloc] initWithContentsOfFile:filePath];
}
It works fine.
But I want to check Result String, directly, without making file.
"NSData -> file -> NSString" (now) ====> "NSData -> NSString" (i want)
Help me plz.
It's dependent your data.
If your data is Image
UIIMage * image = [[UIImage alloc] initWithData:Receivedata
If data is string
NSMutableString *string = [[NSMutableString alloc] initwithData:Receivedata encoding:nil]
In didReceiveData write to an NSMutableData object, then in checkLinkResult create a string from the NSMUtableData using the appropriate encoding.
It's actually how it's done in the apple NSConnection tutorial.
Follow the following steps:
Declare a file scope NSMutableData instance.
in your connection:DidRecieveData: callback append "data" to the previously created NSMutableData instance.
In connectionDidFinishLoading: callback use initWithData:encoding: of NSString and pass the NSMutableData instance and NSUTF8StringEncoding as parameters.

Extracting array from NSMutableData in http response

using iphone sdk 4.0. The callback for an http request gives data as an NSData object
-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
// Append the data received to our data
[theData appendData:data];
}
In my php script on the server i am returning an array as follows
var_dump($array).
How do i get my array back from the NSMutableData object 'theData' obove on my iphone.
Thanks
You have a string describing your array (or maybe several arrays?) stored as a sequence of bytes in your NSMutableData object. In order to turn it back into an array you're going to need to parse the var_dump output, which is likely to be arduous.
If you can find a library (or roll your own code) to return your data in Apple plist format, your task will be much easier: you can use
[NSPropertyListSerialization propertyListFromData:mutabilityOption:format:errorDescription:]
which takes an NSData (or NSMutableData) pointer as its first argument. Try http://code.google.com/p/cfpropertylist/ for a starting point.
From the example code at the cfpropertylist page:
$plist = new CFPropertyList();
$td = new CFTypeDetector();
$guessedStructure = $td->toCFType( $array );
$plist->add( $guessedStructure );
// and then return the plist content with
$plist->toXML()
and in your iOS code:
NSString *errorString = nil;
NSArray *array = [[NSPropertyListSerialization
propertyListFromData:theData
mutabilityOption:NSPropertyListImmutable
format:nil
errorDescription:&errorString] retain];
I would likely use YAJL on iOS, and $var = json_encode($array); in the PHP. Then in the iOS, I would parse that content from the NSData input like:
YAJLParser *parser = [[YAJLParser alloc] initWithParserOptions:YAJLParserOptionsAllowComments | YAJLParserOptionsCheckUTF8];
parser.delegate = [[[MyArrayParserDelegate alloc] init] autorelease];
[parser parse:data];
NSArray *thePhpArrayReceived = parser.delegate.resultantArray;
Please check out how to structure the delegate, and get YAJL here : Get YAJL + Readme
PHP outputs text so you will have to read that NSData as NSString and then parse out the array data according to the format specified by var_dump. As a starting point, the following code snippet should print out the array (as text) to your console:
NSString * dump = [[NSString alloc] initWithData:theData
encoding:NSUTF8StringEncoding];
NSLog(#"%#", dump);
[dump release];
As Seamus Campbell points out, there are better ways of doing this. Another option would be to output XML from your PHP script, and then use Cocoa's XML parsing methods to retreive the array.

iPhone - Corrupt JPEG data for image received over HTTP

I'm getting an image over HTTP, using NSURLConnection, as follows -
NSMutableData *receivedData;
- (void)getImage {
self.receivedData = [[NSMutableData alloc] init];
NSURLConnection *theConnection = // create connection
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
[receivedData appendData:data];
}
-(void)connectionDidFinishLoading:(NSURLConnection *)connection {
[connection release];
UIImage *theImage = [UIImage imageWithData:receivedData];
}
Usually it works just fine, but sometimes I'm seeing this get logged - : Corrupt JPEG data: premature end of data segment
At this point, the image does not completely render. I'll see maybe 75% of it, and then the lower right hand corner is a grey box.
Any ideas on how to approach fixing this? Am I constructing my image improperly?
Your HTTP code looks correct. You might want to log the size of the receivedData once it's done loading and compare it to the expected size of the image on the server. If it's the expected size, then maybe the image itself is corrupted on the server.
ASI-HTTP can fix this problem.
NSURL *coverRequestUrl = [NSURL URLWithString:imageStringURL];
ASIHTTPRequest *coverRequest = [[ASIHTTPRequest alloc] initWithURL:coverRequestUrl];
[coverRequest setDelegate:self];
[coverRequest setDidFinishSelector:#selector(imageRecieved:)];
[appDelegate.queue addOperation:coverRequest];
[appDelegate.queue go];
My queue variable in appDelegate is ASINetwork queue object. Because I send asynchronous request, so I use it.
- (void)imageRecieved:(ASIHTTPRequest *)response
{
UIImage *myImage = [UIImage imageWithData:[response responseData]];
}
I fixed this problem by using an NSMutableDictionary.
NSMutableDictionary *dataDictionary;
In my loadData function, I define my data:
NSMutableData *receivedData = receivedData = [[NSMutableData alloc] init];
Then I load the data into my dictionary where the key is [theConnection description] and the object is my data.
[dataDictionary setObject:receivedData forKey:[theConnection description]];
That way in the delegates, I can look up the correct data object for the connection that is passed to the delegate and save to the right data instance otherwise I end up with the JPEG munging/corruption problem.
In didReceiveData, I put:
//get the object for the connection that has been passed to connectionDidRecieveData and that object will be the data variable for that instance of the connection.
NSMutableData *theReceivedData = [dataDictionary objectForKey:[connection description]];
//then act on that data
[theReceivedData appendData:data];
Similarly, in didReceiveResponse, I put:
NSMutableData *theReceivedData = [dataDictionary objectForKey:[connection description]];
[theReceivedData setLength:0];
And in connectionDidFinishLoading:
NSMutableData *theReceivedData = [dataDictionary objectForKey:[connection description]];
img = [[UIImage alloc] initWithData:theReceivedData];
And this seems to work very well. By the way, my code is based on Apple's tutorial for NSUrlConnection with the addition of an NSMutableDictionary to keep track of individual connections. I hope this helps. Let me know if you want me to post my full image handling code.
I have seen this also. If you save the data to a file and then read the data back into an image, it works perfectly. I suspect there is http header information in the jpeg image data.
Hope someone finds a solution to this because the save to file workaround sucks.
// problem
UIImage *newImage = [UIImage imageWithData:receivedData];
// crappy workaround
[receivedData writeToFile:[NSString stringWithFormat:#"a.jpg"] atomically:NO];
UIImage *newImage = [UIImage imageWithContentsOfFile:#"a.jpg"];
Copying the NSData content using receivedData = [NSData dataWithBytes:receivedData.bytes length:receivedData.length] may be helpful too (and it's more efficient than saving to and reading from the disk).
A possible reason for this is that the original receivedData object does not retain its content (e.g. when created using [NSData dataWithBytesNoCopy:length:]) and you try to read them after they are freed.
This is likely when you encounter this problem on another thread from the thread that created the NSData object.