Project Icon

cacao

Rust绑定库 简化macOS和iOS原生应用开发

cacao是一个为AppKit和UIKit提供Rust绑定的开源库,旨在简化macOS和iOS原生应用开发。它支持窗口、视图、控制器等UI组件,并提供自动布局和WebView等功能。该库为熟悉Swift或Objective-C的开发者提供类似的编程体验,同时发挥Rust的优势。尽管处于早期阶段,cacao已可用于部分应用开发,并提供多个示例辅助开发者学习。

Cacao

这个库为macOS上的AppKit(测试版,相当可用)和iOS/tvOS上的UIKit(内测版,详见仓库)提供了安全的Rust绑定。 它尝试以一种方式实现,如果你之前用Swift或Objective-C编程过这个框架,会感到熟悉。由于Rust的所有权模型,这在Rust中很棘手,但一些创造性的编码和假设可以让我们走得很远。

这个库存在于crates.io上,部分原因是为了让项目得到更广泛的使用,从而为开发提供参考。话虽如此,这个库目前还处于早期阶段,可能存在bug - 使用它的风险由你自己承担。然而,只要你遵循规则(关于内存/所有权),它已经可以用于一些应用程序了。核心仓库有大量示例可以帮助你入门。

重要

如果你从0.2版本迁移到0.3版本,你应该在Cargo.toml中选择appkituikit作为特性。这个改变是为了支持不仅仅是macOS/iOS/tvOS的平台(例如,gnustep, airyx)。这些特性中的一个是必需的;为了便于开发,默认选择了appkit

请注意,这个crate依赖于Objective-C运行时。与运行时交互需要unsafe代码块;这个crate为你处理了那些不安全的交互,并提供了一个安全的包装器,但使用这个crate意味着你理解unsafe的使用是必然的,并且在包装的控件中会相当普遍。这并不意味着你不能评估、审查或质疑unsafe的使用 - 只是要知道它正在发生,而且在很大程度上它不会消失。仅仅涉及unsafe存在的问题将被关闭,不予评论。

如果你想在本地机器上构建这个库的文档,由于特性标志与cargo doc的工作方式,你需要使用以下命令:

RUSTDOCFLAGS="--cfg docsrs" cargo +nightly doc --all-features --open

Hello World

use cacao::appkit::{App, AppDelegate};
use cacao::appkit::window::Window;

#[derive(Default)]
struct BasicApp {
    window: Window
}

impl AppDelegate for BasicApp {
    fn did_finish_launching(&self) {
        self.window.set_minimum_content_size(400., 400.);
        self.window.set_title("Hello World!");
        self.window.show();
    }
}

fn main() {
    App::new("com.hello.world", BasicApp::default()).run();
}

更多详细示例,请查看examples/文件夹。

如果你对更全面的"厨房水槽"示例感兴趣,可以通过以下命令查看todos_list:

cargo run --example todos_list

初始化

由于AppKit和UIKit程序通常的工作方式,我们鼓励你从AppDelegatedid_finish_launching()方法开始进行大部分工作。这确保了应用程序有时间初始化并在后台进行任何必要的内务处理。

当前支持

就大部分可工作的部分而言,下表展示了对各种功能的支持级别。这个列表并不详尽,仅仅是因为更新文档是一件麻烦事 - 所以我们鼓励你查看代码生成的文档以获取更多信息:

注意,虽然iOS有绿色对勾,但一些组件仍然没有很好地定义(例如,Views/ViewControllers在那里仍然处于非常初级的阶段)。

提供AppKit形式或替代品的非苹果平台可能能够使用这个库中的大部分AppKit支持。

组件描述AppKitiOStvOS
App初始化和事件
Window构建、处理、事件
View构建、样式、事件
ViewController构建、生命周期事件
Color系统支持的颜色、主题
ListView可重用列表,带缓存行
Button样式、事件、工具栏支持
Label/TextField文本渲染和输入
Image/ImageView加载、绘制等
Toolbar基本原生工具栏
SplitViewController分割视图(兼容Big Sur)
WebViewWKWebView的包装器
UserDefaults持久化小数据
Autolayout适应不同屏幕的视图布局

可选特性

