"ios" entries

Upward Mobility: Android for iOS Developers, Part 3

Handling Input Events

Now that our Android app lets you choose what planet you’re on, we should use that information to update our “Hello, world” message based on the selection. To do that, we’re going to need to handle the selection event on the spinner we created.

To do this, we need to set the setOnItemSelectedListener property on our spinner to something that implements the OnItemSelectedListener interface. The simplest way to do this is to implement it in our activity.

This is pretty straight-forward stuff. You use the parent.getItemAtPosition call (where parent is the spinner) to get the item that you selected. The item is just the string value of the selection, so we can use a simple string compare to select the appropriate message. In the same way that we got the spinner using it’s id, we can get a handle on the text view at the top of the screen, and then set the message using setText.

There are a couple of things to point out here, however. For one, the onItemSelected message gets called when the widget is created, a fact that irritates the heck out of Android developers. This means that you need to ignore the first call to the method. Thus, the purpose of the spinnerActive flag. Secondly, because we’re using the Activity as the listener, you could end up with problems if you have multiple spinners on the screen, since they would all call the same listener. You could either use the AdapterView value to determine which spinner fired the event, or use private inner classes to handle the various spinners.

Now that we’ve got our listeners implements, the last step is to tell the spinner to use the Activity as the handler.

Now when we fire up the app and select a value from the spinner, we get a personalized welcome message!

Screen Shot 2013-06-21 at 6.13.45 AM

Comment

Upward Mobility: Android for iOS Developers, Part 2

Turning Hello World into something useful

When we last left our application, it was running on the emulator, but didn’t do much.  This week, we’ll add some more controls to our activity and wire up some functionality.

As a reminder, activities are roughly equivalent to view controllers in iOS. Right now, there’s not much in our activity, because all we have is a single label in our activity. As iOS developers, we’re used to never looking at our XIB files in the raw, because they’re pretty much human-unreadable. By contrast Android layout files (which end up in the res/layout folder in a standard Eclipse project) are both readable and intended to be edited. At the moment, here’s what ours looks like:

Read more…

Comment

Upward Mobility: Android for iOS Developers, Part 1

Welcome to the dark side: we have cookies

Like many hardcore iOS developers, I’ve eschewed learning “the other platform” because I was happy in Apple-land. In addition, the few forays I’ve made into Android development seem to show that it was a more complex and difficult platform to work with. However, recent developments (e.g., a new job) have placed me in a position where I’m going to need to have at least a casual familiarity with Android development, so I thought I’d bring you all along on my journey.

Getting the Development Environment Set Up on OS X

The good news is that, unlike iOS, Android is a development-platform agnostic OS. If you go to the Android developers site on a Mac, you’re going to be immediately presented with the option to download a zip file with the complete Android Developer Tools package. Fair warning that it’s pretty large, nearly 400MB. Of course, for folks used to downloading multi-gigabyte XCode drops, that may seem pretty reasonable.

Once it’s downloaded, unzip the file and move the resultant adt-bundle-mac folder into somewhere permanent. The install documentation recommends the /Developer folder, but since /Developer has been deprecated lately, you might want to just create a top level /Android folder instead.)

One additional step I took was to rename the version of Eclipse that ships with ADT to ADT-Eclipse. I already have a version of Eclipse that I use for general Java development, and I don’t want to launch the wrong one from Spotlight accidentally.

Once you’ve finished installing ADT, you can launch their version of Eclipse from Spotlight and, just like every other version of Eclipse, the first thing you’ll be asked is where you want to create your workspace. Just as with the renaming of the Eclipse application, I gave my workspace a unique Android-y name, and told Eclipse not to ask me again. This should prevent me from accidentally opening my normal Java development workspace.

Writing Your First App

Once Eclipse launches, it’s going to ask you if you want to send anonymous statistics to Google. This is a choice between you, your maker, and the NSA, so choose whatever makes you feel happy. The next thing that you’ll be presented with is a welcome popup, with the option to either create a new Android app, or run through some basic tutorials.

The tutorials aren’t actually built into the ADT. Instead, clicking on one of the links will bring you to a web page with a walkthrough. There’s not a lot of value in having me take you through a tutorial that’s already been written in detail, so I’ll hit the high points.

