|
1 | 1 | [](https://kotlinlang.org/docs/reference/multiplatform.html)
|
2 | 2 |
|
3 |
| -:warning: This PoC compile on iOS and Android but I've remove some functionality because Compose changed too much since I started it. I will update it using the compose compiler when it will be possible. There are some hope on the way : |
4 |
| -- [Redwood Compose](https://github.com/cashapp/redwood) by Cash App. [Native UI with multiplatform Compose](https://jakewharton.com/native-ui-with-multiplatform-compose/). Use the compose compiler and native iOS component. |
5 |
| -- [Compose Multiplatform by JetBrains](https://github.com/JetBrains/compose-jb) started native support via Skia ([Skiko](https://github.com/JetBrains/skiko)), you can have a look at the [sample](https://github.com/JetBrains/compose-jb/tree/master/experimental/examples/falling-balls-mpp) but it is still very early. Some of the demos in this repo works but there is still many broken functionality. Touchlab made a demo for [Droidcon NYC App](https://touchlab.co/droidcon-nyc-ios-app-with-compose/) It will use the compose compiler but not native component. |
6 |
| -- [Platform-Kit by IceRock](https://github.com/Alex009/compose-jb/tree/platform-kit-sample/examples/common-platform-uikit) based on Compose Multiplatform by JetBrains, add support via UIKit, thus use the compose compiler and native iOS component. |
7 |
| - |
8 |
| -I've started to experiment with Compose Native, you can have a look at https://github.com/cl3m/kmp-redux/tree/skiko on iOS two views are SwiftUI and two views are Compose (ComposeSpaceView & ComposeCounterView) and share the same store. |
9 |
| - |
10 | 3 | # Multiplatform Compose
|
11 | 4 |
|
12 |
| -A Kotlin library to use Jetpack Compose in Android and iOS. Allow to write UI for both in Kotlin. Still experimental as many compose features are not yet available. |
| 5 | +A demo to show usage of Jetbrains Compose in Android and iOS. Originally a Jetpack Compose implementation with native view and yoga for iOS. |
13 | 6 |
|
14 | 7 | ## Table of contents
|
15 | 8 |
|
16 |
| -- [Requirements](#requirements) |
17 |
| -- [Installation](#installation) |
18 |
| -- [Usage](#usage) |
19 |
| -- [Known issues](#known-issues) |
| 9 | +- [Libraries](#libraries) |
| 10 | +- [Demos](#demos) |
20 | 11 | - [Troubleshooting](#troubleshooting)
|
21 |
| -- [Roadmap](#roadmap) |
22 |
| -- [Contributing](#contributing) |
23 |
| -- [Sponsors](#sponsors) |
| 12 | +- [Alternatives](#alternatives) |
24 | 13 | - [License](#license)
|
25 | 14 |
|
26 |
| -## Requirements |
27 |
| - |
28 |
| -- Android Studio Canary |
29 |
| -- cocoapods (gem install cocoapods) |
30 |
| -- cocoapods-generate (gem install cocoapods-generate) |
31 |
| - |
32 |
| -## Installation |
33 |
| - |
34 |
| -The library is not yet published to Maven Central as it is still experimental. |
35 |
| - |
36 |
| -## Usage |
37 |
| - |
38 |
| -The simpliest code is : |
| 15 | +## Libraries |
39 | 16 |
|
40 |
| -```kotlin |
41 |
| -@Composable |
42 |
| -fun Content(resources: Resources) { |
43 |
| - Text("Hello world!") |
44 |
| -} |
45 |
| -``` |
| 17 | +- kotlinx coroutines |
| 18 | +- ktor |
| 19 | +- Jetbrains Compose (uikit experimental) |
| 20 | +- [PreCompose](https://github.com/Tlaster/PreCompose) (for navigation) |
46 | 21 |
|
47 |
| -A better start would be : |
| 22 | +## Demos |
48 | 23 |
|
49 |
| -```kotlin |
50 |
| -@Composable |
51 |
| -fun Content(resources: Resources) { |
52 |
| - HelloPlatform() |
53 |
| -} |
54 |
| - |
55 |
| -@Composable |
56 |
| -fun HelloPlatform() { |
57 |
| - Column( |
58 |
| - modifier = Modifier.fillMaxSize(), |
59 |
| - verticalArrangement = Arrangement.Center, |
60 |
| - horizontalAlignment = Alignment.CenterHorizontally) { |
61 |
| - Text("Hello, ${Platform().platform}!") |
62 |
| - } |
63 |
| -} |
64 |
| -``` |
65 |
| - |
| 24 | +Run the app to see a demo of compose on ios. |
66 | 25 |
|
67 |
| -More advance sample are in the [demos](https://github.com/cl3m/multiplatform-compose/tree/develop/test/src/commonMain/kotlin/com/rouge41/kmm/compose/test/demos) directory of the test library. |
| 26 | + |
68 | 27 |
|
69 |
| -#### Image |
| 28 | +#### AsyncImage |
70 | 29 |
|
71 | 30 | The image composable allow url loading
|
72 | 31 |
|
73 | 32 | ```kotlin
|
74 |
| -Image(url = "https://loremflickr.com/320/240/ocean", modifier = Modifier.preferredSize(200.dp)) |
75 |
| -``` |
76 |
| - |
77 |
| -### iOS Composables |
78 |
| - |
79 |
| -#### HumanAppearance |
80 |
| - |
81 |
| -Allow iOS styling such as font or global tintColor. |
82 |
| - |
83 |
| -```kotlin |
84 |
| -HumanAppearance(tintColor: Color, backgroundColor: Color?, style: TextStyle) { |
85 |
| - // ... |
86 |
| -} |
| 33 | +AsyncImage(url = "https://loremflickr.com/320/240/ocean", modifier = Modifier.size(200.dp)) |
87 | 34 | ```
|
88 | 35 |
|
89 | 36 | #### SafeArea
|
90 | 37 |
|
91 |
| -Add safe area insets to the view, works in root, TabView and NavigationView |
92 |
| - |
93 |
| -```kotlin |
94 |
| -SafeArea { |
95 |
| - // ... |
96 |
| -} |
97 |
| -``` |
98 |
| - |
99 |
| - |
100 |
| -*Layout without the safe area, with the safe area and on android* |
101 |
| - |
102 |
| -#### TabView |
103 |
| - |
104 |
| -UITabBarController for Compose |
105 |
| - |
106 |
| -```kotlin |
107 |
| -TabView { |
108 |
| - Tab(title = "First", image = UIImage.systemImageNamed("a.circle.fill")) { |
109 |
| - // ... |
110 |
| - } |
111 |
| - Tab(title = "Second", image = UIImage.systemImageNamed("a.circle.fill")) { |
112 |
| - // ... |
113 |
| - } |
114 |
| -} |
115 |
| -``` |
116 |
| - |
117 |
| -#### NavigationView |
118 |
| - |
119 |
| -UINavigationController for Compose, renamed to NavHost but as additional parameter title, leadingButton and trailingButton in composable |
| 38 | +SafeArea.current to get PaddingValues. |
120 | 39 |
|
121 |
| -```kotlin |
122 |
| -val navController = rememberNavController() |
123 |
| -NavHost(navController = navController, startDestination = "first") { |
124 |
| - composable("first", title = "First", trailingButton = Button(onClick = {}) { Text ("Edit") }) { |
125 |
| - SafeArea { |
126 |
| - Button(onClick = { navController.navigate("second") }) { |
127 |
| - // ... |
128 |
| - } |
129 |
| - } |
130 |
| - } |
131 |
| - composable("second", title = "Second") { |
132 |
| - SafeArea { |
133 |
| - // ... |
134 |
| - } |
135 |
| - } |
136 |
| -} |
137 |
| -``` |
| 40 | +#### DarkMode |
138 | 41 |
|
139 |
| -## Known issues |
| 42 | +DarkMode.current to fix dark mode on iOS. |
140 | 43 |
|
141 |
| -- Jetpack Compose require Android Studio Canary and an alpha build of Gradle. There is some workaround in _build.gradle.kts_ to make it work (testApi). |
142 |
| -- Jetpack Compose is not supported in Kotlin Multiplatform Mobile library ([KT-38694](https://youtrack.jetbrains.com/issue/KT-38694)). Unfortunatly, the workaround was messing with actual/expect function and prevent the use of expect function with default value. The library now use @Suppress("ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS") to workaround this problem. If you use an expect function with default value and without the suppress, you will get an error function not found or _java.lang.IllegalStateException: 2. expected value parameter count to be higher_. |
143 |
| -- Jetpack Compose dependencies can not be used in commonMain because they have a dependency on kotlinx-coroutines-android. |
144 |
| -- Android Studio does not autocomplete cocoapods imported library in iosMain. Thus it is in iosx64Main and symlinked to iosArm64Main. |
145 |
| -- Images needs currently to be included in the android and ios resources separately. |
146 |
| -- Navigation is currently not shared in the library |
147 |
| -- Latest Android Studio Canary shows many undefined error but everthing compile fine. It was not the case before. |
148 | 44 |
|
149 | 45 | ## Troubleshooting
|
150 | 46 |
|
151 |
| -### cinteropYogaKitIosArm64 FAILED YogaKit module not found |
| 47 | +### e: java.lang.IllegalStateException: No file for *** |
152 | 48 |
|
153 |
| -You did not read the requirements. Install cocoapods-generate "gem install cocoapods-generate", invalid cache and restart Android Studio |
| 49 | +Compose function and CompositonLocal have to be internal and not exposed to iOS module. |
154 | 50 |
|
155 |
| -## Roadmap |
| 51 | +## Alternatives |
156 | 52 |
|
157 |
| -- More Jetpack Compose feature support |
158 |
| -- Better images/resources support |
159 |
| -- UI Test with Github Actions |
160 |
| -- Performance improvement/optimisation |
161 |
| -- Use Compose compiler and runtime on iOS |
| 53 | +- [Compose Multiplatform by JetBrains](https://github.com/JetBrains/compose-jb) started native support via Skia ([Skiko](https://github.com/JetBrains/skiko)), you can have a look at the [sample](https://github.com/JetBrains/compose-jb/tree/master/experimental/examples/falling-balls-mpp). Touchlab made a demo for [Droidcon NYC App](https://touchlab.co/droidcon-nyc-ios-app-with-compose/) It will use the compose compiler but not native component. |
162 | 54 |
|
163 |
| -## Sponsors |
164 |
| - |
165 |
| -No one yet, be the first [sponsor](https://github.com/sponsors/cl3m)! |
166 |
| - |
167 |
| -## Contributing |
| 55 | +- [Redwood Compose](https://github.com/cashapp/redwood) by Cash App. [Native UI with multiplatform Compose](https://jakewharton.com/native-ui-with-multiplatform-compose/). Use the compose compiler and native iOS component. |
168 | 56 |
|
169 |
| -All development (both new features and bug fixes) is performed in the `develop` branch. This way `master` always contains the sources of the most recently released version. Use git-flow if possible. |
| 57 | +- [Platform-Kit by IceRock](https://github.com/Alex009/compose-jb/tree/platform-kit-sample/examples/common-platform-uikit) based on Compose Multiplatform by JetBrains, add support via UIKit, thus use the compose compiler and native iOS component. |
170 | 58 |
|
171 |
| -You can start a PR with incomplete implementation to shows what you are working on. Please send PRs with bug fixes or new features to the `develop` branch. Documentation fixes in the markdown files are an exception to this rule. They are updated directly in `master`. |
| 59 | +- [multiplatform-compose](https://github.com/cl3m/multiplatform-compose/tree/yoga) This original repo, an experiment with native view and yoga for layout. You can also have a look at [kmp-redux](https://github.com/cl3m/kmp-redux/tree/skiko) that show Compose integration with SwiftUI. |
172 | 60 |
|
173 |
| -The `develop` branch is pushed to `master` on release. |
174 | 61 |
|
175 | 62 | ## License
|
176 | 63 |
|
|
0 commit comments