Change UIImage Class to send to node.js server in iOS? - ios

I am creating an App for chatting. Now I want to send UIImage to server in JSON String so other user can receive image.I am using socket.io so I have to send event with data(JSON String).
Problems- When I try to convert UIImage to NSData and convert it to JSON it gives error 'Invalid type in JSON write (NSConcreteMutableData)'.
What will be the correct way to send UIImage to server?
code
NSData *imgData = UIImageJPEGRepresentation(image, .2);
NSString * imageString =[[NSString alloc]initWithBytes:[imageData bytes] length:[imageData length] encoding:NSASCIIStringEncoding];
also tried
NSString * imageString =[[NSString alloc]initWithData :imgData encoding:NSUTF8StringEncoding];
converted data to dictionary:
NSDictionary *jsonDict = [NSJSONSerialization JSONObjectWithData:imgData options:NSJSONReadingAllowFragments error:&error];
Any help would be appreciated.

The general approach would be to base64 encode the image data. In this way the image data is converted to a string format instead of binary.
Since iOS 7 NSData has provided base64 conversion methods that you can use instead of your current attempted conversion to and from strings.

Related

RNCryptor "encryptData" returning null

New to iOS dev, trying to work on encoding data for secure data storage in db.
I found the current example here: https://github.com/RNCryptor/RNCryptor-objc
This is my code.
NSString * aPassword =#"tempkey";
NSData *data = [#"Data" dataUsingEncoding:NSUTF8StringEncoding];
NSError *error;
NSData *encryptedData = [RNEncryptor encryptData:data
withSettings:kRNCryptorAES256Settings
password:aPassword
error:&error];
NSLog(#"Data: %#", [[NSString alloc] initWithData:encryptedData encoding:NSUTF8StringEncoding]);
My log
2016-10-20 11:41:52.662 BlueBoard[57245:10027277] Data: (null)
Am I missing a step in this process? I've confirmed that it's null because it the db its being stored as null as well.
Your issue isn't that encryptedData is nil, it's that you are attempted to create an NSString from data that doesn't represent a string.
If you wish to convert encryptedData into a string for storage or other purposes, you should convert the data into a Base 64 encoded representation. Do this with the base64EncodedStringWithOptions: method.
NSString *base64String = [encryptedData base64EncodedStringWithOptions:0];
Of course when you want to decrypt the string later, you will need to convert the Base 64 encoded string back into NSData, and then decrypt that data.

Proper way to get the byte array from the JSON

I am trying to get the image from the byte array. I can only get the image if enter the byte array values into the string directly as follows:
NSMutableString *imagen = [[NSMutableString alloc] initWithString:#"-1,-40,-1,-32,0,16,74,70,73,70,0,1,0,1,0,96,0,96,0,0,-1,-2,0,31,76,69,65,68,32,84,101,99,104,110,111,108,111,103,105,101,115,32,73,110,99,46,32,86,49,46,48,49,0,-1,-37,0,-124,0,5,5,5,8,5,8,12,7,7,12,12,9,9,9,12,13,12,12,12,12,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13];
//this way works fine
IF i try to get the byte array into string as follows,then I couldnt get the image:
NSString *logo=[NSString stringWithFormat:#"%#",[[JSON valueForKey:#"request"]valueForKey:#"logo" ]];
NSMutableString *imagen = [[NSMutableString alloc] initWithString:logo];
//this way doesnt work out
I am following this link to get the thing done.this link
Could you please tell me whats the proper way to get byte array from JSON?
This is not executable code, it is a method to use:
You get the JSON in self.receivedData
Convert it into an object with
NSDictionary *jsonObject = NSJSONSerialization JSONObjectWithData:
** Unknown how the image data is encoded in the JSON. If it is Base64 encoded:
Get the Base64image string with
NSString *imageString = jsonObject[#"request"][#"logo"]
Convert the Base64 string into data:
NSData *imageData = [NSData alloc] initWithBase64EncodedString: imageString options:
Get an image with
UIImage *logoImage = [imageData imageWithData]
All in all you have way to much code that accomplished nothing and converting the image data to an NSString is incorrect.
Converting to a string and then back to data accomplishes nothing.
This code seems confused? The link you posted has string encodings which contain negative numbers. You parse these as signed but then assign them to an array of unsigned uint8_t using bytes[i] = (uint8_t)byte;.
I think you need to post the string encoding format and an example?

A string encoding issuse on IOS

I came across a problem with string encoding in ios development. The story is as below:
I create some values in Chinese and then create a NSDictionary for those values, the dictionary is used as parameter for network request:
- (void)createActivity
{
NSString *actionTheme = titleF.text;
NSString *actionTitle = biaotiF.text;
NSDictionary *dic = [NSDictionary dictionaryWithObjectsAndKeys:actionTheme, #"actionTheme", actionTitle, #"actionTitle",nil];
[self networkrequest:];
}
Then some work has been done for the dictionary:
Transform the dictionary to the form of JSON as the type of NSString.
NSData* jsonData = [NSJSONSerialization dataWithJSONObject:param options:NSJSONWritingPrettyPrinted error:nil];
NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
Encoding the string , because of Chinese word in the string.
NSString *urlEncodedString = [jsonString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
At last a full url was create with the string above:
http://app.ic100.com/action/add?paramJson=%7B%22actionTheme%22%3A%22%E6%88%96%E8%80%85%E5%92%8C%E7%94%9F%E6%B4%BB%22%2C%22actionSite%22%3A%22%E5%8E%A (something like this)
I use the third party "ASIFormDataRequest" for network request, and I also set the StringEncoding:
ASIFormDataRequest *requstHttp = [[ASIFormDataRequest alloc] init];
[requstHttp setStringEncoding:NSUTF8StringEncoding];
....
All the datas has been sent to the server successfully, but when I request these data from the server and show then on the iphone. It turn to be unreadable text:
I have carefully checked all the place that I should encode or decode the string, and only utf8 is used. What`s more , for the server side , no other encoding used either. And my colleague has tested sent data from Android platform, no problem. So I think maybe I have missed some points.
Any advise?
By using the class Base64 you can encode or decode the string.
Add Base64 class in your project from HERE
see the mehode in class to encode.
Encode:
+ (NSString *)stringWithBase64EncodedString:(NSString *)string;
- (NSString *)base64EncodedString;
Decode:
- (NSString *)base64DecodedString;

Break image/jpeg into chunks and bind in nsdictionary for sending JSON in iOS

EDIT: I did not do a very good job of explaining for the server works and my apologies for the same. So here are two things in which the server works ( expects data from clients)
1) Server has a size limitation for receiving image data. It expects images to be broken up in chunks of byte array
2) Server expects to receive these chunks of byte array through JSON.
So I am assuming this translates to the following on the client side
1) I need to break the image in parts
2) Create a Byte array of each part
3) Bind those byte array with JSON and send with server
Once received by the server, those are constructed as an Image by the server.
I am trying to achieve the above mentioned goal by the following approach (I keep the image file in NSData, then I create a Byte Buffer and keep chunks of the image file's NSData in that buffer. Post that I bind this buffer with JSON )
Following is the code for above approach:
-(void)dividepacketId:(int)pktId fileData:(NSData*)dt //dt contain the NSData of image file
{
Byte buffer[20480];
long long dtLength,from=0;
long long len=[dt length];
BOOL b=YES;
while (b)
{
int k=0,indexCont=0;
if(len>20480)
{
dtLength=20480;
}
else
{
dtLength=len;
b=NO;
}
[dt getBytes:buffer range:NSMakeRange(from,dtLength)];
NSData *imageData=nil;
imageData = [NSData dataWithBytes:buffer length:dtLength];
len=len-dtLength;
from=from+dtLength;
NSLog(#"sending buffer=%s legth of buffer=%lli len value=%lli",buffer,dtLength,len); //everything is fine till here
NSMutableDictionary *projectDictionary3 = [NSMutableDictionary dictionaryWithCapacity:1];
[projectDictionary3 setObject:#"2100" forKey:#"Action"];
[projectDictionary3 setObject:[NSString stringWithFormat:#"%i",pktId] forKey:#"PacketId"];
[projectDictionary3 setObject:#"101" forKey:#"FileAction"];
if(imageData!=nil)
[projectDictionary3 setObject: imageData forKey:#"FData"];//data
[projectDictionary3 setObject:[NSString stringWithFormat:#"%i",(int)dtLength] forKey:#"DataLength"];//data
NSError *jsonSerializationError = nil;
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:projectDictionary3 options:NSJSONWritingPrettyPrinted error:&jsonSerializationError]; //"here crashed"
if(!jsonSerializationError)
{
NSString *serJSON = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
NSLog(#"Serialized JSON: %#", serJSON);
}
else
{
NSLog(#"JSON Encoding Failed: %#", [jsonSerializationError localizedDescription]);
}
code to send over stream
[self sendDataToServer:jsonData];
} //while loop
}
Here is the challenge. If I send simple data (for example a string) through this code, it goes over to server successfully ( through socket). But when I try to break an actual jpeg image into parts and bind it in nsdictionary to make json, it crashes with the following error.
terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Invalid type in JSON write (NSConcreteData)'. Any help here would be highly appreciated.
EDIT: As explained by bobnoble, I understand the reason for the exception. In that case however, how do I accomplish sending over data to server
Deleting all but the key portions that need to be changed.
As I stated in the comments the data needs to be in a format JSON handles, raw bytes are not acceptable so one way is to encode the data with Base64. The receiver will also need to decode the Base64 string into data.
while (b) {
//get chunk from and dtLength
NSData *imageData = [dt subdataWithRange:NSMakeRange(from, dtLength)];
NSData *imageBase64Data = [imageData base64EncodedDataWithOptions:0];
NSString *imageBase64String = [[NSString alloc] initWithData:imageBase64Data encoding: NSUTF8StringEncoding];
// update len and from
NSLog(#"sending imageData =%#. dtLength =%i len =%lli", imageBase64String, dtLength, len);
// Create projectDictionary3 and add items
// Added image data)
if(imageData.length) {
[projectDictionary3 setObject: imageBase64String forKey:#"FData"];
}
[projectDictionary3 setObject:#(imageBase64String.length) forKey:#"DataLength"];
// serialize projectDictionary3 into JSON and sent to server];
}
From the NSJSONSerialization class reference:
An object that may be converted to JSON must have the following
properties:
The top level object is an NSArray or NSDictionary.
All objects are instances of NSString, NSNumber, NSArray, NSDictionary, or NSNull.
All dictionary keys are instances of NSString.
Numbers are not NaN or infinity.
The second bullet does not include NSData, and is why the exception is being thrown.
Convert the image data to Base64 encoding, then put it in the dictionary as an NSString. Take a look at the NSData base64EncodedStringWithOptions method.

Base64 encoded string wont decode (iOS)

I am base64 encoding some data using the following line:
NSString *theData = [serialized base64EncodedStringWithOptions:kNilOptions];
This works correctly and I then pass this string to my web server which stores it in the database.
Later, I am then retrieving this base64 encoded string back from the web server which also works correctly (I have compared both the original before upload and the after download strings and they are the same).
However, when I try to decode this string using:
NSString *theString = [imageDict objectForKey:#"image"];
NSData *imageData = [[NSData alloc] initWithBase64EncodedString:theString
options:kNilOptions];
it just gives me a null value for imageData.
If I output theString it is the correct base64 encoded string I uploaded.
Any ideas why it won't decode?
Thanks in advance.
I used NSDataAdditions.h < see http://code.ohloh.net/file?fid=28qaXmo6xH1Z4clfmn9_wJqDqNI&cid=xVjpNPxNo_A&s=&fp=308694&mp=&projSelected=true#L0 and for .m http://code.ohloh.net/file?fid=tXQCCVHemN1iAx6ZQSy1VkBACXA&cid=xVjpNPxNo_A&s=&fp=308694&mp&projSelected=true#L0 >
NSData *imageData = [NSData dataWithBase64EncodedString:theString];

Resources