|
9 | 9 |
|
10 | 10 | The coverage report excludes code not intended to be covered.
|
11 | 11 |
|
12 |
| -This avoids the [“broken window” effect](https://blog.codinghorror.com/the-broken-window-theory/): whether coverage is at 43% or 56%, it’s perceived as equally low—so efforts to improve it are often dismissed. In contrast, high or near-100% coverage is seen as achievable and worth tracking. |
| 12 | +This avoids the [“broken window” effect](https://blog.codinghorror.com/the-broken-window-theory/): whether coverage is at 43% or 56%, it's perceived as equally low—so efforts to improve it are often dismissed. In contrast, high or near-100% coverage is seen as achievable and worth tracking. |
13 | 13 |
|
14 | 14 | Refer to the root project's [`build.gradle.kts`](build.gradle.kts#L55-L90) for details.
|
15 | 15 |
|
@@ -38,7 +38,7 @@ Refer to the root project's [`build.gradle.kts`](build.gradle.kts#L55-L90) for d
|
38 | 38 |
|
39 | 39 | > [!INFO] The application is also available as a desktop (Jvm) application and an iOS application as well (using [Compose Multi Platform (aka CMP)](https://www.jetbrains.com/compose-multiplatform/) as UI Toolkit).
|
40 | 40 |
|
41 |
| -> I set out to revisit the classical TODO app, ‘local-first’ syncing with Google Tasks—aiming for an <abbr title="Minimum Viable Experience">MVE</abbr> in 2 weeks, focusing on the 80/20 rule to nail the essentials. |
| 41 | +> I set out to revisit the classical TODO app, ‘local-first' syncing with Google Tasks—aiming for an <abbr title="Minimum Viable Experience">MVE</abbr> in 2 weeks, focusing on the 80/20 rule to nail the essentials. |
42 | 42 |
|
43 | 43 | |  |  |  |  |
|
44 | 44 | | --------------------------------------- |--------------------------------------- | ---------------------------------- | ---------------------------------- |
|
@@ -78,8 +78,9 @@ I do not aim to implement advanced features beyond what is supported by the Goog
|
78 | 78 |
|
79 | 79 | ## 🛠️ Tech stack
|
80 | 80 |
|
81 |
| -- [Kotlin](https://kotlinlang.org/), [Multiplatform (aka KMP)](https://kotlinlang.org/docs/multiplatform.html) (currently Desktop & Android are supported) |
82 |
| - - iOS wasn’t initially planned, but a draft version is available (use it at your own risks, bare minimum support is expected). It uses [Compose Multi Platform (aka CMP)](https://www.jetbrains.com/compose-multiplatform/). |
| 81 | +- [Kotlin](https://kotlinlang.org/), [Multiplatform (aka KMP)](https://kotlinlang.org/docs/multiplatform.html) |
| 82 | + - Android and Desktop are fully supported. |
| 83 | + - iOS wasn't initially planned, but a draft version is available (use it at your own risks, there might be dragons 🐉). |
83 | 84 | - Web is not planned any time soon (contribution are welcome 🤝)
|
84 | 85 | - [Kotlin coroutines](https://kotlinlang.org/docs/reference/coroutines/coroutines-guide.html)
|
85 | 86 | - [Ktor client](https://ktor.io/) (+ [Kotlinx serialization](https://kotlinlang.org/docs/serialization.html))
|
@@ -125,32 +126,13 @@ I do not aim to implement advanced features beyond what is supported by the Goog
|
125 | 126 | - The Desktop application (thin layer fully reusing `:tasks-app-shared`)
|
126 | 127 | - [`:tasks-app-android`](tasks-app-android) <span style="color: #66FF00;">■■■■■■■■</span>□□ 80%
|
127 | 128 | - The Android application (thin layer fully reusing `:tasks-app-shared`)
|
| 129 | +- [`:tasks-app-ios/Taskfolio`](tasks-app-ios/Taskfolio) <span style="color: #33FF00;">■■■■■■■■■</span>□ 90% |
| 130 | + - The iOS application (thin layer fully reusing `:tasks-app-shared`) |
| 131 | + - Xcode project, written in Swift |
128 | 132 | - [`website/`](website) <span style="color: #00FF00;">■■■■■■■■■■</span> 100%
|
129 | 133 | - The [static site](https://opatry.github.io/taskfolio/) presenting the project
|
130 | 134 | - Made with [Jekyll](https://jekyllrb.com/) and served by [Github pages](https://pages.github.com/)
|
131 | 135 |
|
132 |
| -## XXX iOS |
133 |
| - |
134 |
| -Dev environment initial setup (cf. https://touchlab.co/xcodekotlin): |
135 |
| -```bash |
136 |
| -brew install xcode-kotlin |
137 |
| -xcode-kotlin install |
138 |
| -``` |
139 |
| - |
140 |
| -Sync after Xcode update: |
141 |
| -```bash |
142 |
| -xcode-kotlin sync |
143 |
| -``` |
144 |
| - |
145 |
| -Build native `tasks-app-shared` code as iOS XCFramework: |
146 |
| -```bash |
147 |
| -./gradlew tasks-app-shared:linkDebugFrameworkIosSimulatorArm64 |
148 |
| -./gradlew tasks-app-shared:embedAndSignAppleFrameworkForXcode |
149 |
| -``` |
150 |
| - |
151 |
| -Either commit (but what?) or explain how to debug with Add Group > Add folders `tasks-app-shared/{commonMain,iosMain}`. |
152 |
| -cf. https://touchlab.co/xcodekotlin |
153 |
| - |
154 | 136 | ## 🧑💻 Local development
|
155 | 137 |
|
156 | 138 | <details>
|
@@ -187,6 +169,58 @@ When clicking on it, it will open a new window with the hot reload status.
|
187 | 169 | 
|
188 | 170 | </details>
|
189 | 171 |
|
| 172 | +## 🍎 Build for iOS target |
| 173 | + |
| 174 | +The support of iOS works more or less _as-is_ and gets the job done. It's provided without guarantees, use at your own risk. |
| 175 | +Feedback and contributions are welcome though 🤝. |
| 176 | + |
| 177 | +<details> |
| 178 | +<summary>See details…</summary> |
| 179 | + |
| 180 | +> [!INFO] iOS support is _opt-in_ and disabled by default to avoid unnecessary time and disk usage during the initial Gradle sync when the iOS target isn't required. |
| 181 | +> You can enable it by setting `ios.target` Gradle property to `all`, `simulator` or `device` from either `local.properties` or CLI using `-P`. |
| 182 | +> When building from Xcode, it automatically sets `-Pios.target=simulator` based on `Config.xcconfig`. |
| 183 | +
|
| 184 | +You can build the `:tasks-app-shared` code for iOS using Gradle (to check if evertyhing compiles on Kotlin side): |
| 185 | + |
| 186 | +```bash |
| 187 | +./gradlew tasks-app-shared:linkDebugFrameworkIosSimulatorArm64 -Pios.target=simulator |
| 188 | +``` |
| 189 | + |
| 190 | +For full XCFramework build (to be consumed by the iOS application), you'll have to rely on `xcodebuild` (or build directly from Xcode): |
| 191 | + |
| 192 | +```bash |
| 193 | +cd tasks-app-ios |
| 194 | +IOS_TARGET=simulator xcodebuild -project Taskfolio.xcodeproj \ |
| 195 | + -scheme Taskfolio \ |
| 196 | + -sdk iphonesimulator \ |
| 197 | + -arch arm64 \ |
| 198 | + -configuration Debug \ |
| 199 | + build \ |
| 200 | + CODE_SIGNING_ALLOWED=NO \ |
| 201 | + CODE_SIGN_IDENTITY="" \ |
| 202 | + CODE_SIGNING_REQUIRED=NO |
| 203 | +``` |
| 204 | +This triggers the `:tasks-app-shared:embedAndSignAppleFrameworkForXcode` Gradle task under the hood. |
| 205 | + |
| 206 | +For Xcode integration, it's recommended to install the [Xcode Kotlin plugin](https://touchlab.co/xcodekotlin): |
| 207 | + |
| 208 | +```bash |
| 209 | +brew install xcode-kotlin |
| 210 | +xcode-kotlin install |
| 211 | +``` |
| 212 | + |
| 213 | +When you update Xcode, you'll have to sync the plugin: |
| 214 | + |
| 215 | +```bash |
| 216 | +xcode-kotlin sync |
| 217 | +``` |
| 218 | + |
| 219 | +If you want to debug the Kotlin code from Xcode, you'll have to add the needed source sets in Xcode: |
| 220 | +Add Group > Add folders as **reference** > `tasks-app-shared/{commonMain,iosMain}` (or any other module you want to debug). |
| 221 | +If you properly installed the Xcode Kotlin plugin, you'll be able to set a breakpoint in the Kotlin code and see syntax coloring as well. |
| 222 | +</details> |
| 223 | + |
190 | 224 | ## ⚖️ License
|
191 | 225 |
|
192 | 226 | ```
|
|
0 commit comments