Tag Archives: ios

ShareEverywhere

ShareEverwhere main screen
ShareEverwhere main screen

I was so busy when it came out that I never quite got around to blogging about it here: I have a new app out! It’s called ShareEverywhere. It is built exclusively for iOS 8 and uses the new, built-in “share” functionality, allowing you to share to a good number of services from any app that uses the standard share button.

When I first wrote it, I wasn’t sure how many, if any, developers would build share widgets into their apps. Now that we know the answer is “a lot of them,” I still use ShareEverywhere because it beats having a dozen widgets hiding in your action menu. And there are still services, like Pinboard.in, that don’t have their own native apps.

It’s available now in the App Store for your iPhone or iPad. It costs £1.49, $1.99, €1.79 or your local equivalent.

Swift Types

If you look at the Swift Language guide, you get the distinct impression that the type system is sleek and modern. However the more you dig into it the more eccentricities you find.

The one I’m going to look at today makes sense only if you look at the problem domain from a slightly skewed perspective. I’ve been trying to think whether this is a sensible, pragmatic way of designing a language or a mistake. Judge for yourself.

So, the feature. Let’s define a dictionary:

var test1 = [ "Foo" : "Bar" ]

Check the type and we find that it’s of type Dictionary<String,String>. The generics and type inference are doing exactly what you’d image.

test1["Test"] = "Works"

So basically it’s all good.

So, what type is this expression?

var test2 = [:]

And why does this not work?

test2["Test"] = "Doesn't work"

Let’s take a step back. What’s the problem? Well, [:] is an empty dictionary but give us no clue what the type is. Remember, Swift dictionaries and arrays use generics, so the compiler only allows objects of a particular type to be added.

A good guess for the type would be Dictionary<AnyObject,AnyObject>. But a little fishing around tells you that’s not the case because AnyObject is neither “Hashable” or “Equatable” and keys need to be both.

The answer? test2 is an NSDictionary. That is, in this one circumstance, Swift extends outside its native dictionary type and decides to use a class found in Foundation.

Once you know that, it is clear that the second line should be:

test2.setValue("Does work now", forKey:"Test")

Maybe if you’re familiar with the guts of both Objective C and Swift this behaviour makes sense, but a language built-in returning a completely different type just because it can’t figure out the type feels broken to me.

In the end I think I’ve convinced myself that, while it might be convenient to allow this syntax, it’s a bad idea to saddle the language with these semantics so early on. In a few years when no one uses Objective C or when Swift is no longer fully tied to Cocoa, will this make sense?

I would prefer to see it being a compiler error with the correct approach being explicit with the type:

var test2:Dictionary<String,String> = [:]

Thoughts?

Swift Hate

I’m seeing a surprising amount of vitriol aimed at Swift, Apple’s new programming language for iOS and Mac development. I understand that there can be reasoned debate around the features (or lack thereof), syntax and even the necessity of it but there can be little doubt about the outcome: if you want to consider yourself an iOS developer, it’s a language that you will need to learn.

The only variable I can think of is when you learn it.

I think it’s perfectly reasonable to delay learning it as you have code to deliver now and because Swift is, well, very beta currently.

But asking what the point of Swift is not constructive. Asking what problems can be solved exclusively by Swift makes no sense at all you can do almost anything in most programming languages. Just because Intercal is Turing complete doesn’t mean that you’d want to use it for any real work. What varies between languages is what’s easy and what’s hard.

Objective-C undoubtedly makes some things easier than Swift. It’s a more dynamic language and its C foundations open up a lot of low-level optimisations that probably are not there in higher level languages.

But that same flexibility comes with a price: segmentation faults and memory leaks; pointers; easy-to-get-wrong switch statement; a lack of bounds checking. It also inherits a lot of ambiguity from original C language specification which makes certain automatic optimisations impossible.

How many applications require low-level optimisations more than safety? (And that’s ignoring that the biggest optimisations are usually found in designing a better algorithm or architecture.) How often is it better to have five lines of code instead of one? Every line is a liability, something that can go wrong, something that needs to be understood, tested and maintained.

Whatever its failings, it’s already clear that Swift is more concise and safer than Objective C.

There are absolutely applications where Objective C, C or C++ would be a better choice than Swift. It’s the old 80-20 rule applied to a programming language. And, for those resistant to learning a new language, the 80% is not on “your” side.

