clipboard_plus 1.0.0
clipboard_plus: ^1.0.0 copied to clipboard
A Flutter plugin for enhanced clipboard functionality with iOS UIPasteboard support.
clipboard_plus #
A Flutter plugin for enhanced clipboard functionality with iOS UIPasteboard support.
The Problem #
Starting with iOS 14, Apple introduced a privacy feature that shows a notification banner whenever an app reads from the clipboard:
"App would like to paste from Other App"
This notification appears every time your app calls Clipboard.getData(), even if you just want to check if the clipboard contains a URL. This creates a poor user experience:
- Users see the paste notification even when the clipboard contains irrelevant content (like plain text when your app only cares about URLs)
- Users may become suspicious or annoyed by frequent clipboard access notifications
- There's no way to silently check clipboard content type before reading
The Solution #
iOS provides UIPasteboard properties that check content types without triggering the paste notification:
| Property | Description |
|---|---|
hasURLs |
Check if clipboard contains URLs |
hasStrings |
Check if clipboard contains text |
hasImages |
Check if clipboard contains images |
hasColors |
Check if clipboard contains colors |
This plugin exposes these APIs to Flutter, allowing you to:
- Silently check if the clipboard has content your app cares about
- Only request access when relevant content is present
- Provide a better UX by avoiding unnecessary permission dialogs
Installation #
dependencies:
clipboard_plus:
path: plugins/clipboard_plus # or publish to pub.dev
Usage #
Check Content Types (No Permission Dialog) #
import 'package:clipboard_plus/clipboard_plus.dart';
// Check for URLs - NO permission dialog on iOS
final hasUrls = await ClipboardPlus.hasUrls();
// Check for strings - NO permission dialog on iOS
final hasStrings = await ClipboardPlus.hasStrings();
// Check for images - NO permission dialog on iOS
final hasImages = await ClipboardPlus.hasImages();
// Check for colors - NO permission dialog on iOS
final hasColors = await ClipboardPlus.hasColors();
// Or get all types at once
final types = await ClipboardPlus.getContentTypes();
if (types.hasUrls) {
// Clipboard has a URL
}
Read Content (Will Trigger Permission Dialog on iOS) #
// Get URL
final url = await ClipboardPlus.getUrl();
// Get text
final text = await ClipboardPlus.getText();
// Get image as PNG bytes
final Uint8List? imageBytes = await ClipboardPlus.getImage();
Write Content #
// Set text
await ClipboardPlus.setText("Hello, World!");
// Clear clipboard
await ClipboardPlus.clear();
Example: Smart URL Detection #
Future<void> checkForCopiedUrl() async {
// Step 1: Silently check if clipboard has a URL (no dialog)
final hasUrl = await ClipboardPlus.hasUrls();
if (!hasUrl) {
// Clipboard doesn't have a URL - do nothing
// User never sees any permission dialog!
return;
}
// Step 2: Clipboard has a URL, now read it (shows permission dialog)
final url = await ClipboardPlus.getUrl();
if (url != null) {
// Step 3: Ask user if they want to use the URL
showSaveUrlDialog(url);
}
}
Platform Support #
| Platform | Silent Check (hasX) | Read Content |
|---|---|---|
| iOS | Native UIPasteboard APIs | Shows permission dialog |
| Android | ClipboardManager | No permission dialog |
Note: On Android, there are no clipboard permission dialogs like iOS.
API Reference #
Silent Check Methods (No iOS Permission Dialog) #
| Method | Returns | Description |
|---|---|---|
hasUrls() |
Future<bool> |
Check if clipboard has URLs |
hasStrings() |
Future<bool> |
Check if clipboard has text |
hasImages() |
Future<bool> |
Check if clipboard has images |
hasColors() |
Future<bool> |
Check if clipboard has colors |
getContentTypes() |
Future<ClipboardContentType> |
Check all types at once |
Read Methods (Shows iOS Permission Dialog) #
| Method | Returns | Description |
|---|---|---|
getUrl() |
Future<String?> |
Get URL from clipboard |
getText() |
Future<String?> |
Get text from clipboard |
getImage() |
Future<Uint8List?> |
Get image as PNG bytes |
Write Methods #
| Method | Returns | Description |
|---|---|---|
setText(String) |
Future<void> |
Set text to clipboard |
clear() |
Future<void> |
Clear the clipboard |
Implementation Notes #
hasStrings(),getText(), andsetText()delegate to Flutter's built-inClipboardclasshasUrls(),hasImages(),hasColors(),getUrl(), andgetImage()use native platform channels- This provides a unified API while avoiding code duplication
License #
MIT