Swift 1.2 Nullability is Improving My Objective C Code

Swift 1.2 introduced ‘nullability’, a feature whereby you can annotate your Objective C headers and declare method parameters, propterties, and returned objects as ‘possibly nil’ or ‘never nil’ (a third edge case will be undiscussed here).

I support a library that might be used with earlier versions of Swift and/or Xcode, so need to use the annotation in a backward compatible fashion.

What I discovered is that the ‘pragma’s don’t generate any warnings so it would appear you can just add those:

#pragma clang assume_nonnull begin // start of interface
// interface
#pragma clang assume_nonnull end // end of interface

However, the ‘nullable’ and ‘non-nullable’ annotations cause older Xcodes errors, and files won’t compile. The workaround is to use this construct:

#if ! __has_feature(nullability)
#define nullable
#define nonnull
#endif

So the above is one way to deal with the mechanics of using this new feature. But what of the actual feature itself?

When I sat down and looked at my code, I realized that I was often returning nil for an array that could have returned objects, but no objects met the criteria. After all, we all know that ‘[array count]’ return 0 for a nil array and for an actual array with no objects, right?

But really, this is sloppy coding. In one case, I have a protocol method that can return an array of objects and an optional NSError – if success always return an array and no error, and if failure then no array and an error.

This now maps much better into Swift – I can use ‘if let’ to test for an array, if there process as a successful return, and in no array then use ‘!’ on the NSError as it must be there.

I spent an hour or two really thinking about what I was doing in the public facing interfaces, and tweaking them to be more Swift friendly, which also meant they are now more internally consistent and don’t seem so haphazard.

Advertisements

First Swift Style Guide

I’ve spent a good deal of time reading the Swift manual, to learn this critical new piece of Apple Technology. All the gray-haired old timers are learning it, spending at least as much time as fresh-outs for sure. We know only too well how fast and relentless Apple pushes its technology, and those who dally will be left in the dust.

So many have asked “What constitutes good Swift coding practices?”, the stock answer being “No one knows yet”. Well, one good step forward is to more or less agree on a coding style (even thought Apple’s sample code is all over the map). It seems that Ray Wenderlich posted a Swift Style Guide  around the start of August, and I just read it.

Mostly I agree with it, and remember that this style guide is for code posted on its site, so in some sense must be more readable than code we write for ourselves. Not sure about making my tab stops 2 spaces, but I can see the logic in it – the big problem for real coders is going to be switching back and forth between older ObjC code and Swift, so different tab stops is a huge PITA.

An Interesting Approach to handling NSNulls in JSON objects

I was the lead developer of the Lot18 app – Lot18 is an e-commerce wine marketplace. In that role, I used the web REST interface to retrieve product, inventory, and reviews.  While processing thousands of different objects I’d occasionally stumble on a crash or UI anomaly caused by a NSNull null object buried deep in some dictionary or array.

My first approach to deal with this was to created mutable arrays and dictionaries, and walk the full tree, looking for dictionaries. It worked, but just kept getting more and more complex, and at some point you realize you’ve taken the wrong approach.

The light bulb went on, and I found a method that really worked well: add a category to NSNull. Thinking about it, the issue wasn’t the NSNull null per se, but the methods that my UITableView code would throw it at: asking for a count, or a property, or a value. A prime example of this was inventoryCount. If a product had entered stock, the number could be anywhere from negative (yeah! had to deal with that in a crash!), zero, or some large positive number. However, if the product had not been stocked at least once, the return was a NSNull null object.

So, my approach was to create a NSNull category and essentially deal with any odd method, and return a sane value:


@implementation NSNull (JSON)
- (NSUInteger)length { return 0; }
- (NSInteger)integerValue { return 0; };
- (CGFloat)floatValue { return 0; };
- (NSString *)description { return @"0(null)"; }
- (NSArray *)componentsSeparatedByString:(NSString *)separator { return @[]; }
- (id)objectForKey:(id)key { return nil; }
- (BOOL)boolValue { return NO; }
@end

There well may be other methods that need to be added to this list, but the above was sufficient for me. Note the returned description string – it makes it clear when NSLogging objects that the value was NSNull null.

[ Note that this post was extracted from an earlier StackOverFlow answer.]

Now that Xcode 5 supports doxygen annotation, it’s time for you to start using it!

