How do I encode a NSString to send it to a PHP iOS - ios

I need to send a NSString to a PHP file that goes into a MySQL database.
The problem that I have is with especial characters like "é". When I get the string (from the Facebook SDK for iOS) it comes like this: "Thenáme Thesurnamé", for example.
I send it to a PHP on a server using unicode as charset (I also tried with utf8), but in the database it appears with "é" instead of "é".
The encoding of the database is utf8_unicode_ci

You can always user the ampersand in html to encode such chars.

Try this code:
NSString *resStr = [[NSString alloc] initWithCString:[srcStr cStringUsingEncoding:[NSString defaultCStringEncoding]] encoding:NSMacOSRomanStringEncoding];

Related

Create RTF file with Objective-C

I want to create an RTF file by creating my own source code of the RTF file and inserting in variables from my model.
I am creating the source coude using for example :
NSMutableString *body = [NSMutableString stringWithString:"{\rtf1\ansi\ansicpg1252\deff0\nouicompat\deflang3084\deflangfe3084{\fonttbl{\f0\froman\fprq2\fcharset0 Times New Roman;}{\f1\fswiss\fprq2\fcharset0 Calibri;}{\f2\froman\fprq2\fcharset2 Symbol;}}{\colortbl ;\red255\green255\blue255;\red0\green0\blue255;}{\*\generator Riched20 10.0.10240}\viewkind4\uc1\trowd\trgaph70\trleft-108\trbrdrl\brdrs\brdrw10 \trbrdrt\brdrs\brdrw10 \trbrdrr\brdrs\brdrw10 \trbrdrb\brdrs\brdrw10 \trpaddl70\trpaddr70\trpaddfl3\trpaddfr3\clbrdrl\brdrw10\brdrs\clbrdrt\brdrw10\brdrs\clbrdrr\brdrw10\brdrs\clbrdrb\brdrw10\brdrs \cellx2818\clbrdrl\brdrw10\brdrs\clbrdrt\brdrw10\brdrs\clbrdrr\brdrw10\brdrs\clbrdrb\brdrw10\brdrs"];
I want this string to be saved as an RTF file and then the RTF reader will conver this code to a readable RTF File. The problem is that Xcode gives me numerous errors (unknown escape sequence) due to the characters such as * \d \c \g . Moreover it says "Incomplete universal character name".
How can I have my NSString be treated like source code and ignore all those errors so that it can be parsed in an RTF file.
You need to escape your escape characters "\". When you write it to the console or file your string will output correctly.
NSMutableString *body = [NSMutableString stringWithString:#"{\\rtf1\\ansi\\ansicpg1252\\deff0\\nouicompat\\deflang3084\\deflangfe3084{\\fonttbl{\\f0\\froman\\fprq2\\fcharset0 Times New Roman;}{\\f1\\fswiss\\fprq2\\fcharset0 Calibri;}{\\f2\\froman\\fprq2\\fcharset2 Symbol;}}{\\colortbl ;\\red255\\green255\\blue255;\\red0\\green0\\blue255;}{\\*\\generator Riched20 10.0.10240}\\viewkind4\\uc1\\trowd\\trgaph70\\trleft-108\\trbrdrl\\brdrs\\brdrw10 \\trbrdrt\\brdrs\\brdrw10 \\trbrdrr\\brdrs\\brdrw10 \\trbrdrb\\brdrs\\brdrw10 \\trpaddl70\\trpaddr70\\trpaddfl3\\trpaddfr3\\clbrdrl\\brdrw10\\brdrs\\clbrdrt\\brdrw10\\brdrs\\clbrdrr\\brdrw10\\brdrs\\clbrdrb\\brdrw10\\brdrs \\cellx2818\\clbrdrl\\brdrw10\\brdrs\\clbrdrt\\brdrw10\\brdrs\\clbrdrr\\brdrw10\\brdrs\\clbrdrb\\brdrw10\\brdrs"];

NSString: dealing with UTF8-based API

Which characterset is the default characterset for NSString, when i get typed content from a UITextField?
I developed an app, which sends such NSStrings to a UTF8-based REST-API. At the backend, there is an utf8 based MySQL-Database and also utf8-based varchar-fields.
My POST-Request sends string data from the iOS App to the server. And with a GET-Request i receive those strings from the REST API.
Within the App, everything is printed fine. Special UTF-8-Characters like ÄÖÜ are showed correctly after sending them to the server and after receive them back.
But when i enter the mysql-console of the server of the REST API, and do a SELECT-Command at these data, there are broken characters visible.
What could be the root cause? In which characterset does Apple use a NSString?
It sounds like it is a server issue. Check that the version you are using supports UTF-8, older versions do not. See : How to support full Unicode in MySQL database
MySQL’s utf8 encoding is different from proper UTF-8 encoding. It doesn’t offer full Unicode support.
MySQL 5.5.3 (released in early 2010) introduced a new encoding called utf8mb4 which maps to proper UTF-8 and thus fully supports Unicode.
NSString has in internal representation that is essentially opaque.
The UITextField method text returns an NSString.
When you want data from a string use to send to a server use - (NSData *)dataUsingEncoding:(NSStringEncoding)encoding and specify the encoding such as NSUTF8StringEncoding.
NSData *textFieldUTF8Data = [textFieldInstance.text dataUsingEncoding: NSUTF8StringEncoding];
If, by "mysql console", you are referring to the DOS-like window in Windows, then you need:
The command "chcp" controls the "code page". chcp 65001 provides utf8, but it needs a special charset installed, too. some code pages
To set the font in the console window: Right-click on the title of the window → Properties → Font → pick Lucida Console
Also, tell the 'console' that your bytes are UTF8 by doing SET NAMES utf8mb4.

Some utf-8 strings base64 encoded by php can not be decoded using iOS base64 library?

Here is one piece of Chinese utf-8 text which is encoded by PHP on the server-side, but when I decode it with iOS, it returns null.
I also tried this online tool where text can be decoded well.
NSData *decodedData = [[NSData alloc] initWithBase64EncodedString:content options:0];
content = [[NSString alloc] initWithData:decodedData encoding:NSUTF8StringEncoding];
5aW96ZuF77yM5ZKx5p2l5LiA5L+X55qE77yM5pS56Ieq5Lic5Y2X6KW/5YyX6aOO44CCCuS4juS9oOebuOmAou+8jOWFqOaYr+acuue8mOW3p+WQiOOAguWPr+Wtpui1t+adpeWNtOW/g+aGlOaCtOOAggrmgLvmmK/ovpPkuoborqnlho3ljrvlrabvvIzlrabkuobo
Here is the test code for debug this issue with xcode:
NSString * = #"5aW96ZuF77yM5ZKx5p2l5LiA5L+X55qE77yM5pS56Ieq5Lic5Y2X6KW/5YyX6aOO44CCCuS4juS9oOebuOmAou+8jOWFqOaYr+acuue8mOW3p+WQiOOAguWPr+Wtpui1t+adpeWNtOW/g+aGlOaCtOOAggrmgLvmmK/ovpPkuoborqnlho3ljrvlrabvvIzlrabkuobo";
//
NSData *decodedData = [[NSData alloc] initWithBase64EncodedString: options:0];
NSString *content = [[NSString alloc] initWithData:decodedData encoding:NSUTF8StringEncoding] ;
NSLog(content);
Your revised question features a base64 string of:
5aW96ZuF77yM5ZKx5p2l5LiA5L+X55qE77yM5pS56Ieq5Lic5Y2X6KW/5YyX6aOO44CCCuS4juS9oOebuOmAou+8jOWFqOaYr+acuue8mOW3p+WQiOOAguWPr+Wtpui1t+adpeWNtOW/g+aGlOaCtOOAggrmgLvmmK/ovpPkuoborqnlho3ljrvlrabvvIzlrabkuobo
This string has a length that is a multiple of four bytes, so the lack of the =/== terminator at the end is not the problem. And, in fact, initWithBase64EncodedString decodes it successfully:
e5a5bde9 9b85efbc 8ce592b1 e69da5e4 b880e4bf 97e79a84 efbc8ce6 94b9e887
aae4b89c e58d97e8 a5bfe58c 97e9a38e e380820a e4b88ee4 bda0e79b b8e980a2
efbc8ce5 85a8e698 afe69cba e7bc98e5 b7a7e590 88e38082 e58fafe5 ada6e8b5
b7e69da5 e58db4e5 bf83e686 94e682b4 e380820a e680bbe6 98afe8be 93e4ba86
e8aea9e5 868de58e bbe5ada6 efbc8ce5 ada6e4ba 86e8
The issue here is that this appears to not be a valid UTF8 string. In fact, when I run it through the http://base64decode.net site you referenced in your original question, it is also unable to convert it to a UTF8 string (I notice that your screen snapshots are using a different converter web site). When I ran it through another converter, it converted what it could, but then complained about the character following 学了 (which is, coincidentally, the character at which your base64 converter web site stopped, too).
By the way, the UTF8 representation of 了 is e4 ba 86. And you'll see that near the end of the hex representation of your base 64 string, followed by one more byte, e8. The thing is, e8, by itself, is not a valid UTF8 character. It almost looks looks like you took a base64 encoded string and just grabbed the first 200 bytes, disregarding whether that resulted in cutting the UTF8 character off in the middle or not.
The original question featured a base64 string of:
5aW96ZuF77yM5ZKx5p2l5LiA5L+X55qE77yM5pS56Ieq5Lic5Y2X6KW/5YyX6aOO44CCCuS4juS9oOebuOmAou+8jOWFqOaYr+acuue8mOW3p+WQiOOAguWPr+Wtpui1t+adpeWNtOW/g+aGlOaCtOOAggrmgLvmmK/
That is not valid base64. It should be a multiple of four bytes in length, but that is only 163 characters, which is missing a character. Either your server isn't properly terminating the base64 string, or it got cut off for some reason.
For example, if I add a = to get it up to 164 characters, I get a valid base64 string:
5aW96ZuF77yM5ZKx5p2l5LiA5L+X55qE77yM5pS56Ieq5Lic5Y2X6KW/5YyX6aOO44CCCuS4juS9oOebuOmAou+8jOWFqOaYr+acuue8mOW3p+WQiOOAguWPr+Wtpui1t+adpeWNtOW/g+aGlOaCtOOAggrmgLvmmK/=
Adding the = would be the right solution if the server simply neglected to terminate the base64 string properly. Anyway, that can be base64-decoded to:
好雅,咱来一俗的,改自东南西北风。
与你相逢,全是机缘巧合。可学起来却心憔悴。
总是
Is that what you were expecting?
Perhaps you should take a look at your base64 routine on your server? Or if it's getting truncated, look at how you are receiving it and compare the server's original base64 string length to what you have here.
For information about adding = or == to the end of a base 64 encoded string, see the base64 wikipedia page.
#Rob is right.
Check this Check NSData won't accept valid base64 encoded string
But in case if your server is not returning valid JSON with "=" or "==" then you need to use external methods to perform base64decode. Those methods can decode even if base64string does not have "=" symbol at the end.

XML Parsing with parseFromString with portuguese characters

I have a Blackberry app developed using PhoneGap. I am using suds client to call web service. There are some Portuguese character in the webservice XML. I am not able to parse to XMLDoc using the DOMParser.
I am using
xmlDoc = parser.parseFromString(_xml, "text/xml");
The encoding type is UTF-8. Without the Portuguese character, parsing is working perfectly.
"I am using is UTF-8 encoding type." - this can mean several things, so it is unclear what exactly you do in order to support UTF-8 end-to-end.
E.g. you should check:
your web service really sends data in UTF-8 (when it converts string chars into bytes to be sent into output stream it should use UTF-8)
the device code that reads data from web really uses UTF-8 to convert bytes to string _xml
P.S. I'm not familiar with phonegap API so this is just a general plan.

How to get a unique hash or id from a URL in Cocoa?

In my application, I am reading RSS feeds and saving them to a Core Data db using the URL of each specific article as the key. Passing these URLs around the system can be problematic because they can be lengthy, and I'd like a way to generate a unique identifier to store in the db and just pass that around.
I'd also like it to be reconstructable using the same string so that if I get a duplicate URL, I can generate the identifier from it and simply check Core Data for the identifier.
Is there an easy way to do this?
When most people are talking about hashes, they are generally thinking about one-way hashes like SHA1, SHA2, or MD5. While these are imminently useful, they will not allow you to take a hash and reverse it into its original form. They will, however, allow you to do things like compare a user entered password with one they've entered before without ever having to store the actual password -- only the hash.
What you seem to want is string compression or deflation. Luckily, gzip is supported out of the box using the ASIHTTPRequest class. Here's some code for using gzip found in this discussion.
NSString *encodedGzippedString = #"GgAAAB+LCAAAAAAABADtvQdgHEmWJSYvbcp7f0r1StfgdKEIgGATJNiQQBDswYjN5pLsHWlHIymrKoHKZVZlXWYWQMztnbz33nvvvffee++997o7nU4n99//P1xmZAFs9s5K2smeIYCqyB8/fnwfPyK+uE6X2SJPiyZ93eaX+TI9Lcuiatvx/wOwYc0HGgAAAA==";
NSData *decodedGzippedData = [NSData dataFromBase64String:encodedGzippedString];
NSData* unGzippedJsonData = [ASIHTTPRequest uncompressZippedData:decodedGzippedData];
NSString* unGzippedJsonString = [[NSString alloc] initWithData:unGzippedJsonData encoding:NSASCIIStringEncoding];
NSLog(#"Result: %#", unGzippedJsonString);
There is a very good article that discusses hashing using MD5 here:
http://cocoawithlove.com/2009/07/hashvalue-object-for-holding-md5-and.html
Using the CommonCrypto library, there are a number of hash algorithms already built in. You can use the MD5 hasing algorithm like this:
#import <CommonCrypto/CommonDigest.h>
char input[] = "Some data value.";
char result[16];
CC_MD5(input, strlen(input), result);
This will print out the hash in human-readable hex form:
printf("MD5 (\"%s\") = %02x%02x%02x%02x%02x%02x
%02x%02x%02x%02x%02x%02x
%02x%02x%02x%02x\n",
input,
result[0], result[1], result[2], result[3],
result[4], result[5], result[6], result[7],
result[8], result[9], result[10], result[11],
result[12], result[13], result[14], result[15]);
If you would like more information on forward-only hashing, I posted some info as well as production-ready code in this SO answer.
Use SHA1 (apple implementation of it on iOS), it will meet all your requirements (re-running it with the same input generates the same output, changing a single character in the input drastically changes the output).
Using a security hashers like MD5 SHA1 or SHA256 leads to a source code which has to change a hasher function each time the algorithm will become obsolete or week. Then corporations which uses automated audit tools will reject the source code with those functions.
So if you need a hasher function for just removing special characters from urls it's better to have a custom hasher than one of those security hashers.

Resources