diff --git a/CHANGELOG.md b/CHANGELOG.md index 2f6cdf09..61511b96 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,18 @@ -## Next Release - ## Newest Release +### 2.2.0 - 14 Feb 2022 + +- This release requires you to update your Android project's `compileSdkVersion` to version 31. Please refer to [our migration guide](https://pspdfkit.com/guides/react-native/migration-guides/react-native-2-2-migration-guide) for this release. +- Adds a `destroyView()` function to `PSPDFKitView` to be used as a workaround for crash caused by a [`react-native-screens` issue](https://github.com/software-mansion/react-native-screens/issues/1300) when navigating back. (#32960) +- Improves the file structure of the Catalog sample project for better readability. (#32685) +- Improves the file structure of the NativeCatalog sample project for better readability. (#32887) +- Updates for PSPDFKit 8.1.1 for Android. (#33017) +- Updates for PSPDFKit 11.2.2 for iOS. (#33017) +- Fixes an issue where the `spreadFitting` configuration value is inverted on Android. (#32789) +- Removes `signingConfig` from React Native Android's sample projects app-level `build.gradle` files. (#32767) + +## Previous Releases + ### 2.1.0 - 06 Jan 2022 - Adds documentation for all the configuration options. (#31898) @@ -11,8 +22,6 @@ - Updates for PSPDFKit 11.2 for iOS. (#32495) - Fixes an issue where some examples using `Form_example.pdf` would not work. (#32495) -## Previous Releases - ### 2.0.4 - 07 Dec 2021 - Updates the Xcode build settings of the Catalog and Native Catalog example projects to work on iOS simulators on Apple Silicon Macs. (#32129) diff --git a/README.md b/README.md index b9e2ff68..fcd2c00d 100644 --- a/README.md +++ b/README.md @@ -21,6 +21,7 @@ Windows is not currently supported, please use the previous version [1.24.9](htt - [How to Extend React Native APIs for Windows](https://pspdfkit.com/blog/2019/how-to-extend-react-native-apis-for-windows/) - [How to Bridge Native iOS Code to React Native](https://pspdfkit.com/blog/2020/how-to-bridge-native-ios-code-to-react-native/) - [How to Open a PDF in React Native Using the Document Picker](https://pspdfkit.com/blog/2021/how-to-open-a-pdf-in-react-native-using-the-document-browser/) +- [How to Build a React Native PDF Viewer](https://pspdfkit.com/blog/2021/how-to-build-a-react-native-pdf-viewer/) ### PSPDFKit diff --git a/android/build.gradle b/android/build.gradle index e9f1678c..86c17699 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -15,7 +15,7 @@ * Contains gradle configuration constants */ ext { - PSPDFKIT_VERSION = '8.0.2' + PSPDFKIT_VERSION = '8.1.1' } buildscript { diff --git a/android/src/main/java/com/pspdfkit/react/ConfigurationAdapter.java b/android/src/main/java/com/pspdfkit/react/ConfigurationAdapter.java index e237203e..b3e517f7 100644 --- a/android/src/main/java/com/pspdfkit/react/ConfigurationAdapter.java +++ b/android/src/main/java/com/pspdfkit/react/ConfigurationAdapter.java @@ -350,10 +350,10 @@ private void configureSpreadFitting(@Nullable final String mode) { return; } if (mode.equals(SPREAD_FITTING_FIT)) { - configuration.fitMode(PageFitMode.FIT_TO_WIDTH); + configuration.fitMode(PageFitMode.FIT_TO_SCREEN); } else if (mode.equals(SPREAD_FITTING_FILL)) { - configuration.fitMode(PageFitMode.FIT_TO_SCREEN); + configuration.fitMode(PageFitMode.FIT_TO_WIDTH); } } diff --git a/android/src/main/java/com/pspdfkit/react/PSPDFKitModule.java b/android/src/main/java/com/pspdfkit/react/PSPDFKitModule.java index 4aaef603..c0dba717 100644 --- a/android/src/main/java/com/pspdfkit/react/PSPDFKitModule.java +++ b/android/src/main/java/com/pspdfkit/react/PSPDFKitModule.java @@ -48,12 +48,15 @@ import com.pspdfkit.ui.PdfFragment; import java.io.File; +import java.util.ArrayList; import java.util.EnumSet; import java.util.HashMap; import java.util.Map; public class PSPDFKitModule extends ReactContextBaseJavaModule implements Application.ActivityLifecycleCallbacks, ActivityEventListener { + /** Hybrid technology where the application is supposed to be working on. */ + private static final String HYBRID_TECHNOLOGY = "ReactNative"; private static final String VERSION_KEY = "versionString"; private static final String FILE_SCHEME = "file:///"; @@ -183,14 +186,14 @@ public void run() { @ReactMethod public void setLicenseKey(@Nullable String licenseKey) { - PSPDFKit.initialize(getReactApplicationContext().getApplicationContext(), licenseKey); + PSPDFKit.initialize(getReactApplicationContext().getApplicationContext(), licenseKey, new ArrayList<>(), HYBRID_TECHNOLOGY); } @ReactMethod public void setLicenseKeys(@Nullable String androidLicenseKey, @Nullable String iOSLicenseKey) { // Here, we ignore the `iOSLicenseKey` parameter and only care about `androidLicenseKey`. // `iOSLicenseKey` will be used to activate the license on iOS. - PSPDFKit.initialize(getReactApplicationContext().getApplicationContext(), androidLicenseKey); + PSPDFKit.initialize(getReactApplicationContext().getApplicationContext(), androidLicenseKey, new ArrayList<>(), HYBRID_TECHNOLOGY); } @ReactMethod diff --git a/android/src/main/java/com/pspdfkit/react/ReactPdfViewManager.java b/android/src/main/java/com/pspdfkit/react/ReactPdfViewManager.java index 75fe4b7b..5cb13ae7 100644 --- a/android/src/main/java/com/pspdfkit/react/ReactPdfViewManager.java +++ b/android/src/main/java/com/pspdfkit/react/ReactPdfViewManager.java @@ -60,6 +60,7 @@ public class ReactPdfViewManager extends ViewGroupManager { public static final int COMMAND_SET_FORM_FIELD_VALUE = 9; public static final int COMMAND_REMOVE_ANNOTATION = 10; public static final int COMMAND_GET_ALL_ANNOTATIONS = 11; + public static final int COMMAND_REMOVE_FRAGMENT = 12; private CompositeDisposable annotationDisposables = new CompositeDisposable(); @@ -110,6 +111,7 @@ public Map getCommandsMap() { commandMap.put("setFormFieldValue", COMMAND_SET_FORM_FIELD_VALUE); commandMap.put("removeAnnotation", COMMAND_REMOVE_ANNOTATION); commandMap.put("getAllAnnotations", COMMAND_GET_ALL_ANNOTATIONS); + commandMap.put("removeFragment", COMMAND_REMOVE_FRAGMENT); return commandMap; } @@ -285,6 +287,11 @@ public void accept(JSONObject jsonObject) { annotationDisposables.add(annotationDisposable); } break; + case COMMAND_REMOVE_FRAGMENT: + // Removing a fragment like this is not recommended, but it can be used as a workaround + // to stop `react-native-screens` from crashing the App when the back button is pressed. + root.removeFragment(true); + break; } } diff --git a/index.js b/index.js index 98de7fb1..edf5e371 100644 --- a/index.js +++ b/index.js @@ -101,6 +101,7 @@ class PSPDFKitView extends React.Component { this._requestMap.delete(requestId); }; + /** * Enters the annotation creation mode, showing the annotation creation toolbar. */ @@ -505,6 +506,26 @@ class PSPDFKitView extends React.Component { } }; + /** + * Removes the currently displayed Android Native PdfUiFragment. + * + * This function should only be used as a workaround for a bug in `react-native-screen` that causes a crash when + * `navigation.goBack()` is called or a hardware back button is used to navigate back on Android. Calling this + * function will prevent the crash by removing the fragment from the `PdfView` before the navigation takes place. + * + * Note: this function is available for Android only, it will have no effect on iOS. + */ + destroyView = function () { + if (Platform.OS === "android") { + UIManager.dispatchViewManagerCommand( + findNodeHandle(this.refs.pdfView), + this._getViewManagerConfig("RCTPSPDFKitView").Commands + .removeFragment, + [] + ); + } + }; + _getViewManagerConfig = (viewManagerName) => { const version = NativeModules.PlatformConstants.reactNativeVersion.minor; if (version >= 58) { diff --git a/ios/RCTPSPDFKit/RCTPSPDFKitManager.m b/ios/RCTPSPDFKit/RCTPSPDFKitManager.m index 1886bada..9786db33 100644 --- a/ios/RCTPSPDFKit/RCTPSPDFKitManager.m +++ b/ios/RCTPSPDFKit/RCTPSPDFKitManager.m @@ -22,17 +22,19 @@ @implementation RCTPSPDFKitManager +PSPDFSettingKey const PSPDFSettingKeyHybridEnvironment = @"com.pspdfkit.hybrid-environment"; + RCT_EXPORT_MODULE(PSPDFKit) RCT_REMAP_METHOD(setLicenseKey, setLicenseKey:(nullable NSString *)licenseKey resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) { - [PSPDFKitGlobal setLicenseKey:licenseKey]; + [PSPDFKitGlobal setLicenseKey:licenseKey options:@{PSPDFSettingKeyHybridEnvironment: @"ReactNative"}]; resolve(@(YES)); } RCT_REMAP_METHOD(setLicenseKeys, setLicenseKeys:(nullable NSString *)androidLicenseKey iOSLicenseKey:(nullable NSString *)iOSLicenseKey resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) { // Here, we ignore the `androidLicenseKey` parameter and only care about `iOSLicenseKey`. // `androidLicenseKey` will be used to activate the license on Android. - [PSPDFKitGlobal setLicenseKey:iOSLicenseKey]; + [PSPDFKitGlobal setLicenseKey:iOSLicenseKey options:@{PSPDFSettingKeyHybridEnvironment: @"ReactNative"}]; resolve(@(YES)); } diff --git a/package.json b/package.json index 8d705542..3b08d6e4 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "react-native-pspdfkit", - "version": "2.1.0", + "version": "2.2.0", "description": "React Native PDF Library by PSPDFKit", "keywords": [ "react native", diff --git a/samples/Catalog/.gitignore b/samples/Catalog/.gitignore index ad572e63..be2672c2 100644 --- a/samples/Catalog/.gitignore +++ b/samples/Catalog/.gitignore @@ -39,8 +39,6 @@ yarn-error.log buck-out/ \.buckd/ *.keystore -!debug.keystore - # fastlane # # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the diff --git a/samples/Catalog/Catalog.js b/samples/Catalog/Catalog.js index 16b616c9..8a0043b5 100644 --- a/samples/Catalog/Catalog.js +++ b/samples/Catalog/Catalog.js @@ -8,27 +8,27 @@ // Imports import React, {Component} from 'react'; -import { - StyleSheet, - Text, - View, - Button, - Image, - TouchableHighlight, - FlatList, - NativeModules, - processColor, - PermissionsAndroid, - Dimensions, -} from 'react-native'; +import {FlatList, Image, processColor, StyleSheet, Text, TouchableHighlight, View} from 'react-native'; import {createStackNavigator} from 'react-navigation-stack'; import {createAppContainer} from 'react-navigation'; -import PSPDFKitView from 'react-native-pspdfkit'; -// Constants -const PSPDFKit = NativeModules.PSPDFKit; +import {exampleDocumentName, exampleDocumentPath, pspdfkitColor, tiffImagePath} from "./configuration/Constants"; +import {extractFromAssetsIfMissing} from "./helpers/FileSystemHelpers"; +import {PSPDFKitViewComponent} from "./examples/PSPDFKitViewComponent"; +import {OpenImageDocument} from "./examples/OpenImageDocument"; +import {ManualSave} from "./examples/ManualSave"; +import {EventListeners} from "./examples/EventListeners"; +import {StateChange} from "./examples/StateChange"; +import {PSPDFKit} from "./helpers/PSPDFKit"; +import {AnnotationProcessing} from "./examples/AnnotationProcessing"; +import {ProgrammaticAnnotations} from "./examples/ProgrammaticAnnotations"; +import {ProgrammaticFormFilling} from "./examples/ProgrammaticFormFilling"; +import {SplitPDF} from "./examples/SplitPDF"; +import {ToolbarCustomization} from "./examples/ToolbarCustomization"; +import {HiddenToolbar} from "./examples/HiddenToolbar"; +import {CustomFontPicker} from "./examples/CustomFontPicker"; + const fileSystem = require('react-native-fs'); -const pspdfkitColor = '#267AD4'; // By default, this example doesn't set a license key, but instead runs in trial mode (which is the default, and which requires no // specific initialization). If you want to use a different license key for evaluation (e.g. a production license), you can uncomment @@ -40,29 +40,8 @@ const pspdfkitColor = '#267AD4'; // To set the license key for the currently running platform, use: // PSPDFKit.setLicenseKey("YOUR_REACT_NATIVE_LICENSE_KEY_GOES_HERE"); -// Document names -const exampleDocumentName = 'PSPDFKit_Quickstart_Guide.pdf'; -const formDocumentName = 'Form_example.pdf'; -const tiffImageName = 'PSPDFKit_Image_Example.tiff'; - -// Document paths -const exampleDocumentPath = - Platform.OS === 'ios' - ? 'PDFs/' + exampleDocumentName - : 'file:///android_asset/' + exampleDocumentName; -const formDocumentPath = - Platform.OS === 'ios' - ? 'PDFs/' + formDocumentName - : 'file:///android_asset/' + formDocumentName; -const tiffImagePath = - Platform.OS === 'ios' - ? 'PDFs/' + tiffImageName - : 'file:///android_asset/' + tiffImageName; -const writableDocumentPath = - fileSystem.DocumentDirectoryPath + '/' + exampleDocumentName; - // Configurations -const exampleConfiguration = { +const exampleDocumentConfiguration = { iOSBackgroundColor: processColor('white'), showPageNumberOverlay: true, grayScale: false, @@ -219,7 +198,7 @@ const examples = [ description: 'Customize various aspects of the document by passing a configuration dictionary.', action: () => { - PSPDFKit.present(exampleDocumentPath, exampleConfiguration); + PSPDFKit.present(exampleDocumentPath, exampleDocumentConfiguration); }, }, { @@ -297,1199 +276,6 @@ class Catalog extends Component { ); }; } -class AutoHidingHeaderComponent extends Component { - static navigationOptions = ({navigation}) => { - if (Platform.OS === 'android') { - return { - // Since the PSPDFKitView provides it's own toolbar and back button we don't need a header in Android. - headerShown: false, - }; - } - }; -} - -class PSPDFKitViewComponent extends AutoHidingHeaderComponent { - render() { - return ( - - { - this.props.navigation.goBack(); - }} - menuItemGrouping={[ - 'freetext', - {key: 'markup', items: ['highlight', 'underline']}, - 'ink', - 'image', - ]} - style={{flex: 1, color: pspdfkitColor}} - /> - - ); - } -} - -class OpenImageDocument extends AutoHidingHeaderComponent { - render() { - return ( - - - - ); - } -} - -class ManualSave extends AutoHidingHeaderComponent { - render() { - return ( - - - - -