8

I need to do a HTTP Post from my iPhone app to a Google Doc. It works fine for English, but the Hebrew shows as question marks in the Google Doc.

This is what I'm doing:

NSString *post = [Util append:@"&entry.xxxxx=", self.firstName.text, @"&entry.yyyyyyy=", self.phone.text, @"&entry.zzzzzzzz=", self.email.text, nil];
NSData *postData = [post dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
NSString *postLength = [NSString stringWithFormat:@"%d", [postData length]];

NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
[request setURL:[NSURL URLWithString:@"https://docs.google.com/forms/d/FORM_ID/formResponse"]];
[request setHTTPMethod:@"POST"];
[request setValue:postLength forHTTPHeaderField:@"Content-Length"];
[request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];
[request setHTTPBody:postData];

NSHTTPURLResponse* urlResponse = nil;
NSError *error = [[NSError alloc] init];
[NSURLConnection sendSynchronousRequest:request returningResponse:&urlResponse error:&error];

What am I missing?

EDIT: I tried the solution offered here and looked at ahmedalkaf's link here but no luck.

Eliza Wilson
  • 1,161
  • 1
  • 13
  • 35
Eddy
  • 3,075
  • 12
  • 48
  • 75
  • @ahmedalkaff can you be more specific? I tried NSUTF8StringEncoding but that only generates empty fields, not even junk characters. – Eddy Aug 22 '13 at 11:29
  • I found this post where you can check the encoding of the data. hope this helps: [link](http://stackoverflow.com/questions/9701776/nsutf8stringencoding-returns-nil-nsstring) – ahmedalkaff Aug 22 '13 at 11:36

5 Answers5

3

Option 1

You have set your Content-Type to application/x-www-form-urlencoded, but you haven't url-encoded your contents.

URL-encoding your post NSString and changing the Encoding to UTF-8 (I cant tell you why, but it's needed to make it work) should do the job.

NSString *post = [Util append:@"&entry.xxxxx=", self.firstName.text, @"&entry.yyyyyyy=", self.phone.text, @"&entry.zzzzzzzz=", self.email.text, nil];
post =[post stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSData *postData = [post dataUsingEncoding:NSUTF8StringEncoding allowLossyConversion:YES];

Everything else can stay the same. However you should think about using an asynchronous request. When using a synchronous request, your user interface will become unresponsive, until the request is finished. This doesn't happen with an asynchronous request.

Option 2

For HTTP-Requests I usually use the ASIHTTPRequest Library: http://allseeing-i.com/ASIHTTPRequest/

It takes a couple of minutes to integrate into your project, but it makes everything way more simple. You don't have to mess around with encodings etc.

NSURL *url =[NSURL URLWithString:@"https://docs.google.com/forms/d/FORM_ID/formResponse"];
ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:url];

[request addPostValue:self.firstName.text forKey:@"entry.xxxx"];
[request addPostValue:self.phone.text forKey:@"entry.yyyy"];
[request addPostValue:self.email.text forKey:@"entry.zzzz"];

[request startAsynchronous];

That's it.

To set up ASIHTTPRequest follow these instructions http://allseeing-i.com/ASIHTTPRequest/Setup-instructions and remember to add a -fno-objc-arc compiler flag to the libraries files under Project Settings -> Build Phases -> Compile Sources if you are using ARC.

Tim Bodeit
  • 9,446
  • 3
  • 25
  • 57
  • Regarding option 2, there's a simpler way to send async requests. Check [here](http://stackoverflow.com/questions/8515667/how-to-send-asynchronous-url-request). And thanks, @Tim Bodeit – Eddy Sep 01 '13 at 10:57
  • 1
    I do realize, that you can use `NSURLConnection` to do asynchronous requests. The reason, why I mentioned ASIHTTPRequest, was, because it makes Post-Requests way easier. No matter if synchronous or asynchronous. – Tim Bodeit Sep 01 '13 at 11:02
3

(This mainly explains why UTF-8 encoding is needed over ASCII. I'm not going to explain about the URL-encoding part of this problem, as Tim Bodeit already did nicely.)

Basic Explanation:

ASCII encoding only contains English, unaccented characters, while UTF-8 contains characters for most languages.

Details:

ASCII has only the characters shown from the image below, although it fits into only seven bits (or eight, depending on which way you look at it).

ASCII Characters and how they are encoded. From the blog post by Joel Spolsky in the link below

However, both Unicode and UTF-8 can contain any characters from almost all major languages. UTF-8 is preferred over Unicode, because when your app is using characters that are in ASCII (English), it will be only one byte. When your app is using Hebrew, the string will be a few bytes longer. If you use Unicode, your string will ALWAYS have more than one byte, whether its in English or in Hebrew.

The solution? Just change everything that says ASCII to UTF8.

You (and every other programmer) should absolutely read this article.

It's by Joel Spolsky (co-founder of Stack Exchange), and it's very beneficial for any program using strings, which is most programs. You especially will benefit if you are doing work using both Hebrew and English.

By the way, you should remove the tags iOS, iPhone, iPad, and replace it with Objective-C, as your code snippet can apply to programming for Macs, too.

Community
  • 1
  • 1
Eliza Wilson
  • 1,161
  • 1
  • 13
  • 35
2

Swift 4 Solution for escaping string that contains Hebrew

let dataString = "firstname=בני&lastname=דוידוביץ".addingPercentEncoding(withAllowedCharacters: CharacterSet.urlQueryAllowed) ?? ""

let urlString = "http://be.repoai.com:5080/WebRTCAppEE/streams/home/משדר_מיוחד_לכבוד_יום_הזעכרון_לחללי_מערכות_ישראל_ופעולות_האיבה.mp4".addingPercentEncoding(withAllowedCharacters: CharacterSet.urlQueryAllowed) ?? ""
Benny Davidovitz
  • 1,084
  • 12
  • 16
1

For Hebrew character to post data on server used NSUTF8StringEncoding


NSString *post = [Util append:@"&entry.xxxxx=", self.firstName.text, @"&entry.yyyyyyy=", self.phone.text, @"&entry.zzzzzzzz=", self.email.text, nil];
NSData *postData = [post dataUsingEncoding:NSUTF8StringEncoding allowLossyConversion:YES];
NSString *postLength = [NSString stringWithFormat:@"%d", [postData length]];
Sumeet kumar
  • 438
  • 2
  • 7
1

You can use AFNetworking, this will send your data as utf-8 encoding i use this library for my projects in spanish and always get the correct character for áéóúñ:

NSString *encodeUrl  = [@"document/d/Hphb4NsfxZLxTl7p3LMCWCpm9MCWskgoTFWzhP1Fpqap/edit" stringByAddingPercentEscapesUsingEncoding: NSUTF8StringEncoding];  

//setup the post using AFHTTPClient  
AFHTTPClient *afHttpRequest = [[[AFHTTPClient alloc] initWithBaseURL:[NSURL URLWithString:@"https://docs.google.com"]] autorelease];  
NSURLRequest *request = [afHttpRequest requestWithMethod:@"POST" path:encodeUrl parameters:post];  

//loading indicator  
[[AFNetworkActivityIndicatorManager sharedManager] setEnabled:YES];  
[[AFNetworkActivityIndicatorManager sharedManager] incrementActivityCount];  

[AFJSONRequestOperation addAcceptableContentTypes:[NSSet setWithObject:@"text/html"]];  
AFJSONRequestOperation *operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request  
    success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON){  
        //some response  
    }  
    failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, id JSON){  
        //the request fails  
    }  
];  
//fire the request  
[operation start]; 

what does [Util append] ? add some extra encoding to the fields ? or just append

Alejo JM
  • 771
  • 5
  • 12