Right now, some of this requires a bit of a leap of faith. Swift clearly isn’t finished. You can either learn it now and potentially have some say on what the “final” version looks like, or you can learn it afterwards and just have to accept what’s there. But, either way, you’ll probably using it next year. Get used to it.

Learning Swift

Swift is a new programming language designed by Apple for development on OS X and iOS. I thought that I should try to learn it a little so I decided to convert a non-trivial collection of classes from one of my apps (www.cut) into Swift. I always find it better to work on a real project rather than just to play around with things aimlessly. Also, by re-working an old project, I knew that all the problems I would find would be language related rather than anything to do with the architecture.

The classes are also data related rather than being UI, so it is mostly a test of the language itself rather than how it interfaces with Objective C.

First impressions are good. Swift is mostly nice and consistent, which although sounding like damning with faint praise, is actually a compliment. I read a little of the language guide and dove straight in. A lot of the attempts to get the following right were me just typing stuff, guessing the syntax rather than looking it up.

Quite by accident I think my code sample inadvertently shows an area of strength for Objective-C and weakness for Swift.

The idea of the code is that it reads a Plist, instantiates a class based on that configuration and fills in a number of properties.

The first half of the code looks like this:

        NSError* error = nil;
        NSString *plistPath = [[NSBundle mainBundle] pathForResource:@"XXX" ofType:@"plist"];
        NSData *plistXML = [[NSFileManager defaultManager] contentsAtPath:plistPath];
        NSDictionary *temp = (NSDictionary *)[NSPropertyListSerialization propertyListWithData:plistXML
                                                                                       options:NSPropertyListMutableContainersAndLeaves
                                                                                        format:NULL
                                                                                         error:&error];
        NSArray* values = [temp objectForKey:@"Entries"];

This was pretty straight forward to convert into Swift, though the type system gave me issues:

    let plistPath =  NSBundle.mainBundle().pathForResource("XXX", ofType: "plist")
    let plistXML = NSFileManager.defaultManager().contentsAtPath(plistPath)

    var error:NSError? = nil
    var format:CMutablePointer<NSPropertyListFormat>? = nil
    let immutable:NSPropertyListReadOptions = 0
    var pList = NSPropertyListSerialization.propertyListWithData(plistXML,
        options:NSPropertyListReadOptions(NSPropertyListMutabilityOptions.Immutable.toRaw()),
        format:format!,
        error: &error) as NSDictionary

Getting the options property seems very clumsy; I’m sure that there must be a better way of doing it.

I had a real problem with the in/out parameters format and error. Not only was the documentation confusing but the Swift Playground kept crashing making it difficult to distinguish between what I was doing wrong and where the compiler itself was messing up. It’s also a bit odd that, though both are in/out parameters, that they both need different methods to extract the values.

(To be fair, this is a beta and it is the first version of a whole language and compiler. I mention the crashes not because they’re unexpected or even especially bad, just as an honest description of the difficulty I had.)

The next section, using the data in the plist, was much more problematic. The code looks like this, but I’ve trimmed a lot so what we have here isn’t terribly useful now!

        proxy = nil;
        for (NSDictionary* i in values) {
            if ([thing isEqualToString:[i objectForKey:@"Class"]]) {
                dynamicClass = NSClassFromString([i objectForKey:@"BaseClass"]);
                proxy = [[dynamicClass alloc] init];
            }
        }

I didn’t do the straight conversion. A few more years of Cocoa programming allowed me to notice an optimisation:

    let valueList = values.filteredArrayUsingPredicate(NSPredicate(format: "Class = %@", value))
    let valueData = valueList[0] as NSDictionary

This same approach would work in Objective-C.

Next I tried:

  let dynamicClass = NSClassFromString(valueData["BaseClass"])
  let proxy = dynamicClass()

The first line works as expected. The second line doesn’t compile.

Is there anything else that we can do with dynamicClass? Let’s see. It’s an AnyClass which is a type alias for AnyObject.Type. Which doesn’t really help.

I tried casting it to a base class but no matter what I tried I couldn’t alloc/init it (in Objective C terms).

Josh Smith figured out how to do it by creating a factory class in Objective-C.

I tried (and failed) to get it to work by calling some of the Objective-C runtime directly:

var bytes:Byte[] = [0,0,0,0]
let b = objc_constructInstance(a, &bytes)

But the second line doesn’t work when using ARC. (To be fair, Xcode struck through the definition so I didn’t have much confidence that it would work!)

So that leaves Josh’s call out to Objective-C to be the best method that I’m aware of.

