Speedify SDK


This SDK lets you build the Speedify VPN engine right into your own iOS app.

Getting Started

To get started copy the sample project SpeedifySDK to the directory you wish to run it in.

A few provisioning profiles are needed in order to run the sample application and integrate the SDK into your app. For the sample application, first go to Apple Developer and create the following two App IDs, replacing com.mycompany with a domain you associate with your Developer Program:

com.mycompany.SpeedifySampleApp com.mycompany.SpeedifySampleApp.PacketTunnel

For the SDK, first create the App ID, again replacing com.mycompany with your Developer Program domain and replacing myapp with your application name:


And then create a provisioning profile for this new App ID, again including the NetworkExtension entitlements if you have them.

Important note: You must run the app on a device and not on a simulator.

After your profiles are set up, open with Xcode and press run. Upon opening the app you will be requested to give VPN Permissions. The SDK will not run without these permissions. Once permissions are granted you will be presented with a list of command buttons. If you wish to change the directory URL please to do that first.

All users will start out in a logged out state. You will need to log in to perform the majority of the commands. If you need a Speedify license when running the sample application please contact support@speedify.com

Connect via Settings app

In order for the VPN to connect from the iOS settings application, the SDK needs to know if the UI is in the foreground or background. To accomplish this just ensure you have setup App Groups. Then set a key in your info.plist <key>NSExtensionFileProviderDocumentGroup</key> <string>YOUR APP GROUP NAME</string>.

API Docs

The API Documents are provided as convenient HTML in the docs/index.html directory.


The use of this SDK is dependent on you having a licensing agreement with Connectify, Inc.

This SDK uses a number of third party, open source libraries. Information on them and their licenses can be found here.


We are here to support our developers! If you have any issues, questions or concerns, please email us at support@speedify.com


Speedify 13.3

  • New Error type device_limit when an account has reached it’s device limit

Speedify 13.2

  • New calls to globally enable or disable all local proxy domain watchlist entries func setLocalProxyGlobalDomainWatchlistEnable(watchlistEnabled: Bool)and reset back to defaults func resetLocalProxyDomainWatchlist()

Speedify 13.1.1

  • Stability release

Speedify 13.1

  • Many settings are now reset when a logout() is issued

Speedify 13.0.3

  • Stability release

Speedify 13.0.2

  • Stability release

Speedify 13.0.1

  • Stability release

Speedify 13.0

  • We now use AES256 for encryption, instead of AES128.

Speedify 12.8.0

  • Added the ulpReportInvervalSeconds setting to represent the ULP reporting interval in seconds.
  • Added the setUlpReportIntervalSeconds function to control the ulpReportInvervalSeconds setting.

Speedify 12.7.0

  • Added NONE, for cases when there is nothing to report, to the disconnect reasons.

Speedify 12.6.0

  • New connect method IGNORELAST will choose a server other than the last used server using the current selection setting.

Speedify 12.5.1

  • Support for Safebrowsing dynamic library. Safebrowsing functions were removed from the Speedify SDK API and added to a separate Cujo SDK framework.
  • The following functions were removed:
    • startSafeBrowsing
    • stopSafeBrowsing
    • initSafeBrowsing
    • setSafeBrowsingConfig
    • setSafeBrowsingEnabled
    • setSafeBrowsingLogLevel
    • setSafeBrowsingSafeNetworkOverride
    • refreshSafeBrowsingToken
    • reportSafeBrowsingHomeNetwork
    • updateSafeBrowsingExtraInfo was already deprecated and removed completely’
    • refreshSafeBrowsing
    • refreshSafeBrowsingStats
    • safeBrowsingSettingsDidUpdate
    • safeBrowsingSettingsStatsDidUpdate
    • safeBrowsingLookupErrorReported
    • safeBrowsingConnectErrorReported
    • safeBrowsingBlockReported
    • requestedSafeBrowsingTokenRefresh

