Native Apple TLS in sgcWebSockets: TLS 1.3 on iOS and macOS, No OpenSSL

· Components
Native Apple TLS in sgcWebSockets: TLS 1.3 on iOS and macOS, No OpenSSL

Shipping TLS in an iOS or macOS app built with Delphi or C++Builder used to mean bundling OpenSSL: a libssl.dylib and a libcrypto.dylib packaged with the app, version-matched and patched by you. sgcWebSockets removes that requirement. A new native TLS backend, iohAppleTLS, uses Apple's own TLS, so your app connects securely with no OpenSSL .dylib to deploy. It is available in the Enterprise edition.

Better still, on modern systems it gives you TLS 1.3. The backend auto-selects the best system API for the device, all behind a single setting, so you do not branch on OS version and your code stays the same everywhere.

One line to switch

The TLS backend is selected through TLSOptions.IOHandler. To use Apple's native TLS, set it to iohAppleTLS. The rest of your networking code does not change.

uses
  sgcWebSocket, sgcWebSocket_Types;

WSClient.TLS := True;
WSClient.TLSOptions.IOHandler := iohAppleTLS;
WSClient.URL := 'wss://www.esegece.com:2053';
WSClient.Active := True;

On other platforms you keep the backend that fits: iohOpenSSL works everywhere, iohSChannel is native on Windows, and iohAndroidTLS is the native, deploy-nothing option on Android. A small conditional keeps one client component correct on every target.

WSClient.TLS := True;
{$IF Defined(IOS) or Defined(MACOS)}
WSClient.TLSOptions.IOHandler := iohAppleTLS;     // native, no OpenSSL .dylib
{$ELSEIF Defined(ANDROID)}
WSClient.TLSOptions.IOHandler := iohAndroidTLS;   // native, no OpenSSL .so
{$ELSEIF Defined(MSWINDOWS)}
WSClient.TLSOptions.IOHandler := iohSChannel;     // native on Windows
{$ELSE}
WSClient.TLSOptions.IOHandler := iohOpenSSL;      // OpenSSL elsewhere
{$ENDIF}
WSClient.URL := 'wss://www.esegece.com:2053';
WSClient.Active := True;

No OpenSSL .dylib to deploy

With the native backend there is no OpenSSL to bundle, version-match or patch. The TLS stack ships with the operating system, so the app is leaner and free of a third-party crypto dependency. For App Store submissions this also means one less native library to justify, and your TLS policy follows Apple's rather than a library build you froze months ago. Security fixes arrive through OS updates.

TLS 1.3 with automatic fallback

The single iohAppleTLS setting picks the right system API per device. On macOS 10.14+ and iOS 12+ it uses Network.framework, which brings TLS 1.3. On older systems it falls back to Secure Transport, which tops out at TLS 1.2. You do not write any version checks, the backend selects the path and your code is identical on both.

A complete TLS client

This is a full client, not a trimmed-down one. It uses the system trust store, performs SNI and hostname verification, and exposes an OnAppleTLSVerifyPeer callback so you can inspect the certificate and accept or reject it yourself. You can trust a private authority with a custom CA root through RootCertFile, present a client certificate for mutual TLS with CertFile and Password, and advertise application protocols such as http/1.1 through ALPN.

WSClient.TLS := True;
WSClient.TLSOptions.IOHandler := iohAppleTLS;
WSClient.TLSOptions.VerifyCertificate := True;
WSClient.TLSOptions.ALPNProtocols.Add('http/1.1');
WSClient.TLSOptions.RootCertFile := '';   // optional custom CA (PEM/DER)
WSClient.TLSOptions.CertFile := '';       // optional client cert (PKCS#12) for mTLS
WSClient.TLSOptions.Password := '';       // client cert password
WSClient.OnAppleTLSVerifyPeer := DoVerifyPeer;  // optional custom validation
WSClient.Host := 'your.server.com';
WSClient.Port := 443;
WSClient.Active := True;

The verify-peer callback gives you the certificate subject and its SHA-256 fingerprint, the trust evaluation result, and an Accept flag you set to allow or block the connection. It is the natural place to pin a certificate or apply your own policy on top of the system trust decision.

Works with the components you already use

The backend sits behind the shared TLSOptions, so it is not limited to the WebSocket client. The TCP and HTTP/2 clients and the other components that expose TLSOptions select it the same way. If your code already configures TLSOptions, enabling native Apple TLS is a single assignment, with no change to how you connect or exchange data.

The same idea on Android

If you also target Android, the companion iohAndroidTLS backend does the same job there: it uses Android's own TLS through the platform SSLEngine, with no OpenSSL .so to deploy. The pattern is identical, you pick the native handler per platform. The details are on the Native Android TLS page.

Availability

Native Apple TLS (iohAppleTLS) ships in the Enterprise edition of sgcWebSockets. For the full breakdown of the four TLS backends, OpenSSL on every platform, SChannel on Windows, and the native Android and Apple handlers, see the SSL / TLS section and the Native Apple TLS page.

Download from the sgcWebSockets download page, or grab it through GetIt or your registered account.

Questions, feedback or help moving an iOS or macOS app off OpenSSL? Get in touch, you will get a reply from the people who wrote the code.