Using NSData::compressed() on Linux Swift

Hello there, new to this forum and not sure if this is the right section. Apologies if it isn't!

I'm currently trying to write a server-side Swift WebSockets backend using Vapor, and I'm trying to compress/decompress all my messages.

My code

let compressedData = try Data(referencing: NSData(data: data).compressed(using: .lzfse))

compiles fine on Darwin, but gives this error when I compile on my Ubuntu server.

error: value of type 'NSData' has no member 'compressed'

The same occurs for NSData's decompressed method.

Any idea how I can get them to compile on Linux?

Ubuntu 18.04
Swift version 5.3.3 (swift-5.3.3-RELEASE)
Target: x86_64-unknown-linux-gnu

My swift on Darwin is:
Apple Swift version 5.3.2 (swiftlang-1200.0.45 clang-1200.0.32.28)
Target: x86_64-apple-darwin20.2.0

EDIT:
I've also tried using .zlib instead of .lzfse, in hopes that something that is more cross-platform might fix the issue, but nope: the same issue still occurs.

So this has annoyed me in the past. The short of it is Data on Apple platforms is actually bridged NSData, located in the ObjC Foundation framework. The Swift.Foundation module is a completely different thing that mirrors the API surface.

There's also no apparent way to explicitly import Swift.Foundation on Apple device to ensure you're building portable code. I mean there could be but I couldn't figure it out.

Apple's Compression framework is probably where the extensions for NSData come from and it doesn't appear to be part of the Swift project; it's closed source. You'll need to import a Linux platform library that handles data compression. Or create your own systemLibrary package if Swift doesn't expose one.

Unless there's another Swifty way to do it, but I'm not aware of any atm.

2 Likes

This looks interesting. I only breezed over it but it appears to be what you would want.
tsolomko/SWCompression: A Swift framework for working with compression, archives and containers. (github.com)