以下是可以启用或禁用的Cargo特性列表。

  • appkit:链接AppKit.framework
  • uikit:链接UIKit.framework(仅限iOS/tvOS)。
  • cloudkit:链接CloudKit.framework并提供一些CloudKit功能的包装器。目前功能尚不完整。
  • color_fallbacks:为较旧的系统提供不存在systemColor类型的后备颜色。这个特性非常少见,你可能不需要它。
  • quicklook:链接QuickLook.framework并提供生成文件预览图像的方法。
  • user-notifications:链接UserNotifications.framework并提供在macOS和iOS上发送通知的功能。注意,这要求你的应用程序进行代码签名,否则无法工作。
  • webview:链接WebKit.framework并提供由WKWebView支持的WebView控件。这个特性在tvOS上不支持,因为该平台没有webview控件。由于WKWebView控件和非苹果平台上的不同支持,这个特性可能也只支持macOS/iOS。
  • webview-downloading-macos:通过私有接口启用从WebView下载文件的功能。这不是一个App Store安全的特性,所以在启用之前要注意这一点。这个特性在iOS上不支持(用户会以非常不同的方式处理下载),在tvOS上也不支持(那里根本没有网络浏览器)。

一般说明

为什么不扩展现有的cocoa-rs crate?
这是一个好问题。归根结底,我认为那个crate(如果我理解错了,请纠正我)在某种程度上与Servo绑定,而我想尝试在Rust中表示Cocoa UI模型的最佳方法。这个crate也并非完全忽视了他们的工作 - 内部使用并重新导出了core_foundationcore_graphics以供一般使用。 为什么我应该使用Rust编程,而不是X语言?

就我而言,我希望能够为我的设备(以及我喜欢为之构建产品的平台)编写原生应用程序,而不必局限于使用苹果特定的语言...也不必使用C/C++或JavaScript(注:指的是工具链,而非语言本身 - ES6/TypeScript是可以的)。我之所以想这样做,是因为我厌倦了每次想要将应用程序移植到其他生态系统时都要面对大量工作。我认为Rust提供了一个(正在成长但已相当重要的)可行模式,可以在不牺牲性能的情况下跨平台和生态系统共享代码。

(这里通常会引发互联网上关于Electron、Qt等的激烈讨论 - 我们在此不再赘述,因为这个话题已经被讨论得很透彻了)

这个crate对那些不需要完全投入苹果生态系统,但希望相对轻松地将其工作移植到该平台的人来说是有用的。我们并不期望所有人都会突然想用Rust重写他们的macOS/iOS/tvOS应用。

Objective-C是否已经过时了? 是,也不是。

诚然,苹果确实更青睐Swift,这是有充分理由的(我作为一个毫不掩饰的Objective-C爱好者也这么说)。话虽如此,我会感到惊讶如果我们没有至少5年以上的支持;苹果虽然很快就会弃用旧技术,但完全移除Objective-C运行时需要大量的时间和精力。也许SwiftUI会终结它,谁知道呢。围绕这些内容的包装器应该可以在将来需要更换底层UI后端时更容易地进行切换。

需要注意的一点是,苹果已经开始发布仅支持Swift的框架。对于需要使用这些框架的情况,应该可以通过某种链接和桥接的组合来实现 - 这将为未来某个时候如何切换底层UI后端提供参考。

有些人可能会谴责Objective-C速度慢。对此,我想指出以下几点:

  • 你的UI引擎可能不是性能瓶颈。
  • Swift通常更好,因为它修复了Objective-C无法捕获的一类bug;大多数情况下,它仍然建立在现有的Cocoa框架之上(尽管这种说法可能很快就会过时)。
  • Objective-C中的消息分发比你编写的大部分代码都要优化得更好,对大多数情况来说已经足够快了。

简而言之,它可能已经足够好了,而且你可以使用Rust来满足性能需求。

为什么不直接包装UIKit,然后依赖Catalyst? 我还没有见过一个使用Catalyst感觉良好的应用程序。不过,这个目标是好的,如果它发展到看起来就是未来的方向(比如,苹果直接终止AppKit),那当然是一个选择。

你不可能在这里包装所有平台特定的行为... 没错!每个UI控件都包含一个objc字段,你可以将其用作逃生舱 - 如果控件不支持某些功能,你可以自由地降级到Objective-C运行时并自行处理。

