Build an Ethereum/Bitcoin price tracking app in Swift

Max Stein
maxste.in
6 min readOct 10, 2017

--

Ethereum, Bitcoin, and cryptocurrencies at large have been exploding in value lately. Even if you’re not invested in cryptocurrencies yourself now is a great time to learn how to program apps that leverage them.

Today we will be building a very simple Ethereum/Bitcoin price tracker in Swift 4 using Xcode 9. To get started download the base project here then open “CryptoTracker.xcodeproj”.

Try running the app (⌘+R) in the iOS Simulator and you’ll notice the text “$0.00” with “Ethereum Price” under it. If you select “Main.storyboard” from the projects pane on the left-hand side you’ll see we have a horizontally and vertically aligned stack view with the two labels. Select the “$0.00” label and reveal the connections inspector (⌘+⌥+6) and you’ll see it has a @IBOutlet connection to “ViewController.swift” with the name etherValueLabel. We will edit this label with the real value of the currency later.

Getting Connected

Our price tracker wouldn’t be very good without up to date information on prices. The best way to get this information is through the use of an API, and CryptoCompare has a great one that supports numerous types of currencies.

For now, we want to use it to make an API call to get back Ethereum’s price in USD so we can display that in our app. Open up “ViewController.swift” from the projects pane and add the following below the etherValueLabel @IBOutlet at the top of the file:

let apiURL = URL(string: "https://min-api.cryptocompare.com/data/price?fsym=ETH&tsyms=USD")

This is the API URL we will be connecting to in order to fetch the data we now read to write a GET request in order to retrieve the latest price information from this URL. Add the following function below the didReceiveMemoryWarning function:

Our function takes in a URL and has a completion block which returns an optional value. We will send this information back later when we complete our request or send back nil if there is an error.

On the first line, we perform a basic dataTask request that takes in the URL, this is done using Apple’s URLSession API. It returns data from the call, a response(which returns information about the call that was made), and an optional error in the event of failure.

We also do request.resume() at the end which actually starts the call. Up to this point though we are not doing anything with the information returned from the call, so replace the TODO with the following:

This confirms that the data we got back isn’t nil and that there weren’t any errors. In the else case we send back nil since no data was found and try to print the error, for safety we unwrap it using ? to get back a description of the error and if no description is found we just print an empty String. The error should never be nil in this case but using optionals is a good habit to get into for writing safe code.

Now we have the data safely unwrapped and made sure there aren’t any errors, now its time to fetch the USD value from the JSON response we got back from the server. To do so add the following underneath the guard block we just added:

In order to read the JSON data in Swift, we use the JSONSerialization class from Apple, which takes JSON data and converts it into a dictionary which can be read in Swift. This must be done using a Swift try-catch block, which is why we need to add do at the beginning and catch to handle an error in the case that we aren’t able to get back the JSON data.

Once we have the dictionary we can start reading values, inside the JSON dictionary is the key “USD” which contains the US price of Ethereum as a number so we cast that value to NSNumber.

If for whatever reason we can’t get back the value we pass nil to the completion block again and return. If we do get the value back safely though we pass it to the completion block.

Next, we’ll write a small helper function that takes the value number and formats it to a US currency string. Add the following underneath the makeValueGetRequest function we just wrote:

NumberFormatter is a class from Apple that takes numbers and represents them in various text formats. By setting the locale to en_us and the numberStyle to .currency we can use the NumberFormatter to represent the value in US dollars.

Now we need to unwrap the value passed into the formatAsCurrencyString function to ensure it’s not nil and format it using the NumberFormatter instance we just created.

We unwrap the value using a guard and use the NumberFormatter string function which takes a NSNumber and converts it to a String following the formatter’s rules (which here was that we print a currency style String using US values). At the end, we return the formattedCurrencyAmount String which we can use to print that value on the screen.

Great! Now we can get a numerical value back from the API and we can format that value into US dollars. All that we have to do now is make the request and populate the on-screen etherValueLabel with the value.

Recall that in the beginning, we added the following line to store the URL for the CryptoCompare API:

let apiURL = URL(string: "https://min-api.cryptocompare.com/data/price?fsym=ETH&tsyms=USD")

Now we want to use that URL to make a GET request for the data. Before we can use that URL though we first have to unwrap its value. By default, URL objects initialized with a String are optional since the URL could potentially return nil if the String resolves to an invalid web address.

To do so add the following under super.viewDidLoad() in your viewDidLoad function:

A quick, simple guard statement ensures apiURL on the left-hand side is safely unwrapped and ready to be used to fetch that data.

Recall that earlier we created the makeValueGETRequest function which takes in a URL and has a completion block that returns the value of Ethereum as a number.

We can pass in the now unwrapped apiURL then we can use that formatAsCurrencyString function to convert that value to a String in US dollar currency format. Finally, we can display that String on the etherValueLabel so the user’s of our app can see it.

We call the makeValueGETRequest function we created earlier with our now unwrapped apiURL and get back value in NSNumber format which represents the cost of 1 ETH in US dollars.

For the next part, we have to use a DispatchQueue, a class provided by Apple to deal with multithreading. The makeValueGETRequest performs the GET request in the background so that it won’t interrupt the main thread, which is used by iOS to update the UI on the screen. By doing this work in the background we can avoid interrupting any interface changes with our GET request.

To get back to the main thread using DispatchQueue we use DispatchQueue.main.async a method that creates a block where we can update the UI on the main thread after coming back from a background operation.

Once inside we assign the etherValueLabel.text with our value for 1 ETH in US dollars. The ?? after the formatAsCurrencyString is known as nil coalescing which means since formatAsCurrencyString returns an optional String (either the US dollars value or nil in the case of a failure), the ?? acts as an OR clause essentially which in the case of failure will simply print the StringFailed” to the user.

Whenever you’re dealing with API’s it’s always good to handle failure gracefully, there are many ways to do so and the nil coalescing operator is certainly a handy tool to keep in mind.

Try running the app (⌘+R) and you should now see the value of 1 ETH!

Whats Next?

You can download the final version of this project with some added comments here.

Update: part 2 is out now! Go check it out to learn how to build a more robust price tracker with Bitcoin, Ethereum, Litecoin, Monero, Ripple, and NEO support!

--

--

Max Stein
maxste.in

iOS Engineer @ Amazon, Blockchain Engineer & Enthusiast. Creator of https://maxste.in, a full-service App development company. @maxsteinapps