Speedify 12.5


Version call in now static and can be access without the SDK running

Speedify 12.4.1


Bug Fixes

Speedify 12.4

  • Adapters now support AUTOMATIC connection priorities, where Speedify will manage the priority based on the dynamically discovered connection type. This feature is enabled via enableAutomaticConnectionPriority.
  • AdapterData has 2 new fields:
    • workingPriority - the priority the adapter is functioning under
    • isp - the discovered Internet Service Provider of the connection

Speedify 12.3

The ConnectionStats field protocolUsed is now available on historic tunnel stats.

Speedify 12.2

Speedify 12.0

  • Set overflow threshold for active priority traffic via setPriorityOverflowThreshold

Speedify 11.9.4

  • No new features. This is a stability release.

Speedify 11.9

  • Fixes around setting public func setAllowTunnelBypass

Speedify 11.8

  • SDK now takes an app name parameter to identify your app on the server side. This may be set manually via setAppName(appName: String). This must be called before any login method.
  • Generate logs will now return immediately if the extension is not connected
  • New property vpnManager which will return the current instance of NEVPNManager


Bug fix when starting the tunnel that may cause it to stop and restart

Speedify 11.7

  • No new features. This is a stability release.

Speedify 11.6

  • No new features. This is a stability release.

Speedify 11.5.1

  • No new features. This is a stability release.

Speedify 11.5

  • New Types.StreamStats, giving an indication of how well the stream is performing.
  • New Types.StreamingStats fields:
    • Types.StreamingStatsbadLoss
    • Types.StreamingStatsbadLatency
    • Types.StreamingStatsbadMemory
  • New Types.ConnectionStats fields:
    • Types.ConnectionStats.jitterMs
    • Types.ConnectionStats.mos

Speedify 11.4

  • Fix type on Types.ConnectionStats.lossReceive and Types.ConnectionStats.lossSend

Speedify 11.3

  • Updated Captive portal functionality

Speedify 11.2.3

  • No new features. This is a stability release.

Speedify 11.2.1

  • No new features. This is a stability release.

Speedify 11.2

  • New Full IPv6 support through the tunnel, including firewall and local proxy including functions setLocalProxyIPv6
  • New ability to subscribe to events in the extension enableEventUpdates. Currently only streamingStats is supported

Speedify 11.0.1

  • New function func setOnDemandWithRules(with onDemandRules:[NEOnDemandRule]?, onDemandEnabled: Bool) to allow onDemand rules to be set on the fly.
  • New property var lastDisconnectReason: DisconnectReason? so a user can read the last disconnect reason without the need for a delegate.