In the end I just used a switch statement to select between the relatively limited number of options that I had to choose between. Not as clever, but maybe that’s a good thing?

Not so smart phones

The flood of new so-called smart watches continues. Some people seem to love theirs, others remain to be convinced.

Count me in with the unconvinced, though only because the current ones seem to be poorly conceived.

Marco Arment says:

Portability is critical to modern device usefulness, and there are only two classes that matter anymore: always with you, and not… Smartphones dominate always with you.

I think this gets to the heart of why the current range of devices — both those for sale and also those just announced at CES — just are not very compelling.

Let’s ignore for the moment the fact that most of them look awful.

Actually, no. Let’s not. You can’t sell a device for hundreds of pounds, one designed to sit on your wrist, replacing the only jewellery that many men wear, and make it look like a digital watch from 1981. I half expect the next smart watch to have a calculator keyboard on like the old Casios.

(For what it’s worth, I think new Pebbles are a big step forward over the original version. Unfortunately I like my super-thin Skagen so I’d still consider it a long way from acceptable.)

But yes, let’s assume the form-factor was more pleasing. Then it still doesn’t work. They’re not replacing anything. They’re accessories for an already expensive and always-with-you device. Sure, looking at your wrist is easier than getting your phone out of your pocket, but is it really that much easier? Is it several hundred pounds better? Is it worth the hit on you phones battery life and the inconvenience of yet another device to charge? I think most people will conclude, no.

So in summary, I think that smart watches have two main problems:

  1. Aesthetics
  2. They’re companion devices

The first is solvable with advancing technology and a degree of taste. The latter means that not every manufacturer will solve it but once the components become small enough putting them in an attractive case becomes possible.

Moore’s Law can partly solve the second point, too, but it’s not enough on its own. You’d also need changes in the way you interact with the device if it’s to be a full replacement for a smartphone.

I don’t think the answer to that is speech. Sure, Siri will get better, but there are places where you can’t or wouldn’t want to talk to your devices. And it would be hard to do an Android and get bigger and bigger screens — at least until we evolve to have bigger fore-arms.

Instead, I wonder if smart-watches are really a bit of a technological dead-end. If over time components tend smaller and smaller, then why stop at wrist watch size?

The other side of the equation is the smart phone. Is it really the best form-factor that we can possibly imagine? Do we use smart phones because they are the best place to put small computers, radios and piles of sensors?

Or put another way: if you could have the same functionality that’s currently in your smart phone in the form of a watch, would you take it? If you could take all that functionality and not even have to wear a watch, would you take it?

The smart phone is a great compromise. It’s small and with you most of the time. But you still have to carry it. You can still easily lose or drop it and break it.

Smart watches and Google Glass try to solve these problems but, as Marco says, they do so with some pretty serious draw-backs. The smartphone is better for most people right now but that won’t always be the case.

What you forgot from your Computer Science Degree

Last night I did a short presentation about my WSLHTMLEntities open source project at the London iOS Developer Group meeting. You can see the slides here:

Since last time I did a talk there people snickered because I built the slides using PowerPoint, this time I decided to use the latest Apple technology: Keynote in iCloud. Unfortunately this was a bit too new for the Mac Pro they use in the Apple Store, so we ended up downloading a copy in PowerPoint format and loading that into the local copy of Keynote. Nothing is ever simple.

One question I got at the end that I was unable to answer is how well it performs compared to other solutions.

This afternoon I ran a few quick tests.

Firstly I added two further methods of performing the HTML entity replacement:

  • Google Cocoa Toolbox
  • Use the new iOS 7 NSAttributedString feature where it can load a HTML document

The last option, while built-in and easy to implement, is not something you’d want to consider if you had any performance requirements. First, it has to run on the main thread. Second, it’s memory footprint is way higher than either of the other two solutions. And, finally, it’s slow. In my tests I did a loop of 10,000 iterations. Because of the memory problem I only ran 1000 iterations of the NSAttributedString solution, but it was still about 15 times slower than my version when doing the full 10,000 records (i.e., over 150 times slower overall).

So I’ve not included it in the charts below.

HTMLEntityChart

I ran eight simple tests with each of the parsers.

There is no clear winner.

As I speculated, WSLHTMLEntities is much more consistent than the other two. Google’s varies a lot depending on where in the mapping list the “solution” lies. Replacing &loz; (near the end of the list) takes 50% longer than &amp; (near the beginning) for example.

Still, you’d have to be pretty obsessive to pick one of these solutions for performance reasons alone. Interesting to find out, though!