CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-org-jetbrains-compose-runtime--runtime-uikitx64

Compose Multiplatform runtime library for iOS UIKit x64 target providing core runtime functionality for declarative UI framework integration.

Pending
Overview
Eval results
Files

ios-integration.mddocs/

iOS Integration

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

Capabilities

ComposeUIViewController

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

/**
 * Creates a UIViewController that hosts Compose content
 * @param content Composable content to display
 * @return UIViewController containing the Compose content
 */
fun ComposeUIViewController(
    content: @Composable () -> Unit
): UIViewController

/**
 * Creates a UIViewController with custom configuration
 * @param configure Configuration block for customizing the view controller
 * @param content Composable content to display
 * @return Configured UIViewController containing the Compose content  
 */
fun ComposeUIViewController(
    configure: UIViewController.() -> Unit = {},
    content: @Composable () -> Unit
): UIViewController

Usage Examples:

// Basic usage in iOS app
class ViewController: UIViewController {
    override fun viewDidLoad() {
        super.viewDidLoad()
        
        val composeVC = ComposeUIViewController {
            MyComposeApp()
        }
        
        addChild(composeVC)
        view.addSubview(composeVC.view)
        composeVC.didMove(toParent = this)
    }
}

// Advanced configuration
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
    var window: UIWindow?
    
    fun scene(scene: UIScene, willConnectTo session: UISceneSession, options: UISceneConnectionOptions) {
        val windowScene = scene as UIWindowScene
        window = UIWindow(windowScene = windowScene)
        
        val rootVC = ComposeUIViewController(
            configure = {
                modalPresentationStyle = UIModalPresentationStyle.UIModalPresentationFullScreen
                navigationController?.isNavigationBarHidden = true
            }
        ) {
            App() // Your main Compose app
        }
        
        window?.rootViewController = rootVC
        window?.makeKeyAndVisible()
    }
}

UIKitView Integration

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

/**
 * Composable that embeds a UIKit UIView within Compose content
 * @param factory Function that creates the UIView instance
 * @param modifier Compose modifier for layout and styling
 * @param update Callback for updating the UIView when composition changes
 * @param onResize Callback when the view size changes
 * @param onRelease Callback when the view is about to be disposed
 */
@Composable
fun UIKitView(
    factory: () -> UIView,
    modifier: Modifier = Modifier,
    update: (UIView) -> Unit = {},
    onResize: (UIView, CGRect) -> Unit = { _, _ -> },
    onRelease: (UIView) -> Unit = {}
)

/**
 * Typed variant for specific UIView subclasses
 * @param T Specific UIView subclass type
 * @param factory Function that creates the typed UIView instance
 * @param modifier Compose modifier for layout and styling
 * @param update Callback for updating the typed UIView
 * @param onResize Callback when the view size changes
 * @param onRelease Callback when the view is disposed
 */
@Composable
fun <T : UIView> UIKitView(
    factory: () -> T,
    modifier: Modifier = Modifier,
    update: (T) -> Unit = {},
    onResize: (T, CGRect) -> Unit = { _, _ -> },
    onRelease: (T) -> Unit = {}
)

Usage Examples:

@Composable
fun MapViewExample() {
    var showUserLocation by remember { mutableStateOf(false) }
    
    // Embed native MKMapView in Compose
    UIKitView(
        factory = {
            val mapView = MKMapView()
            mapView.mapType = MKMapType.MKMapTypeStandard
            mapView
        },
        modifier = Modifier
            .fillMaxWidth()
            .height(300.dp),
        update = { mapView ->
            mapView.showsUserLocation = showUserLocation
        }
    )
    
    Button(onClick = { showUserLocation = !showUserLocation }) {
        Text(if (showUserLocation) "Hide Location" else "Show Location")
    }
}

