swiftyjourney/swiftui-uikit-interop-skill · Archived

swiftui-uikit-interop

>- Use this skill to bridge SwiftUI and UIKit in either direction. Embed SwiftUI in a UIKit app -- present or child-embed a UIHostingController, put SwiftUI in UICollectionView/UITableView cells via UIHostingConfiguration, or build a widget / Live Activity. Wrap UIKit for use in SwiftUI -- UIViewRepresentable / UIViewControllerRepresentable with a Coordinator for delegates and data sources. Pass data and state across the boundary (init params, @Binding, closures, environment/trait forwarding), …

First seen Jul 15, 2026

Installation

$ npx skills add swiftyjourney/swiftui-uikit-interop-skill --skill swiftui-uikit-interop

Stronger alternatives

This repository is archived — consider an actively maintained alternative.

Similar popular skills

Related neighbors and high-traction skills in the same topics — useful to compare before installing.

More details

Agent compatibility

Declared targets from SKILL.md / docs. Unmarked agents are not listed — the skill may still install via the CLI.

Claude Code Not declared
Cursor Not declared
Codex Not declared
GitHub Copilot Not declared
Windsurf Not declared
Gemini CLI Not declared
Cline Not declared
OpenCode Not declared

Also listed on

Alternate registries and mirrors of this skill.

Repository health

License LICENSE
Default branch main
Open issues 0
Status Archived

Skill metadata

Parsed from SKILL.md frontmatter.

Version1.0.0
More metadata
version
1.0.0
author
SwiftyJourney

Package contents

Files included with this skill beyond the listing page.

  • skill md SKILL.md 7,209 B
  • docs SUMMARY.md 1,015 B

History

  1. First seen on skills.sh
  2. First recorded snapshot · 5 installs

SKILL.md

SwiftUI ⇄ UIKit Interop

This skill covers the boundary between SwiftUI and UIKit — embedding one inside the other and passing data across. It does not cover pure-SwiftUI view design (use swiftui-expert) or the app's dependency graph (use ios-architecture-expert).

Agent Behavior Contract

When this skill is active, follow these rules strictly:

  1. This skill is only about the boundary. Pure SwiftUI view code → defer to swiftui-expert; app architecture / composition root / DI → defer to ios-architecture-expert.
  2. Wrap UIKit in SwiftUI with a representable — UIViewRepresentable for a view, UIViewControllerRepresentable for a view controller. Never new up a UIKit view directly inside a SwiftUI body.
  3. Route all UIKit delegate / data-source / target-action callbacks through a Coordinator (makeCoordinator()), never store mutable UIKit state on the representable struct.
  4. Data flows one way per direction: SwiftUI state → updateUIView/updateUIViewController; UIKit events → Coordinator → @Binding/closure. Don't mutate SwiftUI state synchronously from inside updateUIView.
  5. Embed SwiftUI in UIKit with UIHostingController — and when embedding (not presenting), add it as a child view controller (addChild / didMove(toParent:)), not just its view.
  6. Use UIHostingConfiguration for SwiftUI in collection/table cells (iOS 16+) — one configuration per cell, not a UIHostingController per cell.
  7. Keep hosting sizing correct — set sizingOptions / honor intrinsicContentSize / safeAreaRegions so Auto Layout and self-sizing cells measure the SwiftUI content.
  8. Gate version-specific APIs (UIHostingConfiguration iOS 16, UIHostingController.sizingOptions iOS 16, trait-bridged environment iOS 17, @UIApplicationDelegateAdaptor lifecycle) with #available/@available.

Interop Diagnostic Table

Symptom First check Smallest fix Deep dive
Show a SwiftUI screen from a UIKit view controller Present vs embed Present a UIHostingController references/hosting-controller.md
Embed a SwiftUI view inside an existing UIKit screen Child VC containment Add UIHostingController as a child VC references/hosting-controller.md
SwiftUI content in a collection/table cell Cell configuration UIHostingConfiguration (iOS 16+) references/hosting-configuration.md
Use a UIKit view (map, camera, web) in SwiftUI View wrapping UIViewRepresentable + Coordinator references/representables.md
Use a UIKit view controller in SwiftUI VC wrapping UIViewControllerRepresentable + Coordinator references/representables.md
Delegate/data-source callbacks from wrapped UIKit Callback routing Route through the Coordinator references/representables.md
Pass data/state between SwiftUI and UIKit Direction of flow init params + @Binding/closures; forward environment via traits references/passing-data-across-the-boundary.md
Hosted SwiftUI doesn't resize / clips / fights Auto Layout Hosting sizing sizingOptions / intrinsic size / safe-area references/hosting-controller.md
SwiftUI in a widget or Live Activity Extension target WidgetKit + SwiftUI references/widgets-and-live-activities.md
Move a UIKit app onto the SwiftUI lifecycle Incremental migration Adopt App/Scene, bridge with delegate adaptors references/lifecycle-migration.md

Direction Decision Tree

  1. Which framework owns the screen you're adding to?

- UIKit owns it, you're adding SwiftUI → embed (UIHostingController, or UIHostingConfiguration for cells) - SwiftUI owns it, you need a UIKit view/VC → wrap (UIViewRepresentable / UIViewControllerRepresentable)

  1. Is it a whole screen or a piece? Whole screen → present/push a hosting controller or a representable VC. A piece → child-embed a hosting controller, or wrap a single UIKit view.
  2. Does the UIKit side report events back? → add a Coordinator and bridge via @Binding/closures.
  3. Crossing the lifecycle? Migrating the app entry point → references/lifecycle-migration.md.

Guardrails

  • Do not instantiate UIKit views/VCs directly in a SwiftUI body — wrap them in a representable
  • Do not put delegate/data-source conformance on the representable struct — use the Coordinator (a class)
  • Do not mutate @State/@Binding synchronously inside updateUIView/updateUIViewController (causes update loops) — dispatch or guard for actual change
  • Do not add a hosting controller's view as a subview without also doing child-VC containment (addChild/didMove) — you lose lifecycle and safe-area forwarding
  • Do not create a UIHostingController per cell — use UIHostingConfiguration
  • Do not solve app architecture/DI here — that is ios-architecture-expert's job
  • Do not re-teach pure SwiftUI patterns — defer to swiftui-expert

Reference Router

Open the smallest reference that matches the task:

  • Embedding SwiftUI in UIKit

- [hosting-controller.md](references/hosting-controller.md) — UIHostingController: present, child-embed, subclass, sizing - [hosting-configuration.md](references/hosting-configuration.md) — UIHostingConfiguration for collection/table cells (iOS 16+)

  • Wrapping UIKit in SwiftUI

- [representables.md](references/representables.md) — UIViewRepresentable, UIViewControllerRepresentable, the Coordinator pattern

  • Crossing the boundary

- [passing-data-across-the-boundary.md](references/passing-data-across-the-boundary.md) — init params, @Binding, closures, environment/trait forwarding, observation

  • Extensions

- [widgets-and-live-activities.md](references/widgets-and-live-activities.md) — SwiftUI in WidgetKit widgets and Live Activities

  • Migration

- [lifecycle-migration.md](references/lifecycle-migration.md) — moving a UIKit AppDelegate/SceneDelegate app to the SwiftUI App lifecycle