To start, create a new Android project. If you still have the welcome screen up, you can do that by clicking on the New Android Application... button. Otherwise, you can get to it from the File->New->Android Application Project toolbar item. You’ll immediately be presented with the New Android Application dialog.

The Android New Project Screen

The Android New Project Screen

There are a couple of important decisions you need to make here. The first is the package name for the project. This is equivalent to the bundle identifier in iOS development, and it needs to be unique. Luckily, iOS chose to adopt a Java-like reversed domain-name structure for bundle identifiers, so you should already be familiar with this concept.

The other big decision is the minimum version of the SDK that you will support. In iOS, we’re used to dropping support for old versions of iOS on a regular basis. Most iOS developers don’t support iOS4 anymore, and it’s not uncommon to see iOS6 as the required version for newer apps. This is because Apple has been very aggressive about carrying forward devices to new versions of the operating system; about the only things left behind by iOS6 were the original iPad and some iPod touch models.

By contrast, most Android users are at the mercy of their carriers for OS upgrades, and the story isn’t pretty. If you check Google’s own adoption stats, nearly half of all Android users are still stuck back on Gingerbread, a release now more than two years old. And, in fact, the wizard recommends you go back even further, to Froyo.

Does this mean that you can’t take advantage of the latest and greatest features in Android, and still deploy an app that the majority of users can run? No, but it does mean that you’re going to have to fail gracefully when new features aren’t available. iOS developers have had to occasionally do this in the past. For example, when new callback methods were delivered in iOS6, we had to keep both versions around to make iOS5 work. But the long, long version tail of Android means that you will have to take this practice to the next level.
Read more…

Comments: 2

Upward Mobility: Give Your iOS Table Cells Some Class

You're not stuck with the stock options when creating tables

UITableView is the meat and potatoes of many iOS UIs, but if you restrict yourself to the off-the-shelf table cell styles, you’re missing out on a lot of opportunities for customization. By using a combination of variable cell heights and a custom UITableViewCell class, you can make UIs that look nothing like a standard table.

To see how you can make this happen in your applications, let’s start with the world’s most boring table example, a list of my favorite foods.

simpletable

The implementation for this is the stock table view code you’ll see in any iOS tutorial:

So, what can we do to take this design and make it our own? We can start by designing our own class that extends UITableViewCell, and that has its own XIB file, which we’ll call FavoriteFoodCell. There’s not much to it:

Next, create a new Interface Builder XIB file of type View. Set the class of the View to FavoriteFoodCell (not the FileOwner; keep that as a generic UIViewController.) We’ll add a label and an image view, so that the cell looks like this:

tablecell_in_ib

 
Read more…

Comment

Upward Mobility: Special Effects Wizardry

Dress up your UIViews with a few simple tricks

Most developers aren’t great UI designers (although, as with everything, there are exceptions). But there are a few quick tricks that can dress up an app, even if you don’t eat and breathe Photoshop. Let’s look at a simple iPad single-view app with two views, each of which contains a label and a text box.

iOS Simulator Screen shot May 20, 2013 7.05.42 AM

This is about as Plain Jane as you can get in an application; the only concession to visual appeal that has been made is to use a grey background with white UIViews bounding the labels and text boxes. One easy tweak we can use is to make the UIView corners rounded instead of square, which will lend a bit of flare to the design.

This is actually harder than it should be. To set rounded corners, you need to dig down into the CALayer underneath the view:

You need to set masksToBounds, because otherwise the corners will not be transparent, and the background color of the view will block whatever is beneath it in the parent view. The resulting view is subtly more classy. You can get more rounding by adjusting the cornerRadius value.

Screen Shot 2013-05-20 at 7.17.42 AM

 

So far, so good. But that solid grey background is kind of blah, so we should dress it up a bit. An easy way to make a background pop is to use a gradient fill, a technique that the aforementioned Photoshop jockeys know and love.
Read more…

Comment

Upward Mobility: Dump Those iOS Delegates

Blocks are the way to go

Because so much of iOS programming involves the delegate pattern (the UITableViewDelegate being a prime example), it’s natural that when programmers are developing their own classes that need to be able to asynchronously call back to a client class, they would use the delegate pattern as well. The problem with delegates is that they are fairly inflexible. For example, let’s consider the following (totally inappropriate) use of a delegate:

The problem lies when you need to call this method twice from the same class.

So far, so good, but what happens if you want to have a second method in the same class call multiply? You can only have a single delegate method, so you have to start jumping through hoops to let the delegate method know where to put the resulting value.

The modern solution to this is to use blocks. People tend to shy away from them, because the syntax is a bit arcane and un-Objective-C, but they are incredibly powerful, and Apple has signaled that they are the future, by starting to use them heavily in areas such as animation.
Read more…

Comment

Weekly Highlights and Insights: May 6-10

Fit2Cure, unit testing core data, data skepticism, mobile casual gaming market, and the beehive fence

Fit2CureScreenshot

Fit2Cure: Andy Oram introduces a game that crowdsources the search for drugs to cure under-researched diseases of developing countries.

Unit testing core data: James Turner shows iOS developers a less painful way to set up an OCUnit project to test code that uses Core Data.

Even more data skepticism: Beau Cronin and Mike Loukides continue to weigh in on the dangers of blindly copying data collection and analysis methods.

Developing mobile casual games: Jesse Freeman on the impact of HTML5 on game development and the mobile casual gaming market.

Beehive fence saves African elephants: Lucy King’s inventive fence exploits an elephant’s fear of bees to save lives and crops.

Comment

Upward Mobility: Unit Testing Core Data

There's no reason to leave your database-centric code untested

One of the more common issues that arises in creating OCUnit tests in iOS is how to test code that uses Core Data. There are several challenges, but with a little foresight, you can be sailing right along.

The first issue that most people encounter is getting access to the managed object context. If, like most people, you’ve followed the code snippets that Apple provides, or followed a tutorial on the web, you hung it off the AppDelegate, and use

to get a handle on the context when you need it. Alternatively, some people pass the context all the way down the view container chain, making it a property on each controller. I find this incredibly painful, and since most applications only have a single database instance open at once, there’s no reason not to keep the context around globally.

In any event, the problem with having your Core Data specific classes get the context from the sharedApplication is that when you run OCUnit tests, sharedApplication returns nil, and there’s no way to mock it. But, this is easily solved by creating a helper class that you use to access the context.
Read more…

Comments: 6

Conquering iOS Core Data

Worth the Blood, Sweat, and Tears?

Joshua Smith (@kognate) is a Lead Mobile Developer at iRx Reminder, frequent Cocoa Conference speaker and author of an upcoming book with O’Reilly on core data. We recently sat down to talk about core data and its complexities.

  • What exactly is core data? [Discussed at the 0:18 mark.]
  • Which is right for your persistent data – Atomic, memory, or NSSQLite? [Discussed at the 2:15 mark.]
  • Core Data is hard to learn, not use. [Discussed at the 3:51 mark.]
  • Using templates like Helios or MagicalRecord can make things easier. [Discussed at the 6:04 mark.]
  • Concurrency within core data is all about the context. [Discussed at the 6:41 mark.]
  • What are the differences between how Android OS and iOS handle data structures? [Discussed at the 9:50 mark.]
  • You can view the entire interview in the following video:

    Read more…

    Comment

    Upward Mobility: Should There Be Only One?

    Admittedly, the idea of Ballmer, Cook and Schmidt all battling it out Highlander-style is appealing...

    As long as most people can remember, the smartphone space has been a contested one. Before the iPhone became temporarily ubiquitous, RIM and Palm were fighting it out to own the market, and today you have a plethora of platforms to choose from, including Android, iOS, Windows, and Blackberry. And because many mobile OS vendors license their products to third-party manufacturers, some mobile operating systems have little market share wars of their own, such as HTC fighting it out with Samsung and Motorola for the Android customer base.

    I’ve talked before, in the context of languages, about the damage that the paradox of choice can bring to societies. Having more product choices may not make us any happier, or even lead to better products, but only create the vague uncertainty that whichever product choice we make, it wasn’t the correct one.

    For obvious reasons, a monopoly doesn’t usually work out that well either, at least in mature markets with stable standards. Very few will argue that Microsoft’s most innovative years occurred during the period that they sat “fat, dumb and happy” with 90%+ desktop market share. But I would argue that there comes a time when some choices should be left to die a dignified death, and that both Windows and Blackberry mobile products are at that point.
    Read more…

    Comments: 2