@Composable
fun CameraPreviewExample() {
    UIKitView(
        factory = {
            val previewView = UIView()
            // Setup AVCaptureVideoPreviewLayer
            val captureSession = AVCaptureSession()
            val previewLayer = AVCaptureVideoPreviewLayer(session = captureSession)
            previewView.layer.addSublayer(previewLayer)
            previewView
        },
        modifier = Modifier.fillMaxSize(),
        onResize = { view, rect ->
            // Update preview layer frame
            view.layer.sublayers?.firstOrNull()?.frame = rect
        },
        onRelease = { view ->
            // Cleanup camera resources
            (view.layer.sublayers?.firstOrNull() as? AVCaptureVideoPreviewLayer)
                ?.session?.stopRunning()
        }
    )
}

iOS Lifecycle Integration

Integration with iOS application and view controller lifecycle events.

/**
 * Effect that observes iOS application lifecycle events
 * @param onActive Callback when app becomes active
 * @param onInactive Callback when app becomes inactive
 * @param onBackground Callback when app enters background
 * @param onForeground Callback when app enters foreground
 */
@Composable
fun IOSApplicationLifecycleEffect(
    onActive: () -> Unit = {},
    onInactive: () -> Unit = {},
    onBackground: () -> Unit = {},
    onForeground: () -> Unit = {}
)

/**
 * Effect that observes UIViewController lifecycle events
 * @param onViewDidLoad Callback when view controller loads
 * @param onViewWillAppear Callback when view will appear
 * @param onViewDidAppear Callback when view did appear
 * @param onViewWillDisappear Callback when view will disappear
 * @param onViewDidDisappear Callback when view did disappear
 */
@Composable
fun IOSViewControllerLifecycleEffect(
    onViewDidLoad: () -> Unit = {},
    onViewWillAppear: () -> Unit = {},
    onViewDidAppear: () -> Unit = {},
    onViewWillDisappear: () -> Unit = {},
    onViewDidDisappear: () -> Unit = {}
)

Usage Examples:

@Composable
fun LifecycleAwareContent() {
    var isAppActive by remember { mutableStateOf(true) }
    
    IOSApplicationLifecycleEffect(
        onActive = {
            isAppActive = true
            // Resume timers, restart animations
        },
        onInactive = {
            isAppActive = false
            // Pause timers, save state
        },
        onBackground = {
            // Save user data, pause network requests
        },
        onForeground = {
            // Refresh data, resume network requests
        }
    )
    
    if (isAppActive) {
        ActiveContent()
    } else {
        InactiveOverlay()
    }
}

Memory Management

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

/**
 * Effect that creates an autorelease pool for the composition scope
 * Essential for managing Objective-C objects in Compose
 */
@Composable
fun AutoreleasePoolEffect()

/**
 * Remember function that properly retains iOS objects
 * @param calculation Factory for creating the iOS object
 * @return Properly retained iOS object
 */
@Composable
fun <T : Any> rememberIOSObject(
    vararg keys: Any?,
    calculation: () -> T
): T

/**
 * Effect for managing iOS object lifecycle with proper cleanup
 * @param factory Creates the iOS object
 * @param onDispose Cleanup callback when object should be released
 */
@Composable
fun <T : Any> IOSObjectLifecycleEffect(
    vararg keys: Any?,
    factory: () -> T,
    onDispose: (T) -> Unit = {}
)

Usage Examples:

@Composable
fun IOSObjectManagementExample() {
    // Proper autorelease pool management
    AutoreleasePoolEffect()
    
    // Retain location manager across recompositions
    val locationManager = rememberIOSObject {
        CLLocationManager().apply {
            delegate = LocationDelegate()
        }
    }
    
    // Manage camera capture session lifecycle
    IOSObjectLifecycleEffect(
        factory = {
            AVCaptureSession().apply {
                // Configure capture session
            }
        },
        onDispose = { session ->
            session.stopRunning()
        }
    )
}

Threading and Dispatchers

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

/**
 * Dispatcher for iOS main thread operations
 * Ensures UIKit operations run on the main thread
 */
