This library is a code generator that allows you to declare deeplinks in a simple way and generate the code to parse them into classes or objects under a sealed interface.
add the following dependencies to your gradle file:
implementation("com.ziina.library:deeplinkgenerator:<version>")
ksp("com.ziina.library:deeplinkgenerator:<version>")
First of all, you need to declare the supported schemas and hosts in the manifest file
<activity android:name=".DeepLinkActivity">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="example" />
</intent-filter>
<intent-filter android:autoVerify="true">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="https" />
<data android:host="example.com" />
<data android:host="www.example.com" />
</intent-filter>
</activity>
To declare deeplinks you need to create an interface and annotate it with @DeeplinkRoot
@DeeplinkRoot(
schemas = ["https", "example"],
defaultHosts = ["example.com", "www.example.com"]
)
interface Deeplinks
To declare a deeplink you need to create a function and annotate it with @Deeplink
@Deeplink(path = "/example1")
fun example1()
You can also add parameters to the deeplink
@Deeplink(path = "/example3/{id}/details/{name}")
fun example3(id: String, name: String)
And specify custom hosts list
IMPORTANT NOTE: if hosts
field is specified in the annotation, the defaultHosts
field in
the @DeeplinkRoot
annotation will be IGNORED
@Deeplink(path = "/{paymentId}", hosts = ["pay.example.com"])
fun example5(paymentId: String)
Code processor will generate:
- a sealed interface named as the name and a package of the interface annotated with
the
@DeeplinkRoot
with the suffixImpl
; - a function to parse the deeplink in the generated interface that will return the
proper
data class
ordata object
; - for each deeplink declared in the interface annotated with
@Deeplink
adata class
with the parameters declared in the function or adata object
if no parameters are declared.
example:
sealed interface DeeplinksImpl {
data object Example1 : DeeplinksImpl {
fun fromUrl(url: String): Example1? {
//...
}
}
data object Example3 : DeeplinksImpl {
companion object {
fun fromUrl(url: String): Example3? {
//...
}
}
}
data object Example5 : DeeplinksImpl {
companion object {
fun fromUrl(url: String): Example5? {
//...
}
}
}
companion object {
fun parse(url: String): DeeplinksImpl? {
val parsedUrl = parseUrl(url) ?: return null
if (parsedUrl.schema !in listOf("https", "example")) return null
Example1.fromUrl(url)?.let { return it }
Example3.fromUrl(url)?.let { return it }
Example5.fromUrl(url)?.let { return it }
return null
}
}
}
To use the generated code you can call the parse
function from the generated interface, and then
use when
function on returned object to handle the deeplink properly
fun handleUrl(url: String) {
val deeplink = DeeplinksImpl.parse(url) ?: return
when (deeplink) {
DeeplinksImpl.Example1 -> {
// navigate to example1 screen
}
is DeeplinksImpl.Example3 -> {
// navigate to example3 screen with params id and name
println(deeplink.id)
println(deeplink.name)
}
is DeeplinksImpl.Example5 -> {
// don't navigate but save params into the database
println(deeplink.paymentId)
}
}
}