PSPDFKit wrapper for Flutter.
If you are new to Flutter, make sure to check our blog:
Platform specific README exists for Android and iOS.
Let’s create a simple app that integrates PSPDFKit and uses the Flutter pspdfkit plugin.
flutter create --org com.example.myapp myapp
.myapp/pubspec.yaml
and under dependencies
add pspdfkit_flutter:
git:
url: git://github.com/PSPDFKit/pspdfkit-flutter.git
Spaces are important, so don’t forget them.
myapp
run flutter packages get
to install the packages.myapp/android/local.properties
and specify the following propertiessdk.dir=/path/to/your/Android/sdk
flutter.sdk=/path/to/your/flutter/sdk
flutter.buildMode=debug
myapp/android/app/build.gradle
and modify minSdkVersion
from 16
to 21
, enable multiDex, and add compile options to enable desugaringcompileOptions {
sourceCompatibility 1.8
targetCompatibility 1.8
}
Three changes to edit:
...
android {
compileSdkVersion 29
+ compileOptions {
+ sourceCompatibility 1.8
+ targetCompatibility 1.8
+ }
lintOptions {
disable 'InvalidPackage'
}
defaultConfig {
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId "com.example.myapp"
- minSdkVersion 16
+ minSdkVersion 21
targetSdkVersion 29
+ multiDexEnabled true
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
}
...
myapp/lib/main.dart
and replace the whole content with a simple example that will load a pdf document from local device filesystemimport 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:pspdfkit_flutter/pspdfkit.dart';
void main() => runApp(new MyApp());
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => new _MyAppState();
}
class _MyAppState extends State<MyApp> {
String _frameworkVersion = '';
void present() {
Pspdfkit.present("file:///sdcard/document.pdf");
}
void showDocument(BuildContext context) async {
try {
if (await Pspdfkit.checkAndroidWriteExternalStoragePermission()) {
present();
} else {
AndroidPermissionStatus permissionStatus =
await Pspdfkit.requestAndroidWriteExternalStoragePermission();
if (permissionStatus == AndroidPermissionStatus.authorized) {
present();
} else if (permissionStatus == AndroidPermissionStatus.deniedNeverAsk) {
_showToast(context);
}
}
} on PlatformException catch (e) {
print("Failed to open document: '${e.message}'.");
}
}
@override
initState() {
super.initState();
initPlatformState();
}
// Platform messages are asynchronous, so we initialize in an async method.
void initPlatformState() async {
String frameworkVersion;
// Platform messages may fail, so we use a try/catch PlatformException.
try {
frameworkVersion = await Pspdfkit.frameworkVersion;
} on PlatformException {
frameworkVersion = 'Failed to get platform version. ';
}
// If the widget was removed from the tree while the asynchronous platform
// message was in flight, we want to discard the reply rather than calling
// setState to update our non-existent appearance.
if (!mounted) return;
setState(() {
_frameworkVersion = frameworkVersion;
});
// Replace
Pspdfkit.setLicenseKey("YOUR_LICENSE_KEY_GOES_HERE");
}
void _openSettings(ScaffoldState scaffold) {
scaffold.hideCurrentSnackBar();
Pspdfkit.openAndroidSettings();
}
void _showToast(BuildContext context) {
final scaffold = Scaffold.of(context);
scaffold.showSnackBar(
SnackBar(
content: const Text('PSPDFKit Flutter example requires file system permissions to open a PDF document into the sdcard folder.'),
action: SnackBarAction(
label: 'Open Settings', onPressed: () => _openSettings(scaffold)
),
),
);
}
@override
Widget build(BuildContext context) {
final ThemeData themeData = Theme.of(context);
return new MaterialApp(
home: new Scaffold(
appBar: new AppBar(
title: new Text('PSPDFKit Flutter Plugin example app'),
),
body: Builder(
// Create an inner BuildContext so that the onPressed methods
// can refer to the Scaffold with Scaffold.of().
builder: (BuildContext context) {
return Center(
child: new Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
new Text('PSPDFKit for $_frameworkVersion\n',
style: themeData.textTheme.display1
.copyWith(fontSize: 21.0)),
new RaisedButton(
child: new Text('Tap to Open Document',
style: themeData.textTheme.display1
.copyWith(fontSize: 21.0)),
onPressed: () => showDocument(context))
]));
},
)),
);
}
}
In lib/main.dart
replace YOUR_LICENSE_KEY_GOES_HERE
with your PSPDFKit license key.
Before launching the app you need to copy a PDF document onto your development device or emulator
adb push /path/to/your/document.pdf /sdcard/document.pdf
myapp
run flutter run
.gem install cocoapods
)flutter create --org com.example.myapp myapp
cd myapp
pubspec.yaml
and under dependencies
add path_provider: ^0.4.1
pspdfkit_flutter:
git:
url: git://github.com/PSPDFKit/pspdfkit-flutter.git
PDFs
directory with a document in it in the root directory: myapp/PDFs/PSPDFKit.pdf
and specify it in your pubspec.yaml
: assets:
- PDFs/
Spaces are important, so don’t forget them.
Runner.xcworkspace
from the ios
folder in Xcode: open ios/Runner.xcworkspace
iOS Deployment Target
is set to 12.0 or higher.Info.plist
.Always Embed Swift Standard Libraries
:flutter packages get
to install the packages.Podfile
: open ios/Podfile
and edit it as follows:# Uncomment this line to define a global platform for your project
- # platform :ios, '9.0'
+ platform :ios, '12.0'
...
target 'Runner' do
use_frameworks!
use_modular_headers!
flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))
+ pod 'PSPDFKit', podspec:'https://customers.pspdfkit.com/pspdfkit-ios/latest.podspec'
end
lib/main.dart
and replace the whole content with a simple example that will load a PDF document from local device filesystem:import 'dart:io';
import 'dart:typed_data';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:path_provider/path_provider.dart';
import 'package:pspdfkit_flutter/pspdfkit.dart';
const String DOCUMENT_PATH = 'PDFs/PSPDFKit.pdf';
const String PSPDFKIT_FLUTTER_PLUGIN_TITLE = 'PSPDFKit Flutter Plugin example app';
const String OPEN_DOCUMENT_BUTTON = 'Tap to Open Document';
const String PSPDFKIT_FOR = 'PSPDFKit for';
const double FONT_SIZE = 21.0;
void main() => runApp(new MyApp());
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => new _MyAppState();
}
class _MyAppState extends State<MyApp> {
String _frameworkVersion = '';
void showDocument() async {
try {
final ByteData bytes = await DefaultAssetBundle.of(context).load(DOCUMENT_PATH);
final Uint8List list = bytes.buffer.asUint8List();
final tempDir = await getTemporaryDirectory();
final tempDocumentPath = '${tempDir.path}/$DOCUMENT_PATH';
final file = await new File(tempDocumentPath).create(recursive: true);
file.writeAsBytesSync(list);
Pspdfkit.present(tempDocumentPath);
} on PlatformException catch (e) {
print("Failed to open document: '${e.message}'.");
}
}
@override
initState() {
super.initState();
initPlatformState();
}
String frameworkVersion() {
return '$PSPDFKIT_FOR $_frameworkVersion\n';
}
// Platform messages are asynchronous, so we initialize in an async method.
void initPlatformState() async {
String frameworkVersion;
// Platform messages may fail, so we use a try/catch PlatformException.
try {
frameworkVersion = await Pspdfkit.frameworkVersion;
} on PlatformException {
frameworkVersion = 'Failed to get platform version. ';
}
// If the widget was removed from the tree while the asynchronous platform
// message was in flight, we want to discard the reply rather than calling
// setState to update our non-existent appearance.
if (!mounted) return;
setState(() {
_frameworkVersion = frameworkVersion;
});
// Replace
Pspdfkit.setLicenseKey("YOUR_LICENSE_KEY_GOES_HERE");
}
@override
Widget build(BuildContext context) {
final ThemeData themeData = Theme.of(context);
return new CupertinoApp(
home: new CupertinoPageScaffold(
navigationBar: CupertinoNavigationBar(
middle: Text(PSPDFKIT_FLUTTER_PLUGIN_TITLE,
style: themeData.textTheme.title
)
),
child: new Center(
child: new Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
new Text(frameworkVersion(),
style: themeData.textTheme.display1.copyWith(fontSize: FONT_SIZE)),
new CupertinoButton(
child: new Text(OPEN_DOCUMENT_BUTTON),
onPressed: showDocument)
])),
),
);
}
}
lib/main.dart
replace YOUR_LICENSE_KEY_GOES_HERE
with your PSPDFKit license key.flutter emulators --launch apple_ios_simulator
to launch the iOS Simulator.flutter run
.To see PSPDFKit Flutter in action check out our Flutter example app.
Showing a PDF document inside your Flutter app is as simple as this:
showDocument() async {
try {
Pspdfkit.present("file:///document.pdf");
} on PlatformException catch (e) {
print("Failed to open document: '${e.message}'.");
}
}
Please ensure you signed our CLA so we can accept your contributions.
To update Flutter to the latest version, all you have to do is run flutter upgrade
.
Among the tools provided by Flutter, there is flutter doctor
, a very handy program that checks your system configuration for you and provides step-by-step actions to take in case of problems.
The verbose mode of flutter doctor is even more helpful; it prints out extensive information about the nature of an issue and how to fix it. To run the verbose mode, all you have to do is type flutter doctor -d
.
If asdf is installed in your machine it might create problems when running Cocoapods, and Flutter will erroneusly suggest to install CocoaPods via brew with brew install cocoapods
. This won’t work because for this specific configuration CocoaPods needs to be installed via RubyGems. To fix this configuration issue just type gem install cocoapods && pod setup
.
Author: PSPDFKit
Demo: https://pspdfkit.com/blog/2018/starting-with-flutter/
Source Code: https://github.com/PSPDFKit/pspdfkit-flutter
#flutter #dart #mobile-apps