tauri-plugin-ios-window 1.0.0

Tauri plugin for iOS window management
Documentation
# Tauri Plugin iOS Window

A Tauri plugin for opening modal windows with WebView on iOS, perfect for OAuth flows and external authentication.

## Features

- 🪟 **Modal Presentation** - Opens as popover on iPad, modal on iPhone
- 🎨 **Customizable UI** - Set custom titles, follows Apple HIG
- 📊 **Progress Tracking** - Built-in loading indicator and progress bar
- 🔄 **Navigation** - Back/forward swipe gestures enabled
-**Native Feel** - Follows iOS Human Interface Guidelines
- 🔐 **OAuth Ready** - Perfect for Sign in with Apple, OAuth flows

## Installation

```bash
# Install the plugin
npm install tauri-plugin-ios-window-api
# or
yarn add tauri-plugin-ios-window-api
# or
pnpm add tauri-plugin-ios-window-api
```

Add the plugin to your Tauri app's `src-tauri/Cargo.toml`:

```toml
[dependencies]
tauri-plugin-ios-window = { git = "https://github.com/yourusername/tauri-plugin-ios-window" }
```

Register the plugin in your Tauri app's `src-tauri/src/lib.rs`:

```rust
fn run() {
    tauri::Builder::default()
        .plugin(tauri_plugin_ios_window::init())
        .run(tauri::generate_context!())
        .expect("error while running tauri application");
}
```

## Usage

### Basic Example

```typescript
import { open } from "tauri-plugin-ios-window-api";

// Open a URL with default title
await open("https://example.com");

// Open with custom title
await open("https://example.com", "My Custom Title");
```

### OAuth Flow Example (SplitFire Pattern)

This example shows how to integrate with an OAuth provider like Sign in with Apple:

```typescript
import { open } from "tauri-plugin-ios-window-api";

async function signInWithApple() {
    try {
        // Your OAuth configuration
        const baseUrl = "https://splitfire.ai";
        const redirectUri = "your-app://oauth/callback";
        
        // Build OAuth URL
        const oauthUrl = `${baseUrl}/synch-apple/auth?redirect_uri=${encodeURIComponent(redirectUri)}`;
        
        // Open OAuth window
        await open(oauthUrl, "Sign in with Apple");
        
        // Handle the callback (implement based on your needs)
        // Option 1: Deep link handler
        // Option 2: Local server listener
        // Option 3: Custom URL scheme
        
    } catch (error) {
        console.error("OAuth failed:", error);
    }
}
```

### Complete OAuth Implementation

```typescript
import { open } from "tauri-plugin-ios-window-api";
import { listen } from "@tauri-apps/api/event";

async function startOAuthFlow(provider: "apple" | "spotify" | "youtube") {
    try {
        // Start local OAuth server (Rust backend)
        const port = await invoke("start_oauth_server");
        
        // Configure redirect
        const redirectUri = `http://localhost:${port}`;
        const baseUrl = "https://splitfire.ai";
        const oauthUrl = `${baseUrl}/synch-${provider}/auth?redirect_uri=${redirectUri}`;
        
        // Open OAuth window
        await open(oauthUrl, `Sign in with ${provider}`);
        
        // Listen for OAuth callback
        const unlisten = await listen("oauth-callback", (event) => {
            const { code, state } = event.payload;
            
            // Exchange code for access token
            invoke("exchange_oauth_token", { code, provider })
                .then((response) => {
                    console.log("OAuth successful:", response);
                    // Handle successful authentication
                })
                .catch((error) => {
                    console.error("Token exchange failed:", error);
                });
        });
        
    } catch (error) {
        console.error("OAuth flow failed:", error);
    }
}
```

## API Reference

### `open(url: string, title?: string): Promise<void>`

Opens a new modal window with a WebView.

**Parameters:**
- `url` (string, required) - The URL to open in the WebView
- `title` (string, optional) - Custom title for the navigation bar. Defaults to "Sign in"

**Returns:**
- `Promise<void>` - Resolves when the window is presented

**Example:**
```typescript
// Basic usage
await open("https://example.com");

