paint-brush
口令化されたポータル: Rust を实用する Swift アプリの作为形式 に@ockam
10,751 測定値
10,751 測定値

暗号化されたポータル: Rust を使用する Swift アプリの作成方法

Ockam5m2024/01/01
Read on Terminal Reader

長すぎる; 読むには

Swift に組み込まれた Portals for Mac アプリが Ockam Rust ライブラリを使用して、エンドツーエンドの暗号化ポータル経由で友人とサービスをプライベートに共有する方法。
featured image - 暗号化されたポータル: Rust を使用する Swift アプリの作成方法
Ockam HackerNoon profile picture
0-item
1-item

。これはオープン ソースであり、 Rust ライブラリを使用して、エンドツーエンドで暗号化された Ockam ポータルを介して Mac から友人と TCP または HTTP サービスをプライベートに共有します。共有サービスがローカルホストに表示されます。


この期刊投稿では、SwiftUI macOS アプリが Rust コードとどのように対話するかを詳しく説明します。


興味がある場合は、Portals for Mac を試してみてください。詳細についてはご覧ください。インストールは次のように Homebrew を选择して行われます。


 brew install build-trust/ockam/portals


アプリケーションの動作を示す 2 分間のビデオは次のとおりです。

スウィフト <> ラスト

ポータル機能は、Ockam Rust ライブラリにすでに実装されていました。私たちは、優れた macOS ネイティブ エクスペリエンスを弄成することに取り組みました。


アプリを構築する这一の試みは、Tauri を选用することでした。私たちは Ockam Rust ライブラリを选用したいと考えており、チームのほとんどのメンバーが Rust での構築に慣れているため、これは理にかなっています。この这一のバージョンは構築が簡単で、有必要な几乎機能がすべて備えられていました。ただし、アプリの选用感はあまり良くありませんでした。 Tauri は、メニューがどのようにレンダリングされるか、およびユーザーがメニューを控制したときに何が起こるかについて、世界上最大限の制御しか作为しませんでした。 macOS Sonoma に組み込まれている十分的に使いやすいメニューバー項目と比較すると、このバージョンのアプリは 10 年里のバージョンの macOS に属しているように感じられました。


私たちが望むリッチなエクスペリエンスを実現するには、SwiftUI を安全使用してアプリを構築する必要条件があることに気付きました。


残念ながら、Swift と Rust を統合する、両方の長所を生かした既製のソリューションは見つかりませんでした。 Rust の安全管理性と、SwiftUI のリッチな macOS ネイティブ エクスペリエンスです。さらに詳しく調べた結果、C-89 を采用して 2 つを接続できることがわかりました。 Rust は C 呼び出し規約と互換性があり、Swift は C-89 のスーパーセットである Objective-C と相互间運用很有可能です。


Swift と Rust の通信方法



Swift から見えるようにする有需要がある Rust データ構造を 2 回書きました。 1 つのバージョンは Rust で慣用的であり、使いやすいです。もう 1 つのバージョンは C と互換性があり、ポインターと malloc で手動で割り当てられるメモリを适用します。また、unsafe Rust で raw ポインターを适用して慣用的なデータ構造を C 互換バージョンに変換する、いくつかの C 互換 API も公開しました。最後に、cbindgen ライブラリを适用して C ヘッダーを自動的に转化しました。


Swift 側では、C API を直接呼び出すこともできましたが、C データ構造は Swift の第一級市民ではありません。これにより、SwiftUI コード内で慣用的に使用することが難しくなります。代わりに、Swift でデータ構造を複製し、C と Swift の間で変換することを選択しました。これは面倒に思えるかもしれませんが、実際には、共有状態はそれほど頻繁には変化しません。 if let ...ForEachenumなどの構造を使用して SwiftUI でコンポーネントをすばやく構築できる機能は非常に便利で、トレードオフの価値があります。


同じ構造の 4 つの类型の例を次に示します。


 // 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 }


Swift アプリはコンパイル時に Rust ライブラリに静的にリンクされます。データ フローはシンプルです。UI インタラクションは C API を呼び出すことによってアクションとして Swift から Rust に送信され、変更イベントは Rust によってのみ発行され、UI の更新系统につながるコールバックを运用して Swift に温馨提示されます。


SwiftUI ビュー内のほとんどのコードは、他の SwiftUI アプリケーションとまったく同じように見えます。


 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") } } } ...


さらに詳しく知りたい場合は、 クレートとのコードをチェックしてください。 Swift フォルダー内のすべてがどのように構築されリンクされているかを調べるのにも適した場所です。


の Swift または Rust コードに貢献することに興味がある場合は、毎週新しいを追加し、新しい貢献者を协防することに喜びを感じています。に参加者してください。


にも登場します。


바카라사이트 바카라사이트 온라인바카라