Ever since Xcode 5 added native support for doxygen, it really pays to annotate your code with doxygen style comments, which only require a few extra characters to comments you may already make.

In looking for tips and tricks, I turned up an excellent how-to written 4 years ago (but still correct) that offers many different techniques. For example, you can remind yourself (and others) how to use a particular variable:

 @property(assign) int ts; ///< Short Comment

or line wrap for up to 3 lines of comments:

@property(assign) int ts; ///< Set the complete ...
                          ///< the progress ...

If you’d rather use C-style comments you can:

@property(assign) int ts; /**< Set the complete ...
                               the progress ... */

The parser seems really smart about how finding continuation comments and also ignoring leading white space. In my examples, I indented the second lines, but you can leave them pegged to the left margin if you prefer.

The more common doxygen usage is to provide annotation blocks above methods, and the oodles of options you can use to do that can be found in this recent post on StackOverFlow (make sure to upvote the question and answer!):

You can add this handy code snippet to your Xcode Code Snippet library:

/**
 <#description#>
 @param <#parameter#>
 @returns <#retval#>
 @exception <#throws#>
 */

as detailed here (and I just did!):

From then on you and others can get help during autocomplete, as well as by option-clicking on a method. I was slow to start using this, but now its getting to be second nature.

Also, if you start posting your open source code (using podspecs) to Cocoapods, they run doxygen on your files and create really nice documentation for them on CocoaDocs.

The Near-Perfect Email Validating Regular Expression

There have been hundreds of posts on the internet by developers claiming to have an “excellent” regular expression through which an app can validate an address supplied by an end user. However, what you get is a quite long unintelligible string. While you can test it against one or more addresses, you don’t really know its limitations or what its going to reject.

Fortunately some interested parties have created sites for the sole purpose of testing supplied expressions: the one I’ve most often used is here. However, as you can see there, no expression passes all good addresses or rejects all the bad addresses.

What really got me interested in this was the inconsistency of the expressions, the lack of traceability to the relevant specs, and even the opportunity to fix a known failure (as if I could even read the expression)! Then, while trying to find a URL validator, I tripped on a site created by Jeff Roberson, who constructed a complicated URL validator by using the relevant RFC, then developing a small regular expression snippet for each of the components, then finally assembling the final full-featured expression. Really impressive.

So early in 2013 I set out to develop a totally standards compliant regular expression. The first big hurtle was the claim that the spec used recursion, and thus no regular expression could ever meet it. Well, it turns out that only comments embedded within an email can be nested, and whoever saw a comment in an email address!

Comments take the form “(some text)”, and nesting occurs when “some text” contains a comment. So, all this fuss about recursion is focused on a feature that no one uses! In the end, to insure the regular expression I produced would pass some pretty severe existing tests, I implemented comments to a user specified fixed level using the “or”regular expression feature. Thus, a “comment” is { “comment” | “comment nested to one level” | “comment nested to two levels” }. Note that to pass the tests you need to handle a nesting level of 5, which greatly increases the size of the regular expression, and which no real app would ever use.

The second hurtle is that the test suites do not rely solely on the principal RFC (RFC-5322), but on related RFCs, some of which contradict 5322! In the end I had to incorporate information relating to the specification of IPV6 addresses (complex!), IPV4 addresses, part lengths, and even contradictions within the core RFC (text says one thing, the ABNF says something else).

A final hurtle was dealing with “deprecated” rules, those that the spec officially recommends and those are old and should be supported but shouldn’t be used anyway. In the end I solved this by deciding to NOT support deprecated rules (made my life easier).

It became obvious immediately that there is no “perfect” RFC – if the text and ABNF contradict themselves, you can have it one way or the other, but not both ways! The solution was to punt the decision to the final URL creator, and let that person make the decision as to what to accept and what not to.

Another issue was what to do about regex syntax: ObjectiveC on the Mac uses the ICU package, which was based on Perl. Portions of that syntax are not supported by the “C” POSIX side of Macs, and any other POSIX derived regular expression package. The spec uses terms that better match Perl too. In the end, I was able to craft the regular expression so that it would mostly work on both, and could be tailored for one or the other by changing a few items.

The final result is a Mac App that can construct a Regular Expression to your specification, output it in text or string format, and can be used to interactively test against a text the user entered or pastes into the app. Additionally, the app contains a class for use in validating or extracting regular expressions, and could be with some small effort ported to other languages. There is a C function to validate a single email address too.

