or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

composition-lifecycle.mdcomposition-local.mdeffects.mdindex.mdios-integration.mdsnapshot-system.mdstate-management.md

ios-integration.mddocs/

0

# iOS Integration

1

2

Platform-specific integration for embedding Compose Multiplatform in iOS UIKit applications. Provides seamless interoperability between Compose runtime and iOS UIKit framework.

3

4

## Capabilities

5

6

### ComposeUIViewController

7

8

Main entry point for hosting Compose content within iOS UIKit applications.

9

10

```kotlin { .api }

11

/**

12

* Creates a UIViewController that hosts Compose content

13

* @param content Composable content to display

14

* @return UIViewController containing the Compose content

15

*/

16

fun ComposeUIViewController(

17

content: @Composable () -> Unit

18

): UIViewController

19

20

/**

21

* Creates a UIViewController with custom configuration

22

* @param configure Configuration block for customizing the view controller

23

* @param content Composable content to display

24

* @return Configured UIViewController containing the Compose content

25

*/

26

fun ComposeUIViewController(

27

configure: UIViewController.() -> Unit = {},

28

content: @Composable () -> Unit

29

): UIViewController

30

```

31

32

**Usage Examples:**

33

34

```kotlin

35

// Basic usage in iOS app

36

class ViewController: UIViewController {

37

override fun viewDidLoad() {

38

super.viewDidLoad()

39

40

val composeVC = ComposeUIViewController {

41

MyComposeApp()

42

}

43

44

addChild(composeVC)

45

view.addSubview(composeVC.view)

46

composeVC.didMove(toParent = this)

47

}

48

}

49

50

// Advanced configuration

51

class SceneDelegate: UIResponder, UIWindowSceneDelegate {

52

var window: UIWindow?

53

54

fun scene(scene: UIScene, willConnectTo session: UISceneSession, options: UISceneConnectionOptions) {

55

val windowScene = scene as UIWindowScene

56

window = UIWindow(windowScene = windowScene)

57

58

val rootVC = ComposeUIViewController(

59

configure = {

60

modalPresentationStyle = UIModalPresentationStyle.UIModalPresentationFullScreen

61

navigationController?.isNavigationBarHidden = true

62

}

63

) {

64

App() // Your main Compose app

65

}

66

67

window?.rootViewController = rootVC

68

window?.makeKeyAndVisible()

69

}

70

}

71

```

72

73

### UIKitView Integration

74

75

Embed native UIKit views within Compose compositions for seamless native interoperability.

76

77

```kotlin { .api }

78

/**

79

* Composable that embeds a UIKit UIView within Compose content

80

* @param factory Function that creates the UIView instance

81

* @param modifier Compose modifier for layout and styling

82

* @param update Callback for updating the UIView when composition changes

83

* @param onResize Callback when the view size changes

84

* @param onRelease Callback when the view is about to be disposed

85

*/

86

@Composable

87

fun UIKitView(

88

factory: () -> UIView,

89

modifier: Modifier = Modifier,

90

update: (UIView) -> Unit = {},

91

onResize: (UIView, CGRect) -> Unit = { _, _ -> },

92

onRelease: (UIView) -> Unit = {}

93

)

94

95

/**

96

* Typed variant for specific UIView subclasses

97

* @param T Specific UIView subclass type

98

* @param factory Function that creates the typed UIView instance

99

* @param modifier Compose modifier for layout and styling

100

* @param update Callback for updating the typed UIView

101

* @param onResize Callback when the view size changes

102

* @param onRelease Callback when the view is disposed

103

*/

104

@Composable

105

fun <T : UIView> UIKitView(

106

factory: () -> T,

107

modifier: Modifier = Modifier,

108

update: (T) -> Unit = {},

109

onResize: (T, CGRect) -> Unit = { _, _ -> },

110

onRelease: (T) -> Unit = {}

111

)

112

```

113

114

**Usage Examples:**

115

116

