Danish special characters (æ, ø, å) are not getting encoded properly - ios

I'm facing the url encoding issue for kCFStringEncodingISOLatin1 encoding:
I have tried as below:
NSString *urlEncoded = (__bridge_transfer NSString *)CFURLCreateStringByAddingPercentEscapes(
NULL,
(__bridge CFStringRef) string,
NULL,
(CFStringRef)#"!*'\"();:#&=+$,?%#[]% ",
kCFStringEncodingISOLatin1);//æøå (if kCFStringEncodingUTF8 >> not encoding properly)
It's returning NULL value.
i'm writing an image to path which has the danish special chars. the issue is the file name must not encoded and it should be display with same chars with-out any encoded chars.
Any help would be appreciated!!

Related

Emoji cStringUsingEncoding with NSASCIIStringEncoding not working

I have an array with data :
MY_ARRAY: (
"email="My_Email_ID"",
"message=\Ud83d\Ude0a",
"key="MY_KEY"
"id="MY_ID""
)
In the message field I have added emoji and it is showing it's hex value.
But when I try converting it to string :
string = [MY_ARRAY componentsJoinedByString: #"&"];
the output in terminal shows:
email="My_Email_ID"&message=😊&key="MY_KEY"&id="MY_ID"
why is it converting back to emoji?
The problem which I am facing is at this line:
const char *charData = [string cStringUsingEncoding:NSASCIIStringEncoding];
as I am getting null here.
Changing below line:
const char *charData = [string cStringUsingEncoding:NSASCIIStringEncoding];
to
const char *charData = [string cStringUsingEncoding:NSUTF8StringEncoding];
solved my issue.
Thanks to this forum.
If at all possible, stay away from anything other than UTF8.
NSASCIIStringEncoding will break (return NULL) whenever there is a non-ASCII character in the string. There is no reason to take the risk. Only use cStringUsingEncoding: if you actually for whatever strange reason need a string in that particular encoding. Since NSLog expects UTF8 strings, any encoding that isn't a subset of UTF8 will produce strange results.

NSURL encoding with special characters

I am trying to submit a request using NSURL to the following:
http://api.allsaints.com/v1/product/?category=Women's Knitwear
when putting this URL in a browser with the ' and the space int the category, the browser (chrome) is modifying the request to:
http://api.allsaints.com/v1/product/?category=Women%27s%20Knitwear which works.
However, I can not get the right encoding to work as part of a NSURL and NSDATA request on iOS. I tried various encoding using stringByAddingPercentEscapesUsingEncoding to normalise the URL but it keep on failing.
Can someone point me in the right direction to an encoding that not only swaps the space to a %20 but also swaps the ' to a %27?
Refer to NSString stringByAddingPercentEscapesUsingEncoding: you should use CFURLCreateStringByAddingPercentEscapes to custom which character you want to escape.
- (NSString *) urlencodeStr:(NSString *)str
{
return (NSString *)CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(
NULL,
(__bridge CFStringRef) str,
NULL,
CFSTR("!*'();:#+$,/?%#[]"),
kCFStringEncodingUTF8));
}
CFSTR("!*'();:#+$,/?%#[]") contains the characters will be escaped.

NSLog() vs printf() when printing C string (UTF-8)

