Post an NSString with spaces to an online form - objective-c

I have the following code:
NSString * myName = #"Sjakelien Vleeschbaardt";
NSString *urlString= [NSString stringWithFormat:#"http://www.myhost.nl/createUser.php?name=%#", myName];
NSString *url =[urlString stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLFragmentAllowedCharacterSet]];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:url]];
With the URL, I store myName in an online mySQL database.
I understand, that a URL shouldn't contain spaces, and that these spaces should be escaped. As a result of above code, myName ends up in the database, encapsulated with 'single quotes'.
The question is, where/when should I compensate for this problem?
In the code above? Maybe I should use a different encoding?
Server side? Can mySQL or PHP fix this before storing?
Upon retrieving the data, by bluntly removing the quotes? And what if somebody's name is O'Hara?
UPDATE: MY BAD
I'm awfully sorry.
I discovered that what I simplified in my example as "NSString * myName=" in my real code is represented by something that introduces the single quotes.
I hope somebody makes the same mistake, and can find some comfort here.

Related

Escaping NSURL characters

Im working on a library for the LinkedIn api. In some cases i need to send a escaped url.
Im using CFURLCreateStringByAddingPercentEscapes for this task and seems to work find for me.
Why this is not a valid URL?
NSURL *base = [NSURL URLWithString:#"https://api.linkedin.com"];
NSString *r = #"/v1/people/url={www.linkedin.com%2Fin%2Fbilby91}";
NSURL finalUrl = [NSURL URLWithString:r relativeToURL:base];
finalUrl is always null and i think is correctly escaped. The original url is www.linkedin.com/Fin/bilby91
Thanks
add this
NSString *r = [#"/v1/people/url={www.linkedin.com%2Fin%2Fbilby91}" stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
The problem was that this characters '{' '}' need to be encoded even though they are not reserved. Some characters including the ones before are considered unsafe and can be misunderstood in the url so its better to always encode them.
[NSString stringWithFormat:#"%#",[r stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
use this, this may help u

Is there any benefit to condensed code?

Let's say I have a statement which is several lines long:
NSString *urlString = #"http://www.example.com";
NSURL *url = [NSURL urlWithString:urlString];
ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:url];
Is there any benefit to condense it to one line like so?
ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:[NSURL urlWithString:#"http://www.example.com"]];
The benefit to the one-line version is that you don't have to create temporary intermediate variables. This is particularly beneficial if you have no other use for those intermediate variables. In some cases it looks neater to use the one-liner but in other situations it can look clunky. There's no hard-and-fast rule to follow, it is entirely up your own aesthetics. Personally I would choose the one-line version for your scenario but there are probably others that would disagree.
One time that I know I avoid one-liners is when an initialiser method takes multiple arguments, because it can get messy and hard to follow, especially if you go several layers deep. For a lite example:
id someObject = [MyClass myClassWithThing:[Thing thingWithX:5 andY:5] supportingThing:[SupportingThing supportingThingWithString:#"Tada!"] error:NULL];
Some people prefer to use Eastern Polish Christmas Tree notation, which would look like:
id someObject = [MyClass myClassWithThing:[Thing thingWithX:5 andY:5]
supportingThing:[SupportingThing supportingThingWithString:#"Tada!"]
error:NULL];
Again, there's no rule to follow here. Although Objective-C has conventions on how to name classes and methods, I've yet to encounter a convention for nested message sending.
First and foremost, code for readability and maintainability.

Removing unicode and backslash escapes from NSString converted from NSData

I am converting the response data from a web request to an NSString in the following manner:
NSData *data = self.responseData;
if (!data) {
return nil;
}
NSStringEncoding encoding = CFStringConvertEncodingToNSStringEncoding(CFStringConvertIANACharSetNameToEncoding((__bridge CFStringRef)[self.response textEncodingName]));
NSString *responseString = [[NSString alloc] initWithData:data encoding:encoding];
However the resulting string looks like this:
"birthday":"04\/01\/1990",
"email":"some.address\u0040some.domain.com"
What I would like is
"birthday":"04/01/1990",
"email":"some.address#some.domain.com"
without the backslash escapes and unicode. What is the cleanest way to do this?
The response seems to be JSON-encoded. So simply decode the response string using a JSON library (SBJson, JsonKit etc.) to get the correct form.
You can replace (or remove) characters using NSString's stringByReplacingCharactersInRange:withString: or stringByReplacingOccurrencesOfString:withString:.
To remove (convert) unicode characters, use dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES (from this answer).
I'm sorry if the following has nothing to do with your case: Personally, I would ask myself where did that back-slashes come from in the first place. For example, for JSON, I'd know that some sort of JSON serializer on the other side escapes some characters (so the slashes are really there, in the response, and that is not a some weird bug in Cocoa). That way I'd able to tell for sure which characters I have to handle and how. Or maybe I'd use some kind of library to do that for me.

passing JSON from ASIHTTPRequest to django

I've exhausted other threads, so I'm posting this question here. Please pardon any newbie mistakes I've made along the way. I've been reading a lot, and I think I'm getting confused.
The Goal:
I'm trying to pass data from a form in objective-c to my django web service. In an effort to assist with this, I've employed the ASIHTTPRequest class to facilitate information transfer. Once sent to the web service, I'd like to save that data to my sqlite3 database.
Procedure:
On the Objective-C side:
I've stored the inputted form data and their respective keys in an NSDictionary, like this:
NSDictionary *personInfo = [NSDictionary dictionaryWithObjectsAndKeys:firstName.text, #"fName", middleName.text, #"mName", lastName.text, #"lName", nil];
I've added it to my ASIHTTPRequest in a different class by using a delegate. I've made the NSDictionary the same as above in the code block below for simplicity, like so:
NSString *jsonPerson = [personInfo JSONRepresentation];
[request addRequestHeader: #"Content-Type" value:#"application/json; charset=utf-8"];
[request appendPostData:[jsonPerson dataUsingEncoding:NSUTF8StringEncoding]];
[request setRequestMethod:#"POST"];
[request startAsynchronous];
And a NSLog shows the string I'm passing to look like this, which validates at least in JSONLint
{"mName":"Arthur","lName":"Smith","fName":"Bob"}
Because I'm seeing what appears to be valid JSON coming from my ASIHTTPRequest, and actions are running from requestfinished: rather than requestfailed:, I'm making the assumption that the problem more than likely isn't on the Objective-C side, but rather on the django side.
Here's what I've tried so far:
json.loads(request.POST)
>>expected string or buffer
json.loads('request.POST')
>>no JSON object to decode
json.loads(request.raw_post_data)
>>mNamelNamefName
incoming = request.POST
>>{"mName":"Arthur","lName":"Smith","fName":"Bob"}
incoming = request.POST
onlyValues = incoming.iterlists()
>>(u'{"mName":"Arthur","lName":"Smith","fName":"Bob"}', [u''])
...and a smattering of other seemingly far-fetched variations. I've kept a log, and can elaborate. The only hope I've been able to find is in the last example; it looks like it's treating the entire string as the key, rather than breaking up each dict object and key as I would have expected.
I realize this is terribly elementary and I don't normally ask, but this problem has me particularly stumped. I do also remember reading somewhere that python won't recognize the double-quotes around each object and key, that to get it to something django likes, each should be surrounded by single-quotes. I just don't have any idea how to get them that way.
Thanks!
This might be a little cumbersome but you may try some simple regexp in objective c just to see if that is really the case
NSError *error = NULL;
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:#"\"" options:NSRegularExpressionCaseInsensitive error:&error];
NSString *json = [regex stringByReplacingMatchesInString:jsonPerson options:0 range:NSMakeRange(0, [jsonPerson length]) withTemplate:#"'"];
There might be some errors because I didn't run the code.

NSString writeToFile with URL encoded string

I have a Mac application that keeps it's own log file. It appends info to the file using NSString's writeToFile method. One of the things that it logs are URL's of web services that it is interacting with. To encode the URL, I'm doing this:
searchString = (NSString *)CFURLCreateStringByAddingPercentEscapes(NULL, (CFStringRef)searchString, NULL, (CFStringRef)#"!*'();:#&=+$,/?%#[]", kCFStringEncodingUTF8 );
The app then appends searchString to the rest of the URL and writes it to the log file. Now the problem is that after adding that URL encoding line, nothing seems to be getting written to the file. The program functions as expected otherwise however. Removing the line of code above results in all of the correct information being logged to the file (removing that line is not an option because searchString must be URL encoded).
Oh and I am using NSUTF8StringEncoding when writing the NSString to the file.
Thanks for any help.
EDIT: I know there's also a similar function to CFURLCreateStringByAddingPercentEscapes in NSString, but I've read that it doesn't always work. Can anyone shed some light on this if my original question cannot be answered? Thanks! (EDIT: same problem occurs when using stringByAddingPercentEscapesUsingEncoding:)
EDIT 2: Here's the code that I'm using to append messages to the log file.
+(void)logText:(NSString *)theString{
NSString *docsDirectory = [NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory,NSUserDomainMask,YES) objectAtIndex:0];
NSString *path = [docsDirectory stringByAppendingPathComponent:#"Folder/File.log"];
NSString *fileContents = [[[NSString alloc] initWithContentsOfFile:path] autorelease];
if([fileContents lengthOfBytesUsingEncoding:NSUTF8StringEncoding] >= 204800){
fileContents = #"";
}
NSString *timeStamp = [[NSDate date] description];
timeStamp = [timeStamp stringByAppendingString:#": "];
timeStamp = [timeStamp stringByAppendingString:theString];
fileContents = [fileContents stringByAppendingString:timeStamp];
fileContents = [fileContents stringByAppendingString:#"\n"];
[fileContents writeToFile:path atomically:YES encoding:NSUTF8StringEncoding error:NULL];
}
Because after almost a whole day no one else has offered any answers, I'm going to post a wild guess here: you're not accidentally using the string you want to output (with percent characters in it) as a format string are you?
That is, making the mistake of doing:
NSLog(#"In format strings you can use %# as a placeholder for an object, and %i for a plain C integer.")
Instead of:
NSLog(#"%#", #"In format strings you can use %# as a placeholder for an object, and %i for a plain C integer.");
But I'm going to be surprised if this turns out to be the cause of your problem, as it usually causes random-looking output, rather than absolutely no output. And in some cases, Xcode also gives compiler warnings about it (when I tried NSLog(myString), I got "warning: format not a string literal and no format arguments").
So don't shoot me down if this answer doesn't help. It would be easier to answer your question if you could show us more of your logging code. As for the one line you provided, I can't detect anything wrong with it.
Edit: Oops, I kind of missed that you mentioned you're using writeToFile:atomically:encoding:error: to write the string to the file, so it's even more unlikely you're accidentally treating it as a format string somewhere. But I'm going to leave this answer up for now. Again, you should really show us more of your code though ...
Edit: Regarding your question on a method in NSString that has similar percent encoding functionality, that would be stringByAddingPercentEscapesUsingEncoding:. I'm not sure what kind of problems you're thinking of when you say you've heard it doesn't always work. But one thing is that CFURLCreateStringByAddingPercentEscapes allows you to specify extra characters that don't normally have to be escaped but which you still want to be escaped, while the method of NSString doesn't allow you to specify this.