paint-brush
Şifreli Portallar: Rust Kullanan Swift Uygulamasını Nasıl Oluşturdukile@ockam
10,773 okumalar
10,773 okumalar

Şifreli Portallar: Rust Kullanan Swift Uygulamasını Nasıl Oluşturduk

ile Ockam5m2024/01/01
Read on Terminal Reader

Çok uzun; Okumak

Swift'de yerleşik Mac için Portals uygulamasının, hizmetleri Uçtan Uca Şifrelenmiş Portallar üzerinden arkadaşlarınızla özel olarak paylaşmak için Ockam Rust kitaplığını nasıl kullandığını öğrenin.
featured image - Şifreli Portallar: Rust Kullanan Swift Uygulamasını Nasıl Oluşturduk
Ockam HackerNoon profile picture
0-item
1-item

Portals, Swift'te yerleşik bir Mac uygulamasıdır . Açık kaynaktır ve Uçtan Uca Şifrelenmiş Ockam Portalları üzerinden Mac'inizdeki TCP veya HTTP hizmetlerini arkadaşlarınızla özel olarak paylaşmak için Ockam Rust kitaplığını kullanır. Yerel ana bilgisayarlarında paylaşılan bir hizmet görünüyor!


Bu yazıda SwiftUI macOS uygulamasının Rust koduyla nasıl etkileşime girdiğini inceleyeceğiz.


Merak ediyorsanız Mac için Portals'ı deneyin. Bu makalede bunun hakkında daha fazla bilgi edinebilir ve Homebrew'u şu şekilde kullanarak kurulum yapabilirsiniz:


 brew install build-trust/ockam/portals


İşte uygulamanın çalışır haldeki 2 dakikalık videosu:

Hızlı <> Pas

Portallar işlevi Ockam Rust kütüphanesinde zaten uygulanmıştı. Harika bir macOS yerel deneyimi yaratmak için yola çıktık.


Uygulamayı oluşturmaya yönelik ilk girişimimiz Tauri'yi kullanmaktı. Ockam'ın pas kütüphanesini kullanmak istediğimiz için bu mantıklıydı ve ekibimizdeki çoğu kişi Rust'ta bir şeyler oluşturma konusunda rahat. Bu ilk sürümün oluşturulması kolaydı ve istediğimiz tüm temel işlevlere sahipti. Ancak uygulamayı kullanma deneyimi pek iyi değildi. Tauri bize menünün nasıl oluşturulduğu ve kullanıcı menüyle etkileşime girdiğinde ne olduğu konusunda minimum düzeyde kontrol sağladı. Uygulamanın bu sürümü, macOS Sonoma'da yerleşik, kullanımı son derece kolay menü çubuğu öğeleriyle karşılaştırıldığında, macOS'un 10 yıllık bir sürümüne aitmiş gibi geldi.


İstediğimiz zengin deneyime sahip olmak için uygulamayı SwiftUI kullanarak oluşturmamız gerektiğini fark ettik.


Ne yazık ki Swift ve Rust'u entegre edecek, bize her iki dünyanın da en iyisini verecek hazır bir çözüm bulamadık; Rust'un güvenliği ve SwiftUI'nin zengin macOS yerel deneyimi. Biraz daha kazı yaptıktan sonra ikisini C-89 kullanarak bağlayabileceğimizi fark ettik. Rust, C çağırma kuralıyla uyumludur ve Swift, C-89'un bir üst kümesi olan Objective-C ile birlikte çalışabilir.


Swift ve Rust nasıl iletişim kurar?



Swift'in iki kere görünür olması gereken Rust veri yapılarını yazdık. Bir versiyon Rust'ta deyimseldir ve kullanımı kolaydır. Diğer sürüm, malloc ile manuel olarak tahsis edilen işaretçileri ve belleği kullanan C uyumludur. Ayrıca, deyimsel veri yapılarını C uyumlu sürümlerine dönüştürmek için güvenli olmayan paslanmada ham işaretçiler kullanan bazı C uyumlu API'leri de açığa çıkardık. Son olarak cbindgen kütüphanesinin yardımıyla otomatik olarak bir C başlığı oluşturduk.


Swift tarafında C API'lerini doğrudan çağırabilirdik ama Swift'de C veri yapıları birinci sınıf vatandaşlar değil. Bu onların SwiftUI kodunda deyimsel olarak kullanılmasını zorlaştırır. Bunun yerine Swift'deki veri yapılarını çoğaltmayı ve C ile Swift arasında dönüştürmeyi seçtik. Bu külfetli görünebilir ancak pratikte paylaşılan durum çok sık değişmez. if let ... , ForEach , enum vb. yapıları kullanarak SwiftUI'da bileşenleri hızlı bir şekilde oluşturma yeteneği son derece faydalıdır ve ödün vermeye değerdir.


İşte aynı yapının 4 formundaki bir örneği:


 // 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 uygulaması derleme zamanında Rust kütüphanemize statik olarak bağlıdır. Veri akışı basittir: Kullanıcı arayüzü etkileşimleri Swift'den Rust'a C API'leri çağrılarak eylemler olarak gönderilir, değişiklik olayları yalnızca Rust tarafından yayınlanır ve Swift, kullanıcı arayüzünde güncellemelere yol açan geri aramalar kullanılarak bilgilendirilir.


SwiftUI görünümlerindeki çoğu kod diğer SwiftUI uygulamalarına benzer.


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


Daha fazlasını öğrenmek istiyorsanız ockam_app_lib kasasının koduna ve Swift'deki Portallar uygulamasına göz atın. Swift klasöründeki Makefile, her şeyin nasıl oluşturulduğunu ve birbirine bağlandığını keşfetmek için de iyi bir yerdir.


Mac'in Swift veya Rust kodu için Portallara katkıda bulunmak istiyorsanız, her hafta yeni iyi ilk sayılar ekliyoruz ve yeni katkıda bulunanlara yardımcı olmayı seviyoruz. Katkıda bulunanların anlaşmazlığında bize katılın.


Ayrıca burada görünür.