Skip to content

Commit

Permalink
Introduce SKIE
Browse files Browse the repository at this point in the history
Co-authored-by: Russell Wolf <[email protected]>
Co-authored-by: Jigar Brahmbhatt <[email protected]>
  • Loading branch information
3 people committed Sep 27, 2023
1 parent e81643a commit 2b7561d
Show file tree
Hide file tree
Showing 39 changed files with 480 additions and 527 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/KaMPKit-Android.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ jobs:
- uses: actions/setup-java@v3
with:
distribution: corretto
java-version: 11
java-version: 17

- name: Build
run: ./gradlew build
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/KaMPKit-iOS.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ jobs:
- uses: actions/setup-java@v3
with:
distribution: corretto
java-version: 11
java-version: 17

- name: Build
run: ./gradlew :shared:iosX64Test
Expand Down
46 changes: 27 additions & 19 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,40 +5,43 @@

![KaMP Kit Image](kampkit.png)

***Welcome to KaMP Kit!***
***Welcome to KaMP Kit!***

## 2022 Update
## Intro

KaMP Kit started a little over 2 years ago with the goal of helping developers interested in KMP and KMM get started
KaMP Kit started a little under 4 years ago with the goal of helping developers interested in Kotlin Multiplatform (aka KMP) get started
quickly with a great set of libraries and patterns. At the time, there were not many sample apps and getting started
was not trivial. The KMM situation has improved considerably since then, and various barriers to entry have been
removed.

