The goal of Project Two is to get familiar with Tauri, a Rust framework for creating cross-platform apps.
This project focuses on the Android and iOS platforms.
It helps users memorize contacts from their phone's contact book. That said, the functionality itself isn't the main focus here, as the primary goal is to gain familiarity with creating mobile apps using Tauri and Svelte."
The app has only two screens:
| Contacts list| Card|
|:-|:-|
||
|
To choose colors for the app I used The complete color harmony book.
In color theory, each color or combination of colors influences human emotions. I chose a palette from the book to create a casual mood.
This what I choose.
|1|2|3|4|
|:-|:-|:-|:-|
||
|
|
|
In css colors can be represented as hsl() function.
This function is based on Munsell color system
This representation is very convenient: hue defines the base color, while saturation and lightness enable easy creation of monochromatic variations, which is particularly useful in UI development.
In my case I was only changing saturation. Using Pantone color as a middle value and changing saturation with a step of 5%.
Code could be found here Colors.svelte.
This is the final color set vars.css
--bgColor-primary: var(--color-2566CP-1);
--bgColor-primary-light: var(--color-2566CP-7);
--bgColor-second: var(--color-2311CP-3);
--color-primary: var(--color-2311CP-3);
--color-second: var(--color-2566CP-1);
--accentColor-primary: var(--color-1535UP-10);
--accentColor-second: var(--color-1535UP-10);
--btnColor-primary: var(--accentColor-primary);
--borderColor-primary: var(--color-1535UP-2);
For a layout I used approach based on Every Layout book. (This book is fantastic).
Svelte is a great way to build user interfaces (UIs). It feels so natural, like actual vanilla web development.
Here are a few resources that I used as references for Svelte UI development:
One thing I struggled with was state management in Svelte (I mean it is easy I just did't know).
I wanted to load contact lists from the phone book or a stored file and manage that state across the entire app.
Here's the approach I took:
$state()
value
state and add all new values. If just replace value
in contactState.value
with a new array reactance is gone.This is my first experience with Tauri.
My initial impression is that it's a great way to build cross-platform apps.
I won't explain the core Tauri concepts or project bootstrapping here, as that's covered in the Tauri quick start. I'll just share what I did.
To interact with the native OS (in my case, Android and iOS), I used Tauri plugins. Tauri has a solid list of plugins.
For example, I used the file system plulgin to store the app's state in the file system.
I also created a custom plugin to access the contacts list on each mobile platform. What I found challenging was developing and debugging the plugins' native code on these mobile platforms.
Here I will highlight some parts that were not very obvious for me.
pnpm create tauri-app project-name
cd project-name
pnpm tauri android init
pnpm tauri ios init
pnpm tauri plugin new --directory /full-path/project-name/plugins/plugin-name plugin-name
cd plugin-name
pnpm tauri plugin android init
pnpm tauri plugin ios init
For android
add to AndroidManifest.xml
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_CONTACTS" />
For iOS
add to Info.plist
<key>NSContactsUsageDescription</key>
<string>This app needs access to your contacts to show them in your contact list.</string>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>NSPrivacyAccessedAPITypes</key>
<array>
<dict>
<key>NSPrivacyAccessedAPIType</key>
<string>NSPrivacyAccessedAPICategoryFileTimestamp</string>
<key>NSPrivacyAccessedAPITypeReasons</key>
<array>
<string>C617.1</string>
</array>
</dict>
</array>
</dict>
</plist>
This was a confgs part.
Apps also need to obtain permissions at runtime. Tauri already provides two commands
for this purpose, which we need to expose: check_permissions
and request_permissions
.
Look into these files
In android part - plugin should have permissions annotation ContactsPlugin.ktl
In iOS part - ContactsPlugin.swift checkPermissions
and requestPermissions
should be overwritten.
Permission state has three types prompt
| denied
| granted
This is example how these commands are used in contacts.svelte.js
pnpm tauri info
- gives the info about the project.pnpm tauri ios dev --open
- run project on ios emulator. If it is already open omit --open
pnpm tauri android dev --open
- run project on android emulator. If it is already open omit ---open