Tutorials (51)


Accessing Raspberry Pi GPIO Pins (With Swift)

You can do quite a bit with GPIO (general purpose input/output) pins on devices like the Raspberry Pi and Beaglebone. Here I’ll show you how to set it up to perform a couple of simple tasks, like blink an LED and read the temperature from temperature sensor called the DS1820B. If you don’t know much about electronics, that’s OK – there’s nothing major here, just a few points to follow as you go along. I’ll explain them in further detail at the right time.

Setting Up

These examples will focus on the Raspberry Pi, because that’s what I have easiest access to, but with some minor modifications they could work with a Beaglebone black. At the time of this writing, Swift is available for the Raspberry Pi 2 & 3, including package manager. You can download the Swift 3.0 binaries from Joe Bell’s Jenkins build if you don’t wish to compile Swift yourself. I personally like to keep a couple versions of Swift builds and symlink to the “current” one, with ~/swift/current/ (a symlink) listed in my bash profile’s $PATH  list. That way I can change the symlink at will.

Side note: I work with both Raspbian and Xenial (Ubuntu/ARM). At the time of this writing, there appears to be some issue getting the 1wire interface to work on Xenial, though I am able to compile swift completely, which proves difficult on Raspbian. Basic functionality, like blinking LEDs, seems to work on Xenial, but I haven’t had an opportunity to try other interfaces. On the surface level they appear available and usable.

Sanity + Smoke Test

The ribbon cable between the Raspberry Pi and the breakout board can be inserted either way (right or wrong), so it’s important to do the check first. Hook up your jumper cables from the 3.3 or 5V pin on the breakout to the breadboard row containing your 220Ω resistor. Following this diagram below. Make sure your LED is inserted properly (long let at positive). Click for full-sized view.

Cobbler sanity check

Sanity check. If your ribbon cable and jumpers are inserted properly, the LED should light up. This configuration connects the 3.3V pin directly to the resistor/LED. It should light up if all is connected properly.

Next, connect the jumper from 3.3V to the row corresponding to GPIO Pin 17.

LED Hookup

It may be worthwhile to install WiringPi so you can test GPIO connections via the command line rather than compiling swift every time. In our example above with pin17 connected to the LED:

This should work for you, but I did run into some issues from time to time where it simply refused to work properly (I’m sure I did something wrong!).. You should see the LED turn on.

SwiftyGPIO

Check out SwiftyGPIO and see how the examples are configured. It’s quite straightforward. Using this, we’re going to build on them to read from a 1-wire digital temperature sensor (DS18B20). Let’s get started configuring the Pi to user the 1-wire interface.

First, a brief overview. You define the GPIO type by passing an enum value for your hardware. In this case the .RaspberryPi2 applies to both the Pi2 and Pi3. We’ll go with that. We’ll then keep a reference to the GPIO #17 pin, as in the above smoke test. Note that this is the actual GPIO number, not the number as it would apply to the pin number on the circuit board.

You set the direction (either IN for things like sensors, or OUT for things like LEDs)

and finally turn on the LED,

From the SwiftyGPIO examples, let’s look at what a continuously blinking LED program would look like, modified for our hardware example.

You can include the SwiftyGPIO.swift  file next to your main and compile the whole with swiftc *.swift && sudo ./main

The programming really isn’t very hard, so let’s move on to our temperature sensor.

Hardware Config

First you need to enable GPIO on the Pi, and to do that you need to write some configs to the boot config file. If you’re running Raspbian (and expect to use pre-build binaries), you’ll need to edit the /boot/config.txt  file; if you’re on Xenial/Ubuntu, it’s /boot/firmware/config.txt  .

add this line to the end, if it’s not already in there:

Reboot the machine.

You’ll then need to check that everything worked just fine

The output will look something along these lines,

That t= value is degrees C * 1000. We’ll end up parsing it in the readTemp program.

See this set of articles for further details.

Temperature Sensor

