visit
app built in Swift. It’s open source and uses the Rust library to privately share TCP or HTTP services from your Mac with your friends over End-to-End Encrypted Ockam Portals. A shared service appears on their localhost!
brew install build-trust/ockam/portals
On the Swift side, we could have called the C APIs directly, but C data structures are not first class citizens in Swift. This makes them harder to use idiomatically within SwiftUI code. Instead, we chose to duplicate the data structures in Swift and convert between C and Swift. This may seem burdensome, but practically, the shared state doesn't change very often. The ability to quickly build components in SwiftUI using constructs like if let ...
, ForEach
, enum
etc. is super helpful and worth the tradeoff.
// Rust idiomatic structure
#[derive(Default, Clone, Debug, Eq, PartialEq)]
pub struct LocalService {
pub name: String,
pub address: String,
pub port: u16,
pub shared_with: Vec<Invitee>,
pub available: bool,
}
// Rust C-compatible structure
#[repr(C)]
pub struct LocalService {
pub(super) name: *const c_char,
pub(super) address: *const c_char,
pub(super) port: u16,
pub(super) shared_with: *const *const Invitee,
pub(super) available: u8,
}
// Generated C header structure
typedef struct C_LocalService {
const char *name;
const char *address;
uint16_t port;
const struct C_Invitee *const *shared_with;
uint8_t available;
} C_LocalService;
// Swift idiomatic structure
class LocalService {
let name: String
@Published var address: String?
@Published var port: UInt16
@Published var sharedWith: [Invitee]
@Published var available: Bool
}
VStack(alignment: .leading, spacing: 0) {
Text(service.sourceName).lineLimit(1)
HStack(spacing: 0) {
Image(systemName: "circle.fill")
.font(.system(size: 7))
.foregroundColor( service.enabled ? (service.available ? .green : .red) : .orange)
if !service.enabled {
Text(verbatim: "Not connected")
} else {
if service.available {
Text(verbatim: service.address.unsafelyUnwrapped + ":" + String(service.port))
} else {
Text(verbatim: "Connecting")
}
}
}
...