Sep 29, 2017 8 min read
Using WebSockets with the Intrinio API in Swift 4
A short tutorial on how to stream real-time stock information
Senior Application Developer
For the sake of brevity we will cover only the data integration portion of the build in this tutorial, but our demo application code is also included in the GitHub repository for your use.
The Intrinio API is capable of utilizing WebSockets to stream real-time stock information. This provides a great advantage over traditional polling-based methods of retrieving quote data because it is sent only as needed — in other words if the price isn’t changing on a stock we don’t have to keep polling over and over again to check the price.
This project was created using Xcode 9, Beta 4.
Let’s get started!
Create a new iOS project: in the example provided, we use the Page Based App template provided in Xcode. Close the project once it has been created, and make your way over to your terminal. Change directory to the top level of your project, and run the following command to initialize CocoaPods for your project:
This creates a file named
Podfile in your top level project directory. Now you need to add Starscream to your
Podfile and install it. In your
Podfile under the line
use_frameworks! enter the line:
pod 'Starscream', '~> 2.1'
Save the file and then run the following:
You should see some green text that tells you this was successful. Now re-open your project using the .xcworkspace project file (this is important because it allows the pod we just installed to be used in your project).
Now we are ready to get into the data integration component of the project. Add a new Swift file to your project called
IntrinioConnector.swift, this will contain all of the Swift code for our API connector. Add another new Swift file called
Utilities.swift, this will contain the necessary data structures for parsing our JSON.
IntrinioConnector.swift file enter the following:
What we have done here is imported the necessary modules, namely the Starscream module that will enable us to use WebSockets. We have also defined a class named
IntrinioConnector and made it a WebSocket delegate, allowing it to handle any events our WebSocket generates. Finally we have created a property
socket to contain the handle for our WebSocket.
Next let’s add the following code to
Here we have defined the rest of the class properties we will need. You will need to fill in
password with your respective API username and password from Intrinio. We also define a timer object
heartbeater to contain the timer that controls our heartbeat to the WebSocket. Intrinio requires a heartbeat ping be sent every 20 seconds (we have it set to 15 in ours) in order to keep the connection alive. We have also defined a couple of event handlers that represent pointers to callback functions;
eventReadyis called when the socket is established and ready to receive requests from our application and
eventHandler is used to handle all subsequent data related events.
Next, we define the function
start which begins the connection process. First we initialize a basic NSMutableURLRequest to the Intrinio authentication URL through our private function
getRequestForURL. This function embeds our username and password in the header for basic HTTP authentication and returns a request object.
Now we can create a HTTP request
task and write a closure to handle the response. In the response handler, we assign the returned API token to our class property, and then use the token to begin initiating the actual WebSocket connection. We initialize a
WebSocket handle and assign it to the variable
socket, tell it to use the current class as it’s event delegate, and then attempt to connect. Finally we must start this whole order of operations by calling
task.resume(), and then wait for a callback to notify us of any state change to our socket.
To handle these callbacks, we must add the following code:
First, let’s clear some overhead code out of the way. When we establish our socket, we will need to send periodic “heartbeats” to the remote server over our socket. The function above
heartbeat simply writes this request.
If our socket successfully connects, then we will receive a callback to
websocketDidConnect. In this function, we define the connection state as being ready by assigning
connectionReady, and clear out any previously stored subscription data (it all gets invalidated whenever a connection drops). Then we initialize the timer to handle the heartbeat requests at an interval of 15 seconds. Finally we dispatch a new thread to handle the callback to our ready event we initialized earlier. At this point our app would know our Intrinio API feed is open for business.
If the socket did not connect successfully, or if at any point our connection breaks the function
websocketDidDisconnect() is called. This function will invalidate our heartbeat process, change the state variable
false and print any debugging information to your console. I’m sure at some point if I continued to develop this demo I would probably also need a callback handler for the disconnect event the same as we have an
eventReady that is called upon a successful connection.
Now that the connection is setup, let’s get down to adding some subscriptions, which will allow us to listen for updates on various ticker symbols.
subscribeToTicker allows us to request updates for a specific ticker symbol (i.e. AAPL, AMZN, etc). I’ve added some controls to both of these functions above to check whether a ticker is subscribed already, to prevent hammering the API server with duplicate requests. If it’s already subscribed, then we’ll skip adding it again, and if it’s not already subscribed… well then we need to subscribe!
unSubscribeToTicker is used to stop listening for updates on a given ticker symbol.
Once we’ve subscribed to some ticker symbols, we should start seeing quotes trickling in (assuming markets are open and the symbol is active in trading). To handle this we need to create a couple of new methods:
These two methods, as you’ll notice, are very similar — essentially depending on the type of data being received (text vs binary) one or the other will be called.
websocketDidReceiveMessage is the only one that this demo will use, but you should be aware that both exist.
When a message is received from our Intrinio data feed, the
websocketDidReceiveMessage callback is called. Here we take advantage of some of the new shiny Swift 4 features and use the new
Decodable interface. Basically, if we define structs that match the expected structure of the JSON we’re attempting to parse, then Swift will pretty much do all the work of serializing it into usable objects for you. First we initialize a
JSONDecoder object, then we call
decode on it using the text we just received. We should now have a generic event object that can be passed through in a new thread to the
eventHandler callback our application initialized earlier. It’s up to your application how to handle various events, you can see a few examples in the source code provided with this article. Here is an excerpt of our demo application’s callback for this:
As you can see, using a switch statement we examine the
event property of the
withEvent structured passed to the function. The only event our application expects to receive is “quote” and thus any other event is simply dumped into the console. When we receive a “quote” event we find the symbol and update the price, then kick off a series of events that update our application’s interface.
Finally, let’s define the contents of our
Here we have defined all of the basic JSON elements we need to parse responses from Intrinio’s API.
IEXEvent implements the
Decodable interface which allows it to be used directly with the
JSONDecoder to parse data. In this example
IEXEvent.event will equal “quote” and
IEXEvent.payload will contain data as outlined in the
IEXPayload structure, which represents quote data.
That’s it! You should have all the knowledge needed to create a working WebSocket connection with Intrinio’s real-time data feed. Don’t forget to check out our github repository containing all of the code from this article as well as further examples of integrating the data with your application.
Link to GitHub repository: IntrinioDemo