Here’s a little program (http://github.com/iamcam/swiftyArm/readTemp) with 1-wire temp sensor (DS18B20) and two status LEDs. Follow the wiring diagram below. I’ve included the Pin numbers on labels because sometimes the Fritzing pin numbering can be a bit blurry. The gist of this little project is to perform a temperature reading whilst making an LED blink on a separate thread

1wire-temp-sensor

 

Assuming you have a functioning Swift build on your Pi, you should be able to download the repo, build the readTemp project with package manager, and run the output.

Then execute it:

Some lights will blink and partway through, the read status LED will illuminate and the temperature will print out to the command line,

27.562 °C / 81.6116°F

And that’s about it. Besides getting a stable Swift working, this project wasn’t very hard. Getting the wiring set up properly is probably the most difficult. Surely in a few months time we’ll have a stable Swift that’s less of a moving target.




Compile Swift 3.0 on Your ARM computers (Raspberry Pi, BeagleBone Black, etc)

I often write these blog posts in part to remind my future self how I did something as well as for the benefit others. Today I’m looking at what’s involved with compiling Swift for ARM devices, namely the popular Raspberry Pi. While these are meant for the RPi, they should also apply generally to devices like the BeagleBone Black. Before you get started, you should be reminded that Swift3 is very much an alpha-level project, especially on ARM devices. There are times when swift won’t even compile properly, or even if it does compile, there could be issues running it smoothly. armv7 devices (BeagleBone Black, Raspberry Pi2, and others) seem to be most reliable; armv8 (Raspberry Pi3) are in the weeds, so to speak, because there’s been little effort toward that architecture due to resources. It will probably work in the future, just not as well in June, 2016. Now that you’ve been adequately warned, let’s begin.

[NB: If you’re setting up a new system, start over on Part 1: Readying Your Pi for Swift]

Contents

  • Making a Swapfile
  • Installing required components
  • Getting and building the source
  • Cross compiling
  • Conclusion

 

Make a Big Ol’ Swapfile

  • You’ll need to have a lot of memory to compile swift, and while the Raspberry Pi has 1GB, it’s not enough. Let’s start with increasing the swapfile size by following the from over here. (Paraphrased below)

Edit the configuration file at /etc/dphys-swapfile

 

Find  CONF_SWAPSIZE and set the value to 2048 :

Reboot or stop/start the dphys-swapfile service

It may take several minutes, so be patient.

One point some have noted is that having a large swapfile as this lends to decreasing the lifespan of the memory card due to the large amount of writes you’d expect in a swapfile. It’s a risk you run, but 32GB memory cards are inexpensive. Keep backups if it concerns you

Required Components

Next, we need to install required components (CMAKE, ninja, & other dev tools) – from the Swift README

 

Once that is finished, clone Joe Bell’s package-swift repo on your Pi. This provides some handy shortcuts for building swift on ARM devices: https://github.com/iachievedit/package-swift.git

 

Start a new screen session so that we don’t have to remain logged in during the whole build (in other words, if you lose your connection, you can resume where you left off)

To resume the screen session, simply log back in and type

 

Get and Build the Source

Inside the Package Swift repo, run the get script to download the appropriate repos used for arm builds

or (it doesn’t really matter much)

Just one note – notice the tee command at the end. That takes the input and write it to a file. Since the Swift build process doesn’t output build logs, we pipe the build output to tee so we can save it, in case there was an error along the way. Sometimes these errors are minor and occur after the swift binaries successfully build. It’s important to know.

Now, it’s time to wait several hours for first build. You remember to enter a screen session, right?

When it’s all said and done, you should be able to run swiftc on a simple helloWorld.swift

 

Cross-Compiling

Attempting to build Swift on these low-powered devices is a noble effort, but it takes a very long time. I personally don’t like having to wait several hours to find out the build failed. That’s where cross-compiling comes in. This process means you build binaries on one platform (for example, a Mac/Intel) that work on another (Linux/armv7). Usually takes less than an hour. The following instructions are meant to be executed on a Mac.

First, you need to install dpkg so the build system can create a proper debian package

 

Next, make sure you have Joe Bell’s Package Swift repo, mentioned above: https://github.com/iachievedit/package-swift.git

Download all the appropriate repos and branches using ./crosscompile_get.sh

Next, it’s time to build: ./crosscompile_build.sh -t linux-armv7

When the build is complete, copy it over to your Pi. If all went well, you should have functioning Swift binaries*.

*Of course, there may still be issues with Swift on ARM itself – it’s still alpha.

Conclusion

I hope this tutorial was helpful. At the time of this writing, there were still several considerable issues with Swift on ARM devices, but it is possible to compile it yourself. If you continue to run into issues, it may be worthwhile to check back at Joe’s Website for updates and downloadable binaries.




Ready Your Raspberry Pi for Swift

I’m working on a series in conjunction with some talks I’m giving this spring/summer at the All Things Swift meetup here in San Diego. As one might expect, many Swift developers don’t have much linux experience. That’s perfectly fine – it doesn’t take a much to get started. I even come back to this setup process every time I set up new Raspberry Pis. Everything here assumes a Raspberry Pi 3 with Raspbian Jessie. Otherwise YMMV.

Before we get started, I’ll add this one note – Swift is under heavy development right now. Joe Bell has created a Swift-2.2 Debian package (below), and a number of people are working hard on Swift-3.0 for ARM devices. Development on Swift-2.2 has ceased in favor of bringing Swift-3.0 up to speed. Only recently has anyone been able to compile Swift on a somewhat consistent basis. There’s a good chance that within a few months many of the issues will be worked out.

Connecting

First, let’s make connecting our Pi a bit easier – install VNC and Bonjour (netatalk + avahi). The former enables screen sharing, and the latter allows you to connect to your Pi at an address such as vnc://pi.local/  on your local network – much easier than remembering an IP address. Contributor fguillen posted a concise set of instructions on StackOverflow. Rather than re-hash his instructions, head over there. Remember to reboot the Pi when you’re finished (sometimes VNC doesn’t work properly without it).

If during setup, you did not change the default hostname, you can now connect to your Pi at vnc://pi@raspberrypi . If you’d like to change it, as I did, you can run the raspi-config tool (via the GUI or command line). By running raspi-config, all the necessary config file changes are made for you.

At this point there’s little reason to keep the Pi connected to a monitor or TV. My next step is to stash it away somewhere out of the way so I can clear up some desk space. From now on, I’m connecting to the pi at ssh pi@pi.local .
.

Cut the Fat

If you plan on compiling Swift on your Pi (more on that another day), you’ll need at least a 16GB memory card. If you’re on the lower end, you may need to remove some extra cruft. Let’s start with LibreOffice, Mathematica, and Wolfram.

Swift  via apt-get

The easiest way to get swift running on your RPi is to install Swift 2.2 via apt-get. There are several steps involved, but Joe Bell laid them out well. Follow them, but with a few important changes:

The rcn-ee debian packages have been updated, so use this instead:

Go ahead and complete his instructions. When you’re finished, you’ll have a working Swift-2.2 installation.

There’s something important you need to know – the Swift REPL doesn’t work (yet). Neither does the Swift Package Manager. While you won’t be able to use any libraries that come via SwiftPM, you can still write some simple apps using Foundation and Glibc.

Let’s try a very simple Hello World…

Compile and run…

Finally! Doesn’t it feel great to see something familiar running outside the Walled Garden?

I mentioned compiling Swift from source above. That will come another time – certainly more involved than I intended for this post.

 




Currently, Swift on Raspberry Pi3

I’ve taken recent interest in working on the Raspberry Pi now that Swift is open source. Given the amount of products built specifically for the Pi, there’s a huge potential for new, fun projects. DIY electronics have been gaining momentum over the last few years and there’s a lot of information to help you get started. Depending on how things go in the coming months, I may be able to start pitching physical computing devices for client projects.

At the time of this writing (April 2016), there’s not much to be said about getting Swift working properly on devices like the Raspberry Pi. While a few individuals have made great headway into making swift compile for linux arm7, the work isn’t complete and a few critical pieces are missing. Even now, not a lot of progress has been made since January, when it all started to work.

To put it simply this is what does and does not work. Set your expectations accordingly.

  • A build of Swift 2.2 “works” – you can compile and link to Foundation + Glibc
  • That build is from February, 2016
  • The Swift REPL doesn’t work – crashes with a memory bug
  • Full set of Swift3 tools don’t compile (yet)

Getting Started

I’m using a Raspberry Pi3 running the latest Raspbian Jessie. Head over to Joe Bell’s instructions for the Raspberry Pi and follow them exactly. This will give you a workable Swift 2.2 install via apt-get. I’m sorry there aren’t more exciting instructions here, but that’s really the crux of our predicament – that seems to be the only reliable way to get swift running on the Pi for now.

Once you have Swift properly installed, give some examples a try (scroll down) – using Foundation and Glibc. It feels good to see Swift running on something other than an iPhone or Mac.

Next Steps

I’m currently working with (I use that word loosely – I don’t have the knowledge to be a productive contributor) with Joe Bell, Will Dillon, and Morris Cornell-Morgan to see if we can figure out what how we can get builds working for the Pi and other armv7 devices.

I had the most success attempting to compile Swift on the Pi in over a month last night – this happened to be within just a day or so of the main Swift repo switching over to swift-3.0 development. Most of the tools appeared to compile fine, but package manager failed, and there were some issues with linking (this could be a build config issue). I remain hopeful.

I’ll continue to post progress as it comes. In the meantime, I’m preparing a talk on this subject at the All Things Swift meetup in May.

EDIT April 27, 2016: Joe is putting together a concerted effort to get Swift3 on the Pi.He’s also provided a Jenkins build workflow to test integrations.




Automating iOS + Watchkit build numbers, with Git, for iTunes Connect

This wasn’t especially difficult, but it was a little tedious to track down.

I’ve relied on a handy little build phase script (I wish I remember where I found it) for automating build numbers from git commits for iOS apps since Apple gave us access to TestFlight via iTunes Connect. This same script didn’t work for my Apple Watch app as I anticipated, so it took a little bit to work out the kinks for AppStore submission.

It boils down to this

  1. Set the build number = the number of git commits on the branch.
  2. Change the Info.plist build numbers for the iOS app target, the Watch App target, and the Watch Extension target. This is done in a script build phase before the “Copy Bundle Resources” phase.
  3. Reset the Info.plist build numbers after all the build phases have run (another script build phase)

See the gist I posted for the complete script. Make sure to check the directory paths for the correct app name.

Happy building!




Localizing Your iOS App: Tutorial, Tips, and Tricks

I recently ran through the process localizing a client’s app. It took some time to fully wrap my head around the inner workings, but now in hindsight it seems relatively simple.

The general overview looks something like this:

  1. Identify strings that need localization
  2. Generate .strings files
  3. Export & send to translator
  4. Import translations
  5. Some Gotchas [Edit – this is new since this post was first published; I will add to it from time to time.]

If you would like to follow along at home, you can checkout the project on Github.

Pre-flight Check

Before we get going, it’s important to make sure all our ducks are in a row. You need to ensure your project settings file has Base Localization turned on. Go ahead and add a second language, which will kick off a few other operations you’d have to run manually. Among them is adding the en.lproj and the other language’s lproj directory.

Xcode project settings

In most cases, you want to turn on Base localization for your storyboard and xibs. Do this by opening the storyboard or xib, and checking “Base” in the Localization section of the File Inspector. Make sure English and the second language are both checked and the type is Localizable Strings, not Interface Builder Storyboard. This tells the app to use the base localized storyboard for all the layout, and the strings as the language-specific content source.

Interface builder view

You should have something similar to this

Project file list

Identification

The first step is to identify strings that need to be localized. It shouldn’t be hard – anything user-facing should be translated, except for a few words, such as brand and app names (though you can localize the app name if you wish).

Let’s start with some code.

This is a likely scenario – you’re setting text programmatically. The problem is that it’s only going to be in one language. The first step is to use the NSLocalizedString to provide a key name, and a comment used by the translator.

While you can rely on autocomplete to give you a rather verbose NSLocalizedString function, use this tip to take advantage of default values, leaving you with something equivalent to the Objective-C macro. For starters, use your English string as the key:

(We’ll change the key name later). Do this for every string you want translated.

Generate Your Strings

It’s time to run the genstrings command in the terminal – this will take all those NSLocalizedString keys and comments and spit them out in a strings file.

Note: This will only work if you have the en.lproj directory created as part of our Pre Flight. Go ahead and drag the en.lproj/Localizable.strings file into your project. Put it in the Supporting Files group. Open it up. You should see this,

Caution: From this point on, you should not run genstrings on everything – only on new files that haven’t been processed yet. genstrings will overwrite.

Let’s change the key name in the .swift file and the .strings file:

Run the app. Still works. Now, go through your strings and swap out the keys for something not quite so specific. After all, your text could change, so a descriptive key would be helpful.

Now, change the value in the Localizable.strings file and re-run. Great, right!? You can see it’s working just fine – NSLocalizedString is correctly loading the content from the strings file. Time to move on.

Standard translation Changed the translation string.

Storyboards & xibs

Remember the preflight where some things happened, and maybe you didn’t understand it? Let’s look to storyboard in the Project Navigator. Notice that disclosure arrow to the left? Click it. I’m looking at the Main.storyboard (Base), Main.strings (English), and Main.strings (Spanish). Go ahead and click on the Main.strings (English) file.

Yuck!

Unfortunately, your’e kind of stuck with these ugly key names. They refer to the XML IDs in the interface file. If you look at the strings file in my demo project, you’ll also see accessibilityHint and accessibilityLabel values. It’s important that accessibility information (you should have it) be localized for screen readers.

Change one of the normalTitle values and re-run the app.

Pretty neat, huh?

Tip: If you ever need to add new UI elements to the interface file, work on the Base storyboard, then toggle the development language (e.g., English) From Localizable Strings to Interface Builder Storyboard, and back to Strings. The file will be re-generated. (You’ll be asked to confirm you want to do the conversion at both points).

Tip: Don’t bother trying to change the comments, either, unless you absolutely know you’re done tweaking the interface. It is more helpful to provide translators with screenshots if they are kind enough to take them. Context goes a long way.

Caution: There’s one problem you will run into – UITextViews. For some reason, as of iOS 8.1, an iOS bug prevents UITextView text values from updating. You’ll have to set it separately via NSLocalizedString. It’s a pain.

Export

Time for export. Xcode 6 introduces xliff file support – something that I understand is an industry standard in the translation community. To begin, select the top-level project in the Project Navigator, then go to the Editor menu > Export for localization…

In the dialogue that follows, select “Development Language Only”.

Save the file anywhere (I like to keep it versioned in the project root… on the filesystem, not in the actual Xcode project). I usually give it a name like “Translation Files”. It might take a few moments to process.

When you’re done, you’ll have a handy file called en.xliff (if English is your dev language). This is what you send off to the translator.

Import

The import process is easy. Select the project, then go to Editor > Import Localizations… . Xcode will do the rest.

Testing

Besides testing in your development language, make sure all the strings are displayed properly. You can even do this before a single word has been translated. Try running the app with pseudo localization. Open the scheme settings (Product > Scheme > Edit Scheme), select the Run group, and then click on the Options tab.

Check Localization Debugging (will show non-localized strings in all-caps).

Application Language – I often use Double Length pseudo language.  It makes all your strings twice as long. Sometimes you’ll see some funny formatting, especially if you have string substitutions (e.g. stringWithFormat) as part of your values. That’s ok – it’ll still work.

You can also export your xliff to an online service that will provide you with automatically generated pseudo languages you can try in the app. It’s funky looking, but it gets the job done. They’ll provide you with the appropriate instructions for their service.


Some Gotchas

NSLocalizedString with table

I didn’t catch this at first on a recent project. It’s subtle, yet frustrating to diagnose.

When using NSLocalizedString, and you reference a table, the translation export procedure will create an entry in the xliff file for the tableName.strings, which means on import, the appropriate .strings file will be generated. It’s worth noting.

Look for tableGenerationExample() in the demo ViewController, then look in the en.xliff export file. Scroll down until you find this section,

Look familiar?




iOS TDD (Test Driven Development) – Convincing Myself

By no means is TDD (Test Driven Development) a new concept; I’ve known about it for years. I had sone some unit testing on projects prior, they became an integral part of routine when I started consulting for HP’s Software R&D lab. We’ve been very good about testing out all the important logic of the application, save automated functional testing of the UI (more on that in another post).

This post is really about TDD, not convincing you to unit test your code (something you should be doing). Actually, I’m not a diehard TDD fanatic. Rather I use principles of testing first before writing application logic. I don’t want to get stuck the pedantics of true TDD development.

My journey, if you will, started as I had a turning point in two projects for Pivotal Action that convinced me. The first project involved a bit of interplay between iBeacons (CLBeacon) and networking, which would be impractical to manually test with physical hardware. The second project involves a lot of transformations being applied to objects, and some networking. In both cases, relying on rather extensive unit tests could ensure I wasn’t breaking functionality with new features.

My general approach involves a few simple practices:

  1. Create a mock data set for input. I often use JSON files because it’s easily readable, and you can use the same data on multiple tests if you need. Also helpful if you’re testing mock network response data
  2. Create a test data set, or scenario. First pass, go with the “golden path” – the best case scenario
  3. Determine what your desired outcomes are in a best-case scenario
  4. Create separate test cases for each kind of data you may have to deal with. Again – start with the best case scenario
  5. Write some logic code to either transform data, or respond to it
  6. Go back to step 1 and create a new set of data representing one type of problem, or family of very similar problems. This could be malformed data, error codes from API services, etc. as well as common problems : out-of-bounds errors, off by one, nil, and others.
  7. Keep repeating 2-5 until you’ve exhausted just about every scenario you can reasonably think of.

This may seem boring and repetitive, but I assure you that thoroughly testing your logic will uncover holes in your implementation before you even start writing application and UI code. You’re also more likely to survive refactoring unscathed if you have extensive unit tests covering the changing code. I recently benefitted from this when I converted a set of model classes over to a CoreData stack. It wasn’t a perfect 1:1 refactor, but it uncovered some places where I had to adapt my expectations and logic so that the transformations would be the same in the end.

I’m not perfect at this, but I can say that doing unit testing before really getting into the guts of an application has saved me a lot of work farther down the road. I also have more confidence that changes I make aren’t breaking existing functionality. Give it a shot.




An Overview on Providing OAuth for Your Mobile App

I was recently playing around with an idea – a proof of concept – for an mobile app API. If you’ve never done this before, keep reading.

The high-level requirements:

  • A mobile app that you have control over
  • An API you’re working on
  • Users must be authenticated

As I am the app and API owner, I thought it best and easiest to use a two-legged OAuth implementation – username & password plus some secret keys (3-legged vs 2-legged explanation). This is what your users will expect when logging into your app & service. Before you can start, find an appropriate library for your web framework. There are plenty out there, so pick your poison. I’m familiar and develop relatively quickly with CakePHP, so I went with seddonmeida cakephp-oauth-server. I’ll spare you from too much code.

First, you’ll have to set up an OAuth client in the database. This is for your app and nobody else. Follow your library’s instructions; you’ll find out you can’t read values from the database because they should be hashed. Once you have it installed and are sure it’s working, you can start the setup. In the CakePHP plugin,

Save your client_id and client_secret in a safe place. You’ll need it in your app. Now, the fun part. You can test this in your browser, but it will work the same way in your app.

First, Grant the Token

In OAuth terms, we’re doing a password type grant with the client_id and client_secret.

https://domain.ext/oauth/token?grant_type=password&client_id={SOME20CHARACTERLONGID}&client_secret={some40characterlongsecretkey}&username={username}&password={password}

You’ll get JSON in return with a few important keys, namely access_token and refresh_token. They will serve as your ID badge for future requests. Keep them around. NB: access_token is used most, but refresh_token has a special place.

Request Something

Making a request for protected resources is easy. Assuming your back-end is set up properly, you should be able to run something like this with no problem:

https://domain.ext/oauth/userinfo?access_token={whateverAccessTokenYouWereGiven}

I know the above URL is at /oauth/, but that doesn’t mean your entire API has to be handled with your OAuth controller. In practice, you should include your OAuth library as a component of each appropriate controller wherever you’re accessing the API, or at least secured content.

Refreshing Your Token

A lot of services using OAuth aren’t going to expire your token. Seddonmeida’s implementation uses an expiration, but in practice doesn’t actually enforce it; that’s up to you. In the case you do have an expiring token, it’s best to refresh your user’s keys from time to time so they aren’t “logged out.” To get a fresh new token, access our OAuth token action and request a refresh_token grant type using the client_id, client_secret, and the refresh_token you received when first authenticating.

http://domain.ext/oauth/token?grant_type=refresh_token&refresh_token={youGotThisAtAuth}&client_id={some20charid}&client_secret={a40charstring}

A Note About HTTPS

Make these requests over HTTPS if you have any option at all. Otherwise, HTTP is sending your username and password over in cleartext, which we all know isn’t a great idea.




GeoLocation Near You

We at Pivotal Action were recently given a task for a client – develop a tool for a mobile API where admin can upload a list of retailers so that their mobile app users could find locations near them. It’s basically a “Find near me” utility.

This type of project is broken down into 3 parts: Upload & store geolocation data, find addresses near a given point, and display those locations either textually or on a map display. This quick tutorial will cover the first two parts.

Part 1, Getting Located

The goal of this part is to obtain and store latitude/longitude pairs for given addresses. I’m going to assume you can already get a list of addresses, whether for a spreadsheet/csv file, or other source. With a parsed address, you can obtain the lat/lng pairs from the Google Maps API. Just be forewarned that Google limits you to 2,500 requests per 24h period. That could be a problem for some applications, so you may need another provider like SimpleGeo.com

There are a couple key parts in there. First, you need to URL encode the address details. Second, the curl stuff is pretty standard – you can find similar versions all over the net. Third, the response data comes back as a JSON string, so you need to decode it into a PHP array to make it useful. My default value for lat/lng pairs is 0.0/0.0. There may be cases where Google doesn’t understand the address information or perhaps you’ve gone over your rate limit, so you have to accept more or less a throw-away response. The important thing is that you have your address coordinates saved (dare I say, cached) in your DB. You need this.

Part 2, Finding Yourself

Now how are you supposed to find these stores that are near you, at this moment, without having to use a lame web form or other manual means? You’re going to use the Haversine, aka Great Circle  Formula. Don’t click that link unless you really want to be confused. Here’s the gist – the globe is a big sphere, and we know from high school and/or college trigonometry classes that you can figure out lengths and distances on geometric objects. Some guy long ago (whose name was not Haversine) sat down and figured this out for us. What we get as a result of running these maths is the distance between to points on earth, using lat/long pairs. The caveat is these are as the crow flies, not driving directions. What I’m going to show you below is some SQL you can use to find the N closest points within a given distance. This will work on MySQL, and I’m assuming other SQL-compliant DBs. YMMV.

(Thank Pavel Chuchuva on Stack Overflow for the SQL [answer here]). You only need a couple parameters to get this chugging along and giving you a list of distances, closest to farthest from the point you are feeding it. Along with your address information, you’re also provided a distance in miles (using 3959 for measurement in Km).

Now you can use these results to display distances to your users. Let Google be your guide for implementing Part 3.




Quiet NSLog() in Release Builds

On the heels of the previous post, here’s a little snippit I picked up from Marek Bell to quiet NSLog() output in release builds.

Add this to your {MyApp}-prefix.pch file

#ifndef __OPTIMIZE__
#    define NSLog(…) NSLog(__VA_ARGS__)
#else
#    define NSLog(…) {}
#endif

The reasoning behind using __OPTIMIZE__ is that it’s set only on release builds of your app, not in debug versions. It’s very simple and allows you to use NSLog() instead of having to come up with your own version.