Skip to content
Lucent
SEARCH LUCENT

Search guides, APIs, and examples.

GitHub

Very early and experimental. The language, the generated native code and every package API change without notice. Do not use Lucent in production.

Call an iOS API

Import a framework from lucent:ios/* and call it with Swift's names, inside main() when it's main-thread only.

battery.lucent.ts
import { PLATFORM } from "lucent:platform";
import { UIDevice, UIDevice_BatteryState } from "lucent:ios/UIKit";
import { main } from "lucent:thread";
import { error } from "lucent:core";
export async function isCharging(): Promise<boolean> {
if (PLATFORM === "ios") {
return main(() => {
UIDevice.current.isBatteryMonitoringEnabled = true;
const state = UIDevice.current.batteryState;
return state === UIDevice_BatteryState.charging || state === UIDevice_BatteryState.full;
});
} else {
throw error("E_UNSUPPORTED", "Only iOS is implemented");
}
}
See the C++
m_battery.mm
// Generated by Lucent from battery.lucent.ts. Do not edit.
#import <UIKit/UIKit.h>
#include <lucent/platform/ios.h>
#include "m_battery.h"
#pragma push_macro("isCharging")
#undef isCharging
#pragma push_macro("state")
#undef state
static_assert(UIDeviceBatteryStateCharging == 2, "UIDevice_BatteryState.charging in the UIKit binding schema");
static_assert(UIDeviceBatteryStateFull == 3, "UIDevice_BatteryState.full in the UIKit binding schema");
namespace lucent_app {
lucent::Promise<bool> m_battery::isCharging() {
#line 7 "battery.lucent.ts"
{
#line 8 "battery.lucent.ts"
lucent::Fn<bool()> v0_ = lucent::Fn<bool()>([]() mutable -> bool {
#line 9 "battery.lucent.ts"
lucent::NativeRef v0_ = lucent::objc::wrap([UIDevice currentDevice], "UIDevice.current");
(void)({ auto v_ = true; [((UIDevice*)lucent::objc::unwrap(v0_)) setBatteryMonitoringEnabled:v_ ? YES : NO]; v_; });
#line 10 "battery.lucent.ts"
lucent::NativeRef v3_ = lucent::objc::wrap([UIDevice currentDevice], "UIDevice.current");
double state = static_cast<double>([((UIDevice*)lucent::objc::unwrap(v3_)) batteryState]);
#line 11 "battery.lucent.ts"
double v6_ = 2.0;
bool v7_ = state == v6_;
bool v11_{};
if (v7_) {
v11_ = v7_;
} else {
double v9_ = 3.0;
v11_ = state == v9_;
}
#line 11 "battery.lucent.ts"
return v11_;
});
#line 8 "battery.lucent.ts"
lucent::Promise<bool> v1_ = lucent::runOnMain(v0_);
bool v2_ = co_await v1_;
co_return v2_;
}
}
void m_battery::init() {
}
} // namespace lucent_app
#pragma pop_macro("state")
#pragma pop_macro("isCharging")
  • Import from lucent:ios/<Framework>: any framework of your Xcode's SDK, or of the app's pods.
  • Names are Swift's. A nested type joins its parts with _: Swift's UIDevice.BatteryState is UIDevice_BatteryState.
  • UIKit is main-thread only, so the calls sit inside main(). Anywhere else they fail to compile with LUCENT3006.
  • Return plain values: SDK objects can't cross to JavaScript.

A method with a completion handler is also a promise, under the name Swift gives its async form. An NSError becomes a thrown error. SDK types has every rule.