为什么你不使用绑定来自动生成这些内容? 出于初步探索的目的,我主要是手动完成这些工作的,因为我想在投入绑定生成之前找到一种适合Rust模型的方法。现在我已经让东西"运行"得足够好了,这可能是我下一步要关注的重点。

这与Swift项目Cacao有关吗? 没有。这个问题中提到的项目旨在将Cocoa和UIKit的部分内容映射到Linux上运行,但已经有一段时间没有活动了(它确实很酷!)。

2020年的开源项目命名就像试图购买一个.com域名:所有好名字都被占用了。幸运的是,多个项目可以共享一个名称...所以这里就会出现这种情况。

这是不是有点欺骗Rust的对象模型? 这取决于你如何看待它。我个人并不太在意 - 对于某些类型的产品来说,这些平台的GUI层是一个硬性要求,放弃它们也意味着放弃了经过实战检验的工具,用于处理诸如无障碍性和更深层次的操作系统集成等问题。话虽如此,内部确实在努力尝试让事物尊重Rust的工作模型。

你可以把这看作类似于gtk-rs。如果你想支持或尝试一个更"纯粹"的模型,可以去看看Druid之类的项目。:)

许可证

采用MIT/MPL-2.0双重许可。有关更多信息,请参阅本仓库中的相应文件。Apple、AppKit、UIKit、Cocoa和其他商标是Apple, Inc.的版权。

问题、评论等

你可以在Twitter上关注我,或者通过电子邮件与我联系,讨论那些不适合作为issue提出的问题。

项目侧边栏1项目侧边栏2
推荐项目
Project Cover

豆包MarsCode

豆包 MarsCode 是一款革命性的编程助手,通过AI技术提供代码补全、单测生成、代码解释和智能问答等功能,支持100+编程语言,与主流编辑器无缝集成,显著提升开发效率和代码质量。

Project Cover

AI写歌

Suno AI是一个革命性的AI音乐创作平台,能在短短30秒内帮助用户创作出一首完整的歌曲。无论是寻找创作灵感还是需要快速制作音乐,Suno AI都是音乐爱好者和专业人士的理想选择。

Project Cover

有言AI

有言平台提供一站式AIGC视频创作解决方案,通过智能技术简化视频制作流程。无论是企业宣传还是个人分享,有言都能帮助用户快速、轻松地制作出专业级别的视频内容。

Project Cover

Kimi

Kimi AI助手提供多语言对话支持,能够阅读和理解用户上传的文件内容,解析网页信息,并结合搜索结果为用户提供详尽的答案。无论是日常咨询还是专业问题,Kimi都能以友好、专业的方式提供帮助。

Project Cover

阿里绘蛙

绘蛙是阿里巴巴集团推出的革命性AI电商营销平台。利用尖端人工智能技术,为商家提供一键生成商品图和营销文案的服务,显著提升内容创作效率和营销效果。适用于淘宝、天猫等电商平台,让商品第一时间被种草。

Project Cover

吐司

探索Tensor.Art平台的独特AI模型,免费访问各种图像生成与AI训练工具,从Stable Diffusion等基础模型开始,轻松实现创新图像生成。体验前沿的AI技术,推动个人和企业的创新发展。

Project Cover

SubCat字幕猫

SubCat字幕猫APP是一款创新的视频播放器,它将改变您观看视频的方式!SubCat结合了先进的人工智能技术,为您提供即时视频字幕翻译,无论是本地视频还是网络流媒体,让您轻松享受各种语言的内容。

Project Cover

美间AI

美间AI创意设计平台,利用前沿AI技术,为设计师和营销人员提供一站式设计解决方案。从智能海报到3D效果图,再到文案生成,美间让创意设计更简单、更高效。

Project Cover

AIWritePaper论文写作

AIWritePaper论文写作是一站式AI论文写作辅助工具,简化了选题、文献检索至论文撰写的整个过程。通过简单设定,平台可快速生成高质量论文大纲和全文,配合图表、参考文献等一应俱全,同时提供开题报告和答辩PPT等增值服务,保障数据安全,有效提升写作效率和论文质量。

投诉举报邮箱: service@vectorlightyear.com
@2024 懂AI·鲁ICP备2024100362号-6·鲁公网安备37021002001498号