val IOSMainDispatcher: CoroutineDispatcher

/**
 * Dispatcher for iOS background operations
 * Uses iOS global concurrent queue
 */
val IOSBackgroundDispatcher: CoroutineDispatcher

/**
 * Effect that ensures operations run on iOS main thread
 * @param block Operations that require main thread execution
 */
@Composable
fun IOSMainThreadEffect(
    vararg keys: Any?,
    block: suspend CoroutineScope.() -> Unit
)

Usage Examples:

@Composable
fun ThreadingExample() {
    val data = remember { mutableStateOf<List<String>>(emptyList()) }
    
    LaunchedEffect(Unit) {
        // Background data loading
        withContext(IOSBackgroundDispatcher) {
            val result = loadDataFromNetwork()
            
            // Switch to main thread for UI updates
            withContext(IOSMainDispatcher) {
                data.value = result
            }
        }
    }
    
    // Main thread effect for UIKit operations
    IOSMainThreadEffect {
        // This automatically runs on main thread
        UIView.animate(
            withDuration = 0.3,
            animations = {
                // UIKit animations
            }
        )
    }
}

Platform Detection

Utilities for detecting iOS platform characteristics and capabilities.

/**
 * iOS platform information
 */
object IOSPlatform {
    /** Current iOS version */
    val version: String
    
    /** Device model identifier */
    val deviceModel: String
    
    /** Whether running on iPad */
    val isIPad: Boolean
    
    /** Whether running on iPhone */
    val isIPhone: Boolean
    
    /** Whether running in iOS Simulator */
    val isSimulator: Boolean
    
    /** Screen scale factor */
    val screenScale: Float
    
    /** Whether dark mode is enabled */
    val isDarkMode: Boolean
    
    /** Current locale */
    val locale: NSLocale
}

/**
 * Composable that provides iOS platform information as state
 * @return State containing current iOS platform information
 */
@Composable
fun rememberIOSPlatformState(): State<IOSPlatform>

Usage Examples:

@Composable
fun PlatformAdaptiveContent() {
    val platformState by rememberIOSPlatformState()
    
    when {
        platformState.isIPad -> {
            // iPad-specific layout
            TwoColumnLayout()
        }
        platformState.isIPhone -> {
            // iPhone-specific layout
            SingleColumnLayout()
        }
    }
    
    // Adapt to dark mode
    val colors = if (platformState.isDarkMode) {
        DarkColorScheme
    } else {
        LightColorScheme
    }
    
    MaterialTheme(colorScheme = colors) {
        Content()
    }
}

Error Handling

iOS-specific error handling and crash prevention.

/**
 * Exception thrown when UIKit operations are called off main thread
 */
class IOSMainThreadException(message: String) : IllegalStateException(message)

/**
 * Exception thrown when iOS object lifecycle is violated
 */
class IOSObjectLifecycleException(message: String) : IllegalStateException(message)

Performance Considerations

Memory Management

  • Use AutoreleasePoolEffect for compositions that create many Objective-C objects
  • Properly dispose of camera sessions, location managers, and other resource-heavy objects
  • Monitor memory usage with iOS Instruments when using heavy UIKit integration

Threading

  • Always use IOSMainDispatcher for UIKit operations
  • Use IOSBackgroundDispatcher for CPU-intensive work
  • Avoid blocking the main thread in Compose content

Resource Cleanup

  • Implement proper cleanup in onRelease callbacks for UIKitView
  • Use IOSObjectLifecycleEffect for objects requiring explicit cleanup
  • Monitor for memory leaks when bridging between Compose and UIKit

Install with Tessl CLI

npx tessl i tessl/maven-org-jetbrains-compose-runtime--runtime-uikitx64

docs

composition-lifecycle.md

composition-local.md

effects.md

index.md

ios-integration.md

snapshot-system.md

state-management.md

tile.json