iphone SDK displaying image in uitableview from image data in JSON string - iphone

I'm new to this, so here goes..
I'm having a problem with displaying images in uitableview, that are downloaded from a mysql database. Here's what I'm doing:
converting images using UIImagePNGRepresentation.
uploading to MYSQL database via webservice.
So far so good..
The images are downloaded from MYSQL using JSON.
NSDictionary used to create array of image data from JSON String.
[UIImage imageWithData:[imageArray objectAtIndex:indexpath.row]] fails with error: [NSCFString bytes]: unrecongnised selector sent to instance.
I can understand why this is happening, but don't know how to resolve it. The imageWithData is expecting NSData object, but I've converted the string to NSData with no success.
Any help will be greatly appreciated.

Are you converting to and from data properly?
To data:
NSData* theData;
theData = [theNSString dataUsingEncoding:NSASCIIStringEncoding];
To string:
NSString* theNSString;
theNSString = [[NSString alloc] initWithData:theData encoding:NSASCIIStringEncoding];

Thanks for your response.
Yes I was doing the conversion to/from data, as you stated, the only difference being that I was using NSUTF8StringEncoding rather than NSASCIIStringEncoding.
I've tried it with NSASCIIStringEncoding, but the results is the same. It seems that the converted data is different to that stored on the database.
The data from the JSON string (NSData to NSString) is:
<89504e47 0d0a1a0a 0000000d 49484452 00000087 0000005a 08020000 001d25d2 ac000020 00494441 54780174 bd7778dc e775e73b bdf78e19 f40e1004 c002764a ec942cdb b12ccb55 b6e3123b 8e539e44 cecd3ad7 bbc9c6eb f4dc2789 b3297e9c 4d1cc5b1 2dc9b264 4bb22a25 52ec0401 16f45e07 184ceff3 ....
However, the conversion back to NSData gives the following data:
<3c383935 30346534 37203064 30613161 30612030 30303030 30306420 34393438 34343532 20303030 30303038 37203030 30303030 35612030 38303230 30303020 30303164 32356432 20616330 30303032 30203030 34393434 34312035 34373830.....
This may be the same, but [UIImage imageWithData:theData] returns null image.

Related

NSMutableString becomes (null) when converted from NSData with length 4000+

