Swifty Switch

I've been gone from the blog for a while, not because I'm lazy (maybe a little bit), but because I just started a new job. I now work at Google as an iOS Software Engineer. I know, it's ironic, isn't it? Working for the company that creates Android, but work on the iOS app. :)

Anyway, with my new job, we decided that the app would be written entirely in Swift. That doesn't mean that everything that we write on top of would be Swift. For instance, Google has a whole bunch of internal libraries that we rely on, and all of them are Objective-C, as well as all of Foundation and UIKit.

Today I'm not going to talk about Objective-C and Swift interoperability, though that maybe a very interesting topic that I could write about in the future, but I wanted to talk about switch/case in Swift.

As you may have heard, Swift implements pattern matching in a very good way that you can actually use it for a lot of things. In this case, I want to show you a couple of things that I found interesting with Swift's switch/case.

Optional Binding

Switch statement in Swift has the ability to do optional binding, which means that it will safely unwrap the optional, and bind it to a variable, if the condition meets. Let's take a look at a snippet of code here:


let view: UIView = ...
   
switch (view) {
case let button = view as? UIButton:
    button.showsTouchWhenHighlighted = true
case let textField = view as? UITextField:
    textField.placeholder = "This is me"
default:
    break

As you can see above, if view is an instance of a UIButton class, the first case will get executed, and the variable button will be set. This is really nice because you can be sure that button is of type button, and even if view is an optional type (UIView?), we would still be sure that button is not nil.

I usually use this to cast variables to different types especially when I have a non-generic array type from Objective-C, or even a base type array such as an array of UIView.

Breaks not required

When you look at the above code, you'll see one thing missing from each case statement. There is no more break in each case statement, unless the case statement is empty. This is new in Swift, and could be unfamiliar to C/Objective-C developers. The question, though, is how is this going to work if you want to case to fall through. For instance, you may have code that handles 2 different enum values the same way. Swift introduces a keyword fallthrough to allow that. Let's take a look at an example.

These are some of the things that I found interesting about Swift's switch statement, and I hope you learn something from this posting. I'll be posting something soon, hopefully.


enum DownloadState {
    case: Unknown, None, Downloading, Downloaded
}

let state: DownloadState = ...
switch (state) {
case .Unknown:
    print("Unknown state")
    fallthrough
case .None:
    print("None")
case .Downloading:
    print("Downloading")
case .Downloaded:
    print("Downloaded")
}

In this case, if the variable state is .Unknown, the console output would be:

Unknown state
None

Android's ListView Recycle Bin

This blog post is going to be a reminder for me and I hope would be good information for other people on how Android's ListView works. So everybody knows that Android doesn't create a new list item view (iOS people would call it UITableViewCell) for every items in a list view, but it recycles them when you scroll, so the list view doesn't create too many objects. However, there are times that you want to have a special list view item that will have a different type of view in the list view, and you only use that view one at a time. A stupid implementation of this would be creating a single instance of the view as an instance variable and return that in your list adapter. However, it DOES NOT work. It will look like it works fine, but the problem is your getView() will get called so many times in a second and it degrades your performance. I found that as a nasty bug in my program. So to fix it, what my colleague and I did was we actually just create a new view within the getView() method and let the Android's list view manage everything. I found that if you try to outsmart the system, things will not work as well as you think it might be. So, basically, this is a lesson for me that I should not try to "overly" optimize my program, and try to follow the framework as much as I can so I don't break anything serious. :)

It's so hard to make a good Android app

I’m just so sick of writing programs on Android nowadays. I do Android development for a living, but I can say wholeheartedly that it is very very hard to make a good application for Android. Don’t get me wrong, it’s not like Android is not a good platform, it is a good free and open platform, but it’s half-baked. If any of you have been programming Android, you will usually find that some of the Android’s APIs are broken, some of them work differently in different versions, and some of them just don’t work at all. Normally, programming on Android is fine when you don’t have to touch a lot of lower level stuff, especially the Android Media Player. It is broken beyond repair. How can it not support streaming from an HTTPS URL? How can it deadlock itself when there’re two instances of it running at the same time? And remember that this comes from Google!! not from some b.s. company that we don’t know.

Also if you look at Google’s Android platform versions page, it shows you that most of the time, you can guarantee that the phones will run at least Android 2.1 (Eclair); however, you have to remember that this is only the statistics of phones that access Android’s Market. If that particular phone doesn’t access Android Market, it doesn’t get counted here. Personally, I have to write an application that supports Android platform since version 1.6 (Donut), sometimes it is really hard to make use of new features of the platform, but also make sure that I have a comparable feature for older devices. As you know, Android 2.2 (Froyo) added a whole lot of new features into the platform, such as AudioFocus listener, car mode, and night mode GUI, for instance. If we want to use those features in the application but still allow the application to run in the older version of the platform, we have to wrap all those features in our class, so Dalvik (Android’s JVM) doesn’t load that class up and that will prevent it from crashing. I suppose this is normal for Java development, but still for a mobile platform with a lot of different versions, we need to find a better way to do this.

There are also some good things about Android that if I don’t talk about will make Android looks like it’s born from hell. For instance, there’re a bunch of libraries that are available on the platform right away without the developers having to add them to the application. For instance, the JSON framework, Apache HTTP framework, or the XmlPullParser framework are very nice additions. Also, the way to construct layouts in Android is quite good if you have to work with different screen sizes. The XML is easy to understand and quite easy to construct once you understand it. If we compare it to construct a layout in an iOS platform, it’s a completely different approach. iOS uses Interface Builder that creates a serialized XML of the view that we’re constructing and it also has a visual designer. However, making an interface in Interface Builder could be challenging when having to work with multiple screen sizes and resolutions. There’re tradeoffs to both approaches and it’s up to you to decide which approach is your preference.

I can’t talk about Android development without talking about Eclipse. Google recommends Eclipse to be the platform of choice on developing Android application. However, Eclipse is NOT the best IDE out there. I found that when working with Java, Eclipse is a very decent IDE, but when trying to work with something else like XML, Eclipse just sucks. I couldn’t get Eclipse to do autocomplete when I’m constructing my layouts or my styles, even though sometimes it will show up. Personally, I’d recommend IntelliJ IDEA as an IDE to develop Android in. I know that there are license fees and IDEA might not have the “up-to-date” Google tools, but believe me, you will be much much happier working in IDEA than in Eclipse (especially when you’re working in a large project). If you’re interested in using IDEA with Android, you can take a look at JetBrain’s website, they’re integrating more and more Android support into their IDE.

There’re so many factors to make a good mobile application, but the platform itself is a very big factor in it. If Google cannot solve Android fragmentation and the problem persists for a long time, maybe the platform of choice to the user would be Microsoft Windows Phone 7, or the iOS platform, which are really good. (Windows Phone 7 comes with the best IDE and the best modern language at the moment, C#, and iOS comes with a very intuitive IDE + easy to use UI builder + a hugh support from other developers) Only time will tell who will win this competition.