Whereas KaMP Kit started with the goal of being a minimal sample, we now intend it to be less "getting started" and
more "best practice model". Watch this repo and follow [@TouchlabHQ](https://twitter.com/TouchlabHQ) for updates!
Whereas KaMP Kit started with the goal of being a minimal sample, we now intend it to be less `getting started` and
more `best practice model`. Watch this repo and follow [@TouchlabHQ](https://twitter.com/TouchlabHQ) for updates!

### 2023 Update

We updated `KaMPKit` to make sure of Touchlab's new [SKIE](https://skie.touchlab.co/) tool. SKIE allowed use to remove a lot of boilerplate code related to `ViewModel` sharing, and also we can now use Kotlin sealed classes as Swift enums in iOS code. Take a look at our detailed [migration case study](https://touchlabpro.touchlab.dev/touchlab/training/skie-architecture/migrating-kampkit-to-skie)

> ## Subscribe!
>
> We build solutions that get teams started smoothly with Kotlin Multiplatform Mobile and ensure their success in production. Join our community to learn how your peers are adopting KMM.
> We build solutions that get teams started smoothly with Kotlin Multiplatform and ensure their success in production. Join our community to learn how your peers are adopting KMM.
[Sign up here](https://go.touchlab.co/newsletter-gh)!

## Getting Help

KaMP Kit support can be found in the Kotlin Community Slack, [request access here](http://slack.kotlinlang.org/). Post in the "[#touchlab-tools](https://kotlinlang.slack.com/archives/CTJB58X7X)" channel.
KaMP Kit support can be found in the Kotlin Community Slack, [request access here](http://slack.kotlinlang.org/). Post in the [#touchlab-tools](https://kotlinlang.slack.com/archives/CTJB58X7X) channel.

For direct assistance, please [contact Touchlab](https://go.touchlab.co/contactkamp) to discuss support options.

## About

### Goal

The goal of KaMP Kit is to facilitate your evaluation of Kotlin Multiplatform (aka KMP). It is a collection of code and
The goal of KaMP Kit is to facilitate your evaluation of KMP. It is a collection of code and
tools designed to get you started quickly. It's also a showcase of Touchlab's typical choices for architecture,
libraries, and other best practices.

The KMP ecosystem has generated a lot of excitement, and has evolved very rapidly. As a result, there's a lot of old or
conflicting documentation, blog posts, tutorials, etc. We, Touchlab, have worked with several teams looking at KMM (
Kotlin Multiplatform Mobile) and KMP, and have found that the **primary** stumbling block is simply getting started.
conflicting documentation, blog posts, tutorials, etc. We, Touchlab, have worked with several teams looking at KMP, and have found that the **primary** stumbling block is simply getting started.

KaMP Kit is designed to get you past that primary stumbling block. You should be able to set up your development environment, clone the repo, and have a running sample app very quickly. From there, you can focus on what you want to build.

Expand All @@ -48,7 +51,7 @@ This kit exists because the info you may find from Google about KMM and KMP is l

### Audience

We (Touchlab) are focused primarily on using KMP for native mobile development (now called KMM). As a result, this kit is primarily targeted at native mobile developers (Android or iOS), as well as engineering managers for native mobile teams. You should have little-to-no experience with KMP, although some of the information after setup may be useful if you do have KMP experience.
We (Touchlab) are focused primarily on using KMP for native mobile development. As a result, this kit is primarily targeted at native mobile developers (Android or iOS), as well as engineering managers for native mobile teams. You should have little-to-no experience with KMP, although some of the information after setup may be useful if you do have KMP experience.

## What's Included?

Expand All @@ -68,10 +71,9 @@ The central part of the "Kit" is the starter app. It includes a set of libraries

You will need the following:

* JVM 8
* Android SDK and the latest stable Android Studio(2021.2.1+) or IntelliJ(2021.2+)
* Intellij Kotlin plugin with 1.7.10 support (should be included in the latest Android Studio or IDEA)
* Mac with Xcode 14+ for the iOS build
- JVM 17
- Android SDK and the latest stable Android Studio (2022.3+) or IntelliJ(2023.2+)
- Mac with Xcode 14+ for the iOS build

For a more detailed guide targeted at iOS developers, see [DETAILED_DEV_SETUP](docs/DETAILED_DEV_SETUP.md).

Expand Down Expand Up @@ -99,7 +101,7 @@ If the app is building, it's a good time to take a break and get some background

### KMP Intro

It's important to understand not just how to set up the platform, but to get a better perspective on what the tech can do and why we think it'll be very successful. KMP is distinct from other code sharing and "cross platform" systems, and understanding those distinctions is useful.
It's important to understand not just how to set up the platform, but to get a better perspective on what the tech can do and why we think it'll be very successful. KMP is distinct from other code sharing and `cross platform` systems, and understanding those distinctions is useful.

[Longer intro to KaMP Kit](docs/WHAT_AND_WHY.md) - Original version of this doc's intro. Cut because it was pretty long.

Expand All @@ -108,20 +110,26 @@ It's important to understand not just how to set up the platform, but to get a b
### "Selling" KMP

KaMPKit can help you demonstrate to management and other stakeholders the value of sharing code with KMP. Check out these resources for more advice on pitching KMP to your team:

[Kotlin Multiplatform Mobile for Teams](https://www.youtube.com/watch?v=-tJvCOfJesk&t=2145s)

[Building a Business Case for KMP](https://touchlab.co/building-business-case-kotlin-multiplatform/)

[7 ways to convince your engineering manager to pilot Kotlin Multiplatform](https://touchlab.co/7-ways-convince-engineering-manager-pilot-kotlin-multiplatform/)

### Xcode Debugging

For information on how to debug Kotlin in Xcode, check out the [Debugging Kotlin In Xcode](docs/DEBUGGING_KOTLIN_IN_XCODE.md) doc.
For information on how to debug Kotlin in Xcode, check out the [Debugging Kotlin In Xcode](docs/DEBUGGING_KOTLIN_IN_XCODE.md) doc.

## 5) Integrating 'shared' With Existing Apps

As part of your evaluation, you'll need to decide if you're going to integrate KMP into existing apps. Some teams feel integrating with their production apps is a better demonstration of KMP's viability. While KMP's interop is great, relative to other technologies, **integrating *anything* into a production app build process can be a difficult task**. Once integrated, development is generally smooth, but modifying production build systems can be a time consuming task.

[Adopting Kotlin Multiplatform In Brownfield Applications](https://www.youtube.com/watch?v=rF-w_jL0qsI)

### Android

The Android side is somewhat more straightforward. Kotlin is the preferred language for Android, and the library can be integrated as just another module library. We'll be updating soon with a general Android integration doc. In the meantime, the simplest method would be to copy the shared module into your standard Android build, and use the `app` module as a reference for dependency resolution.
The Android side is somewhat more straightforward. Android development is Kotlin-first nowadays, and the library can be integrated as just another module library. We'll be updating soon with a general Android integration doc. In the meantime, the simplest method would be to copy the shared module into your standard Android build, and use the `app` module as a reference for dependency resolution.

### iOS

Expand Down Expand Up @@ -160,5 +168,5 @@ We have made KMP the focus of Touchlab. We had possibly the first KMP* app publi

> ## Subscribe!
>
> We build solutions that get teams started smoothly with Kotlin Multiplatform Mobile and ensure their success in production. Join our community to learn how your peers are adopting KMM.
> We build solutions that get teams started smoothly with Kotlin Multiplatform and ensure their success in production. Join our community to learn how your peers are adopting KMP.
[Sign up here](https://go.touchlab.co/newsletter)!
3 changes: 3 additions & 0 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ android {
}
compileOptions {
isCoreLibraryDesugaringEnabled = true
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
}

lint {
Expand All @@ -32,6 +34,7 @@ android {

buildFeatures {
compose = true
buildConfig = true
}

composeOptions {
Expand Down
49 changes: 36 additions & 13 deletions app/src/main/kotlin/co/touchlab/kampkit/android/ui/Composables.kt
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,10 @@ fun MainScreen(
val dogsState by viewModel.breedState.collectAsStateWithLifecycle()
val scope = rememberCoroutineScope()

LaunchedEffect(viewModel) {
viewModel.activate()
}

MainScreenContent(
dogsState = dogsState,
onRefresh = { scope.launch { viewModel.refreshBreeds() } },
Expand All @@ -74,22 +78,23 @@ fun MainScreenContent(
val refreshState = rememberPullRefreshState(dogsState.isLoading, onRefresh)

Box(Modifier.pullRefresh(refreshState)) {
if (dogsState.isEmpty) {
Empty()
}
val breeds = dogsState.breeds
if (breeds != null) {
LaunchedEffect(breeds) {
when (dogsState) {
is BreedViewState.Empty -> Empty()
is BreedViewState.Content -> {
val breeds = dogsState.breeds
onSuccess(breeds)
Success(successData = breeds, favoriteBreed = onFavorite)
}
Success(successData = breeds, favoriteBreed = onFavorite)
}
val error = dogsState.error
if (error != null) {
LaunchedEffect(error) {

is BreedViewState.Error -> {
val error = dogsState.error
onError(error)
Error(error)
}

BreedViewState.Initial -> {
// no-op (just show spinner until first data is loaded)
}
Error(error)
}

PullRefreshIndicator(dogsState.isLoading, refreshState, Modifier.align(Alignment.TopCenter))
Expand Down Expand Up @@ -182,11 +187,29 @@ fun FavoriteIcon(breed: Breed) {
@Composable
fun MainScreenContentPreview_Success() {
MainScreenContent(
dogsState = BreedViewState(
dogsState = BreedViewState.Content(
breeds = listOf(
Breed(0, "appenzeller", false),
Breed(1, "australian", true)
)
)
)
}

@Preview
@Composable
fun MainScreenContentPreview_Initial() {
MainScreenContent(dogsState = BreedViewState.Initial)
}

@Preview
@Composable
fun MainScreenContentPreview_Empty() {
MainScreenContent(dogsState = BreedViewState.Empty())
}

@Preview
@Composable
fun MainScreenContentPreview_Error() {
MainScreenContent(dogsState = BreedViewState.Error("Something went wrong!"))
}
2 changes: 0 additions & 2 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,6 @@ allprojects {
repositories {
google()
mavenCentral()
maven("https://androidx.dev/storage/compose-compiler/repository/")
maven("https://maven.pkg.jetbrains.space/kotlin/p/kotlin/dev/")
}
}

Expand Down
12 changes: 6 additions & 6 deletions docs/APP_BUILD.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
## Prerequisites
Before you build the app you will require these items:

* JVM 8
* Android SDK and Android Studio or IntelliJ
* Mac with Xcode 11+ for the iOS build
* JVM 17
- Android SDK and the latest stable Android Studio (2022.3+) or IntelliJ(2023.2+)
- Mac with Xcode 14+ for the iOS build

For more details, check out the [DETAILED_DEV_SETUP](DETAILED_DEV_SETUP.md) document.

Expand All @@ -17,7 +17,7 @@ git clone https://github.com/touchlab/KaMPKit.git

### 2) Build Android
1. Open the project in Android Studio/IntelliJ and wait for indexing to finish.
2. Make sure you see the run config for the Android app
2. Make sure you see the run config for the Android app
![](runconfig.png)
3. Run the Android app on either the Emulator or a phone. If the app builds correctly, you should see this:

Expand All @@ -26,8 +26,8 @@ git clone https://github.com/touchlab/KaMPKit.git
### 3) Build iOS

1. [Optional] Run gradle build. If you are more familiar with Android it may be easier to run the gradle build and confirm that the shared library builds properly before moving into Xcode land, but this isn't necessary. The shared library will also build when run in Xcode.
1. Open a Terminal window or use the one at the bottom of Android Studio/IntelliJ.
2. Navigate to the project's root directory (`KaMPKit/` - not `KaMPKit/ios/` - which is iOS project's root directory).
1. Open a Terminal window or use the one at the bottom of Android Studio/IntelliJ.
2. Navigate to the project's root directory (`KaMPKit/` - not `KaMPKit/ios/` - which is iOS project's root directory).
3. Run the command `./gradlew build` which will build the shared library.
2. Open Xcode **workspace** project in the `ios/` folder: `KaMPKitiOS.xcworkspace`.
3. Run the iOS app on either the Simulator or a phone. If the app builds correctly, you should see this:
Expand Down
24 changes: 9 additions & 15 deletions docs/DETAILED_DEV_SETUP.md
Original file line number Diff line number Diff line change
@@ -1,29 +1,26 @@
# KMP Development Environment Setup

Not assuming anything if you're an iOS developer. You may not have the Android/JVM setup necessary to run everything.

Not assuming anything if you're an iOS developer. You may not have the Android/JVM setup necessary to run everything.


## Install JDK

You'll need a JDK (Java Development Kit), preferably version 8. We recommend
[Amazon Corretto](https://docs.aws.amazon.com/corretto/latest/corretto-8-ug/macos-install.html). Download the pkg
You'll need a JDK (Java Development Kit), version 17. You can use the one already comes built-in the Android Studio but if you prefer a standalone JDK installation then, we recommend
[Amazon Corretto](https://docs.aws.amazon.com/corretto/latest/corretto-17-ug/macos-install.html). Download the pkg
installer and go through the setup instructions.

Some alternative options, if desired:

- [SDKMan](https://sdkman.io/) - JDK version manager and installer.
- [AdoptOpenJDK](https://adoptopenjdk.net/) - Alternate JDK distribution.



## Install the IDE(s)

You'll also need either Android Studio, IntelliJ, or both. Android Studio is an Android development
focused skin of IntelliJ, which is more platform agnostic. There is a built-in KMM plugin in the
Android Studio, which enables you to run and debug the iOS part of your application on iOS targets
straight from Android Studio. IntelliJ IDEA has a newer Kotlin API platform and gets bugfixes
sooner, but it has an older version of Android plugin. If you don't have either, we recommend
sooner, but it has an older version of Android Gradle Plugin. If you don't have either, we recommend
installing both through
the [Jetbrains Toolbox](https://www.jetbrains.com/toolbox-app/download/download-thanks.html).

Expand All @@ -34,29 +31,26 @@ If you just want one or the other, you can use the following links:
- [IntelliJ setup guide](https://www.jetbrains.com/help/idea/run-for-the-first-time.html)

You can use [KDoctor](https://github.com/Kotlin/kdoctor) to help you set-up your environment for
Kotlin Multiplatform Mobile app development. It ensures that all required components are properly
Kotlin Multiplatform app development. It ensures that all required components are properly
installed and ready for use. If something is missed or not configured KDoctor highlights the problem
and suggests how to fix the problem.

## Open IDE

Once you have your IDE installed, open it. If it's Android Studio, select **Open an Existing Android Studio Project** and if it's IntelliJ select **Import Project**. In the finder that opens up, select the root directory of your clone of this repository.

Opening this project in Android Studio should automatically configure the project's `local.properties` file. If for some reason it doesn't, or if you open the project in IntelliJ, you'll need to configure this file manually. To do so, open `local.properties`, and set the value of `sdk.dir` to `/Users/[YOUR_USERNAME]/Library/Android/sdk`.
Opening this project in Android Studio should automatically configure the project's `local.properties` file. If for some reason it doesn't, or if you open the project in IntelliJ, you'll need to configure this file manually. To do so, open `local.properties`, and set the value of `sdk.dir` to `/Users/[YOUR_USERNAME]/Library/Android/sdk` (or path to where Android SDK is installed).

On the left, above the project structure (or the Project Navigator in Xcode-ese), there's a dropdown menu above your project's root directory. Make sure that it's set to "Project" (_for context: the IDE may think that you're working on a traditional Android project and set this menu to "Android" or make some similar mistake, and organize the files in the navigator accordingly_).



## Install an Android Emulator

The Android corollary to a Simulator is an Emulator. To install an Emulator, you need to open the Android Virtual Device (AVD) Manager, which is the corollary to the Device and Simulators window in Xcode.

If you're in Android Studio, go to Tools -> AVD Manager. If you're in IntelliJ, there's one extra step: go to Tools -> Android -> AVD Manager. After this first step, the process is the same in Android Studio and IntelliJ. Select **+ Create New Virtual Device...**.

You'll have a large choice of devices to choose from, but we recommend you install the newest, largest Pixel device to emulate (Pixel 3 XL at the time this is being written). Go to the next step and select the newest API level, and then go to the last step and select **Finish**.
The Android corollary to a Simulator is an Emulator. To install an Emulator, you need to open the Android Virtual Device (AVD) Manager, which is the corollary to the Device and Simulators window in Xcode.

If you're in Android Studio, go to Tools -> AVD Manager. If you're in IntelliJ, there's one extra step: go to Tools -> Android -> AVD Manager. After this first step, the process is the same in Android Studio and IntelliJ. Select **+ Create New Virtual Device...**.

You'll have a large choice of devices to choose from, but we recommend you install the newest, latest Pixel device to emulate. Go to the next step and select the newest API level, and then go to the last step and select **Finish**.

## Next Steps

Expand Down
Loading

0 comments on commit 2b7561d

Please sign in to comment.