Swift WebSockets: Starscream or URLSession in 2021?
Building applications such as online games and real-time chat has never been more straightforward since the standardization of the WebSocket protocol in 2011. Before that, most app experiences were plagued with manual refreshes to access the latest data available. Remember F5? Since then, most apps use WebSockets in some form to update their user interface with new data as soon as it is available.
For Swift programmers targeting iOS, macOS, and other Apple platforms in 2021, two main libraries help you connect to a WebSocket server: Starscream and Apple's URLSession. While both are capable libraries, they also have advantages and disadvantages that are important to consider before choosing one.
In this article, we'll go over several positive and negative characteristics of Starscream and URLSession to help you decide which fits best with your requirements. Let's dig in!
What is the WebSocket Protocol
The WebSocket Protocol enables two-way communication between a client running untrusted code in a controlled environment to a remote host that has opted-in to communications from that code. The security model used for this is the origin-based security model commonly used by web browsers. The protocol consists of an opening handshake followed by basic message framing, layered over TCP. The goal of this technology is to provide a mechanism for browser-based applications that need two-way communication with servers that does not rely on opening multiple HTTP connections (e.g., using XMLHttpRequest or \<iframe>s and long polling).
Starscream is a conforming WebSocket (RFC 6455) library written in Swift targeting the iOS and macOS systems. Years before Apple's URLSession even supported WebSockets, Starscream was the Swift library of choice. For reasons we'll go over shortly, it is the library we use at Stream for building our iOS Chat SDK.
Starscream will compile for iOS 8+ (7+ with some tweaks) and macOS 10.10+. If supporting devices with old operating systems is a requirement, you have almost no choice but to go with this library. That is one of the main reasons we chose to go with Starscream for the Stream Chat iOS SDK, which supports iOS 11 onwards.
Starscream has been around for a long time. It's been tested by thousands of apps and improved upon for years. It presents reliability that may be currently unmatched among WebSocket libraries. That is another critical point in our decision to stick with Starscream, and it will be obvious (spoiler alert) when we talk about URLSession's reliability issues for WebSockets.
Starscream is fully open-source up to its usage of CFNetwork calls, so it's possible to make changes if you need. It's also possible to use URLSession underneath for supported systems, but that's not enabled by default.
PS: Technically, CFNetwork and URLSession are open-source, but you're not meant to compile your version of them for production use in Apple platforms, so it doesn't count.
Since Starscream is not shipped with Apple's operating systems, including it in your project will cause an increase in your binary size of about 500kb. That is not terrible for regular apps but could be a real issue for size-restrictive targets such as the new App Clips.
Since the release of URLSession support for WebSockets in 2019, the Starscream repository has seen a steady decrease in activity with many unanswered issues and pull requests. The last commit merged in August 2020. That is a sign that if you run into bugs or need a new feature, it could be a dead-end unless you handle it yourself. However, it's still too soon to say the project is completely unmaintained.
URLSession is Apple's high-level networking library for HTTP(S) requests. To be more precise, URLSession is a class that's part of the Foundation library. It coordinates a group of related network data-transfer tasks, and, as of iOS 13 and macOS 10.15, it supports WebSockets as one of those tasks (URLSessionWebSocketTask).
Using URLSession in your app will not cause any noticeable increase in your final binary size since it's part of the system's Foundation library. When you need to optimize for size, such as when building an App Clip, URLSession is your library of choice!
Maintained By Apple
Apple maintains URLSession, and it should receive regular updates for the foreseeable future. However, you can only take advantage of these by installing new operating system patches, which not all your users will do. You can also ask for support directly from Apple if you are enrolled in their paid developer program.
No Legacy Support
URLSession only received WebSockets support in 2019 when iOS 13 and macOS 10.15 were released—as such, using it for Web Sockets will restrict your app to those versions and up.
URLSession is closed-source, so it's impossible to make any changes to the underlying implementation if you need them. Again, using a looser definition of closed-source, since technically you can get the source code on GitHub, but it's not viable to compile your version of it for Apple platforms.
Unreliability & Crashes
It's to be expected that a function developed not long ago still presents rough edges. If you search the web for "URLSessionWebSocketTask crash" or "URLSessionWebSocketTask bug", you'll find many instances on StackOverflow and even Apple's forums of developers reporting crashes and other issues.
Which You Should Choose
Given that URLSession has implemented support for WebSockets relatively recently, it's not currently as reliable as Starscream, which existed for years before the URLSession implementation. Many projects that migrated from Starscream to URLSession reported mysterious bugs and crashes. Reliability alone gives Starscream the top spot among Swift WebSocket libraries. But keep on reading, there are other things to consider.
When Apple fixes the reliability issues, the most defining point in choosing these libraries will be legacy support. If your app needs to support system versions lower than iOS 13 / macOS 10.15, your best bet will be to use Starscream. If your app only supports those versions and up, it will be better to take advantage of the native URLSession framework and Apple's extended support of it.
For App Clips, URLSession is currently preferred due to Starscream's 500kb binary size impact. With just a little bit of luck, you might escape its reliability issues.
- Keeping Public API in Check With the Kotlin Binary Validator Plugin
- macOS Performance Comparison: Flutter Desktop vs. Electron
- Clean Chat Example App with Jetpack Compose
- React Native: How To Build Bidirectional Infinite Scroll
- Activity Feed Personalization 101: Top Feed Features to Improve User Engagement
- Flutter vs React Native: The Ultimate Comparison