Aria 2.0.0
C++23 MVVM framework (C++20 minimum) — reactive, coroutine-first, ABI-layered
Loading...
Searching...
No Matches
UIKit Adapter

Integrating Aria with iOS native UIKit applications. The UIKit adapter provides UIKitAdapter (widget binding) and UIKitView (view wrapper).

Include: #include "aria/adapters/uikit/UIKitAdapter.hpp"

Note: This header is .mm-only — it imports <UIKit/UIKit.h>. Compile the consuming file as Objective-C++. The CMake target is INTERFACE because UIKit only links inside an iOS app target; the consuming application compiles the .mm directly.


Setup

Initialize

#import "aria/adapters/uikit/UIKitAdapter.hpp"
aria::adapters::uikit::UIKitAdapter adapter;
aria::binding::BindingEngine engine(adapter,
aria::binding::BindingEngine::DispatchPolicy::SmartMarshal);

UIKitView — Wrap Any UIView

// Wrap a native UIView*
auto view = std::make_shared<aria::adapters::uikit::UIKitView>(textField);

UIKitView retains the UIView* via ARC (__strong). On destruction, fire_destroy_() is called while the native view is still valid, letting BindingEngine clean up subscriptions.

Type-Safe Cast

auto* tf = view->as<UITextField>();

Widget Bindings

Text (UITextField)

aria::Property<std::string> query{""};
// Two-way: user typing → Property, Property → text field
auto tf_view = std::make_shared<aria::adapters::uikit::UIKitView>(searchField);
engine.bind_text(query, *tf_view);

Internally, on_text_changed uses an AriaUITextTarget that hooks into UIControlEventEditingChanged.

Bool (UISwitch)

aria::Property<bool> notifications_enabled{true};
auto sw_view = std::make_shared<aria::adapters::uikit::UIKitView>(toggleSwitch);
engine.bind_bool(notifications_enabled, *sw_view);

Uses AriaUIToggleTarget hooked to UIControlEventValueChanged.

Int (UIStepper)

aria::Property<int> quantity{1};
auto stepper_view = std::make_shared<aria::adapters::uikit::UIKitView>(stepper);
engine.bind_int(quantity, *stepper_view);

Uses AriaUIStepperTarget hooked to UIControlEventValueChanged.

Double (UISlider)

aria::Property<double> brightness{0.5};
auto slider_view = std::make_shared<aria::adapters::uikit::UIKitView>(brightnessSlider);
engine.bind_double(brightness, *slider_view);

Uses AriaUISliderTarget hooked to UIControlEventValueChanged.

Click (UIButton)

aria::Command<> submit_cmd{[&] { do_submit(); }};
auto btn_view = std::make_shared<aria::adapters::uikit::UIKitView>(submitButton);
engine.bind_command(submit_cmd, *btn_view);

Uses AriaUIClickTarget hooked to UIControlEventTouchUpInside.

Visible / Enabled (Any UIView)

aria::Property<bool> has_results{false};
auto panel_view = std::make_shared<aria::adapters::uikit::UIKitView>(resultsContainer);
engine.bind_visible(has_results, *panel_view);
engine.bind_enabled(can_submit, *btn_view);

Supported Controls Summary

Control Binding Direction
UITextField bind_text Two-way
UILabel bind_text_oneway VM→View
UISwitch bind_bool Two-way
UIStepper bind_int Two-way
UISlider bind_double Two-way
UIButton bind_command View→VM
Any UIView bind_visible / bind_enabled VM→View

Threading

UIKit widgets must be accessed from the main thread. The adapter assumes all methods are called there. If you write to a Property from a background thread, use DispatchPolicy::SmartMarshal with a main-thread dispatcher to ensure VM→View updates land on the main thread.


Full Example

// ViewController.mm
#import "aria/adapters/uikit/UIKitAdapter.hpp"
#import "aria/binding/binding_engine.hpp"
@interface SearchViewController ()
@end
@implementation SearchViewController {
aria::adapters::uikit::UIKitAdapter _adapter;
std::unique_ptr<aria::binding::BindingEngine> _engine;
SearchVm _vm;
}
- (void)viewDidLoad {
[super viewDidLoad];
_engine = std::make_unique<aria::binding::BindingEngine>(
_adapter, aria::binding::BindingEngine::DispatchPolicy::SmartMarshal);
_engine->bind_text(_vm.query,
*std::make_shared<aria::adapters::uikit::UIKitView>(self.searchField));
_engine->bind_text_oneway(_vm.result,
*std::make_shared<aria::adapters::uikit::UIKitView>(self.resultLabel));
_engine->bind_command(_vm.search_cmd,
*std::make_shared<aria::adapters::uikit::UIKitView>(self.searchBtn));
}
@end

See Also