generated from theolm/kmm-template
-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Documentation using MkDocs * Update documentation.yaml * Update documentation.yaml * mkdocs yml * remove logo * Update documentation.yaml
- Loading branch information
1 parent
a1b72a5
commit c09e227
Showing
8 changed files
with
294 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
name: documentation | ||
on: | ||
push: | ||
branches: | ||
- main | ||
permissions: | ||
contents: write | ||
jobs: | ||
deploy: | ||
runs-on: ubuntu-latest | ||
steps: | ||
- uses: actions/checkout@v4 | ||
- name: Configure Git Credentials | ||
run: | | ||
git config user.name github-actions[bot] | ||
git config user.email 41898282+github-actions[bot]@users.noreply.github.com | ||
- uses: actions/setup-python@v5 | ||
with: | ||
python-version: 3.x | ||
- run: echo "cache_id=$(date --utc '+%V')" >> $GITHUB_ENV | ||
- uses: actions/cache@v4 | ||
with: | ||
key: mkdocs-material-${{ env.cache_id }} | ||
path: .cache | ||
restore-keys: | | ||
mkdocs-material- | ||
- run: pip install mkdocs-material | ||
- run: mkdocs gh-deploy --force |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,114 @@ | ||
# Setup | ||
|
||
This guide presupposes the prior configuration of deeplinks within the native platforms: | ||
|
||
- [Android deeplink](https://developer.android.com/training/app-links/deep-linking?hl=pt-br) | ||
- [iOS URL scheme](https://developer.apple.com/documentation/xcode/defining-a-custom-url-scheme-for-your-app) | ||
- [iOS universal link](https://developer.apple.com/documentation/xcode/supporting-universal-links-in-your-app) | ||
|
||
### Android setup | ||
The library provides two types of initialization (KMP only and Compose), you should use the one that fit your needs. | ||
|
||
#### KMP only | ||
On the Android app, inside the `onCreate`, call the extension `RinkuInit()`. | ||
|
||
```kotlin | ||
class MainActivity : ComponentActivity() { | ||
override fun onCreate(savedInstanceState: Bundle?) { | ||
super.onCreate(savedInstanceState) | ||
RinkuInit() | ||
setContent { | ||
App() | ||
} | ||
} | ||
} | ||
``` | ||
|
||
#### With Compose multiplatform | ||
First make sure you included the `rinku-compose-ext`in your `commonMain`. | ||
On the Android app inside the `setContent` use `ComponentActivity.Riku` extension to wrap the root of your app. | ||
|
||
```kotlin | ||
class MainActivity : ComponentActivity() { | ||
override fun onCreate(savedInstanceState: Bundle?) { | ||
super.onCreate(savedInstanceState) | ||
|
||
setContent { | ||
Rinku { | ||
App() | ||
} | ||
} | ||
} | ||
} | ||
``` | ||
|
||
### iOS setup | ||
|
||
For the iOS platform, deep links are processed within the AppDelegate or SceneDelegate, contingent on the project's configuration. The primary objective is to intercept the platform-specific deep link and relay it as an argument to Rinku's handleDeepLink(url) method. | ||
|
||
Example within AppDelegate: | ||
|
||
```swift | ||
@UIApplicationMain | ||
class AppDelegate: NSObject, UIApplicationDelegate { | ||
... | ||
// Provide deepLinkFilter and deepLinkMapper if needed | ||
let rinku = RinkuIos.init(deepLinkFilter: nil, deepLinkMapper: nil) | ||
func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool { | ||
rinku.onDeepLinkReceived(url: url.absoluteString) | ||
return true | ||
} | ||
|
||
func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool { | ||
if userActivity.activityType == NSUserActivityTypeBrowsingWeb, let url = userActivity.webpageURL { | ||
let urlString = url.absoluteString | ||
rinku.onDeepLinkReceived(userActivity: userActivity) | ||
} | ||
return true | ||
} | ||
... | ||
} | ||
``` | ||
|
||
### Common setup | ||
In the common code you just need to listen to the deeplinks and treat them as you need. Once the application (Android or iOS) recieves a deeplink it will parse it into a `Deeplink` data class and pass it into the listener. Use the listener that suite your project. | ||
|
||
#### Using Compose | ||
|
||
Example RootApp in commonMain: | ||
|
||
```kotlin | ||
@Composable | ||
fun RootApp() { | ||
var deepLink by remember { mutableStateOf<DeepLink?>(null) } | ||
DeepLinkListener { deepLink = it } | ||
MainScreen(deepLink) | ||
} | ||
``` | ||
|
||
#### KMP only | ||
Just use the suspend function `listenForDeepLinks` and react as you will. | ||
|
||
Example inside a Decompose component: | ||
|
||
```kotlin | ||
class AppComponentImpl( | ||
private val initialStack: List<Config> = emptyList(), | ||
componentContext: ComponentContext, | ||
) : AppComponent, ComponentContext by componentContext { | ||
private val navigation = StackNavigation<Config>() | ||
|
||
init { | ||
launch { initDeepLinkListener() } | ||
} | ||
|
||
private suspend fun initDeepLinkListener() { | ||
listenForDeepLinks { | ||
navigation.replaceAll( | ||
*it.toScreenStack().toTypedArray() | ||
) | ||
} | ||
} | ||
} | ||
|
||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
# Firing Internal Deeplink | ||
|
||
To invoke an internal deep link within your application, use the handleDeepLink method provided by Rinku. This method accepts a single parameter: the URL of the deep link you wish to trigger. | ||
|
||
```kotlin | ||
Rinku.handleDeepLink("https://test.deeplink/path?query=true") | ||
``` | ||
|
||
In this example, https://test.deeplink/path?query=true represents the URL of the deep link. The URL scheme, path, and query parameters should be replaced with values that are relevant to your application's routing structure. | ||
|
||
By leveraging Rinku's handleDeepLink method, you can enhance your application's navigation capabilities, making it easier to programmatically direct users to specific areas of your app from shared KMP code. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
# Type-safe parameters | ||
|
||
Rinku supports get and create typesafe parameters leveraging the kotlinx-serialization. In order to use the following functions the app/module needs to setup [kotlinx-serialization](https://github.com/Kotlin/kotlinx.serialization). | ||
|
||
### Getting parameters | ||
Use the `DeepLink` extension `<T> DeepLink.getParameter` and pass the key of the argument in the URL query and the KSerializer of the correspoinding kotlin class. | ||
|
||
example: | ||
|
||
```kotlin | ||
@Serializable | ||
data class Name(val name: String) | ||
|
||
fun example() { | ||
val url = "https://theolm/dev/path?test={"name": "Theo"}" | ||
val deepLink = DeepLink(url) | ||
|
||
val param : Name = deepLink.getParameter(name = "wrong name", kSerializer = Name.serializer()) | ||
} | ||
|
||
``` | ||
|
||
### Build a URL using Serializable classes | ||
Rinku also provides the helper funcion `Rinku.buildUrl` that facilitates the creation of internal deeplinks with parameters. In order to do that you first need to create the URL and fire the deeplink. | ||
|
||
example: | ||
|
||
```kotlin | ||
@Serializable | ||
data class Name(val name: String) | ||
|
||
fun example() { | ||
val testModel = Name("Testing") | ||
val testParam = DeepLinkParam( | ||
"testParam", | ||
testModel, | ||
Name.serializer() | ||
) | ||
val url = Rinku.buildUrl(TestUrl, testParam) | ||
Rinku.handleDeepLink(url) | ||
} | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
# Internal Deeplink Filter | ||
|
||
Rinku provides a simple way to filter unwanted external deeplinks. | ||
Instead of filter deeplinks providing specific paths in the AndroidManifest and info.plist you implment the interface `DeepLinkFilter` and pass it into Rinku initialization. With this configuration, when the app recieves a not valid deeplink rinku is not going to handle it. This is usefull to block internal deeplinks from external access without having to include it in platform specific configuration. | ||
|
||
### Deeplink mapper | ||
This feature is used to map external deeplinks into internal deeplinks. | ||
Use case 1: Android and ios application has different deeplinks registered in marketing campaigns. The mapper can be used to map the external deeplink to unique internal deeplink, and the application can handle the deeplink accordingly in a unified way. | ||
Use case 2: External deeplink does not have the full path to represent a valid stack. Use the mapper to provide the full stack. | ||
|
||
```kotlin | ||
// External deeplink rinku://dev.theolm/screenC/ | ||
// The deeplink is missing A and B | ||
|
||
// Implement and pass the mapper into Rinku init. This way the external deeplink will be mapped and can be handle in the commonMain. | ||
object ExampleMapper : DeepLinkMapper { | ||
override fun map(url: String): String { | ||
return if (url == "rinku://dev.theolm/screenC/") { | ||
return "rinku://dev.theolm/screenA/screenB/screenC/" | ||
} else { | ||
url | ||
} | ||
} | ||
} | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
# Demonstrative Samples | ||
|
||
The library includes two illustrative examples utilizing the foremost multiplatform navigation libraries: [Voyager](https://voyager.adriel.cafe/) and [Decompose](https://github.com/arkivanov/Decompose) | ||
|
||
- [Voyager sample](https://github.com/theolm/Rinku/tree/main/samples/voyager) | ||
- [Decompose sample](https://github.com/theolm/Rinku/tree/main/samples/decompose) | ||
|
||
*Note: Only the Voyager sample includes an iOS application. Nonetheless, the setup for Decompose would mirror that of Voyager.* | ||
|
||
*Note 2: Both examples are using Compose multiplatform.* |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
# Welcome to Rinku | ||
|
||
Rinku is a lightweight Kotlin Multiplatform library designed to simplify deep link handling across iOS and Android platforms. By abstracting platform-specific details, Rinku enables developers to manage deep links in a unified manner, enhancing code reuse and maintaining consistency across platforms. | ||
|
||
## Summary | ||
|
||
### 1. [Setup](./1-setup.md) | ||
|
||
### 2. [Firing Internal Deep Links](./2-firing-internal-deeplink.md) | ||
|
||
### 3. [Type-safe parameters](./3-type-safe-parameters.md) | ||
|
||
### 4. [Internal deeplink filter](./4-internal-deeplink-filter.md) | ||
|
||
### 5. [Demonstrative Samples](./5-demonstrative-samples.md) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
site_name: Rinku Documentation | ||
theme: | ||
name: material | ||
font: | ||
text: Merriweather Sans | ||
code: Red Hat Mono | ||
logo: assets/logo.png | ||
favicon: assets/favicon.ico | ||
features: | ||
- navigation.footer | ||
- content.code.annotations # (1)! | ||
palette: | ||
# Dark Mode | ||
- scheme: slate | ||
toggle: | ||
icon: material/weather-sunny | ||
name: Dark mode | ||
primary: green | ||
accent: deep purple | ||
|
||
# Light Mode | ||
- scheme: default | ||
toggle: | ||
icon: material/weather-night | ||
name: Light mode | ||
primary: blue | ||
accent: deep orange | ||
|
||
markdown_extensions: | ||
- smarty | ||
- codehilite: | ||
guess_lang: false | ||
- footnotes | ||
- meta | ||
- toc: | ||
permalink: true | ||
- pymdownx.betterem: | ||
smart_enable: all | ||
- pymdownx.caret | ||
- pymdownx.inlinehilite | ||
- pymdownx.magiclink | ||
- pymdownx.smartsymbols | ||
- pymdownx.superfences | ||
- pymdownx.emoji | ||
- pymdownx.details | ||
- pymdownx.tabbed: | ||
alternate_style: true | ||
- tables | ||
- admonition |