Is there any benefit to condensed code? - objective-c

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.

Related

Post an NSString with spaces to an online form

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.

Nesting statements rather than creating new single-use objects?

Newb question here.
Why would I do this:
NSPredicate *pred = [NSPredicate predicateWithFormat:#"(lineNum = %d)", i];
[request setPredicate:pred];
When I could just do this?
[request setPredicate:[NSPredicate predicateWithFormat:#"(lineNum = %d)", i]];
Every textbook code example I find uses the first method, but as far as I can see the second method will basically do the same thing and just looks neater. "pred" is only called once so why create it as an object?
This has to do primarily with the format of text books: it is hard to fit more than a certain number of characters on a page, because books have no scroll bars. Other than that, the two are identical.
One reason to do it in real life is so that you could set a break point and examine pred before calling setPredicate:.
Which one looks neater is just a matter of preference.
There is no functional difference between the two.
For more complex cases, the first pattern allows for more self-explanatory code, because you can put meaningful variable names:
NSPredicate *correctLineNumber =
[NSPredicate predicateWithFormat:#"(lineNum = %d)", i];
[request setPredicate:correctLineNumber];

Listing localized files

Konichiwa folks,
I'm banging my head over a non-standard procedure to read a bunch of localized xml located in my project.
My purpose is to read recursively all these files in order to feed a coredata sqlite db to create various lang-based versions of the same DB.
In the first place, I've tried an old school technique, like:
NSString *bundleRoot = [[NSBundle mainBundle] bundlePath];
NSArray *dirContents = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:bundleRoot error:nil];
NSArray *onlyXMLs = [dirContents filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:#"self ENDSWITH '.xml'"]];
for (NSString *tString in onlyXMLs) {
/* stuff */
}
with no luck at all, because it pops out all the non-localized xmls in my project and nothing more.
so I was wondering if there would be a way to get those damn't localized xmls out there.
thanks in advance.
If u got doubts or questions don't be a stranger, drop me a line.
-k-
ok, solved it!
for the ones who are seeking for an answer to the problem, here's the solution:
NSArray *onlyXMLs = [[NSBundle mainBundle] pathsForResourcesOfType:#"xml" inDirectory:nil forLocalization:#"English"];
remember that the parameter that carries the desired language
must always be the same of the .plist directory containing the desired files in your project.
so if you've got a English.plist with the stuff you need in it, that must also be the name string to pass (like shown in the above example), otherwise if you're dealing with a en.plist, #"en" shall be the string.
that's it, that's all.

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.

iPhone's Core Data crashes on fetch request

I'm using the following code to grab a few objects from SQLite store (which is a prepared SQLite db file, generated with Core Data on desktop):
NSFetchRequest * request = [[NSFetchRequest alloc] init];
[request setEntity: wordEntityDescription];
[request setPredicate: [NSPredicate predicateWithFormat: #"word = %#", searchText]];
NSError * error = [[NSError alloc] init];
NSArray * results = [[dao managedObjectContext] executeFetchRequest: request error: &error];
Eveyrthing seems to be setup properly, but executeFetchRequest:error: fails deeply inside Core Data (on NSSQLCore _newRowsForFetchPlan:selectedBy:withArgument) producing 256 error to the outside code.
The only kink I had setting up managedObjectContext is I had to specify NSIgnorePersistentStoreVersioningOption option to addPersistentStoreWithType as it was constantly producing 134100 error (and yes, I'm sure my models are just identical: I re-used the model from the project that produced the SQL file).
Any ideas?
P.S. Don't mind code style, it's just a scratch pad. And, of course, feel free to request any additional info. It would be really great if someone could help.
Update 1
Alex Reynolds, thanks for willingness to help :)
The code (hope that's what you wanted to see):
NSEntityDescription * wordEntityDescription; //that's the declaration (Captain Obviousity :)
wordEntityDescription = [NSEntityDescription entityForName: #"Word" inManagedObjectContext: ctx];
As for predicate – never mind. I was removing the predicate at all (to just grab all records) and this didn't make any differences.
Again, the same code works just fine in the desktop application, and that drives me crazy (of course, I would need to add some memory management stuff, but it at least should produce nearly the same behavior, shouldn't it?)
Can you add code to show how wordEntityDescription is defined?
Also, I think you want:
NSError *error = nil;
You may want to switch the equals symbol to like and use tick marks around the searchText field:
[request setPredicate: [NSPredicate predicateWithFormat: #"word like '%#'", searchText]];
NSPredicate objects are not put together like SQL, unfortunately. Check out Apple's NSPredicate programming guide for more info.