```kotlin

117

@Composable

118

fun MapViewExample() {

119

var showUserLocation by remember { mutableStateOf(false) }

120

121

// Embed native MKMapView in Compose

122

UIKitView(

123

factory = {

124

val mapView = MKMapView()

125

mapView.mapType = MKMapType.MKMapTypeStandard

126

mapView

127

},

128

modifier = Modifier

129

.fillMaxWidth()

130

.height(300.dp),

131

update = { mapView ->

132

mapView.showsUserLocation = showUserLocation

133

}

134

)

135

136

Button(onClick = { showUserLocation = !showUserLocation }) {

137

Text(if (showUserLocation) "Hide Location" else "Show Location")

138

}

139

}

140

141

@Composable

142

fun CameraPreviewExample() {

143

UIKitView(

144

factory = {

145

val previewView = UIView()

146

// Setup AVCaptureVideoPreviewLayer

147

val captureSession = AVCaptureSession()

148

val previewLayer = AVCaptureVideoPreviewLayer(session = captureSession)

149

previewView.layer.addSublayer(previewLayer)

150

previewView

151

},

152

modifier = Modifier.fillMaxSize(),

153

onResize = { view, rect ->

154

// Update preview layer frame

155

view.layer.sublayers?.firstOrNull()?.frame = rect

156

},

157

onRelease = { view ->

158

// Cleanup camera resources

159

(view.layer.sublayers?.firstOrNull() as? AVCaptureVideoPreviewLayer)

160

?.session?.stopRunning()

161

}

162

)

163

}

164

```

165

166

### iOS Lifecycle Integration

167

168

Integration with iOS application and view controller lifecycle events.

169

170

```kotlin { .api }

171

/**

172

* Effect that observes iOS application lifecycle events

173

* @param onActive Callback when app becomes active

174

* @param onInactive Callback when app becomes inactive

175

* @param onBackground Callback when app enters background

176

* @param onForeground Callback when app enters foreground

177

*/

178

@Composable

179

fun IOSApplicationLifecycleEffect(

180

onActive: () -> Unit = {},

181

onInactive: () -> Unit = {},

182

onBackground: () -> Unit = {},

183

onForeground: () -> Unit = {}

184

)

185

186

/**

187

* Effect that observes UIViewController lifecycle events

188

* @param onViewDidLoad Callback when view controller loads

189

* @param onViewWillAppear Callback when view will appear

190

* @param onViewDidAppear Callback when view did appear

191

* @param onViewWillDisappear Callback when view will disappear

192

* @param onViewDidDisappear Callback when view did disappear

193

*/

194

@Composable

195

fun IOSViewControllerLifecycleEffect(

196

onViewDidLoad: () -> Unit = {},

197

onViewWillAppear: () -> Unit = {},

198

onViewDidAppear: () -> Unit = {},

199

onViewWillDisappear: () -> Unit = {},

200

onViewDidDisappear: () -> Unit = {}

201

)

202

```

203

204

**Usage Examples:**

205

206

```kotlin

207

@Composable

208

fun LifecycleAwareContent() {

209

var isAppActive by remember { mutableStateOf(true) }

210

211

IOSApplicationLifecycleEffect(

212

onActive = {

213

isAppActive = true

214

// Resume timers, restart animations

215

},

216

onInactive = {

217

isAppActive = false

218

// Pause timers, save state

219

},

220

onBackground = {

221

// Save user data, pause network requests

222

},

223

onForeground = {

224

// Refresh data, resume network requests

225

}

226

)

227

228

if (isAppActive) {

229

ActiveContent()

230

} else {

231

InactiveOverlay()

232

}

233

}

234

```

235

236

### Memory Management

237

238

iOS-specific memory management utilities for proper integration with ARC and autorelease pools.

239

240

```kotlin { .api }

241

/**

242

* Effect that creates an autorelease pool for the composition scope

243

* Essential for managing Objective-C objects in Compose

244

*/

245

@Composable

246

fun AutoreleasePoolEffect()

247

248

/**

249

* Remember function that properly retains iOS objects

250

* @param calculation Factory for creating the iOS object

251

* @return Properly retained iOS object

252

*/

253

@Composable

254

fun <T : Any> rememberIOSObject(

255

vararg keys: Any?,

256

calculation: () -> T

257

): T

258

259

/**

260

* Effect for managing iOS object lifecycle with proper cleanup

261

* @param factory Creates the iOS object

262

* @param onDispose Cleanup callback when object should be released

263

*/

264

@Composable

265

fun <T : Any> IOSObjectLifecycleEffect(

266

vararg keys: Any?,

267

factory: () -> T,

268

onDispose: (T) -> Unit = {}

269

)

270

```

271

272

**Usage Examples:**

273

274

```kotlin

275

@Composable

276

fun IOSObjectManagementExample() {

277

// Proper autorelease pool management

278

AutoreleasePoolEffect()

279

280

// Retain location manager across recompositions

281

val locationManager = rememberIOSObject {

282

CLLocationManager().apply {

283

delegate = LocationDelegate()

284

}

285

}

286

287

// Manage camera capture session lifecycle

288

IOSObjectLifecycleEffect(

289

factory = {

290

AVCaptureSession().apply {

291

// Configure capture session

292

}

293

},

294

onDispose = { session ->

295

session.stopRunning()

296

}

297

)

298

}

299

```

