I have a strange problem with my current app development. the aim of my app is to receive several xhtml websites via NSURLSConnection (yes, no ASIHTTPRequest framework), save them in an array and post them via NSURLConnection to a webservice, which parses some information for me.
problem: I have really strange encoding problems and tried a lot of workarounds.
receiving of xhtml website:
(void)connection:(CustomURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
CFStringEncoding cfEncoding = CFStringConvertIANACharSetNameToEncoding((CFStringRef) [response textEncodingName]);
NSStringEncoding encoding = CFStringConvertEncodingToNSStringEncoding(cfEncoding);
[lastSearch.dataObjectsEncoding setObject:[response textEncodingName] forKey:connection.tag ];
[receivedData setLength:0];}
afterwards I work with the data and want to send it over to the webservice. therefor I do some preparations:
method 1:
NSMutableString *data = [[NSMutableString alloc] initWithData:theData encoding:NSASCIIStringEncoding];
NSArray *escapeChars = [NSArray arrayWithObjects: #"€", #"\n", #";" , #"/" , #"?" , #":" ,
#"#" , #"&" , #"=" , #"+" ,
#"$" , #"," , #"[" , #"]",
#"#", #"!", #"'", #"(",
#")", #"*", nil];
NSArray *replaceChars = [NSArray arrayWithObjects: #"%E2%82%AC", #"", #"%3B" , #"%2F" , #"%3F" ,
#"%3A" , #"%40" , #"%26" ,
#"%3D" , #"%2B" , #"%24" ,
#"%2C" , #"%5B" , #"%5D",
#"%23", #"%21", #"%27",
#"%28", #"%29", #"%2A", nil];
int len = [escapeChars count];
int i;
for(i = 0; i < len; i++)
{
[data replaceOccurrencesOfString: [escapeChars objectAtIndex:i]
withString:[replaceChars objectAtIndex:i]
options:NSLiteralSearch
range:NSMakeRange(0, [data length])];
}
method 2:
NSMutableString *data = [[NSMutableString alloc] initWithData:theData encoding:NSUTF8StringEncoding];
method 3:
CFStringEncoding cfEncoding = CFStringConvertIANACharSetNameToEncoding((CFStringRef) [lastSearchParam.dataObjectsEncoding objectForKey:key]);
NSStringEncoding encoding = CFStringConvertEncodingToNSStringEncoding(cfEncoding);
NSMutableString *data = [[NSMutableString alloc] initWithData:theData encoding: encoding];
method 4:
NSString *data = [[NSString alloc] initWithBytes:theData length:[theData length] encoding:NSUTF8StringEncoding];
method 5:
NSString *data2 = [data stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
after I added some stuff I want to HTTP POST the received XHTML to the webservice. to encode the whole parameters and the received data I add everything to a big string an do a
NSData *postData = [post dataUsingEncoding:NSUTF8StringEncoding allowLossyConversion:NO];
NSString *postLength = [NSString stringWithFormat:#"%d", [postData length]];
most websites are in UTF-8. so I first tried "method 2". if I NSLog the whole received data, everything seems fine, I can view the correct HTML source code, even the € sign is displayed correctly. but if I transmit the HTTP POST to the webservice, there is not all XHTML received by the web service. some special chars seems to break the transmission, e.g. a ";" sign.
so I searched the internet and came up with "method 1", parsing the received xhtml websites to ASCII and do some selfmade special char conversation - this worked for most signs, but e.g. the "€" didn't work and wasn't correctly received by the web service. but in this case, everything got over to the webservice - but sadly with wrong chars.
next try was "method 3", I saved the encoding of the websites while receiving them and use that information later on. but here was the same problem as with UTF8 encoding: the transmission was breaking by some special chars...
"method 4" and "method 5" didn't work as well..
question: why does the transmission breaks during my HTTP POST to the web service?
Related
I am converting NSData to NSString which I got as response of a url using the following method.
NSString *result = [[NSString alloc] initWithData:_Data encoding:NSUTF8StringEncoding];
It works fine and I am using this for a long time but today I faced an issue while loading the data (paging) at one page my result gives null string.
So I searched SO and found a method from this link NSData to NSString converstion problem!
[NSString stringWithCString:[theData bytes] length:[theData length]];
and this works fine.
My queries,
The method was deprecated in iOS 2.0. If I use this will I be facing any issue in future?
I think this is the text that made the method fail What is this and is there any way that I can encode this using NSUTF8StringEncoding?
What is the the alternative encoding that I can use for encoding all the type of characters like in the above pic?
In order to obtain the type of the content which is sent by the server, you need to inspect the Content-Type header of the response.
The content type's value specifies a "MIMI type", e.g.:
Content-Type: text/plain
A Content-Type's value may additionally specify a character encoding, e.g.:
Content-Type: text/plain; charset=utf-8
Each MIME type should define a "default" charset, which is to be used when there is no charset parameter specified.
For text/* media types the default charset is US-ASCII.
(see RFC 6657, §3).
The following code snippet demonstrates how to safely encode the body of a response:
- (NSString*) bodyString {
CFStringEncoding cfEncoding = NSASCIIStringEncoding;
NSString* textEncodingName = self.response.textEncodingName;
if (textEncodingName) {
cfEncoding = CFStringConvertIANACharSetNameToEncoding( (__bridge CFStringRef)(textEncodingName) );
}
if (cfEncoding != kCFStringEncodingInvalidId) {
NSStringEncoding encoding = CFStringConvertEncodingToNSStringEncoding(cfEncoding);
return [[NSString alloc] initWithData:self.body encoding:encoding];
}
else {
return [self.body description];
}
}
Note:
body is a property returning a NSData object representing the response data.
response is a property returning the NSHTTPURLResponse object.
If
NSString *result = [[NSString alloc] initWithData:_Data encoding:NSUTF8StringEncoding];
returns nil then _Data does not contain a valid string in UTF-8 encoding.
You said that
[NSString stringWithCString:[theData bytes] length:[theData length]];
works fine in your case. This method
interprets the data bytes in the "default C string encoding", but it is unspecified which
encoding that is (and therefore this method is deprecated and should not be used).
I think the default C string encoding is still "Mac Roman". In that case
NSString *result = [[NSString alloc] initWithData:_Data encoding:NSMacOSRomanStringEncoding];
would be the correct solution. But in any case, you should find out which encoding
the web service uses for the response, and specify that in the initWithData:encoding:
method.
Try this
NSString *theString = [NSString stringWithFormat:#"To be continued%C", ellipsis];
NSData *asciiData = [theString dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
NSString *asciiString = [[NSString alloc] initWithData:asciiData encoding:NSASCIIStringEncoding];
NSLog(#"Original: %# (length %d)", theString, [theString length]);
NSLog(#"Converted: %# (length %d)", asciiString, [asciiString length]);
It is due to the uncorrect string encoding.
You can try:
save the NSData to the disk with dataPath
use the NSString class method to create the string:
+ (id)stringWithContentsOfURL:(NSURL *)url usedEncoding:(NSStringEncoding *)enc error:(NSError **)error
Notice here:
enc
Upon return, if url is read successfully, contains the encoding used to interpret the data.
So if the method successes, you can get the correct string and all is done by the iOS.
In my app i have a service which supports spanish and return the result in spanish.
Now i am trying to pass some search term to this service to get the result back but its failing because while sending compiler converts the word to some funny word with unidentified characters.
I am doing this:
name here is coming in spanish but when i am adding this in the config dictionary it gets converted again to some funny thing.
-(void)perfromLocationSearchWithName:(NSString *)name{
NSData * nameCode = [[NSData alloc]init];
nameCode = [name dataUsingEncoding:NSUTF8StringEncoding allowLossyConversion:YES];
NSString * namePass = [[NSString alloc]initWithData:nameCode encoding:NSUTF8StringEncoding];
NSLog(#"Name:%#",namePass);
NSMutableDictionary *config = [[[NSMutableDictionary alloc] initWithCapacity:4] autorelease];
NSString * strAction = [NSString stringWithFormat:#"vendorSearchByName"];
if (namePass !=nil){
[config setObject:namePass forKey:#"vendorName"];
//[config setObject:#"001" forKey:#"MakeCode"];
[config setObject:#"5" forKey:#"maxCount"];
[config setObject:strAction forKey:#"action"];
}
NSLog(#"Dict%#",[config description]);
comm = [[CommManager alloc] init];
[comm searchDealerLocationWithOptions:config withDelegate:self];
[namePass release];
}
Please help
Thanks,
Try using NSISOLatin1StringEncoding. Helped us in our app.
First I need to say that I am new to iPhone development, so please I need you to be specific!
I'm developing an application for School scientific project,the question is: How can I insert data into a mysql table from UITextFields on the iPhone?
On my application I have 3 UITextFields, so I need to insert those UITextFields values into the mysql table. It doesn't matter the way you know to do that, I'm in a hurry and I just wanna to put it to work.
1-I working with this PHP code
<?php
if (isset ($_GET["matricula"]))
$matricula = $_GET["matricula"];
else
$matricula = "ELO";
$sql="INSERT INTO chatitems (user, message, matricula) VALUES ('$_GET[user]','$_GET[messages]','$_GET[matricula]')";
$con = mysql_connect($DB_HostName,$DB_User,$DB_Pass) or die(mysql_error());
mysql_select_db($DB_Name,$con) or die(mysql_error());
//$sql = "insert into $DB_Table (matricula) values('$matricula');";
$res = mysql_query($sql,$con) or die(mysql_error());
mysql_close($con);
if ($res) {
echo "success";
}else{
echo "faild";
}// end else
?>
And I insert this CODE on my application(Xcode 4.1)
2
- (IBAction)insert:(id)sender
{
// create string contains url address for php file, the file name is phpFile.php, it receives parameter :name
NSString *strURL = [NSString stringWithFormat:#"http://localhost:8888/phpFile.php?name=%#",txtName.text];
//NSString *strURL = [NSString stringWithFormat:#"http://localhost:8888/phpFile.php?name=%#",txtMatricula.text];
// to execute php code
NSData *dataURL = [NSData dataWithContentsOfURL:[NSURL URLWithString:strURL]];
// to receive the returend value
NSString *strResult = [[[NSString alloc] initWithData:dataURL encoding:NSUTF8StringEncoding]autorelease];
NSLog(#"%#", strResult);
NSString *cont11 = [NSString stringWithFormat:#"http://localhost:8888/UEUO/insertMT.php?name=%#",txtName.text];
NSString *cont21 = [NSString stringWithFormat:#"http://localhost:8888/UEUO/insertMT.php?matricula=%#",txtMatricula.text];
NSData *cont12 = [NSData dataWithContentsOfURL:[NSURL URLWithString:cont11]];
NSData *cont22 = [NSData dataWithContentsOfURL:[NSURL URLWithString:cont21]];
NSString *cont13 = [[[NSString alloc] initWithData:cont12 encoding:NSUTF8StringEncoding]autorelease];
NSLog(#"%#", cont13);
NSString *cont23 = [[[NSString alloc] initWithData:cont22 encoding:NSUTF8StringEncoding]autorelease];
NSLog(#"%#", cont23);
}
This code works fine for only one UItextField, I need three3.
Repenting: How can I insert the values of three UITextFields into a MySql table using PHP and C++?
Please anything is helpful, if you know how please help me or send me a tutorial or a piece of code!
Your PHP script is looking for 3 parameters passed from a single request.
Your iPhone code is sending 2 different requests with 1 parameter each.
Your iPhone code should be sending 1 request with 3 parameters set, as with this sort of request:
NSString *cont11 = [NSString stringWithFormat:#"http://localhost:8888/UEUO/insertMT.php?name=%#&matricula=%#&message=%#",txtName.text, txtMatricula.text, txtMessage.text];
[NSData dataWithContentsOfURL:[NSURL URLWithString:cont11]];
I should also point out that you haven't sanitized your inputs. That's really bad. Sanitize your inputs.
I am trying to parse a JSON response of a GET request. When the characters, are latin no problem.
However when they are not latin the message doesn't come out correctly. I tried greek and instead of "πανος" i get "& pi; & alpha; & nu; & omicron; & sigmaf;"
The code I use for parsing the response is:
NSString *responseString = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];
NSLog(#"response %#", responseString);
// array from the JSON string
NSArray *results = [responseString JSONValue];
When I try to read the response from a website using ajax, everything is fine. The same applies when trying to send a GET request to the application servers with data from iphone. So when i transmit data to the server and read it from the website everything is fine. When i try to show the same data in the app, "Houston we have a problem".
Any clues?
EDIT: To avoid misunderstandings, it's not an issue of HTML, I just point out that for some readon utf-8 characters here are encoded correctly and automatically eg. "&pi" will be converted to "π", however objective c doesn't seem to do this on its own
There is a confusion I think.
π is an HTML entity which is unrelated to text encoding like UTF8 / Latin.
Read wikipedia for details about...
You need a parser to decode these entities like the one previously mentioned by Chiefly Izzy:
NSString+HTML category and method stringByReplacingHTMLEntities
Look at Cocoanetics NSString+HTML category and method stringByReplacingHTMLEntities method. You can find it at:
https://github.com/Cocoanetics/NSAttributedString-Additions-for-HTML/blob/master/Classes/NSString%2BHTML.m
Here's a pretty decent list of lot of HTML entities and their corresponding unicode characters.
Try to use this snippet of code:
NSString *responseString = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];
NSString *decodedString = [NSString stringWithUTF8String:[responseString cStringUsingEncoding:[NSString defaultCStringEncoding]]];
NSLog(#"response %#", decodedString);
// array from the JSON string
NSArray *results = [decodedString JSONValue];
I have faced the same problem, but I solved it by changing the JSON parser. I have started using the SBJSONParser, and now I am getting the appropriate results. This is the code snippet, I have used
NSMutableURLRequest *request = [[[NSMutableURLRequest alloc] init] autorelease];
[request setURL:[NSURL URLWithString:urlString]];
[request setHTTPMethod:#"POST"];
NSData *returnData = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
NSString *returnString = [[NSString alloc] initWithData:returnData encoding:NSUTF8StringEncoding];
SBJSON *parser=[[SBJSON alloc]init];
NSArray *JSONData = (NSArray*)[parser objectWithString:returnString error:nil];
I tried to read the response data from google weather api, but german umlauts aren't shown correctly. Instead of "ö" I get "^".
I think the problem are those two lines of code:
CXMLElement *resultElement = [nodes objectAtIndex:0];
description = [[[[resultElement attributeForName:#"data"] stringValue] copy] autorelease];
How can i get data out of resultElement without stringValue?
PS: I use TouchXML to parse xml
You must be using an NSURLConnection to get your data I suppose. When you receive the data you can convert it to an NSString using appropriate encoding. E.g.
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{
if(xmlResponse == nil){
xmlResponse = [[NSMutableString alloc] initWithData:data encoding:NSISOLatin1StringEncoding];
}
else{
NSMutableString *temp = [[NSMutableString alloc] initWithData:data encoding:NSISOLatin1StringEncoding];
[xmlResponse appendString:temp];
[temp release];
}
}
Here xmlResponse is the NSMutableString that you can pass to your parser. I have used NSISOLatin1 encoding. You can check other kinds of encoding and see what gives you the characters correctly (NSUTF8StringEncoding should do it I suppose).You can check the API doc for a list of supported encodings.