When scanning QR codes with ZBar the string resulting from the process does not display unicode characters properly. The word Márti encoded as a QR code by any free to use QR code generator (like http://qrcode.kaywa.com) would result in Mテ。rti.
In other SO questions (1, 2) it was suggested to embed a BOM at the start of the resulting string, but doing this:
NSString *qrString = [NSString stringWithFormat:#"\xEF\xBB\xBF%#",symbol.data];
or this:
NSString *qrString = [[NSString alloc] initWithFormat:#"\357\273\277%#", symbol.data];
resulted in the same, flawed result with the Asian character. symbol.data is the resulting NSString provided by ZBar.
UPDATE: Based on dda's answer, the solution was the following:
NSString *qrString = symbol.data;
//look for misinterpreted acute characters and convert them to UTF-8
if ([qrString canBeConvertedToEncoding:NSShiftJISStringEncoding]) {
qrString = [NSString stringWithCString:[symbol.data cStringUsingEncoding: NSShiftJISStringEncoding] encoding:NSUTF8StringEncoding];
}
According to the Wikipedia page about QR, the encoding of binary data [for which Márti would apply] is ISO 8859-1. It could be an encoding-as-unicode-encoding problem. But seeing a kanji there, it could be that the problem is an encoding-as-QR-encoding issue: maybe the text, being not ASCII, is encoded by default as Shift JIS X 0208 (ie kanji/kana).
I could create QR codes of "日本語"(japanese) and "Márti" with following libraries:
iOS-QR-Code-Encoder
QR-Code-Encoder-for-Objective-C.
You can read those QR codes with ZBar.
iOS-QR-Code-Encoder:
NSString* orginalString = #"Márti"(or "日本語"(japanese));
NSString *data = [[NSString alloc] initWithFormat:#"\357\273\277%#", orginalString];
UIImage* qrcodeImage = [QRCodeGenerator qrImageForString:data imageSize:imageView.bounds.size.width];
QR-Code-Encoder-for-Objective-C:
NSString* orginalString = #"Márti"(or "日本語"(japanese));
NSString *data = [[NSString alloc] initWithFormat:#"\357\273\277%#", orginalString];
//first encode the string into a matrix of bools, TRUE for black dot and FALSE for white. Let the encoder decide the error correction level and version
DataMatrix* qrMatrix = [QREncoder encodeWithECLevel:QR_ECLEVEL_AUTO version:QR_VERSION_AUTO string:data];
//then render the matrix
UIImage* qrcodeImage = [QREncoder renderDataMatrix:qrMatrix imageDimension:qrcodeImageDimension];
Just a word of caution, the solution as is will exclude use in Japan and scanning of QR Codes with actual Kanji coding inside. In fact it will probably create problems for any QR Code with Unicode characters inside that canBeConvertedToEncoding:NSShiftJISStringEncoding.
A more universal solution is to insert the BOM characters prior to the QR Code encoding to force UTF-8 coding (before it is created). ZBar was never the problem here, it is rooted in the creation of the QR Code.
Related
I have following string, and i want to show it in a UILabel properly with emojies and the new lines. Also I want to draw it using drawInRect method. How do I get them converted/Encoded/Decoded properly?
This string will change on runtime so should show any unicode character/ emoji or special characters such as \n or &
I'm sorry that I do not know proper terms to use to ask this question. Which makes it difficult for me to find an answer online. My knowledge about this topic is very low.
\ud83d\ude02\ud83d\ude02\ud83d\ude02\ud83d\ude02\ud83d\ude02\ud83d\ude05\ud83d\ude06
\u0db8\u0da0\u0d82
\u0d91\u0d9a\u0dca\u0d9a\n#set_with_machan\nkunuharapa na \n#Follow
#lankan_machan\nhttps://www.instagram.com/lankan_machan
after encoding the text should look like this with emojis, unicode characters & new lines.
I was able to find a solution and Edited it a bit. This un escapes the unicode characters perfectly and shows them properly. Shows the new lines too. Thanks #DanZimm for help.
- (NSString*) unescapeUnicodeString2:(NSString*)string
{
NSString* esc1 = [string stringByReplacingOccurrencesOfString:#"\\u" withString:#"\\U"];
NSString* esc2 = [esc1 stringByReplacingOccurrencesOfString:#"\"" withString:#"\\\""];
NSString* quoted = [[#"\"" stringByAppendingString:esc2] stringByAppendingString:#"\""];
NSData* data = [quoted dataUsingEncoding:NSUTF8StringEncoding];
NSString* unesc = [NSPropertyListSerialization propertyListWithData:data options:NSPropertyListImmutable format:NULL error:NULL];
assert([unesc isKindOfClass:[NSString class]]);
return unesc;
}
Solution found here I had to edit it because one of the methods were deprecated.
I have downloaded and added the following category into my project: https://github.com/nicklockwood/Base64
NSString *secret = #"7pgj8Dm6";
NSString *decodedSecret = [secret base64DecodedString];
NSLog(#"decoded Secret = %#", decodedSecret);
This however, always turns out to be nil. What is happening here ?
I hope it will helpful to you
NSString *decodeString = #"Raja";
Encode String
NSData *encodeData = [decodeString dataUsingEncoding:NSUTF8StringEncoding];
NSString *base64String = [encodeData base64EncodedStringWithOptions:0];
DLog(#"Encode String Value: %#", base64String);
Decode String
NSData *decodedData = [[NSData alloc] initWithBase64EncodedString:base64String options:0];
NSString *decodedString = [[NSString alloc] initWithData:decodedData encoding:NSUTF8StringEncoding];
DLog(#"Decode String Value: %#", base64String);
Thanks
I've failed to relax iOS native base64 decoder enough with NSDataBase64DecodingIgnoreUnknownCharacters to process jwt payloads
so I had to revert to a 3rdparty MF_Base64Codec
Sadly you might want to consider doing the 3rdparty route
until Apple will have fixed the bug or relaxed the decoder further to
accept what it currently considers crap input
Your input 7pgj8Dm6is an Invalid base64 encoded string. So the result will be always nil since the method base64DecodedString used only for UTF8 encoding.
As of iOS 7 and Mac OS 10.9, this library is not longer needed.
You can use initWithBase64EncodedString:options:
The default implementation of this method will reject non-alphabet characters, including line break characters. To support different encodings and ignore non-alphabet characters, specify an options value of NSDataBase64DecodingIgnoreUnknownCharacters.
I am very new to Objective C and I've been searching Google for a number of hours trying to find a solution.
I have an NSString which looks like
273350/364D4D002A00041EB8F1E0CEF1E0CCF1E0CCF1E0CCF1E0CCF etc etc
which refers to a TIFF image (I guess in some sort of RAW string format), I want to populate an NSImageView with the data.
This is what I've attempted so far:
NSData *picdata = [NSData dataWithBytes:[albumArtStr UTF8String] length:[albumArtStr length]];
NSImage *myPicture = [[NSImage alloc] initWithData:picdata];
[_albumArtCell setImage:myPicture];
Where "albumArtCell" is the NSImageView
That data looks like hex encoded image with a length in front of it, not an unencoded TIFF, which is a tagged binary format. Perhaps you need to strip the number before the slash and decode e rest of the string from hex digits into NSData and then call [[NSImage alloc] initWithData] using that decided data.
You will need to decode it to binary before handing it to NSImage as it only understands the raw binary form of TIFF.
I believe the problem is due to the fact that [albumArtStr length] returns the number of "unicode character", and not number of "bytes".
So your NSData is probably not set-up to be the right size and so doesn't have the right format for a UIImage to be decoded properly.
Try this instead to create a NSData from NSString instance:
NSData* picData = [albumArtStr dataUsingEncoding: NSUTF8StringEncoding];
I am making an app that posts content from a UITextField, to a PHP script, and store in a database to read later. I am having one heck of a time working with emojis.
Using json, I will get a response like this:
content = "\Uf44d";
id = 104;
time = 1350359055;
In this instance, I used an emoji. But when I do [dictionary objectForKey:#"content"], a box just appears.
I'm thinking I need to convert to UTF-8. But I'm not completely sure. Please help!
U+F44D is a Unicode character in the "Private Use Area" U+E000..U+F8FF, so that is probably not the character you want to display.
On the other hand, U+1F44D is the "THUMBS UP SIGN", so it could be that your Web service does not create a correct JSON response for Unicode characters greater than 0xFFFF.
According to the JSON RFC, characters that are not part of the "Basic Multilingual Plane" can be escaped using a UTF-16 surrogate pair. For the U+1F44D character the JSON Unicode escape sequence would be "\ud83d\udc4d".
The following code shows that it works in general:
const char *s = "{ \"content\": \"\\ud83d\\udc4d\", \"id\": 104, \"time\": 1350359055 }";
NSData *jsonData = [NSData dataWithBytes:s length:strlen(s)];
NSError *error;
NSDictionary *jsonDict = [NSJSONSerialization JSONObjectWithData:jsonData options:0 error:&error];
self.label.text = [jsonDict objectForKey:#"content"];
This displays the "THUMBS UP SIGN" correctly in the label.
But you don't have to escape characters, the Web service could also just send the UTF-8 sequence.
I hope this will help you...I'm using this and e106 is my emoji code.
Only replcare with content line with below line:
content = [NSString stringWithFormat:#"%C", 0xe106];
i have a JSON file that i'm trying to parse using SBJson.
the response string that i'm receiving is displaying arabic characters correctly when i do a
NSLog(#"%#",responseString);
but whenever i use the SBJson parser
NSDictionary *myDictionary = [responseString JSONValue];
and try
NSLog(#"%#", myDictionary);
my arabic characters are transformed to something weird:
\U0633\U0627\U0642\U064a\U0629 \U0627\U0644\U0645\U0633\U0643
please can anyone help
Don't worry. All is well.
\u0633
is equivalence to
س
try this in C++:
std::wstring tStr = L"\u0633";
tStr will equal to س
Just NSLog is not converting
use this :
NSStringEncoding Arabicencoding = CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingWindowsArabic);
NSString *yourstring = [[NSString alloc]initWithData:yourdata encoding:Arabicencoding];
"\U0633\U0627\U0642\U064a\U0629 \U0627\U0644\U0645\U0633\U0643" is actually just the encoding that Objective-C uses for none ascii characters. Try adding a subview/label on whatever you're testing with which will display the text. First try with "responseString" and then "myDictionary" it could display the same.