I have noticed that if I try to print the byte array containing the representation of a string in UTF-8, using the format specifier "%s", printf() gets it right but NSLog() gets it garbled (i.e., each byte printed as-is, so for example "¥" gets printed as the 2 characters: "¬•").
This is curious, because I always thought that NSLog() is just printf(), plus:
The first parameter (the 'format') is an Objective-C string, not a C
string (hence the "#").
The timestamp and app name prepended.
The newline automatically added at the end.
The ability to print Objective-C objects (using the format "%#").
My code:
NSString* string;
// (...fill string with unicode string...)
const char* stringBytes = [string cStringUsingEncoding:NSUTF8Encoding];
NSUInteger stringByteLength = [string lengthOfBytesUsingEncoding:NSUTF8Encoding];
stringByteLength += 1; // add room for '\0' terminator
char* buffer = calloc(sizeof(char), stringByteLength);
memcpy(buffer, stringBytes, stringByteLength);
NSLog(#"Buffer after copy: %s", buffer);
// (renders ascii, no matter what)
printf("Buffer after copy: %s\n", buffer);
// (renders correctly, e.g. japanese text)
Somehow, it looks as if printf() is "smarter" than NSLog(). Does anyone know the underlying cause, and if this feature is documented anywhere? (Couldn't find)
NSLog() and stringWithFormat: seem to expect the string for %s
in the "system encoding" (for example "Mac Roman" on my computer):
NSString *string = #"¥";
NSStringEncoding enc = CFStringConvertEncodingToNSStringEncoding(CFStringGetSystemEncoding());
const char* stringBytes = [string cStringUsingEncoding:enc];
NSString *log = [NSString stringWithFormat:#"%s", stringBytes];
NSLog(#"%#", log);
// Output: ¥
Of course this will fail if some characters are not representable in the system encoding. I could not find an official documentation for this behavior, but one can see that using %s in stringWithFormat: or NSLog() does not reliably work with arbitrary UTF-8 strings.
If you want to check the contents of a char buffer containing an UTF-8 string, then
this would work with arbitrary characters (using the boxed expression syntax to create an NSString from a UTF-8 string):
NSLog(#"%#", #(utf8Buffer));

3rd Party Language support (Xcode + iOS) [duplicate]

I've got a problem with the following code:
NSString *strValue=#"你好";
char temp[200];
strcpy(temp, [strValue UTF8String]);
printf("%s", temp);
NSLog(#"%s", temp);
in the first line of the codes, two Chinese characters are double quoted. The problem is printf function can display the Chinese characters properly, but NSLog can't.
Thanks to all. I figured out a solution for this problem. Foundation uses UTF-16 by default, so in order to use NSLog to output the c string in the example, I have to use cStringUsingEncoding to get UTF-16 c string and use %S to replace %s.
NSString *strValue=#"你好";
char temp[200];
strcpy(temp, [strValue UTF8String]);
printf("%s", temp);
strcpy(temp, [strValue cStringUsingEncoding:NSUTF16LittleEndianStringEncoding]);
NSLog(#"%S", temp);
NSLog's %s format specifier is in the system encoding, which seems to always be MacRoman and not unicode, so it can only display characters in MacRoman encoding. Your best option with NSLog is just to use the native object format specifier %# and pass the NSString directly instead of converting it to a C String. If you only have a C string and you want to use NSLog to display a message instead of printf or asl, you will have to do something like Don suggests in order to convert the string to an NSString object first.
So, all of these should display the expected string:
NSString *str = #"你好";
const char *cstr = [str UTF8String];
NSLog(#"%#", str);
printf("%s\n", cstr);
NSLog(#"%#", [NSString stringWithUTF8String:cstr]);
If you do decide to use asl, note that while it accepts strings in UTF8 format and passes the correct encoding to the syslog daemon (so it will show up properly in the console), it encodes the string for visual encoding when displaying to the terminal or logging to a file handle, so non-ASCII values will be displayed as escaped character sequences.
My guess is that NSLog assumes a different encoding for 8-bit C-strings than UTF-8, and it may be one that doesn't support Chinese characters. Awkward as it is, you might try this:
NSLog(#"%#", [NSString stringWithCString: temp encoding: NSUTF8StringEncoding]);
I know you are probably looking for an answer that will help you understand what's going on.
But this is what you could do to solve your problem right now:
NSLog(#"%#", strValue);
# define NSLogUTF8(a,b) NSLog(a,[NSString stringWithCString:[[NSString stringWithFormat:#"%#",b] cStringUsingEncoding:NSUTF8StringEncoding] encoding:NSNonLossyASCIIStringEncoding])
#define NSLogUTF8Ex(a,b) NSLog(a,[MLTool utf8toNString:[NSString stringWithFormat:#"%#",b]])
+(NSString*)utf8toNString:(NSString*)str{
NSString* strT= [str stringByReplacingOccurrencesOfString:#"\\U" withString:#"\\u"];
//NSString *strT = [strTemp mutableCopy];
CFStringRef transform = CFSTR("Any-Hex/Java");
CFStringTransform((__bridge CFMutableStringRef)strT, NULL, transform, YES);
return strT;
}

Why is it direct commented Encoded string not converting to Arabic?

NSString * string = #"االْحَمْدُ لِلَّهِ رَبِّ الْعَالَمِينَ";
const char *c = [string cStringUsingEncoding:NSUTF8StringEncoding];
NSString *newString = [[NSString alloc]initWithCString:c encoding:NSISOLatin1StringEncoding];
NSLog(#"%#",newString);
// NSString * staticEncodedString = #"اÙÙØ­ÙÙ Ùد٠ÙÙÙÙÙÙ٠رÙبÙ٠اÙÙعÙاÙÙÙ ÙÙÙÙ";
const char *cvvv = [newString cStringUsingEncoding:NSISOLatin1StringEncoding];
NSString *newStringV = [[NSString alloc]initWithCString:cvvv encoding:NSUTF8StringEncoding];
NSLog(#"%#",newStringV);
Why is it direct commented Encoded string not converting to Arabic?
When i hardcode the Arabic it encodes and then decodes correctly, but why can't static encoded string not readable in arabic?
Thanks for your reply Jake. Yes I loose data while decoding the "staticEncodedString".But All I want is to decode the following string back to Arabic.
NSString * staticEncodedString = #"اÙÙØ­ÙÙ Ùد٠ÙÙÙÙÙÙ٠رÙبÙ٠اÙÙعÙاÙÙÙ ÙÙÙÙ";
The encode is in ANSI i think change it to UTF-8 from any tool.
Use Notepad++ to apply for example and then you can use encode it within sqlite or ios.
Latin1 can not represent the Arabic characters, so you can not encode that string to Latin1. Arabic belongs to the Latin4 character set. The method cStringUsingEncoding will return null if the string cannot losslessly be encoded to the specified encoding.
Why would you want to encode an arabic string to LatinX? UTF-8 will most likely be the best representation since it uses only standard characters and a straightforward approach with no headaches. It may take a bit more bytes than Latin4, but in most cases it will be worth it.
Converting to Latin1 will make you lose your text.

Resources