Polotno Docs
Getting started

iOS Swift

Embed Polotno Design Editor into a native iOS Swift application using WKWebView

How to integrate Polotno editor into an iOS app?

Polotno is a React-based web editor. You can embed it into a native iOS Swift application by bundling the editor as a single-file web app and loading it in a WKWebView. This hybrid approach lets you leverage Polotno's full web capabilities while maintaining a native iOS experience.

Architecture overview

The integration uses a hybrid architecture:

  • Native Layer: SwiftUI app with WKWebView to host the editor
  • Web Layer: React + Vite app that runs Polotno editor
  • Communication: JavaScript bridge via WKScriptMessageHandler for bidirectional data exchange

The web editor is built as a single-file bundle (using vite-plugin-singlefile) to avoid module loading issues when loading from local files in WKWebView.

Prerequisites

  • Xcode 15+ (iOS 16+ deployment target)
  • Node.js 18+ and npm (for building the web editor)

Integration approach

The integration involves two main parts:

  1. Web editor: Create a React + Vite app with Polotno, configured to build as a single-file bundle using vite-plugin-singlefile. This generates one HTML file with all JavaScript and CSS inlined.

  2. Swift wrapper: Create a WKWebView wrapper in Swift that loads the bundled HTML file and handles bidirectional communication via WKScriptMessageHandler.

The web editor exposes global functions (e.g., window.__polotnoReceiveInitialDoc, window.saveToNative) that Swift can call. The editor posts messages back to Swift using window.webkit.messageHandlers.editor.postMessage().

See the demo repository for complete implementation details.

Core concepts

Single-file bundle

The editor must be built as a single HTML file with all JavaScript and CSS inlined. This prevents:

  • Module loading errors from local file restrictions
  • Cross-origin issues with separate asset files
  • Network dependency during initial load

Use vite-plugin-singlefile to achieve this.

Message passing

Communication between Swift and JavaScript uses WKScriptMessageHandler:

  • Swift → JavaScript: Use webView.evaluateJavaScript() to call global functions
  • JavaScript → Swift: Use window.webkit.messageHandlers.editor.postMessage() to send data

Data serialization

Design data is passed as JSON strings, base64-encoded for safe transmission. Preview images are base64-encoded PNG data URLs.

FAQ

Can the editor work offline?

The editor code is bundled locally, but Polotno relies on external APIs for stock photos, templates, and fonts. The device must be online for these features.

Enterprise clients: Full offline support (bundling all assets and fonts) is available with enterprise licenses. Contact support for details.

What are the memory considerations?

High-resolution exports or complex designs may consume significant memory. Test on older devices (iPhone 8, iPad Air 2) if targeting a broad user base. Consider:

  • Limiting export resolution for previews
  • Using lower pixel ratios for preview generation
  • Implementing memory warnings and cleanup
  • Rendering on the server side

How do I customize the editor UI?

Modify the React component in web-editor/src/App.jsx:

  • Add custom side panels
  • Modify toolbar actions
  • Change default sections
  • Add custom save flows

Can I export to PDF or other formats?

Yes. Extend the JavaScript bridge to support additional export formats. Use store.toPDF() or other export methods, convert the result to base64, and post it to Swift via the message handler.

How do I handle errors?

Implement error handling in both layers:

  • JavaScript: Wrap Polotno API calls in try-catch blocks
  • Swift: Validate message payloads and handle decoding errors gracefully

Demo repository

See a complete working example with source code: https://github.com/polotno-project/polotno-swift

The repository includes:

  • Complete Xcode project
  • React + Vite web editor setup
  • SwiftUI integration example
  • Build scripts for bundling