I'm sending XML request to some server and getting some response data from it using NSURLConnection:
-(void)connectionDidFinishLoading:(NSURLConnection *)connection
{
NSMutableString *receivedString = [[NSMutableString alloc] initWithData:_receivedData encoding:NSUTF8StringEncoding];
NSLog(#"Size of DATA: %d",[_receivedData length]);
NSLog(#"Body: %#", receivedString);
}
When length of my data is about 4000 - I can normally see the received data in output. But when length of data becomes greater (6000, 10000, etc.), Output shows that my receivedString becomes null!
How can I still save my data to the string, when it's length becomes greater? Thank you.
Are you sure your data is encoded with NSUTF8StringEncoding? Double check the data being returned to you. initWithData:encoding: will return nil if the data is not properly represented by the encoding.
An easy way to test this is to use the same data object, and create a string with incremental pieces of the same data until it fails, then look at the byte that causes it to fail.
I'd bet a piece of southern fried catfish that you have an improperly (or mismatched) encoded byte in that data.

Get objects from a NSDictionary

I get from an URL this result :
NSString *result = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];
it looks like this :
[{"modele":"Audi TT Coup\u00e9 2.0 TFSI","modele_annee":null,"annee":"2007","cilindre":"4 cyl","boite":"BVM","transmision":"Traction","carburant":"ES"},
{"modele":"Audi TT Coup\u00e9 2.0 TFSI","modele_annee":null,"annee":"2007","cilindre":"4 cyl","boite":"BVM","transmision":"Traction","carburant":"ES"}]
So it contains 2 dictionaries. I need to take the objects from all the keys from this result. How can I do this?
I tried this : NSDictionary vehiculesPossedeDictionary=(NSDictionary *)result;
and then this : [vehiculesPossedeDictinary objectForKey:#"modele"]; but this is not working.
Please help me... Thanks in advance
What you have is a JSON string which describes an "array" containing two "objects". This needs to be converted to Objective-C objects using a JSON parser, and when converted will be an NSArray containing two NSDictionarys.
You aren't going to be able to get your dictionary directly from a string of JSON. You are going to have to going to have to run it through a JSON parser first.
At this point, there is not one build into the iOS SDK, so you will have to download a third-party tool and include it in your project.
There are a number of different JSON parser, include TouchJSON, YAJL, etc. that you can find and compare. Personally, I am using JSONKit.
#MatthewGillingham suggests JSONKit. I imagine it does fine, but I've always used its competitor json-framework. No real reason, I just found it first and learned it first. I do think its interface is somewhat simpler, but plenty of people do fine with JSONKit too.
Using json-framework:
require JSON.h
...and then
NSString *myJsonString = #"[{'whatever': 'this contains'}, {'whatever', 'more content'}]";
NSArray *data = [myJsonString JSONValue];
foreach (NSDictionary *item in data) {
NSString *val = [item objectForKey:#"whatever"];
//val will contain "this contains" on the first time through
//this loop, then "more content" the second time.
}
If you have array of dictionary just assign objects in array to dictionary like
NSDictionary *dictionary = [array objectAtIndes:0];
and then use this dictionary to get values.

iPhone/iPad Base64 Image Encoded - Convert to UIImage

I have a base64 encoded image recieved via a web service.
How do I convert that string to a UIImage?
Obj-c or C# answers are fine.
Ian
First you need to convert the base64-encoded data into an NSData. This previous question seems to be a good resource on how to do that.
Then you just pass that NSData object to [UIImage imageWithData:...].
I havent't tried but here there seems to be a working sample code ;)
Hope it helps
In iPhone Monotouch C# this is how it is done:
byte[] encodedDataAsBytes = System.Convert.FromBase64String (Base64String);
string decoded = System.Text.Encoding.Unicode.GetString (encodedDataAsBytes);
NSData data = NSData.FromString (decoded, NSStringEncoding.ASCIIStringEncoding);
return UIImage.LoadFromData (data);
I was not able to get BahaiResearch's MonoTouch code to work -- an exception was thrown in NSData -- but was successful with the following:
byte[] encodedDataAsBytes = Convert.FromBase64String ( base64String );
NSData data = NSData.FromArray ( encodedDataAsBytes );
return UIImage.LoadFromData ( data );

NSUserDefaults and adding void* data in it

I have data in format
struct CardData
{
void* frontimagedata;
}
I need to hold this data in NSUserDefaults [ Need to use this data after app launch again after exit]. I am not using database in my app.
I need to use this format only as this CardData information is shared between Obj c and c++ code.
can anyone help me on this.
thanks,
Sagar
If you save it into an NSData object you'll be able to store it in NSUserDefaults.
NSData* data = [NSData dataWithBytes:frontimagedata length:datalen];

Compress/Decompress NSString in objective-c (iphone) using GZIP or deflate

I have a web-service running on Windows Azure which returns JSON that I consume in my iPhone app.
Unfortunately, Windows Azure doesn't seem to support the compression of dynamic responses yet (long story) so I decided to get around it by returning an uncompressed JSON package, which contains a compressed (using GZIP) string.
e.g
{"Error":null,"IsCompressed":true,"Success":true,"Value":"vWsAAB+LCAAAAAAAB..etc.."}
... where value is the compressed string of a complex object represented in JSON.
This was really easy to implement on the server, but for the life of me I can't figure out how to decompress a gzipped NSString into an uncompressed NSString, all the examples I can find for zlib etc are dealing with files etc.
Can anyone give me any clues on how to do this? (I'd also be happy for a solution that used deflate as I could change the server-side implementation to use deflate too).
Thanks!!
Steven
Edit 1: Aaah, I see that ASIHTTPRequest is using the following function in it's source code:
//uncompress gzipped data with zlib
+ (NSData *)uncompressZippedData:(NSData*)compressedData;
... and I'm aware that I can convert NSString to NSData, so I'll see if this leads me anywhere!
Edit 2: Unfortunately, the method described in Edit 1 didn't lead me anywhere.
Edit 3: Following the advice below regarding base64 encoding/decoding, I came up with the following code. The encodedGzippedString is as you can guess, a string "Hello, my name is Steven Elliott" which is gzipped and then converted to a base64 string. Unfortunately, the result that prints using NSLog is just blank.
NSString *encodedGzippedString = #"GgAAAB+LCAAAAAAABADtvQdgHEmWJSYvbcp7f0r1StfgdKEIgGATJNiQQBDswYjN5pLsHWlHIymrKoHKZVZlXWYWQMztnbz33nvvvffee++997o7nU4n99//P1xmZAFs9s5K2smeIYCqyB8/fnwfPyK+uE6X2SJPiyZ93eaX+TI9Lcuiatvx/wOwYc0HGgAAAA==";
NSData *decodedGzippedData = [NSData dataFromBase64String:encodedGzippedString];
NSData* unGzippedJsonData = [ASIHTTPRequest uncompressZippedData:decodedGzippedData];
NSString* unGzippedJsonString = [[NSString alloc] initWithData:unGzippedJsonData encoding:NSASCIIStringEncoding];
NSLog(#"Result: %#", unGzippedJsonString);
After all this time, I finally found a solution to this problem!
None of the answers above helped me, as promising as they all looked. In the end, I was able to compress the string on the server with gzip using the chilkat framework for .net ... and then decompress it on the iphone using the chilkat framework for iOS (not yet released, but available if you email the guy directly).
The chilkat framework made this super easy to do so big thumbs up to the developer!
Your "compressed" string is not raw GZIP'd data, it's in some encoding that allows those bytes to be stored in a string-- looks like base-64 or something like it. To get an NSData out of this, you'll need to decode it into the NSData.
If it's really base-64, check out this blog post an accompanying code:
http://cocoawithlove.com/2009/06/base64-encoding-options-on-mac-and.html
which will do what you want.
Once you have an NSData object, the ASIHTTPRequest method will probably do as you like.
This worked for me:
from a string gzipeed, then base64 encoded
to un-gzipped string (all utf8).
#import "base64.h"
#import "NSData+Compression.h"
...
+(NSString *)gunzipBase64StrToStr:(NSString *)stringValue {
//now we decode from Base64
Byte inputData[[stringValue lengthOfBytesUsingEncoding:NSUTF8StringEncoding]];//prepare a Byte[]
[[stringValue dataUsingEncoding:NSUTF8StringEncoding] getBytes:inputData];//get the pointer of the data
size_t inputDataSize = (size_t)[stringValue length];
size_t outputDataSize = EstimateBas64DecodedDataSize(inputDataSize);//calculate the decoded data size
Byte outputData[outputDataSize];//prepare a Byte[] for the decoded data
Base64DecodeData(inputData, inputDataSize, outputData, &outputDataSize);//decode the data
NSData *theData = [[NSData alloc] initWithBytes:outputData length:outputDataSize];//create a NSData object from the decoded data
//NSLog(#"DATA: %# \n",[theData description]);
//And now we gunzip:
theData=[theData gzipInflate];//make bigger==gunzip
return [[NSString alloc] initWithData:theData encoding:NSUTF8StringEncoding];
}
#end
I needed to compress data on the iPhone using Objective-c and decompress on PHP. Here is what I used in XCode 11.5 and iOS 12.4:
iOS Objective-c Compression Decompression Test
Include libcompression.tbd in the Build Phases -> Link Binary With Library. Then include the header.
#include "compression.h"
NSLog(#"START META DATA COMPRESSION");
NSString *testString = #"THIS IS A COMPRESSION TESTTHIS IS A COMPRESSION TESTTHIS IS A COMPRESSION TESTTHIS IS A COMPRESSION TESTTHIS IS A COMPRESSION TESTTHIS IS A COMPRESSION TEST";
NSData *theData = [testString dataUsingEncoding:NSUTF8StringEncoding];
size_t src_size = theData.length;
uint8_t *src_buffer = (uint8_t*)[theData bytes];
size_t dst_size = src_size+4096;
uint8_t *dst_buffer = (uint8_t*)malloc(dst_size);
dst_size = compression_encode_buffer(dst_buffer, dst_size, src_buffer, src_size, NULL, COMPRESSION_ZLIB);
NSLog(#"originalsize:%zu compressed:%zu", src_size, dst_size);
NSData *dataData = [NSData dataWithBytes:dst_buffer length:sizeof(dst_buffer)];
NSString *compressedDataBase64String = [dataData base64EncodedStringWithOptions:0];
NSLog(#"Compressed Data %#", compressedDataBase64String);
NSLog(#"START META DATA DECOMPRESSION");
src_size = compression_decode_buffer(src_buffer, src_size, dst_buffer, dst_size, NULL, COMPRESSION_ZLIB);
NSData *decompressed = [[NSData alloc] initWithBytes:src_buffer length:src_size];
NSString *decTestString;
decTestString = [[NSString alloc] initWithData:decompressed encoding:NSASCIIStringEncoding];
NSLog(#"DECOMPRESSED DATA %#", decTestString);
free(dst_buffer);
On the PHP side I used the following function to decompress the data:
function decompressString($compressed_string) {
//NEED RAW GZINFLATE FOR COMPATIBILITY WITH IOS COMPRESSION_ZLIB WITH IETF RFC 1951
$full_string = gzinflate($compressed_string);
return $full_string;
}