KMPizza
Kotlin Multiplatform + Pizza = ❤️

Step 29: Add assets and a placeholder for no internet connection

Remember the task from Step 27?

If you try opening one of the locally saved recipes without internet connection, you’ll notice that there is no image. Fix it by adding a “No Internet” placeholder instead of an empty space when the user can’t download the image.

Here’s my solution.
First, find an image you’d like to show when image libraries fail to load a placeholder image from the Internet.
In Android place this image in res/drawable:

drawable folder

In iOS first create an Asset Catalog by clicking on “New File…” and adding an Asset catalog.

add asset catalog

You’ll see it in your app structure:

ios structure

Then just drag and drop the chosen image to this catalog:

asset image ios

Now we can use this image in our apps.

In Android simply extend the HeaderImage loading with error:

 
AsyncImage(
   model = image,
   modifier = Modifier.size(200.dp),
   contentDescription = null,
   error = painterResource(id = R.drawable.no_pizza)
)

Turn off the connection. Build and run the Android app. You’ll see if the recipe has an image, but it couldn’t be downloaded, there’ll be a no-connection placeholder instead:

android no-connection

Similarly, in iOS we can extend KFImage logics in RecipeDetailView with .placeholder:

 
if (state.recipe?.images.isEmpty == false){
                KFImage(URL(string: state.recipe?.images.first?.image ?? ""))
                    .resizable()
                    .placeholder { Image("no_pizza").resizable() }
                    .frame(width: 180, height: 180)
            }

However, if you try running the app you’ll get an error about a missing AppIcon.
Looks like we accidentally deleted something 😱
But no worries, it’s a good excuse to add an AppIcon to our app!

First, go to https://appicon.co and create a set of icons for you Android and iOS apps.

Then simply take Assets.xcassets and drag it to your iOS project.
Then remove the old Assets catalog and place your no-connection image to the new one.

Also change the name of the iOS app here:

ios app change name

Build and run the app again. Turn off the internet connection and you’ll see a no-connection placeholder image.

ios no-cnnection

And the app has a new icon and name now as well:

ios ap icon

Finally, let’s also add an app icon and change the name in the Android app.
Go to File -> New -> Image Asset

android image asset

Then choose your image

choose image asset

Finally, in Android Manifest specify the app icon (and also the app name):

 
android:label="@string/app_name"
android:icon="@mipmap/ic_launcher"

Build and run the app again. In your Android apps you’ll see the new icon and a new name:

android app icon

Now, KMPizza has grown to be a rather functional KMP app. It has a Ktor backend and a shared business layer. What’s more, it also shares the ViewModel layer between iOS and Android.

But in software development there’s always room for growth. Since I started with KMP a lot of new libraries appeared, which make the development easier. There are also different approaches to a shared local database - for example, using Realm. There are other Kotlin backend frameworks as well, like Kotlin Spring, Micronaut, Vert.X. In general, KMP offers a great playground for your future experiments and projects.

Meanwhile, there are already teams that are using KMP in prouduciton to gain a competitive edge. Once KMP goes stable, there will be even more reasons to adopt it.

May be your KMP project will be the next big thing?

Use your imagination and never stop learning!