objc2/lib.rs
1//! # Objective-C interface and runtime bindings
2//!
3//! Quick links:
4//! - [All Topics][crate::topics].
5//! - [All examples].
6//! - [About framework crates][crate::topics::about_generated].
7//! - [List of framework crates][crate::topics::about_generated::list].
8//!
9#![doc = concat!("[All examples]: https://github.com/madsmtm/objc2/tree/objc2-", env!("CARGO_PKG_VERSION"), "/examples")]
10//!
11//! Objective-C was the standard programming language on Apple platforms like
12//! macOS, iOS, iPadOS, tvOS and watchOS. It is an object-oriented language
13//! centered around "sending messages" to its instances - this can for the
14//! most part be viewed as a function call.
15//!
16//! It has since been superseded by Swift, but most of the core libraries and
17//! frameworks that are in use on Apple systems are still written in
18//! Objective-C, and hence we would like the ability to interact with these
19//! using Rust. This crate enables bi-directional interop with Objective-C, in
20//! as safe a manner as possible.
21//!
22//!
23//! ## Example
24//!
25//! Most of the time, you'll want to use one of [the framework crates], which
26//! contain bindings to `CoreFoundation`, `Foundation`, `AppKit`, `Metal`,
27//! `UIKit`, `WebKit` and so on.
28//!
29//! In this example we're going to be using [`objc2-foundation`] and
30//! [`objc2-app-kit`] to create a simple GUI application that displays a
31//! "Hello World" label.
32//!
33//! ```console
34//! $ # Add the necessary crates to your project.
35//! $ cargo add objc2 objc2-foundation objc2-app-kit
36//! ```
37//!
38#![cfg_attr(target_os = "macos", doc = "```no_run")]
39#![cfg_attr(not(target_os = "macos"), doc = "```ignore")]
40#![doc = include_str!("../examples/hello_world_app.rs")]
41//! ```
42//!
43//! [the framework crates]: crate::topics::about_generated
44//! [`objc2-foundation`]: https://docs.rs/objc2-foundation
45//! [`objc2-app-kit`]: https://docs.rs/objc2-app-kit
46//!
47//!
48//! ## Crate features
49//!
50//! This crate exports several optional cargo features, see [`Cargo.toml`] for
51//! an overview and description of these.
52//!
53//! The features in the framework crates are described [here][cr-feat]. Note
54//! that if you're developing a library for others to use, you might want to
55//! reduce compile times by disabling default features and only enabling the
56//! features you need.
57//!
58#![doc = concat!(
59 "[`Cargo.toml`]: https://docs.rs/crate/objc2/",
60 env!("CARGO_PKG_VERSION"),
61 "/source/Cargo.toml.orig",
62)]
63//! [cr-feat]: crate::topics::about_generated::cargo_features
64//!
65//!
66//! ## Supported operating systems
67//!
68//! - macOS: `10.12-15.5`
69//! - iOS: `10.0-18.5` (including iPadOS and Mac Catalyst)
70//! - tvOS: `10.0-18.5`
71//! - watchOS: `5.0-11.5`
72//! - visionOS: `1.0-2.5`
73//!
74//! The minimum versions are the same as those supported by `rustc`. Higher
75//! versions will also work, but the framework crates will not have bindings
76//! available for newer APIs.
77//!
78//! The framework bindings are generated from the SDKs in Xcode 16.4. The
79//! Xcode version are updated usually within a week of [GitHub Actions]
80//! supporting the new Xcode version, and we try to schedule crate releases
81//! such that align fairly closely with Xcode updates. We only support stable
82//! Xcode versions.
83//!
84//! Note that the bindings are currently generated in a very macOS-centric
85//! manner, so they may try to use types from AppKit, even on iOS, see for
86//! example [#637](https://github.com/madsmtm/objc2/issues/637).
87//!
88//! The bindings _can_ also be used on Linux or *BSD utilizing the
89//! [GNUstep Objective-C runtime](https://github.com/gnustep/libobjc2), see
90//! the [`ffi`] module for how to configure this, but this is very much
91//! second-class.
92//!
93//! [GitHub actions]: https://github.com/actions/runner-images
94//!
95//!
96//! ## Minimum Supported Rust Version (MSRV)
97//!
98//! The _currently_ minimum supported Rust version is `1.71` (to be able to
99//! use `extern "C-unwind"` functions); this is _not_ defined by policy,
100//! though, so it may change in at any time in a patch release.
101//!
102//! Help us define a policy over in [#203].
103//!
104//! [#203]: https://github.com/madsmtm/objc2/issues/203
105
106#![no_std]
107#![cfg_attr(
108 feature = "unstable-autoreleasesafe",
109 feature(negative_impls, auto_traits)
110)]
111#![cfg_attr(
112 feature = "unstable-arbitrary-self-types",
113 feature(arbitrary_self_types)
114)]
115#![cfg_attr(
116 feature = "unstable-coerce-pointee",
117 feature(derive_coerce_pointee, trait_upcasting)
118)]
119// Note: `doc_notable_trait` doesn't really make sense for us, it's only shown
120// for functions returning a specific trait.
121#![cfg_attr(docsrs, feature(doc_cfg))]
122#![cfg_attr(docsrs, doc(auto_cfg(hide(feature = "unstable-objfw"))))]
123#![warn(missing_docs)]
124#![warn(missing_debug_implementations)]
125#![warn(clippy::missing_errors_doc)]
126#![warn(clippy::missing_panics_doc)]
127// Update in Cargo.toml as well.
128#![doc(html_root_url = "https://docs.rs/objc2/0.6.3")]
129
130#[cfg(not(feature = "alloc"))]
131compile_error!("The `alloc` feature currently must be enabled.");
132
133#[cfg(not(feature = "std"))]
134compile_error!("The `std` feature currently must be enabled.");
135
136extern crate alloc;
137extern crate std;
138
139pub use self::downcast::DowncastTarget;
140#[doc(no_inline)]
141pub use self::encode::{Encode, Encoding, RefEncode};
142pub use self::main_thread_marker::MainThreadMarker;
143pub use self::top_level_traits::{
144 AnyThread, ClassType, DefinedClass, MainThreadOnly, Message, ProtocolType, ThreadKind,
145};
146
147#[cfg(any(feature = "unstable-static-sel", feature = "unstable-static-class"))]
148#[doc(hidden)]
149pub use objc2_proc_macros::__hash_idents;
150
151#[cfg(not(any(feature = "unstable-static-sel", feature = "unstable-static-class")))]
152#[doc(hidden)]
153#[macro_export]
154macro_rules! __hash_idents {
155 // Noop; used to make our other macros a bit easier to read
156 ($($x:tt)*) => {
157 ()
158 };
159}
160
161// Note: While this is not public, it is still a breaking change to change,
162// since framework crates rely on it.
163#[doc(hidden)]
164pub mod __framework_prelude;
165#[doc(hidden)]
166pub mod __macro_helpers;
167mod downcast;
168pub mod encode;
169pub mod exception;
170pub mod ffi;
171mod macros;
172mod main_thread_marker;
173pub mod rc;
174pub mod runtime;
175#[cfg(test)]
176mod test_utils;
177mod top_level_traits;
178#[cfg(any(docsrs, doc, doctest, test))]
179pub mod topics;
180mod verify;
181
182/// Deprecated location for a few things that are now in the [`runtime`]
183/// module.
184#[deprecated = "Moved to the `runtime` module"]
185pub mod declare {
186 use super::runtime;
187 pub use super::runtime::{ClassBuilder, ProtocolBuilder};
188
189 /// Use [`runtime::ClassBuilder`] instead.
190 #[deprecated = "Use `runtime::ClassBuilder` instead."]
191 pub type ClassDecl = runtime::ClassBuilder;
192
193 /// Use [`runtime::ProtocolBuilder`] instead.
194 #[deprecated = "Use `runtime::ProtocolBuilder` instead."]
195 pub type ProtocolDecl = runtime::ProtocolBuilder;
196}
197
198/// Deprecated alias of [`DefinedClass`].
199#[deprecated = "renamed to DefinedClass"]
200pub use DefinedClass as DeclaredClass;
201
202/// Deprecated alias of [`AnyThread`].
203#[deprecated = "renamed to AnyThread"]
204pub use AnyThread as AllocAnyThread;
205
206#[cfg(not(feature = "std"))]
207compile_error!("The `std` feature currently must be enabled.");
208
209#[cfg(all(
210 not(docsrs),
211 not(any(
212 target_vendor = "apple",
213 feature = "unstable-compiler-rt",
214 feature = "gnustep-1-7",
215 feature = "unstable-objfw",
216 ))
217))]
218compile_error!("`objc2` only works on Apple platforms. Pass `--target aarch64-apple-darwin` or similar to compile for macOS.\n(If you're absolutely certain that you're using GNUStep, you can specify that with the `gnustep-x-y` Cargo feature instead).");
219
220#[cfg(all(feature = "gnustep-1-7", feature = "unstable-objfw"))]
221compile_error!("Only one runtime may be selected");
222
223#[cfg(feature = "unstable-objfw")]
224compile_error!("ObjFW is not yet supported");
225
226// Link to libobjc
227#[cfg_attr(not(feature = "unstable-objfw"), link(name = "objc", kind = "dylib"))]
228// Link to libobjfw-rt
229#[cfg_attr(feature = "unstable-objfw", link(name = "objfw-rt", kind = "dylib"))]
230extern "C" {}
231
232// Link to Foundation to make NSObject and OS version lookup work.
233#[cfg_attr(target_vendor = "apple", link(name = "Foundation", kind = "framework"))]
234#[cfg_attr(
235 all(feature = "gnustep-1-7", not(feature = "unstable-compiler-rt")),
236 link(name = "gnustep-base", kind = "dylib")
237)]
238extern "C" {}