diff --git a/README.md b/README.md
index d1392d0..3d5acc3 100644
--- a/README.md
+++ b/README.md
@@ -1,5 +1,7 @@
# PDFTron Flutter Sample
-Flutter sample project that integrates a document viewer using [PDFTron Flutter](https://github.com/PDFTron/pdftron-flutter). Check out the [integration guides](https://www.pdftron.com/documentation/android/flutter) to learn how to add PDFTron to your Flutter App.
+A Flutter sample project that integrates a document viewer using PDFTron Flutter.
+
+PDFTron's Flutter PDF library now supports sound null safety and is available on [GitHub](https://github.com/PDFTron/pdftron-flutter) and [pub.dev](https://pub.dev/packages/pdftron_flutter). To learn how to add PDFTron to your Flutter App, check out the [integration guides](https://www.pdftron.com/documentation/guides/flutter).
## Preview
@@ -7,15 +9,17 @@ Flutter sample project that integrates a document viewer using [PDFTron Flutter]
:--:|:--:
|
-## Step
+## Installation
+### Android
1. Create a `local.properties` file inside the android folder with your Android SDK location, for example:
```
sdk.dir=/Users//Library/Android/sdk
```
-2. For iOS, run:
+### iOS
+1. For iOS, run:
```
cd ios
pod install
@@ -23,13 +27,21 @@ pod install
## Run
+### Sample App
+
```
flutter run
```
+### Test
+
+```
+flutter drive --driver=test_driver/integration_test.dart --target=integration_test/app_test.dart
+```
+
## Upgrade
-For updating flutter projects, please check out [here](https://flutter.dev/docs/development/tools/sdk/upgrading).
+For updating flutter projects, please check out [Upgrading Flutter](https://flutter.dev/docs/development/tools/sdk/upgrading).
## License
See [License](./LICENSE)
diff --git a/integration_test/app_test.dart b/integration_test/app_test.dart
index 1b51b34..726af47 100644
--- a/integration_test/app_test.dart
+++ b/integration_test/app_test.dart
@@ -1,36 +1,91 @@
-// This is a basic Flutter integration test.
-//
-// To perform an interaction with a widget in your test, use the WidgetTester
-// utility that Flutter provides. For example, you can send tap and scroll
-// gestures. You can also use WidgetTester to find child widgets in the widget
-// tree, read text, and verify that the values of widget properties are correct.
-
+import 'dart:math';
import 'package:flutter/material.dart';
+import 'package:flutter/services.dart';
+import 'package:flutter_sample/thumbnail.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:integration_test/integration_test.dart';
-
import 'package:flutter_sample/main.dart' as app;
+import 'package:pdftron_flutter/pdftron_flutter.dart';
+
+// Test for the sample app.
+void main() async {
+ IntegrationTestWidgetsFlutterBinding.ensureInitialized();
+ List calls = [];
+
+ setUpAll(() async {
+ // Used to track method calls.
+ MethodChannel('pdftron_flutter').setMockMethodCallHandler( (MethodCall call) async {
+ calls.add(call.method);
+ });
+ });
+
+ tearDown(() {
+ // Clears list after each test.
+ calls.clear();
+ });
+
+ // Destroys the method call tracker after all tests have ran.
+ tearDownAll(() async {
+ MethodChannel('pdftron_flutter').setMockMethodCallHandler(null);
+ });
+
+ testWidgets('Check widget hierarchy of app', (WidgetTester tester) async {
+ Widget myApp = app.MyApp();
+ await tester.pumpWidget(myApp);
-void main() => run(_testMain);
+ expect(find.text("PDFTron Flutter Sample"), findsOneWidget);
+
+ final bodyFinder = find.byKey(Key('body'));
+ expect(bodyFinder, findsOneWidget);
+
+ // Body widget is SafeArea type if app is initialized and storage is permitted.
+ final body = tester.firstWidget(bodyFinder);
+ if (body is SafeArea) {
+ final inkWellFinder = find.descendant(of: bodyFinder, matching: find.byType(InkWell));
+ expect(inkWellFinder, findsWidgets);
-void _testMain() {
- testWidgets('Counter increments smoke test', (WidgetTester tester) async {
- // Build our app and trigger a frame.
- app.main();
+ final imageFinder = find.descendant(of: inkWellFinder.first, matching: find.byType(Image));
+ expect(imageFinder, findsOneWidget);
- // Trigger a frame.
- await tester.pumpAndSettle();
+ } else {
+ // Body widget is Container type if app is not initialized or storage is not permitted.
+ expect(body.runtimeType, Container);
+
+ final alignFinder = find.descendant(of: bodyFinder, matching: find.byType(Align));
+ expect(alignFinder, findsOneWidget);
- // Verify that our counter starts at 0.
- expect(find.text('0'), findsOneWidget);
- expect(find.text('1'), findsNothing);
+ final textFinder = find.descendant(of: alignFinder, matching: find.byType(Text));
+ expect(textFinder, findsOneWidget);
- // Tap the '+' icon and trigger a frame.
- await tester.tap(find.byIcon(Icons.add));
- await tester.pump();
+ Text text = tester.firstWidget(textFinder);
+ assert(text.data == 'Storage permission required.' || text.data == 'PDFTron SDK not initialized.');
- // Verify that our counter has incremented.
- expect(find.text('0'), findsNothing);
- expect(find.text('1'), findsOneWidget);
+ expect(find.byType(Text), findsNWidgets(2));
+ }
});
+
+ testWidgets("Opening Thumbnail", (WidgetTester tester) async {
+ await tester.runAsync(() async {
+ await tester.pumpWidget(app.MyApp());
+ await tester.pump();
+ expect(find.byType(InkWell), findsWidgets);
+
+ // Chooses a random thumbnail to select.
+ Random rng = Random();
+
+ // 6 is used instead of thumbnailList.length as that is the number of thumbnails visible upon loading.
+ int index = rng.nextInt(6);
+ Finder thumbnail = find.byKey(ValueKey(thumbnailList[index].documentUrl));
+
+ // Opens the selected thumbnail.
+ await tester.tap(thumbnail);
+ await tester.pump();
+
+ // Tests to ensure that the PdftronFlutter method were called.
+ await Future.delayed(Duration(seconds: 2), () async {
+ expect(calls.contains(Functions.openDocument), true);
+ });
+ });
+ }, variant: TargetPlatformVariant({TargetPlatform.android, TargetPlatform.iOS}));
}
+
diff --git a/integration_test/driver.dart b/integration_test/driver.dart
deleted file mode 100644
index a03bca0..0000000
--- a/integration_test/driver.dart
+++ /dev/null
@@ -1,8 +0,0 @@
-// This file is provided as a convenience for running integration tests via the
-// flutter drive command.
-//
-// flutter drive --driver integration_test/driver.dart --target integration_test/app_test.dart
-
-import 'package:integration_test/integration_test_driver.dart';
-
-Future main() => integrationDriver();
diff --git a/ios/Podfile.lock b/ios/Podfile.lock
index 4a6af23..e911450 100644
--- a/ios/Podfile.lock
+++ b/ios/Podfile.lock
@@ -2,11 +2,11 @@ PODS:
- Flutter (1.0.0)
- integration_test (0.0.1):
- Flutter
- - PDFNet (8.1.0.76833)
+ - PDFNet (9.0.1.77780)
- pdftron_flutter (0.0.1):
- Flutter
- PDFNet
- - permission_handler (3.0.1):
+ - "permission_handler (5.1.0+2)":
- Flutter
DEPENDENCIES:
@@ -31,10 +31,10 @@ EXTERNAL SOURCES:
SPEC CHECKSUMS:
Flutter: 434fef37c0980e73bb6479ef766c45957d4b510c
integration_test: 6eb66a19f7104200dcfdd62bc0077e1b09686e4f
- PDFNet: 248e57518524fdbb47970216c2db3522e4f51028
+ PDFNet: b9e7a7831af4020a4835e19ecf6abf9b81ce29a4
pdftron_flutter: 32bd96e9bc9254c1861f17725e40dd611a7056cd
- permission_handler: 6e56ded745f5a0b9dcc0327c65c4acd6a33b776b
+ permission_handler: ccb20a9fad0ee9b1314a52b70b76b473c5f8dab0
-PODFILE CHECKSUM: c3dd2ce4973c59b1eed0b8fefd9e24700fcd3376
+PODFILE CHECKSUM: 1256ed743e0e6641e71d5339a76d03b9e411be9b
-COCOAPODS: 1.9.3
+COCOAPODS: 1.10.1
diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj
index 82b64c0..e9b7555 100644
--- a/ios/Runner.xcodeproj/project.pbxproj
+++ b/ios/Runner.xcodeproj/project.pbxproj
@@ -9,7 +9,7 @@
/* Begin PBXBuildFile section */
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
- 7D9D4596AFE603889D0C4AF9 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 156D97EE3B349FF3B0506A4B /* Pods_Runner.framework */; };
+ 943B166731AF29A54E1E56A7 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 204000B1A7320C6A866AAD69 /* Pods_Runner.framework */; };
978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */; };
97C146F31CF9000F007C117D /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 97C146F21CF9000F007C117D /* main.m */; };
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
@@ -33,22 +33,22 @@
/* Begin PBXFileReference section */
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; };
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; };
- 156D97EE3B349FF3B0506A4B /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; };
- 26A290795C8B345E7B54F3D8 /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = ""; };
+ 204000B1A7320C6A866AAD69 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; };
+ 2BE6492F675995FD34402DF3 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; };
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; };
- 3BDFDD4EE7D4A48E6F1023CD /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; };
7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; };
7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; };
7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; };
+ 8C7015EC7AC266049F570AC8 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; };
9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; };
9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; };
- 978AC9E7D689FE7A1CC725C4 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; };
97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; };
97C146F21CF9000F007C117D /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; };
97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; };
97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; };
97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
+ A318E888EA367D38A42C1330 /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = ""; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@@ -56,21 +56,32 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
- 7D9D4596AFE603889D0C4AF9 /* Pods_Runner.framework in Frameworks */,
+ 943B166731AF29A54E1E56A7 /* Pods_Runner.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
- 526543B57B076E700259821D /* Frameworks */ = {
+ 144481D43B8FD6BABC279BD2 /* Frameworks */ = {
isa = PBXGroup;
children = (
- 156D97EE3B349FF3B0506A4B /* Pods_Runner.framework */,
+ 204000B1A7320C6A866AAD69 /* Pods_Runner.framework */,
);
name = Frameworks;
sourceTree = "";
};
+ 68FFF092814E7FD8BDE5D113 /* Pods */ = {
+ isa = PBXGroup;
+ children = (
+ 2BE6492F675995FD34402DF3 /* Pods-Runner.debug.xcconfig */,
+ 8C7015EC7AC266049F570AC8 /* Pods-Runner.release.xcconfig */,
+ A318E888EA367D38A42C1330 /* Pods-Runner.profile.xcconfig */,
+ );
+ name = Pods;
+ path = Pods;
+ sourceTree = "";
+ };
9740EEB11CF90186004384FC /* Flutter */ = {
isa = PBXGroup;
children = (
@@ -88,8 +99,8 @@
9740EEB11CF90186004384FC /* Flutter */,
97C146F01CF9000F007C117D /* Runner */,
97C146EF1CF9000F007C117D /* Products */,
- B73FC6430D1564515ACDA0A8 /* Pods */,
- 526543B57B076E700259821D /* Frameworks */,
+ 68FFF092814E7FD8BDE5D113 /* Pods */,
+ 144481D43B8FD6BABC279BD2 /* Frameworks */,
);
sourceTree = "";
};
@@ -125,17 +136,6 @@
name = "Supporting Files";
sourceTree = "";
};
- B73FC6430D1564515ACDA0A8 /* Pods */ = {
- isa = PBXGroup;
- children = (
- 978AC9E7D689FE7A1CC725C4 /* Pods-Runner.debug.xcconfig */,
- 3BDFDD4EE7D4A48E6F1023CD /* Pods-Runner.release.xcconfig */,
- 26A290795C8B345E7B54F3D8 /* Pods-Runner.profile.xcconfig */,
- );
- name = Pods;
- path = Pods;
- sourceTree = "";
- };
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
@@ -143,15 +143,15 @@
isa = PBXNativeTarget;
buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */;
buildPhases = (
- 828B385D0F4ED6C1571E5C5F /* [CP] Check Pods Manifest.lock */,
+ 428ABE4C58A2A019489A3B39 /* [CP] Check Pods Manifest.lock */,
9740EEB61CF901F6004384FC /* Run Script */,
97C146EA1CF9000F007C117D /* Sources */,
97C146EB1CF9000F007C117D /* Frameworks */,
97C146EC1CF9000F007C117D /* Resources */,
9705A1C41CF9048500538489 /* Embed Frameworks */,
3B06AD1E1E4923F5004D2608 /* Thin Binary */,
- 9F87D447099B0ED1C64C936E /* [CP] Embed Pods Frameworks */,
- 69F2FFE7873B2C24CBEDA23A /* [CP] Copy Pods Resources */,
+ FB76715B0EFF3C89AFE1FCBA /* [CP] Embed Pods Frameworks */,
+ 4243294FAA000FD34AB76E5C /* [CP] Copy Pods Resources */,
);
buildRules = (
);
@@ -223,25 +223,24 @@
shellPath = /bin/sh;
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin";
};
- 69F2FFE7873B2C24CBEDA23A /* [CP] Copy Pods Resources */ = {
+ 4243294FAA000FD34AB76E5C /* [CP] Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
- inputPaths = (
- "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources.sh",
- "${PODS_ROOT}/PDFNet/Tools-Localization",
+ inputFileListPaths = (
+ "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-input-files.xcfilelist",
);
name = "[CP] Copy Pods Resources";
- outputPaths = (
- "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/Tools-Localization",
+ outputFileListPaths = (
+ "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-output-files.xcfilelist",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources.sh\"\n";
showEnvVarsInLog = 0;
};
- 828B385D0F4ED6C1571E5C5F /* [CP] Check Pods Manifest.lock */ = {
+ 428ABE4C58A2A019489A3B39 /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
@@ -277,24 +276,17 @@
shellPath = /bin/sh;
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build";
};
- 9F87D447099B0ED1C64C936E /* [CP] Embed Pods Frameworks */ = {
+ FB76715B0EFF3C89AFE1FCBA /* [CP] Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
- inputPaths = (
- "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh",
- "${PODS_ROOT}/PDFNet/PDFNet.framework",
- "${PODS_ROOT}/PDFNet/Tools.framework",
- "${BUILT_PRODUCTS_DIR}/integration_test/integration_test.framework",
- "${BUILT_PRODUCTS_DIR}/pdftron_flutter/pdftron_flutter.framework",
+ inputFileListPaths = (
+ "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist",
);
name = "[CP] Embed Pods Frameworks";
- outputPaths = (
- "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/PDFNet.framework",
- "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Tools.framework",
- "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/integration_test.framework",
- "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/pdftron_flutter.framework",
+ outputFileListPaths = (
+ "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
diff --git a/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata
index 1d526a1..919434a 100644
--- a/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata
+++ b/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata
@@ -2,6 +2,6 @@
+ location = "self:">
diff --git a/lib/main.dart b/lib/main.dart
index 3d5fcbc..da2b6f9 100644
--- a/lib/main.dart
+++ b/lib/main.dart
@@ -5,7 +5,6 @@ import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_sample/thumbnail.dart';
import 'package:pdftron_flutter/pdftron_flutter.dart';
-import 'package:permission_handler/permission_handler.dart';
void main() => runApp(MyApp());
@@ -15,8 +14,8 @@ const MARGIN = 5.0;
const PORTRAIT_NUM_COLUMNS = 2;
const LANDSCAPE_NUM_COLUMNS = 3;
-final navigationColor = Platform.isIOS ? Color(0xffffffff) : Color(0xff48a1e0);
-final titleColor = Platform.isIOS ? Color(0xff007aff) : Color(0xffffffff);
+final navigationColor = (BuildContext context) => Theme.of(context).platform == TargetPlatform.iOS ? Color(0xffffffff) : Color(0xff48a1e0);
+final titleColor = (BuildContext context) => Theme.of(context).platform == TargetPlatform.iOS ? Color(0xff007aff) : Color(0xffffffff);
class MyApp extends StatefulWidget {
@override
@@ -24,17 +23,12 @@ class MyApp extends StatefulWidget {
}
class _MyAppState extends State {
- bool _storagePermitted = Platform.isIOS;
bool _initialized = false;
@override
void initState() {
super.initState();
initPlatformState();
-
- if (Platform.isAndroid) {
- askForPermission();
- }
}
// Platform messages are asynchronous, so we initialize in an async method.
@@ -52,29 +46,15 @@ class _MyAppState extends State {
}
}
- Future askForPermission() async {
- Map permissions =
- await PermissionHandler().requestPermissions([PermissionGroup.storage]);
- if (granted(permissions[PermissionGroup.storage]) && mounted) {
- setState(() {
- _storagePermitted = true;
- });
- }
- }
-
- bool granted(PermissionStatus status) {
- return status == PermissionStatus.granted;
- }
-
- void openDocument(String document) {
+ void openDocument(String document) async {
// configure the viewer by setting the config fields
Config config = new Config();
PdftronFlutter.openDocument(document, config: config);
}
Widget getBody() {
- if (_initialized && _storagePermitted) {
- return SafeArea(child: Container(
+ if (_initialized) {
+ return SafeArea(key: Key('body'), child: Container(
child: OrientationBuilder(builder: (context, orientation) {
return GridView.builder(
itemCount: thumbnailList.length,
@@ -88,6 +68,7 @@ class _MyAppState extends State {
itemBuilder: (BuildContext context, int index) {
Thumbnail thumbnail = thumbnailList[index];
return InkWell(
+ key: ValueKey(thumbnail.documentUrl),
child: Container(
margin: EdgeInsets.all(MARGIN),
decoration: BoxDecoration(
@@ -116,12 +97,11 @@ class _MyAppState extends State {
));
} else {
return Container(
+ key: Key('body'),
child: Align(
alignment: Alignment
.center, // Align however you like (i.e .centerRight, centerLeft)
- child: Text(_initialized
- ? 'Storage permission required.'
- : 'PDFTron SDK not initialized.'),
+ child: Text('PDFTron SDK not initialized.'),
));
}
}
@@ -134,9 +114,9 @@ class _MyAppState extends State {
centerTitle: true,
title: Text(
'PDFTron Flutter Sample',
- style: TextStyle(color: titleColor),
+ style: TextStyle(color: titleColor(context)),
),
- backgroundColor: navigationColor,
+ backgroundColor: navigationColor(context),
),
body: getBody()),
);
diff --git a/pubspec.lock b/pubspec.lock
index 41932b8..490f2ca 100644
--- a/pubspec.lock
+++ b/pubspec.lock
@@ -7,126 +7,126 @@ packages:
name: _fe_analyzer_shared
url: "https://pub.dartlang.org"
source: hosted
- version: "12.0.0"
+ version: "22.0.0"
analyzer:
dependency: transitive
description:
name: analyzer
url: "https://pub.dartlang.org"
source: hosted
- version: "0.40.6"
+ version: "1.7.1"
archive:
dependency: transitive
description:
name: archive
url: "https://pub.dartlang.org"
source: hosted
- version: "2.0.13"
+ version: "3.1.2"
args:
dependency: transitive
description:
name: args
url: "https://pub.dartlang.org"
source: hosted
- version: "1.6.0"
+ version: "2.1.1"
async:
dependency: transitive
description:
name: async
url: "https://pub.dartlang.org"
source: hosted
- version: "2.5.0-nullsafety.3"
+ version: "2.6.1"
boolean_selector:
dependency: transitive
description:
name: boolean_selector
url: "https://pub.dartlang.org"
source: hosted
- version: "2.1.0-nullsafety.3"
+ version: "2.1.0"
characters:
dependency: transitive
description:
name: characters
url: "https://pub.dartlang.org"
source: hosted
- version: "1.1.0-nullsafety.5"
+ version: "1.1.0"
charcode:
dependency: transitive
description:
name: charcode
url: "https://pub.dartlang.org"
source: hosted
- version: "1.2.0-nullsafety.3"
+ version: "1.2.0"
cli_util:
dependency: transitive
description:
name: cli_util
url: "https://pub.dartlang.org"
source: hosted
- version: "0.2.0"
+ version: "0.3.0"
clock:
dependency: transitive
description:
name: clock
url: "https://pub.dartlang.org"
source: hosted
- version: "1.1.0-nullsafety.3"
+ version: "1.1.0"
collection:
dependency: transitive
description:
name: collection
url: "https://pub.dartlang.org"
source: hosted
- version: "1.15.0-nullsafety.5"
+ version: "1.15.0"
convert:
dependency: transitive
description:
name: convert
url: "https://pub.dartlang.org"
source: hosted
- version: "2.1.1"
+ version: "3.0.0"
coverage:
dependency: transitive
description:
name: coverage
url: "https://pub.dartlang.org"
source: hosted
- version: "0.14.2"
+ version: "1.0.3"
crypto:
dependency: transitive
description:
name: crypto
url: "https://pub.dartlang.org"
source: hosted
- version: "2.1.5"
+ version: "3.0.1"
cupertino_icons:
dependency: "direct main"
description:
name: cupertino_icons
url: "https://pub.dartlang.org"
source: hosted
- version: "1.0.2"
+ version: "1.0.3"
fake_async:
dependency: transitive
description:
name: fake_async
url: "https://pub.dartlang.org"
source: hosted
- version: "1.2.0-nullsafety.3"
+ version: "1.2.0"
file:
dependency: transitive
description:
name: file
url: "https://pub.dartlang.org"
source: hosted
- version: "6.0.0-nullsafety.4"
+ version: "6.1.0"
flutter:
dependency: "direct main"
description: flutter
source: sdk
version: "0.0.0"
flutter_driver:
- dependency: transitive
+ dependency: "direct dev"
description: flutter
source: sdk
version: "0.0.0"
@@ -146,133 +146,159 @@ packages:
name: glob
url: "https://pub.dartlang.org"
source: hosted
- version: "1.2.0"
+ version: "2.0.1"
+ http_multi_server:
+ dependency: transitive
+ description:
+ name: http_multi_server
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "3.0.1"
+ http_parser:
+ dependency: transitive
+ description:
+ name: http_parser
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "4.0.0"
integration_test:
dependency: "direct dev"
description: flutter
source: sdk
- version: "0.9.2+2"
+ version: "0.0.0"
io:
dependency: transitive
description:
name: io
url: "https://pub.dartlang.org"
source: hosted
- version: "0.3.4"
+ version: "1.0.0"
js:
dependency: transitive
description:
name: js
url: "https://pub.dartlang.org"
source: hosted
- version: "0.6.3-nullsafety.3"
- json_rpc_2:
- dependency: transitive
- description:
- name: json_rpc_2
- url: "https://pub.dartlang.org"
- source: hosted
- version: "2.2.2"
+ version: "0.6.3"
logging:
dependency: transitive
description:
name: logging
url: "https://pub.dartlang.org"
source: hosted
- version: "0.11.4"
+ version: "1.0.1"
matcher:
dependency: transitive
description:
name: matcher
url: "https://pub.dartlang.org"
source: hosted
- version: "0.12.10-nullsafety.3"
+ version: "0.12.10"
meta:
dependency: transitive
description:
name: meta
url: "https://pub.dartlang.org"
source: hosted
- version: "1.3.0-nullsafety.6"
- node_interop:
+ version: "1.3.0"
+ mime:
dependency: transitive
description:
- name: node_interop
+ name: mime
url: "https://pub.dartlang.org"
source: hosted
- version: "1.2.1"
- node_io:
+ version: "1.0.0"
+ node_preamble:
dependency: transitive
description:
- name: node_io
+ name: node_preamble
url: "https://pub.dartlang.org"
source: hosted
- version: "1.1.1"
+ version: "2.0.1"
package_config:
dependency: transitive
description:
name: package_config
url: "https://pub.dartlang.org"
source: hosted
- version: "1.9.3"
+ version: "2.0.0"
path:
dependency: transitive
description:
name: path
url: "https://pub.dartlang.org"
source: hosted
- version: "1.8.0-nullsafety.3"
+ version: "1.8.0"
pdftron_flutter:
dependency: "direct main"
description:
- path: "."
- ref: HEAD
- resolved-ref: "0513833f3c555a0806992cff025ce86c509551d1"
- url: "git://github.com/PDFTron/pdftron-flutter.git"
- source: git
- version: "0.0.9"
+ name: pdftron_flutter
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "1.0.0-beta.2"
pedantic:
dependency: transitive
description:
name: pedantic
url: "https://pub.dartlang.org"
source: hosted
- version: "1.10.0-nullsafety.3"
- permission_handler:
- dependency: "direct main"
- description:
- name: permission_handler
- url: "https://pub.dartlang.org"
- source: hosted
- version: "3.0.1"
+ version: "1.11.1"
platform:
dependency: transitive
description:
name: platform
url: "https://pub.dartlang.org"
source: hosted
- version: "3.0.0-nullsafety.4"
+ version: "3.0.0"
pool:
dependency: transitive
description:
name: pool
url: "https://pub.dartlang.org"
source: hosted
- version: "1.5.0-nullsafety.3"
+ version: "1.5.0"
process:
dependency: transitive
description:
name: process
url: "https://pub.dartlang.org"
source: hosted
- version: "4.0.0-nullsafety.4"
+ version: "4.2.1"
pub_semver:
dependency: transitive
description:
name: pub_semver
url: "https://pub.dartlang.org"
source: hosted
- version: "1.4.4"
+ version: "2.0.0"
+ shelf:
+ dependency: transitive
+ description:
+ name: shelf
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "1.1.4"
+ shelf_packages_handler:
+ dependency: transitive
+ description:
+ name: shelf_packages_handler
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "3.0.0"
+ shelf_static:
+ dependency: transitive
+ description:
+ name: shelf_static
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "1.0.0"
+ shelf_web_socket:
+ dependency: transitive
+ description:
+ name: shelf_web_socket
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "1.0.1"
sky_engine:
dependency: transitive
description: flutter
@@ -284,118 +310,133 @@ packages:
name: source_map_stack_trace
url: "https://pub.dartlang.org"
source: hosted
- version: "2.1.0-nullsafety.4"
+ version: "2.1.0"
source_maps:
dependency: transitive
description:
name: source_maps
url: "https://pub.dartlang.org"
source: hosted
- version: "0.10.10-nullsafety.3"
+ version: "0.10.10"
source_span:
dependency: transitive
description:
name: source_span
url: "https://pub.dartlang.org"
source: hosted
- version: "1.8.0-nullsafety.4"
+ version: "1.8.1"
stack_trace:
dependency: transitive
description:
name: stack_trace
url: "https://pub.dartlang.org"
source: hosted
- version: "1.10.0-nullsafety.6"
+ version: "1.10.0"
stream_channel:
dependency: transitive
description:
name: stream_channel
url: "https://pub.dartlang.org"
source: hosted
- version: "2.1.0-nullsafety.3"
+ version: "2.1.0"
string_scanner:
dependency: transitive
description:
name: string_scanner
url: "https://pub.dartlang.org"
source: hosted
- version: "1.1.0-nullsafety.3"
+ version: "1.1.0"
sync_http:
dependency: transitive
description:
name: sync_http
url: "https://pub.dartlang.org"
source: hosted
- version: "0.2.0"
+ version: "0.3.0"
term_glyph:
dependency: transitive
description:
name: term_glyph
url: "https://pub.dartlang.org"
source: hosted
- version: "1.2.0-nullsafety.3"
+ version: "1.2.0"
+ test:
+ dependency: "direct dev"
+ description:
+ name: test
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "1.16.8"
test_api:
dependency: transitive
description:
name: test_api
url: "https://pub.dartlang.org"
source: hosted
- version: "0.2.19-nullsafety.6"
+ version: "0.3.0"
test_core:
dependency: transitive
description:
name: test_core
url: "https://pub.dartlang.org"
source: hosted
- version: "0.3.12-nullsafety.9"
+ version: "0.3.19"
typed_data:
dependency: transitive
description:
name: typed_data
url: "https://pub.dartlang.org"
source: hosted
- version: "1.3.0-nullsafety.5"
+ version: "1.3.0"
vector_math:
dependency: transitive
description:
name: vector_math
url: "https://pub.dartlang.org"
source: hosted
- version: "2.1.0-nullsafety.5"
+ version: "2.1.0"
vm_service:
dependency: transitive
description:
name: vm_service
url: "https://pub.dartlang.org"
source: hosted
- version: "5.5.0"
+ version: "6.2.0"
watcher:
dependency: transitive
description:
name: watcher
url: "https://pub.dartlang.org"
source: hosted
- version: "0.9.7+15"
+ version: "1.0.0"
web_socket_channel:
dependency: transitive
description:
name: web_socket_channel
url: "https://pub.dartlang.org"
source: hosted
- version: "1.1.0"
+ version: "2.1.0"
webdriver:
dependency: transitive
description:
name: webdriver
url: "https://pub.dartlang.org"
source: hosted
- version: "2.1.2"
+ version: "3.0.0"
+ webkit_inspection_protocol:
+ dependency: transitive
+ description:
+ name: webkit_inspection_protocol
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "1.0.0"
yaml:
dependency: transitive
description:
name: yaml
url: "https://pub.dartlang.org"
source: hosted
- version: "2.2.1"
+ version: "3.1.0"
sdks:
- dart: ">=2.12.0-0.0 <3.0.0"
+ dart: ">=2.12.0 <3.0.0"
+ flutter: ">=1.12.0"
diff --git a/pubspec.yaml b/pubspec.yaml
index ee52404..922beb4 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -18,27 +18,26 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev
version: 1.0.0+1
environment:
- sdk: ">=2.7.0 <3.0.0"
+ sdk: ">=2.12.0 <3.0.0"
dependencies:
flutter:
sdk: flutter
- pdftron_flutter:
- git:
- url: git://github.com/PDFTron/pdftron-flutter.git
-
- permission_handler: '3.0.1'
+ pdftron_flutter: '1.0.0-beta.2'
# The following adds the Cupertino Icons font to your application.
# Use with the CupertinoIcons class for iOS style icons.
- cupertino_icons: ^1.0.2
+ cupertino_icons: ^1.0.3
dev_dependencies:
flutter_test:
sdk: flutter
integration_test:
sdk: flutter
+ flutter_driver:
+ sdk: flutter
+ test: any
# For information on the generic Dart part of this file, see the
# following page: https://dart.dev/tools/pub/pubspec
diff --git a/test/widget_test.dart b/test/widget_test.dart
deleted file mode 100644
index ae07987..0000000
--- a/test/widget_test.dart
+++ /dev/null
@@ -1,30 +0,0 @@
-// This is a basic Flutter widget test.
-//
-// To perform an interaction with a widget in your test, use the WidgetTester
-// utility that Flutter provides. For example, you can send tap and scroll
-// gestures. You can also use WidgetTester to find child widgets in the widget
-// tree, read text, and verify that the values of widget properties are correct.
-
-import 'package:flutter/material.dart';
-import 'package:flutter_test/flutter_test.dart';
-
-import 'package:flutter_sample/main.dart';
-
-void main() {
- testWidgets('Counter increments smoke test', (WidgetTester tester) async {
- // Build our app and trigger a frame.
- await tester.pumpWidget(MyApp());
-
- // Verify that our counter starts at 0.
- expect(find.text('0'), findsOneWidget);
- expect(find.text('1'), findsNothing);
-
- // Tap the '+' icon and trigger a frame.
- await tester.tap(find.byIcon(Icons.add));
- await tester.pump();
-
- // Verify that our counter has incremented.
- expect(find.text('0'), findsNothing);
- expect(find.text('1'), findsOneWidget);
- });
-}
diff --git a/test_driver/integration_test.dart b/test_driver/integration_test.dart
new file mode 100644
index 0000000..ad98ece
--- /dev/null
+++ b/test_driver/integration_test.dart
@@ -0,0 +1,20 @@
+import 'dart:io' show Platform, Process;
+import 'package:integration_test/integration_test_driver.dart';
+import 'package:path/path.dart';
+
+// Driver for the integration test.
+Future main() async {
+ // Obtains storage permission on Android.
+ Map vars = Platform.environment;
+ String path = join(vars['ANDROID_SDK_ROOT'] ?? vars['ANDROID_HOME'] as String, "platform-tools", Platform.isWindows ? "adb.exe" : "adb");
+ await Process.run(path, [
+ 'shell',
+ 'pm',
+ 'grant',
+ 'com.example.fluttersample',
+ 'android.permission.WRITE_EXTERNAL_STORAGE'
+ ]);
+
+ // Starts the driver.
+ await integrationDriver();
+}