PSPDFKit Wrapper for Flutter

PSPDFKit Wrapper for Flutter

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

PSPDFKit Flutter

PSPDFKit wrapper for Flutter.

If you are new to Flutter, make sure to check our blog:

Platform specific README exists for Android and iOS.

Setup

Integration into a New Flutter App

Android

Requirements
  • Android SDK 29.0.3 or later
  • PSPDFKit 6.5.3 for Android or later
  • Flutter 1.22.0-12.1.pre or later

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
flutter.buildMode=debug
  1. Open myapp/android/app/build.gradle and modify minSdkVersion from 16 to 21, enable multiDex, and add compile options to enable desugaring
compileOptions {
      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
    }
...
  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';

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))
                      ]));
            },
          )),
    );
  }
}
  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

Requirements
  • The latest Xcode
  • PSPDFKit 10.1.0 for iOS or later
  • Flutter 1.23.0-18.1.pre or later
  • CocoaPods 1.10.0 or later (Update cocoapods with: gem install cocoapods)
Getting Started
  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/PSPDFKit.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 12.0 or higher.

iOS Deployment Target

  1. Change "View controller-based status bar appearance" to YES in Info.plist.

iOS View controller-based status bar appearance

  1. If your application is targeting iOS versions prior to iOS 12.2 and your application does not already contain any Swift code, then you need to make sure Xcode bundles Swift standard libraries with your application distribution. To to so, open your target Build Settings and enable Always Embed Swift Standard Libraries:

Always Embed Swift Standard Libraries

  1. Run flutter packages get to install the packages.
  2. 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, '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
  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/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)
                ])),
      ),
    );
  }
}
  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.

Troubleshooting

Flutter Updates

To update Flutter to the latest version, all you have to do is run flutter upgrade.

Flutter Configuration Problems

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.

Flutter doctor example

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.

CocoaPods Conflicts With Asdf

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.

Download Details:

Author: PSPDFKit

Demo: https://pspdfkit.com/blog/2018/starting-with-flutter/

Source Code: https://github.com/PSPDFKit/pspdfkit-flutter

flutter dart mobile-apps

Bootstrap 5 Complete Course with Examples

Bootstrap 5 Tutorial - Bootstrap 5 Crash Course for Beginners

Nest.JS Tutorial for Beginners

Hello Vue 3: A First Look at Vue 3 and the Composition API

Building a simple Applications with Vue 3

Deno Crash Course: Explore Deno and Create a full REST API with Deno

How to Build a Real-time Chat App with Deno and WebSockets

Convert HTML to Markdown Online

HTML entity encoder decoder Online

Google's Flutter 1.20 stable announced with new features - Navoki

Google has announced new flutter 1.20 stable with many improvements, and features, enabling flutter for Desktop and Web

Top 25 Flutter Mobile App Templates in 2020

Flutter has been booming worldwide from the past few years. While there are many popular mobile app development technologies out there, Flutter has managed to leave its mark in the mobile application development world. In this article, we’ve curated the best Flutter app templates available on the market as of July 2020.

Flutter App Development Trends 2020

As the new decade dawns upon us, a slew of technologies has been making a lot of noise to grab the developers’ attention. While native app development is going strong, the trade winds are now blowing towards going cross-platform.

How To Succeed In Mobile App Wireframe Design?

This article covers everything about mobile app wireframe design: what to do and what not, tools used in designing a mobile or web app wireframe, and more.

Top 10 Mobile App Development Companies in India

The mobile application scenario has been continually changing over the years. In recent years India has become a center for mobile app development companies. The increase of smartphones has instantly increased the requirements for these apps. Every year new technological trends occur due to contin