Skip to content

PSPDFKit Wrapper for Flutter. Flutter is Google's mobile UI framework for crafting high-quality native experiences on iOS and Android in record time.

License

Notifications You must be signed in to change notification settings

ibarrick/pspdfkit-flutter

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

85 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

PSPDFKit Flutter

PSPDFKit wrapper for Flutter.

If you are new to Flutter, make sure to check our introductory blog post "How I Got Started With Flutter"

Platform specific README exists for Android and iOS.

Setup

Integration into a new Flutter app

Android

Let's create a simple app that integrates PSPDFKit and uses the Flutter pspdfkit plugin.

  1. Run flutter create --org com.example.myapp myapp.
  2. Open 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.

  1. From myapp run flutter packages get to install the packages.
  2. Open myapp/android/local.properties and specify the following properties
sdk.dir=/path/to/your/Android/sdk
flutter.sdk=/path/to/your/flutter/sdk
pspdfkit.password=YOUR_PASSWORD_GOES_HERE
flutter.buildMode=debug
  1. Open myapp/android/app/build.gradle and modify compileSdkVersion from 27 to 28, minSdkVersion from 16 to 21, targetSdkVersion from 27 to 28, enable multiDex, and add compile options to enable desugaring
compileOptions {
      sourceCompatibility 1.8
      targetCompatibility 1.8
  }

Four changes to edit:

...
android {
-   compileSdkVersion 27
+   compileSdkVersion 28
    
+    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 27
+       targetSdkVersion 28
+       multiDexEnabled enable
        versionCode flutterVersionCode.toInteger()
        versionName flutterVersionName
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
...
  1. Open myapp/lib/main.dart and replace the whole content with a simple example that will load a pdf document from local device filesystem
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:pspdfkit_flutter/pspdfkit.dart';
import 'package:pspdfkit_flutter/simple_permissions.dart';

void main() => runApp(new MyApp());

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => new _MyAppState();
}

class _MyAppState extends State<MyApp> {
  String _frameworkVersion = '';

  present() {
    Pspdfkit.present("file:///sdcard/document.pdf");
  }

  showDocument(BuildContext context) async {
    try {
      if (await Pspdfkit.checkWriteExternalStoragePermission()) {
        present();
      } else {
        PermissionStatus permissionStatus =
            await Pspdfkit.requestWriteExternalStoragePermission();
        if (permissionStatus == PermissionStatus.authorized) {
          present();
        } else if (permissionStatus == PermissionStatus.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.
  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");
  }

  _openSettings(ScaffoldState scaffold) {
    scaffold.hideCurrentSnackBar();
    Pspdfkit.openSettings();
  }

  _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))
                  ]));
            },
          )),
    );
  }
}
  1. In lib/main.dart replace YOUR_LICENSE_KEY_GOES_HERE with your PSPDFKit license key.

  2. 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
  1. The app is ready to start! From myapp run flutter run.

iOS

  1. Run flutter create --org com.example.myapp myapp.
  2. Step into your newly created app folder: cd myapp
  3. Open pubspec.yaml and under dependencies add
  path_provider: ^0.4.1
  pspdfkit_flutter:
    git:
      url: git://github.com/PSPDFKit/pspdfkit-flutter.git
  1. Add a PDFs directory with a document in it in the root directory: myapp/PDFs/Guide_v4.pdf and specify it in your pubspec.yaml:
  assets:
    - PDFs/   

Spaces are important, so don't forget them.

  1. Open the Runner.xcworkspace from the ios folder in Xcode: open ios/Runner.xcworkspace
  2. Make sure the iOS Deployment Target is set to 10.0 or higher.
  3. Change "View controller-based status bar appearance" to YES in Info.plist.
  4. Run flutter packages get to install the packages.
  5. Open the 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, '10.0'
+   use_frameworks!
...
target 'Runner' do

+   pod 'PSPDFKit', podspec:'https://customers.pspdfkit.com/cocoapods/YOUR_COCOAPODS_KEY_GOES_HERE/pspdfkit/latest.podspec'
...
end  
  1. Open 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/Guide_v4.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 = '';

  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();
  }

  frameworkVersion() {
    return '$PSPDFKIT_FOR $_frameworkVersion\n';
  }

  // Platform messages are asynchronous, so we initialize in an async method.
  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)
                  ])),
              ),
          );
      }
}
  1. In lib/main.dart replace YOUR_LICENSE_KEY_GOES_HERE with your PSPDFKit license key.
  2. Run flutter emulators --launch apple_ios_simulator to launch the iOS Simulator.
  3. Run flutter run.

Example

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}'.");
    }
}

Contributing

Please ensure you signed our CLA so we can accept your contributions.

About

PSPDFKit Wrapper for Flutter. Flutter is Google's mobile UI framework for crafting high-quality native experiences on iOS and Android in record time.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • Swift 28.7%
  • Java 28.6%
  • Dart 26.7%
  • Objective-C 8.7%
  • Ruby 7.3%