Conversion of NSData to NSString fails due to some charecters - iphone

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.

Related

Latin characters display ? objective-c

I am making a call to get a JSON response like this:
NSData *urlData=[NSURLConnection sendSynchronousRequest:serviceRequest returningResponse:&httpResponse error:nil ];
NSString *returnString=[[NSString alloc]initWithData:urlData encoding:NSUTF8StringEncoding];
However, when I print the string using NSLog:
Emiratos �rabes Unidos
When I convert it to NSData like this:
NSData *jsonData = [returnString dataUsingEncoding:NSUTF8StringEncoding];
NSArray * response = [NSJSONSerialization JSONObjectWithData:jsonData options:0 error:nil];
It turns it to be (when I retrieve the value from the array):
Emiratos \Ufffdrabes Unidos
And when I put it in a label it displays it like this:
Emiratos �rabes Unidos
I would like to display in a label like this:
Emiratos Árabes Unidos
How can I do it?
The problem seems to be this line:
NSString *returnString =
[[NSString alloc] initWithData:urlData
encoding:NSUTF8StringEncoding];
You are assuming that the data is a string encoded as UTF8. But apparently it isn't. Therefore you're seeing the "replacement character" (codepoint U+FFFD) at this point.
You'll need to find out what encoding is actually being used. You can probably just experiment with other encodings. Alternatively, use NSLog to look at the data; an NSData object is logged as a sequence of hex bytes, so by looking at the bytes in that position, and by looking up various encodings on the Internet, you may be able to deduce what encoding is being used here.
(But if you use NSLog and you actually see FFFD at this point, then you've had it; the server itself is supplying the bad data and there's nothing you can do about it, as the good data is lost before you can get at it.)

How to encode some text correctly

I have some text formatting issues that I need to solve. I have some strange characters displaying from the NSString below
the original string:
NSString *descriptionStringPreFormatted = [item objectForKey:#"title"];
the formatted string:
NSString *descriptionLabelStringUTF8 = [descriptionStringPreFormatted stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSLog(#"descriptionStringPreFormatted is %#", descriptionStringPreFormatted);
NSLog(#"descriptionLabelStringUTF8 is %#", descriptionLabelStringUTF8);
here's the output which is the same whether I use the UTF8 encoding or not.
the output:
2013-01-05 16:44:51.807 descriptionStringPreFormatted is £144.99...
2013-01-05 16:44:51.810 descriptionLabelStringUTF8 is £144.99...
I think you are receiving dictionary "item" from web services. So try to decode that response string from webservice with NSUTF8StringEncoding.
NSString *str=[[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];
here "responseData" is raw data coming from web services.

how to convert NSString encoding to UTF8

I have done something like:
NSData *dt = [mystr dataUsingEncoding:NSWindowsCP1251StringEncoding];
NSString *str = [NSString alloc] initWithData:dt encoding:NSUTF8StringEncoding];
then NSLog(#"%#", str);
However, if 'mystr' is english then the NSLog would print it as is, but if mystr is Arabic (for ex.) NSLog will not print anything, so how can i change the encoding of mystr to UTF8 ?
thank you in advance.
Your first line creates some data that is in cp1251 encoding. Your second line says "read this data into a string, assuming that the bytes represent a UTF8 encoded string". But because the bytes represent a cp1251 encoded string, that's not likely to work very well.
NSString represents an ordered collection of characters. Internally it uses some encoding to store these characters in memory, but its interface provides an encoding-independent access to the string and you can therefore consider NSString to be encoding-agnostic. If what you want is a collection of bytes that represent the string in UTF8 encoding, then you don't want an NSString. You want to get an NSString to emit such a collection of bytes, perhaps using the -dataUsingEncoding: method you've already found.
Try this one
NSString *s = #"Some string";
const char *c = [s UTF8String];
import
#import "NSString+URLEncoding.h" and
#import "NSString+URLEncoding.m" files
after that where u r doing encode write in .h file this method
-(NSString *)urlEncodeUsingEncoding:(NSStringEncoding)encoding;
after that write in .m file method implementation
-(NSString *)urlEncodeUsingEncoding:(NSStringEncoding)encoding
{
return (NSString *)CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(NULL,
(CFStringRef)self,
NULL,
(CFStringRef)#"!*'\"();:#&=+$,/?%#[]% ",
CFStringConvertNSStringEncodingToEncoding(encoding)));
}
after that use like this
NSString *keyword=#"sample text";
here pass ur string whatever
NSString *url = [NSString stringWithFormat:#"%#",[keyword urlEncodeUsingEncoding:NSUTF8StringEncoding]];
NSLog(#"%#",url);
Did you try [mystr UTF8String] ? This returns a char *
You can try this
1) NSString to NSData(NSWindowsCP1251StringEncoding
NSString *text=#"This is Sample Text Conversion.....";
NSData *data=[text dataUsingEncoding:NSWindowsCP1251StringEncoding];
2)Revers process.
NSString *textRev=[[NSString alloc]initWithData:data encoding:NSWindowsCP1251StringEncoding];
NSLog(#" Actual String.. %#",textRev);

NSData to NSString by changing the value null is returned. I need your help

*cipher.h, cipher.m all code : http://watchitlater.com/blog/2010/02/java-and-iphone-aes-interoperability
Cipher.m
-(NSData *)encrypt:(NSData *)plainText{
return [self transform:KCCEncrypt data:plainText;
}
step1.
Cipher *cipher = [[Cipher alloc]initWithKey:#"1234567890"];
NSData *input = [#"kevin" dataUsingEncoding:NSUTF8StringEncoding];
NSData *data = [cipher encrypt:input];
data variables NSLog print : <4d1c4d7f 1592718c fd588cec 84053e35>
step2.
NSString *changeVal = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
data variables NSLog print : null
NSData to NSString by changing the value null is returned. By converting NSString NSURLConnection want to transfer. I need you help
Kevin, I actually take the result of the cipher encrypt method and use an extension to NSData to convert it to a Base64 encoded string. The cipher text does NOT convert to a valid UTF8 string by itself.

How to find why NSMutableData is invalid

I access a RESTFUL url and get back results. The results are in JSON. I turn the response into a string via:
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
NSString *json = [[NSString alloc] initWithBytes:[self.receivedData mutableBytes] length:[self.receivedData length] encoding:NSUTF8StringEncoding];
The json variable has a value of 0x0. When I mouse over it, I see <Invalid CFStringRef>. How can I debug this to tell why it is invalid? I render the JSON given back through the browser in A JSON parser. That checks out fine.
Results are given back by entering an ID in the URL. Other IDs return results without issue. The result set is fairly large.
First I would use initWithData:encoding: to setup the NSString. Small difference, but that method is there for a reason.
Then, I would do a hexdump of self.receivedData to see what is actually in there. If that data is not properly UTF8 encoded then the initWithData:encoding: will fail.
(Google for NSData hex dump to find other people's utility functions to do this)
I have found that sometimes web services are sloppy with their encoding. So I usually implement a fallback like this:
NSString* html = [[NSString alloc] initWithData: data encoding: NSUTF8StringEncoding];
if (html == nil) {
html = [[NSString alloc] initWithData: data encoding: NSISOLatin1StringEncoding];
if (html == nil) {
html = [[NSString alloc] initWithData: data encoding: NSMacOSRomanStringEncoding];
}
}
It is kind of sad that this is required but many web services are not written or configured properly.
Use NSLog to look at the bytes.