---
title: Tauri 2.0.0-alpha.4 Released
date: 2023-03-20
authors: [lucasfernog]
excerpt: Mobile APIs for Tauri plugins! The 2.0.0-alpha.4 release has been published.
---

import CommandTabs from '@components/CommandTabs.astro';

![Tauri 1.2 Launch Hero Image](./tauri_2_0_0_alpha_0/header.png)

A new alpha release for the 2.0 has been published. This release includes all changes from the upcoming Tauri 1.3 release, an important breaking change on the HTTP client and native mobile capabilities for Tauri plugins.

## Updating dependencies

Make sure to update both NPM and Cargo dependencies to the latest alpha release. You can update the NPM dependencies with:

<CommandTabs
  npm="npm install @tauri-apps/cli@next @tauri-apps/api@next"
  yarn="yarn upgrade @tauri-apps/cli@next @tauri-apps/api@next"
  pnpm="pnpm update @tauri-apps/cli@next @tauri-apps/api@next"
  cargo='cargo add tauri@2.0.0-alpha.4
cargo add tauri-build@2.0.0-alpha.2 --build
cargo install tauri-cli --version "^2.0.0-alpha" --locked'
/>

Recreate the mobile projects to use the new features:

```shell
rm -r src-tauri/gen
tauri android init
tauri ios init
```

## HTTP Client Breaking Change

The default HTTP client using `attohttpc` has been removed due to issues with the development server proxy on Windows. All `reqwest-*` feature flags have been removed because `reqwest` is now the client we use.

## Native Mobile Functionality for Tauri Plugins

A Tauri plugin now can access iOS via Swift and Android APIs via Kotlin or Java code, simplifying usage of platform interfaces such as camera or geolocation. To bootstrap the iOS and Android projects on an existing plugin, run `tauri plugin ios add` and `tauri plugin android add`. New plugins automatically include all the configuration needed to write native mobile code.

Here's an example of a plugin that takes a string value and resolves an object:

**Android plugin:**

```kotlin title="ExamplePlugin.kt"
package com.plugin.example

import android.app.Activity
import app.tauri.annotation.Command
import app.tauri.annotation.TauriPlugin
import app.tauri.plugin.JSObject
import app.tauri.plugin.Plugin
import app.tauri.plugin.Invoke

@TauriPlugin
class ExamplePlugin(private val activity: Activity): Plugin(activity) {
    @Command
    fun ping(invoke: Invoke) {
        val value = invoke.getString("value") ?: ""
        val ret = JSObject()
        ret.put("value", value)
        invoke.resolve(ret)
    }
}
```

**iOS plugin:**

```swift title="ExamplePlugin.swift"
import UIKit
import WebKit
import Tauri

class ExamplePlugin: Plugin {
	@objc public func ping(_ invoke: Invoke) throws {
		let value = invoke.getString("value")
		invoke.resolve(["value": value as Any])
	}
}

@_cdecl("init_plugin_example")
func initPlugin(name: SRString, webview: WKWebView?) {
	Tauri.registerPlugin(webview: webview, name: name.toString(), plugin: ExamplePlugin())
}

```

**Rust code to initialize the plugin:**

```rust
use tauri::{
  plugin::{Builder, TauriPlugin},
  Manager, Runtime,
};

#[cfg(target_os = "ios")]
tauri::ios_plugin_binding!(init_plugin_example);

pub fn init<R: Runtime>() -> TauriPlugin<R> {
  Builder::new("example")
    .setup(|app, api| {
      #[cfg(target_os = "android")]
      api.register_android_plugin("com.plugin.example", "ExamplePlugin")?;
      #[cfg(target_os = "ios")]
      api.register_ios_plugin(init_plugin_example)?;
      Ok(())
    })
    .build()
}
```

**Frontend code to call the plugin command:**

```javascript
import { invoke } from '@tauri-apps/api/tauri';
invoke('plugin:example|ping', { value: 'Tauri' }).then(({ value }) =>
  console.log('Response', value)
);
```

Check out the upcoming [camera plugin](https://github.com/tauri-apps/plugins-workspace/pull/260) and [path plugin](https://github.com/tauri-apps/tauri/pull/6339).