Speedify 11.0

  • New property daemonMessagingIsReady can be used to signal when the extensions daemon is ready for messaging.
  • New notification readyDaemon can be used to be notified when the extensions daemon is ready for messaging.
  • New function to start the daemon inside of the PacketTunnel. func runDaemon(in port: Int, provider: NEPacketTunnelProvider, options: [String : NSObject]?, connectWithHandler: Bool, completionHandler: @escaping (Error?)-> Void), this new function intakes the options set by the containing app so users no longer need to support App Groups for SDK purposes.
  • Deprecated func runDaemon(in port: Int, provider: NEPacketTunnelProvider, connectWithHandler: Bool, completionHandler: @escaping (Error?)-> Void)
  • New simple speed test. This runs an iPerf3 speed test for 10 seconds in both directions over the VPN tunnel. Use startSpeedTest to initiate a new test. Results are provided via {@link com.speedify.speedifysdk.SpeedifyHandler#OnSpeedTestResults OnSpeedTestResults}. Results of prior tests can be retrieved with SpeedifySpeedTestResultsDelegate.
  • Change SafeBrowsingStats -> minTime went from a Double to an Int
  • Change SafeBrowsingStats -> maxTime went from a Double to an Int
  • Change SafeBrowsingStats -> avgTime went from a Double to an Int
  • Change SafeBrowsingStats -> numErrors went from a Double to an Int
  • Change SafeBrowsingStats -> numBlocks went from a Double to an Int

Speedify 10.9.5

Speedify 10.9

  • Deprecated - func loginOAuth(oauthAccessToken: String, serviceAccount: String, completionHandler:@escaping (_ error: ErrorType?)->Void) use func loginOAuth(oauthAccessToken: String, completionHandler :@escaping (_ error: ErrorType?)->Void)

  • Corrected documentation on Types.State.overlimit

  • Support for custom Stream settings. Types.StreamSettings. These can be set via Speedify.shared.setStreamingDomains, Speedify.shared.setStreamingIPv4,Speedify.shared.setStreamingIPv6 and Speedify.shared.setStreamingPorts. Use Speedify.shared.refreshStreamSettings to pull current settings.

  • New Types.DisconnectReason -> DisconnectReason.OVERQUOTA

  • Speed test calls have been removed

Speedify 10.8

  • The language used to for error messages can now be set with Speedify.shared.setLanguage

Speedify 10.7

  • Header compression now defaults to on.
  • Disconnect Reasons have been expanded to include TYPES.DisconnectReason.DNSTIMEOUT and TYPES.DisconnectReason.TUNNELTIMEOUT

Speedify 10.6

  • Deprecated : SpeedifyPacketTunnel.sharedInstance.runDaemon(in: 9330, provider: self, currentDefaults: myDefaults ?? UserDefaults.standard, connectWithHandler: connectWithHandler, completionHandler: completionHandler) ->
  • New: public func runDaemon(in port: Int, provider:NEPacketTunnelProvider, connectWithHandler: Bool, completionHandler: @escaping (Error?)-> Void) The call to runDaemon removes the need to pass in the defaults argument. Speedify will lookup the host plist for the key NSExtensionFileProviderDocumentGroup if one is provided the suite name will be used. If this key is not present a user will no longer be able to connect manually from the device settings application.
  • Calling logout will now reset your connect method to Types.AutoConnectMethod.closest.

Speedify 10.5

Speedify SDK now supports a centralized OAuth gateway for authentication. Setup the gateway URI with setDirectoryGatewayURI before logging in with loginOAuth.

  • Change -> Type Directory now includes new property gatewayUri.
  • Deprectaed PrivacySettings.crashReports
  • Log files and generated log zips may be deleted with eraseAllLogFiles. Note that the current active log file is not erased.

Speedify 10.4

  • Service account key will now be mandatory inside of the app’s info.plist. Please set <key>SpeedifyServiceAccount</key> <string>YOUR_SERVICE_ACCOUNT</string>. The service account is a unique key, specific to your app, to store a user’s UUID in the keychain. Here is an example of a service account string "MyExampleAppUUID". This will ensure the same UUID throughout app deletions and installations. It will assert during DEBUG if you forget to set its key. In production it will set a blank string and a user will be unable to authenticate or connect.
  • New AutoConnectMethod -> case proxy = "proxy"
  • New Type Directory
  • Deprecated setDirectoryDomain(domain: String, completionHandler:@escaping (_ domain: String)->Void) Use setDirectoryWithDomain(domain: String, completionHandler:@escaping (_ directory: Directory)->Void)
  • New setESNIEnabled(enable: Bool) - Sets if ESNI is used when talking to the directory domain
  • New SpeedifyDirectoryDomainDelegate
  • New SpeedifyLastDisconnectDelegate which has a function func disconnectEventDidUpdate(disconnectReason: DisconnectReason) to send back the last disconnected reason. DisconnectReason
  • New public func refreshLastDisconnectEvent() Get the last session disconnect event
  • Change func initializeVPNPermission(profile: String?,startTunnel: Bool, waitUntilConnected: Bool, completionHandler: @escaping (_ didSave: Bool, _ error: Error?)->Void) -> func initializeVPNPermission(profile: String?, onDemandRules: [NEOnDemandRule]?,startTunnel: Bool, waitUntilConnected: Bool, completionHandler: @escaping (_ didSave: Bool, _ error: Error?)->Void). Note: When initializing a VPN profile you may now pass an optional array of NEOndemand rules. Setting onDemandRules to nil will remove the onDemand toggle from the iOS settings app
  • New waitUntilConnected public Boolean. Setting to true will tell the sdk not to send any messages to the extension until it is fully connected. Defaults to false.

Speedify 10.3.1

  • No new features. This is a stability and performance release.

Speedify 10.3

  • No new features. This is a stability and performance release.

Speedify 10.2.1

  • VendorDataDelegate is now SpeedifyVendorUserDataDelegate.
  • func sessionPeriodStatsDidUpdate(sessionStats: SessionStatPeriods) -> func sessionPeriodStatsDidUpdate(sessionPeriodStats: SessionStatPeriods)
  • func firewallSettingsUpdated(settings:FirewallSettings) -> func firewallSettingsDidUpdate(settings:FirewallSettings)
  • Fixed typo inside of protocol SpeedifyLocalProxySettingsDelegate
  • public var stats: [ConnectionStats]? -> public var connectionStats: [ConnectionStats]?
  • vendorDataDelegate -> SpeedifyVendorUserDataDelegate
  • settingsLockDelegate -> settingsErrorDelegate
  • Removed func setCrashReporting(enable: Bool)

Speedify 10.2.0

  • Updated function runDaemon now takes a new parameter called Port which is used for websocket communication with the SpeedifySDK service

Speedify 10.1.1

  • @objc public func initializeVPNPermission now takes an optional string. You may also set the description inside of the plist with the key VPN Localized Description

Speedify 10.1.0

  • runDaemon now has a new paramter called connectWithHandler, this will open the VPN connection right away and a user will see the icon. This should default to false and only in rare circumstances be set to true.
  • initializeVPNPermission now has a new paramter called waitUntilConnected. If set to true it will wait until the Extension has fully connected before sending messages. Be sure to call runDaemon and set the connectWithHandler to match. This should default to false and only in rare circumstances be set to true.
  • checkForExit() has been removed and it is now up to the developer how they would like to close the tunnel when backgrounding. Please see the sample app for an example.
  • @objc public func connectAuto(connectOption: String) This function is meant for Objective-C implementations where a developer needs to call auto connect . It takes a string parameter. Please see AutoConnectMethod for those values.
  • @objc public func currentSpeedifyState() -> Int This function is meant for Objective-C implementations where a Swift object is unreadable. This will give the developer the current Speedify state as an Int. Please see State to get the enum values.
  • resetVpnProfile(startTunnel: Bool) will kick off permissions from the OS. The parameter startTunnel will bring up the extension if true.
  • tunnelWillStop now take’s an optional completionHandler and removes the reason parameter.

Speedify 10.0

Speedify 9.9

New Function

  • public func loginAutoAccount(completionHandler:@escaping (_ message: State?, _ error: ErrorType?)->Void)
  • The Local Proxy API now supports matching by TCP and UDP port: setLocalProxyPorts

Speedify 9.8

New Function

  • public func loginAutoAccount(completionHandler:@escaping (_ message: State?, _ error: ErrorType?)->Void)
  • The Local Proxy API now supports matching by TCP and UDP port: setLocalProxyPorts

Function changes

These all change a non-optional ErrorType to an option ErrorType?
  • public func connectAuto(connectOption: AutoConnectMethod, completionHandler:@escaping (_ serverInformation: ServerInformation?, _ error: ErrorType?)->Void)
  • public func connectByCity(country: String, city: String,completionHandler:@escaping (_ message: ServerInformation?, _ error: ErrorType?)->Void)
  • public func connectByCountry(country: String, completionHandler:@escaping (_ message: ServerInformation?, _ error: ErrorType?)->Void)
  • public func connectByServer(country: String, city: String, num: Int, completionHandler:@escaping (_ message: ServerInformation?, _ error: ErrorType?)->Void)
  • public func login(username: String, password: String, completionHandler:@escaping (_ message: State?, _ error: ErrorType?)->Void)
  • public func loginOAuth(oauthAccessToken: String, completionHandler:@escaping (_ error: ErrorType?)->Void)

Speedify 9.8

SDK now supports building with iOS Simulators.

setVendorUserData - can be used to provide a string of user data for an account.

StreamingStats has new property fields

  • totalRedundantSaves - Total number of redundant saves per session. Please see StreamStats.redundantSaves
  • totalSpeedSaves - Total number of speed saves per session. Please see StreamStats.speedSaves
  • totalStreams - Total number of streams per session
  • uniqueSaves - A stream can be saved multiple times, but the unique save count will only go up by one #### Function changes
  • func startTunnel() is now func startTunnel(shouldStart:Bool) pass in a bool to tell the SDK whether to start the tunnel or just ask permissions and save the profile. The default before this change was true. ### New Protocol *SpeedifyTunnelDelegate this allows a callback to trigger when a user denies permission or cannot save the profile. When these errors occur you MUST restart the tunnel by calling func startTunnel(shouldStart:Bool). Please see LoginViewController in the sample app for more information.

StreamStats has new property fields.

  • downloadSpeed - Download speed of the stream
  • averageDownloadSpeed - Average download speed of this stream, in megabits per second
  • averageUploadSpeed - Average upload speed of this stream, in megabits per second
  • groupID - Unique identifier of this stream
  • name - Name of app/service in use *redundantSaves - When a stream has switched to redundant mode
  • speedSaves - When the network speed dips below the speed of the stream and speedify bonds the connection for more speed

Speedify 9.7

  • No new features, this is a stability and performance release

Speedify 9.6

  • Speedify has a new Streaming Mode to better support video streamers. This can be set via setMode with BondingMode.streaming. Statistics on individual streams are available from refreshStreamingStats, and are provided once per second when enabling enableConnectionStatUpdates.

Speedify 9.5

  • Session stats in sessionPeriodStatsDidUpdate are now tracked over multiple time periods, including current session, last day, last week, last month, and total.

Speedify 9.3

  • The Local Proxy API now supports Domain Watchlists. Watchlists are lists of domains grouped by the service they represent, configurable via setLocalProxyDomainWatchlist. When an attempt to access a watched domain is seen,domainWatchListDelegate is triggered. setLocalProxyDomainWatchlistEnable can then be used to enable that service’s domains to be sent through the local proxy instead of the VPN

Speedify 9.2

  • Speedify SDK provides setLocalVendorSettings for saving a custom JSON object for later consumption.

Speedify 8.2

  • Port forwarding has been added. Call setForwardPorts to forward ports on a dedicated server to the client device.

Speedify 8.0.2

  • setExcludedIPRanges can be set to false to allow private IP ranges to be routed over the tunnel.

Speedify 7.5

  • serverInformationDidUpdate now sends a ServerInformation object with more information on the connect server..

Speedify 7.4

  • You can now set DNS servers used by the VPN via setDNSServers

Speedify 7.0

  • ConnectionStats now shows download and upload speeds, as well as download and upload maximum speed estimates for connections.

Speedify 6.3.4

  • New function func loginOAuth(oauthAccessToken: String) which allows clients to login with JWT.

Speedify 6.3

  • New PrivacySettings struct
  • New delegate function privacySettingsDidUpdate(privacy: PrivacySettings)
  • New function setReportingEncryptionKey(key128bit: String)

Speedify 6.2.1

Speedify 6.2

  • New function disableAdapterMonthlyDataLimit(adapterID: String)
  • New function disableAdapterDailyDataLimit(adapterID: String)

Speedify 6.1

  • New AccountingData struct
  • Deprecated - setUserUniqueID(uniqueID:String) please use loginAutoAccount()
  • New generateLogs method to help you send files from the Speedify Daemon *Require App Group Capabilities

Speedify 6.0

  • ValidationError is now ErrorType which gives you errors on login and when connecting to servers.
  • New property in the AdapterUsageData -> overlimitRatelimit
  • New functions for connecting now with an ErrorType parameter in the closure
  • New function setAdapterOverlimitRatelimit(adapterID: String, bps: Int64)
  • New function setUserUniqueID(uniqueID:String)
  • New Class UUIDProvider. This will help get a unique Id of the device

Speedify 5.9

  • You may now Enable or Disable use of ChaCha for connection encryption.
    • Just call func setChaChaEncrypted(encrypted: Bool) from the SpeedifySDK and listen for updates inside of the protocol func adapterDataDidUpdate(adapterData: [AdapterData])
  • New AdapterUsageData struct which gives information about the data usage and limits for a network adapter. You can watch for changes inside of the protocol func adapterDataDidUpdate(adapterData: [AdapterData]) which falls into a new property of the AdapterData struct named var dataUsage: AdapterUsageData
  • New Speedify Properties. Now you can simply refer to these referenced value types instead of subscribing to a protocol.
    • private(set) public var state: State?
    • private(set) public var version: Version?
    • private(set) public var adapterData: [AdapterData]?
    • private(set) public var serverInformation: ServerInformation?
    • private(set) public var settings: Settings?
    • private(set) public var stats: [ConnectionStats]?
  • Unit Testing. Navigate to SpeedifySDKTests.swift and change the username/password then inside of Xcode press cmd+u to start the tests.

Speedify 5.7.1 -> 5.8 Migration

5.7.1 5.8
ConnectionData AdapterData
ConnectionData.connectionID AdapterData.adapterID
ConnectionData.usageDaily AdapterUsageData.usageDaily
ConnectionData.usageMonthly AdapterUsageData.usageMonthly
NetworkState NetworkType
func setMode(mode: BondingMode,completionHandler:@escaping (_ message: [ConnectionData]?)->Void) func setMode(mode: BondingMode)
func setConnectionPriorities(connection: String, priority: ConnectionPriority, completionHandler:@escaping (_ message: SessionStats)->Void) func setConnectionPriorities(connection: String, priority: ConnectionPriority)
func setConnectionEncryption(connection: String, encrypt: Bool, completionHandler:@escaping (_ message: [ConnectionData]?)->Void) func setConnectionEncryption(adapterID: String, encrypt: Bool)
func setTunnelEncrypted(encrypted: Bool, completionHandler:@escaping (_ message: [ConnectionData]?)->Void) func setTunnelEncrypted(encrypted: Bool)
func setOverflowThreshold(bps: Double, completionHandler:@escaping (_ message: Dictionary<String, Any>)->Void func setOverflowThreshold(bps: Int64)
func addAdapterDailyDataLimitBoost(adapterID: String, additionalBytes: Double, completionHandler:@escaping (_ message: Dictionary<String, Any>)->Void) func addAdapterDailyDataLimitBoost(adapterID: String, additionalBytes: Int64)
func setAdapterDailyDataLimit(adapterID: String, allowedBytes: Double, completionHandler:@escaping (_ message: Dictionary<String, Any>)->Void) func setAdapterDailyDataLimit(adapterID: String, allowedBytes: Int64)
func setAdapterMonthlyDataLimit(adapterID: String, allowedBytes: Double, resetDay: Double, completionHandler:@escaping (_ message: Dictionary<String, Any>)->Void) func setAdapterMonthlyDataLimit(adapterID: String, allowedBytes: Int64, resetDay: Int64)

All rights reserved, Connectify, Inc.
Proprietary and Confidential