300

301

### Threading and Dispatchers

302

303

iOS-specific threading integration ensuring proper main thread usage for UIKit operations.

304

305

```kotlin { .api }

306

/**

307

* Dispatcher for iOS main thread operations

308

* Ensures UIKit operations run on the main thread

309

*/

310

val IOSMainDispatcher: CoroutineDispatcher

311

312

/**

313

* Dispatcher for iOS background operations

314

* Uses iOS global concurrent queue

315

*/

316

val IOSBackgroundDispatcher: CoroutineDispatcher

317

318

/**

319

* Effect that ensures operations run on iOS main thread

320

* @param block Operations that require main thread execution

321

*/

322

@Composable

323

fun IOSMainThreadEffect(

324

vararg keys: Any?,

325

block: suspend CoroutineScope.() -> Unit

326

)

327

```

328

329

**Usage Examples:**

330

331

```kotlin

332

@Composable

333

fun ThreadingExample() {

334

val data = remember { mutableStateOf<List<String>>(emptyList()) }

335

336

LaunchedEffect(Unit) {

337

// Background data loading

338

withContext(IOSBackgroundDispatcher) {

339

val result = loadDataFromNetwork()

340

341

// Switch to main thread for UI updates

342

withContext(IOSMainDispatcher) {

343

data.value = result

344

}

345

}

346

}

347

348

// Main thread effect for UIKit operations

349

IOSMainThreadEffect {

350

// This automatically runs on main thread

351

UIView.animate(

352

withDuration = 0.3,

353

animations = {

354

// UIKit animations

355

}

356

)

357

}

358

}

359

```

360

361

### Platform Detection

362

363

Utilities for detecting iOS platform characteristics and capabilities.

364

365

```kotlin { .api }

366

/**

367

* iOS platform information

368

*/

369

object IOSPlatform {

370

/** Current iOS version */

371

val version: String

372

373

/** Device model identifier */

374

val deviceModel: String

375

376

/** Whether running on iPad */

377

val isIPad: Boolean

378

379

/** Whether running on iPhone */

380

val isIPhone: Boolean

381

382

/** Whether running in iOS Simulator */

383

val isSimulator: Boolean

384

385

/** Screen scale factor */

386

val screenScale: Float

387

388

/** Whether dark mode is enabled */

389

val isDarkMode: Boolean

390

391

/** Current locale */

392

val locale: NSLocale

393

}

394

395

/**

396

* Composable that provides iOS platform information as state

397

* @return State containing current iOS platform information

398

*/

399

@Composable

400

fun rememberIOSPlatformState(): State<IOSPlatform>

401

```

402

403

**Usage Examples:**

404

405

```kotlin

406

@Composable

407

fun PlatformAdaptiveContent() {

408

val platformState by rememberIOSPlatformState()

409

410

when {

411

platformState.isIPad -> {

412

// iPad-specific layout

413

TwoColumnLayout()

414

}

415

platformState.isIPhone -> {

416

// iPhone-specific layout

417

SingleColumnLayout()

418

}

419

}

420

421

// Adapt to dark mode

422

val colors = if (platformState.isDarkMode) {

423

DarkColorScheme

424

} else {

425

LightColorScheme

426

}

427

428

MaterialTheme(colorScheme = colors) {

429

Content()

430

}

431

}

432

```

433

434

## Error Handling

435

436

iOS-specific error handling and crash prevention.

437

438

```kotlin { .api }

439

/**

440

* Exception thrown when UIKit operations are called off main thread

441

*/

442

class IOSMainThreadException(message: String) : IllegalStateException(message)

443

444

/**

445

* Exception thrown when iOS object lifecycle is violated

446

*/

447

class IOSObjectLifecycleException(message: String) : IllegalStateException(message)

448

```

449

450

## Performance Considerations

451

452

### Memory Management

453

- Use `AutoreleasePoolEffect` for compositions that create many Objective-C objects

454

- Properly dispose of camera sessions, location managers, and other resource-heavy objects

455

- Monitor memory usage with iOS Instruments when using heavy UIKit integration

456

457

### Threading

458

- Always use `IOSMainDispatcher` for UIKit operations

459

- Use `IOSBackgroundDispatcher` for CPU-intensive work

460

- Avoid blocking the main thread in Compose content

461

462

### Resource Cleanup

463

- Implement proper cleanup in `onRelease` callbacks for UIKitView

464

- Use `IOSObjectLifecycleEffect` for objects requiring explicit cleanup

465

- Monitor for memory leaks when bridging between Compose and UIKit