Skip to content

Commit f0fb25a

Browse files
feat(shell): support opening URLs on mobile (#1319)
* feat(shell): support opening URLs on mobile closes #595 * Update and rename StorePlugin.swift to ShellPlugin.swift * unwrap * fix func name (ios) * use undeprecated func if avail --------- Co-authored-by: fabianlars <[email protected]>
1 parent 068b9a2 commit f0fb25a

File tree

13 files changed

+231
-0
lines changed

13 files changed

+231
-0
lines changed

plugins/shell/android/.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
/build
2+
/.tauri
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
plugins {
2+
id("com.android.library")
3+
id("org.jetbrains.kotlin.android")
4+
}
5+
6+
android {
7+
namespace = "app.tauri.shell"
8+
compileSdk = 33
9+
10+
defaultConfig {
11+
minSdk = 19
12+
targetSdk = 33
13+
14+
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
15+
consumerProguardFiles("consumer-rules.pro")
16+
}
17+
18+
buildTypes {
19+
release {
20+
isMinifyEnabled = false
21+
proguardFiles(
22+
getDefaultProguardFile("proguard-android-optimize.txt"),
23+
"proguard-rules.pro"
24+
)
25+
}
26+
}
27+
compileOptions {
28+
sourceCompatibility = JavaVersion.VERSION_1_8
29+
targetCompatibility = JavaVersion.VERSION_1_8
30+
}
31+
kotlinOptions {
32+
jvmTarget = "1.8"
33+
}
34+
}
35+
36+
dependencies {
37+
implementation("androidx.core:core-ktx:1.9.0")
38+
implementation("com.fasterxml.jackson.core:jackson-databind:2.15.3")
39+
implementation(project(":tauri-android"))
40+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# Add project specific ProGuard rules here.
2+
# You can control the set of applied configuration files using the
3+
# proguardFiles setting in build.gradle.
4+
#
5+
# For more details, see
6+
# http://developer.android.com/guide/developing/tools/proguard.html
7+
8+
# If your project uses WebView with JS, uncomment the following
9+
# and specify the fully qualified class name to the JavaScript interface
10+
# class:
11+
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12+
# public *;
13+
#}
14+
15+
# Uncomment this to preserve the line number information for
16+
# debugging stack traces.
17+
#-keepattributes SourceFile,LineNumberTable
18+
19+
# If you keep the line number information, uncomment this to
20+
# hide the original source file name.
21+
#-renamesourcefileattribute SourceFile
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
include ':tauri-android'
2+
project(':tauri-android').projectDir = new File('./.tauri/tauri-api')
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
3+
</manifest>
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// Copyright 2019-2023 Tauri Programme within The Commons Conservancy
2+
// SPDX-License-Identifier: Apache-2.0
3+
// SPDX-License-Identifier: MIT
4+
5+
package app.tauri.shell
6+
7+
import android.app.Activity
8+
import android.content.Intent
9+
import android.net.Uri
10+
import app.tauri.annotation.Command
11+
import app.tauri.annotation.TauriPlugin
12+
import app.tauri.plugin.Invoke
13+
import app.tauri.plugin.Plugin
14+
import java.io.File
15+
16+
@TauriPlugin
17+
class ShellPlugin(private val activity: Activity) : Plugin(activity) {
18+
@Command
19+
fun open(invoke: Invoke) {
20+
try {
21+
val url = invoke.parseArgs(String::class.java)
22+
val intent = Intent(Intent.ACTION_VIEW, Uri.parse(url))
23+
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
24+
activity?.applicationContext?.startActivity(intent)
25+
invoke.resolve()
26+
} catch (ex: Exception) {
27+
invoke.reject(ex.message)
28+
}
29+
}
30+
}

plugins/shell/build.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,20 @@ fn main() {
1111
tauri_plugin::Builder::new(COMMANDS)
1212
.global_api_script_path("./api-iife.js")
1313
.global_scope_schema(schemars::schema_for!(scope_entry::Entry))
14+
.android_path("android")
15+
.ios_path("ios")
1416
.build();
17+
18+
let target_os = std::env::var("CARGO_CFG_TARGET_OS").unwrap();
19+
let mobile = target_os == "ios" || target_os == "android";
20+
alias("desktop", !mobile);
21+
alias("mobile", mobile);
22+
}
23+
24+
// creates a cfg alias if `has_feature` is true.
25+
// `alias` must be a snake case string.
26+
fn alias(alias: &str, has_feature: bool) {
27+
if has_feature {
28+
println!("cargo:rustc-cfg={alias}");
29+
}
1530
}

plugins/shell/ios/Package.resolved

Lines changed: 16 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

plugins/shell/ios/Package.swift

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
// swift-tools-version:5.3
2+
// Copyright 2019-2023 Tauri Programme within The Commons Conservancy
3+
// SPDX-License-Identifier: Apache-2.0
4+
// SPDX-License-Identifier: MIT
5+
6+
import PackageDescription
7+
8+
let package = Package(
9+
name: "tauri-plugin-shell",
10+
platforms: [
11+
.iOS(.v13),
12+
],
13+
products: [
14+
// Products define the executables and libraries a package produces, and make them visible to other packages.
15+
.library(
16+
name: "tauri-plugin-shell",
17+
type: .static,
18+
targets: ["tauri-plugin-shell"]),
19+
],
20+
dependencies: [
21+
.package(name: "Tauri", path: "../.tauri/tauri-api")
22+
],
23+
targets: [
24+
// Targets are the basic building blocks of a package. A target can define a module or a test suite.
25+
// Targets can depend on other targets in this package, and on products in packages this package depends on.
26+
.target(
27+
name: "tauri-plugin-shell",
28+
dependencies: [
29+
.byName(name: "Tauri")
30+
],
31+
path: "Sources")
32+
]
33+
)
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
// Copyright 2019-2023 Tauri Programme within The Commons Conservancy
2+
// SPDX-License-Identifier: Apache-2.0
3+
// SPDX-License-Identifier: MIT
4+
5+
import Foundation
6+
7+
import SwiftRs
8+
import Tauri
9+
import UIKit
10+
import WebKit
11+
12+
class ShellPlugin: Plugin {
13+
14+
@objc public func open(_ invoke: Invoke) throws {
15+
do {
16+
let urlString = try invoke.parseArgs(String.self)
17+
if let url = URL(string: urlString) {
18+
if #available(iOS 10, *) {
19+
UIApplication.shared.open(url, options: [:])
20+
} else {
21+
UIApplication.shared.openURL(url)
22+
}
23+
}
24+
invoke.resolve()
25+
} catch {
26+
invoke.reject(error.localizedDescription)
27+
}
28+
}
29+
}
30+
31+
@_cdecl("init_plugin_shell")
32+
func initPlugin() -> Plugin {
33+
return ShellPlugin()
34+
}

0 commit comments

Comments
 (0)