// With custom title
await open("https://appleid.apple.com", "Sign in with Apple");
```

### `close(): Promise<void>`

Programmatically closes the currently opened window.

**Parameters:**
- None

**Returns:**
- `Promise<void>` - Resolves when the window is dismissed

**Example:**
```typescript
// Close the window
await close();

// Open and auto-close after delay
await open("https://example.com", "Loading...");
setTimeout(async () => {
    await close();
}, 3000);
```

## UI/UX Features

### Navigation Bar
- Clean, native iOS design
- Close button on leading edge (per Apple HIG)
- Centered title
- Activity indicator during loading
- Subtle border separator

### Progress Indicator
- 2px blue progress bar
- Smooth animations
- Auto-hides when complete
- Tracks page load progress

### WebView
- Full-screen immersive experience
- Back/forward swipe gestures
- Inline media playback
- Proper dark mode support
- Error state handling

### Modal Presentation
- **iPad**: Popover (400x600)
- **iPhone**: Full-screen modal
- Smooth dismiss animations
- Safe area aware

## Platform Support

- ✅ iOS (iPhone & iPad)
- ⚠️ Desktop (no-op, falls through to default behavior)
- ❌ Android (not supported)

## Best Practices

### OAuth Flows

1. **Use HTTPS in production**
   ```typescript
   const baseUrl = process.env.NODE_ENV === "production" 
       ? "https://splitfire.ai"
       : "https://localhost:3333";
   ```

2. **Handle redirects properly**
   - Use custom URL schemes for mobile: `your-app://oauth/callback`
   - Use localhost for testing: `http://localhost:8080/callback`
   - Always encode redirect URIs

3. **Security**
   - Use PKCE for OAuth 2.0
   - Validate state parameters
   - Store tokens securely
   - Use short-lived access tokens

4. **Error Handling**
   ```typescript
   try {
       await open(oauthUrl, "Sign in");
   } catch (error) {
       // Handle network errors
       // Show user-friendly message
       // Log for debugging
   }
   ```

### UI/UX

1. **Use descriptive titles**
   ```typescript
   await open(url, "Sign in with Apple");  // ✅ Good
   await open(url, "Sign in");              // ⚠️ Generic
   await open(url);                         // ❌ Uses default
   ```

2. **Provide feedback**
   - Show loading states before opening
   - Handle success/error after OAuth
   - Give users clear next steps

3. **Test on both devices**
   - iPad (popover experience)
   - iPhone (modal experience)

### Programmatic Closing

1. **After OAuth completion**
   ```typescript
   // Listen for OAuth callback
   listen("oauth-callback", async (event) => {
       // Process OAuth response
       await handleOAuthToken(event.payload);
       
       // Close the window
       await close();
   });
   ```

2. **Timeout scenarios**
   ```typescript
   // Auto-close if user doesn't complete within time limit
   await open(oauthUrl, "Sign in");
   
   const timeout = setTimeout(async () => {
       await close();
       showMessage("Authentication timed out");
   }, 60000); // 1 minute
   
   // Clear timeout if user completes
   listen("oauth-complete", () => clearTimeout(timeout));
   ```

3. **Error handling**
   ```typescript
   try {
       await open(url, "Sign in");
   } catch (error) {
       // If window fails to open, don't try to close
       console.error("Failed to open:", error);
       return;
   }
   
   // Later, close if needed
   try {
       await close();
   } catch (error) {
       // Window may already be closed by user
       console.log("Window already closed");
   }
   ```

## Example App

Check out the complete example in `examples/tauri-app`:

```bash
cd examples/tauri-app
npm install
npm run tauri ios dev
```

## Development

```bash
# Clone the repository
git clone https://github.com/yourusername/tauri-plugin-ios-window

# Install dependencies
npm install

# Build the plugin
npm run build

# Run example
cd examples/tauri-app
npm run tauri ios dev
```

## Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

## License

MIT

## Credits

Built for [SplitFire](https://splitfire.ai) - OAuth pattern inspired by production usage.