AppScreenShot

So, what does the near-perfect email validating expression look like? Like this:

“^(?:(?:(?:(?: )*(?:(?:(?:\\t| )*\\r\\n)?(?:\\t| )+))+(?: )*)|(?: )+)?(?:(?:(?:[-A-Za-z0-9!#$%&’*+/=?^_`{|}~]+(?:\\.[-A-Za-z0-9!#$%&’*+/=?^_`{|}~]+)*)|(?:\”(?:(?:(?:(?: )*(?:(?:[!#-Z^-~]|\\[|\\])|(?:\\\\(?:\\t|[ -~]))))+(?: )*)|(?: )+)\”))(?:@)(?:(?:(?:[A-Za-z0-9](?:[-A-Za-z0-9]{0,61}[A-Za-z0-9])?)(?:\\.[A-Za-z0-9](?:[-A-Za-z0-9]{0,61}[A-Za-z0-9])?)*)|(?:\\[(?:(?:(?:(?:(?:[0-9]|(?:[1-9][0-9])|(?:1[0-9][0-9])|(?:2[0-4][0-9])|(?:25[0-5]))\\.){3}(?:[0-9]|(?:[1-9][0-9])|(?:1[0-9][0-9])|(?:2[0-4][0-9])|(?:25[0-5]))))|(?:(?:(?: )*[!-Z^-~])*(?: )*)|(?:[Vv][0-9A-Fa-f]+\\.[-A-Za-z0-9._~!$&'()*+,;=:]+))\\])))(?:(?:(?:(?: )*(?:(?:(?:\\t| )*\\r\\n)?(?:\\t| )+))+(?: )*)|(?: )+)?$”

This expression is the result of setting the “Validation” preset in the app, and pasted as one string. Note that it only tests against “local-part@domain” style addresses, not those and “mailbox” specs (DisplayName <local-part@domain>”. If that’s what you want, then check the appropriate box and generate a different one!

The Xcode project used to generate this Mac app can be found on my github site with the (historical) name of EmailAddressFinder.

A property/ivar/outlet was just changed, how do I find out who did it?

I see this post all the time on StackOverflow. The answer is surprisingly simple:

– if you have an ivar, convert it to a property with a synthesize ivar=ivar if needbe to avoid having to prepend a “_” to usages

– write your own setter, and add logic tests and NSLog messages

– put a breakpoint on the NSLog message, and run your app

Voila! You app stops when the value changes, and you can see who the offender is!

URL Verifier, Parser, and Scraper in Objective-C

I just updated the second version of my github project, URLFinderAndVerifier. Needing to verify a http URL as it was typed in to toggle an “Accept” button, I searched the web for such a thing, and unfortunately found oodles of them, none of which had any credentials.

Looking closer on another day, I found a site run by Jeff Roberson where he had meticulously worked through RFC-3896, constructing simple regular expressions then combining them to create a full regular expression that should properly parse any valid URL. Note that the standard allows much of what we think of as necessary information to be empty.

So I started with his expressions, then tweaked them slightly to handle more real world conditions, such as forcing a person to enter (the optional) ‘/’ at the start of the path segment (which acts as a end of authority marker).

Using my previous Email verifier test harness, I constructed a test engine that lets you test out various combinations of options. It has three components:

– construct the regular expressions for use in a text file or a NSString constant

– URLSearcher, a class that uses to regular expression to find or verify URLs

– a test app that you use to test various URLs, or “live” input mode

AppScreenShot

All regular expressions exist in text files that are heavily commented. A pre-processor reads these files and removes comments and extraneous characters (like spaces). This makes the files much more readable and understandable. These partial regular expressions that are used to build a full regular expression based on the options you select in the GUI.

Users can optionally enter Unicode characters, which the regular expression can optionally allow. Given a verified URL, a utility function in URLSearcher converts these syntactically correct strings to ‘%’ encoded ones that fully meet the RFC spec (Europeans should like this!)

Other options are to look for every scheme, or http/https, or http/https/ftp and the ability to spec capture groups to see URL subcomponents: user, host, port, path, query, and fragment.

PS: if you end up using this it would be great if you could give the StackOverflow post an up-arrow.