expo-print 11.0.3 → 11.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -10,6 +10,12 @@
10
10
 
11
11
  ### 💡 Others
12
12
 
13
+ ## 11.0.4 — 2021-11-05
14
+
15
+ ### 🐛 Bug fixes
16
+
17
+ - Fix page-breaks and margins not supported on iOS ([#14383](https://github.com/expo/expo/pull/14802) by [@cruzach](https://github.com/IjzerenHein))
18
+
13
19
  ## 11.0.3 — 2021-10-21
14
20
 
15
21
  _This version does not introduce any user-facing changes._
package/README.md CHANGED
@@ -13,7 +13,7 @@ For managed [managed](https://docs.expo.io/versions/latest/introduction/managed-
13
13
 
14
14
  # Installation in bare React Native projects
15
15
 
16
- For bare React Native projects, you must ensure that you have [installed and configured the `react-native-unimodules` package](https://github.com/expo/expo/tree/master/packages/react-native-unimodules) before continuing.
16
+ For bare React Native projects, you must ensure that you have [installed and configured the `expo` package](https://docs.expo.dev/bare/installing-expo-modules/) before continuing.
17
17
 
18
18
  ### Add the package to your npm dependencies
19
19
 
@@ -3,7 +3,7 @@ apply plugin: 'kotlin-android'
3
3
  apply plugin: 'maven'
4
4
 
5
5
  group = 'host.exp.exponent'
6
- version = '11.0.3'
6
+ version = '11.0.4'
7
7
 
8
8
  buildscript {
9
9
  // Simple helper that allows the root project to override versions declared by this library.
@@ -57,7 +57,7 @@ android {
57
57
  minSdkVersion safeExtGet("minSdkVersion", 21)
58
58
  targetSdkVersion safeExtGet("targetSdkVersion", 30)
59
59
  versionCode 27
60
- versionName "11.0.3"
60
+ versionName "11.0.4"
61
61
  }
62
62
  lintOptions {
63
63
  abortOnError false
@@ -39,6 +39,10 @@ export declare type PrintOptions = {
39
39
  * or `Print.Orientation.landscape`.
40
40
  */
41
41
  orientation?: OrientationType['portrait'] | OrientationType['landscape'];
42
+ /**
43
+ * **Available on iOS only.** Page margins for the printed document.
44
+ */
45
+ margins?: PageMargins;
42
46
  };
43
47
  export declare type Printer = {
44
48
  /**
@@ -57,6 +61,12 @@ export interface OrientationType {
57
61
  portrait: string;
58
62
  landscape: string;
59
63
  }
64
+ export declare type PageMargins = {
65
+ top: number;
66
+ right: number;
67
+ bottom: number;
68
+ left: number;
69
+ };
60
70
  export declare type FilePrintOptions = {
61
71
  /**
62
72
  * HTML string to print into PDF file.
@@ -78,20 +88,14 @@ export declare type FilePrintOptions = {
78
88
  */
79
89
  height?: number;
80
90
  /**
81
- * Padding for the printed document.
91
+ * **Available on iOS only.** Page margins for the printed document.
82
92
  */
83
- padding?: FilePrintPadding;
93
+ margins?: PageMargins;
84
94
  /**
85
95
  * Whether to include base64 encoded string of the file in the returned object.
86
96
  */
87
97
  base64?: boolean;
88
98
  };
89
- export declare type FilePrintPadding = {
90
- top: number;
91
- right: number;
92
- bottom: number;
93
- left: number;
94
- };
95
99
  export declare type FilePrintResult = {
96
100
  /**
97
101
  * A URI to the printed PDF file.
@@ -1 +1 @@
1
- {"version":3,"file":"Print.types.js","sourceRoot":"","sources":["../src/Print.types.ts"],"names":[],"mappings":"","sourcesContent":["// @needsAudit\nexport type PrintOptions = {\n /**\n * URI of a PDF file to print. Remote, local (ex. selected via `DocumentPicker`) or base64 data URI\n * starting with `data:application/pdf;base64,`. This only supports PDF, not other types of\n * document (e.g. images). **Available on Android and iOS only.**\n */\n uri?: string;\n /**\n * HTML string to print. **Available on Android and iOS only.**\n */\n html?: string;\n /**\n * Width of the single page in pixels. Defaults to `612` which is a width of US Letter paper\n * format with 72 PPI. **Available only with `html` option.**\n */\n width?: number;\n /**\n * Height of the single page in pixels. Defaults to `792` which is a height of US Letter paper\n * format with 72 PPI. **Available only with `html` option.**\n */\n height?: number;\n /**\n * URL of the printer to use. Returned from `selectPrinterAsync`. **Available on iOS only.**\n */\n printerUrl?: string;\n /**\n * **Available on iOS only.** Alternative to default option that uses [UIMarkupTextPrintFormatter](https://developer.apple.com/documentation/uikit/uimarkuptextprintformatter)\n * instead of WebView, but it doesn't display images.\n */\n useMarkupFormatter?: boolean;\n /**\n * @deprecated\n * **Available on iOS only.** This argument is deprecated, use `useMarkupFormatter` instead.\n * Might be removed in the future releases.\n */\n markupFormatterIOS?: string;\n /**\n * **Available on iOS only.** The orientation of the printed content, `Print.Orientation.portrait`\n * or `Print.Orientation.landscape`.\n */\n orientation?: OrientationType['portrait'] | OrientationType['landscape'];\n};\n\n// @needsAudit\nexport type Printer = {\n /**\n * Name of the printer.\n */\n name: string;\n /**\n * URL of the printer.\n */\n url: string;\n};\n\n// @needsAudit\n/**\n * The possible values of orientation for the printed content.\n */\nexport interface OrientationType {\n portrait: string;\n landscape: string;\n}\n\n// @docsMissing\nexport type FilePrintOptions = {\n /**\n * HTML string to print into PDF file.\n */\n html?: string;\n /**\n * **Available on iOS only.** Alternative to default option that uses [UIMarkupTextPrintFormatter](https://developer.apple.com/documentation/uikit/uimarkuptextprintformatter)\n * instead of WebView, but it doesn't display images.\n */\n useMarkupFormatter?: boolean;\n /**\n * Width of the single page in pixels. Defaults to `612` which is a width of US Letter paper\n * format with 72 PPI.\n */\n width?: number;\n /**\n * Height of the single page in pixels. Defaults to `792` which is a height of US Letter paper\n * format with 72 PPI.\n */\n height?: number;\n /**\n * Padding for the printed document.\n */\n padding?: FilePrintPadding;\n /**\n * Whether to include base64 encoded string of the file in the returned object.\n */\n base64?: boolean;\n};\n\n// @needsAudit\nexport type FilePrintPadding = {\n top: number;\n right: number;\n bottom: number;\n left: number;\n};\n\n// @needsAudit\nexport type FilePrintResult = {\n /**\n * A URI to the printed PDF file.\n */\n uri: string;\n /**\n * Number of pages that were needed to render given content.\n */\n numberOfPages: number;\n /**\n * Base64 encoded string containing the data of the PDF file. **Available only if `base64`\n * option is truthy**. It doesn't include data URI prefix `data:application/pdf;base64,`.\n */\n base64?: string;\n};\n"]}
1
+ {"version":3,"file":"Print.types.js","sourceRoot":"","sources":["../src/Print.types.ts"],"names":[],"mappings":"","sourcesContent":["// @needsAudit\nexport type PrintOptions = {\n /**\n * URI of a PDF file to print. Remote, local (ex. selected via `DocumentPicker`) or base64 data URI\n * starting with `data:application/pdf;base64,`. This only supports PDF, not other types of\n * document (e.g. images). **Available on Android and iOS only.**\n */\n uri?: string;\n /**\n * HTML string to print. **Available on Android and iOS only.**\n */\n html?: string;\n /**\n * Width of the single page in pixels. Defaults to `612` which is a width of US Letter paper\n * format with 72 PPI. **Available only with `html` option.**\n */\n width?: number;\n /**\n * Height of the single page in pixels. Defaults to `792` which is a height of US Letter paper\n * format with 72 PPI. **Available only with `html` option.**\n */\n height?: number;\n /**\n * URL of the printer to use. Returned from `selectPrinterAsync`. **Available on iOS only.**\n */\n printerUrl?: string;\n /**\n * **Available on iOS only.** Alternative to default option that uses [UIMarkupTextPrintFormatter](https://developer.apple.com/documentation/uikit/uimarkuptextprintformatter)\n * instead of WebView, but it doesn't display images.\n */\n useMarkupFormatter?: boolean;\n /**\n * @deprecated\n * **Available on iOS only.** This argument is deprecated, use `useMarkupFormatter` instead.\n * Might be removed in the future releases.\n */\n markupFormatterIOS?: string;\n /**\n * **Available on iOS only.** The orientation of the printed content, `Print.Orientation.portrait`\n * or `Print.Orientation.landscape`.\n */\n orientation?: OrientationType['portrait'] | OrientationType['landscape'];\n /**\n * **Available on iOS only.** Page margins for the printed document.\n */\n margins?: PageMargins;\n};\n\n// @needsAudit\nexport type Printer = {\n /**\n * Name of the printer.\n */\n name: string;\n /**\n * URL of the printer.\n */\n url: string;\n};\n\n// @needsAudit\n/**\n * The possible values of orientation for the printed content.\n */\nexport interface OrientationType {\n portrait: string;\n landscape: string;\n}\n\n// @needsAudit\nexport type PageMargins = {\n top: number;\n right: number;\n bottom: number;\n left: number;\n};\n\n// @docsMissing\nexport type FilePrintOptions = {\n /**\n * HTML string to print into PDF file.\n */\n html?: string;\n /**\n * **Available on iOS only.** Alternative to default option that uses [UIMarkupTextPrintFormatter](https://developer.apple.com/documentation/uikit/uimarkuptextprintformatter)\n * instead of WebView, but it doesn't display images.\n */\n useMarkupFormatter?: boolean;\n /**\n * Width of the single page in pixels. Defaults to `612` which is a width of US Letter paper\n * format with 72 PPI.\n */\n width?: number;\n /**\n * Height of the single page in pixels. Defaults to `792` which is a height of US Letter paper\n * format with 72 PPI.\n */\n height?: number;\n /**\n * **Available on iOS only.** Page margins for the printed document.\n */\n margins?: PageMargins;\n /**\n * Whether to include base64 encoded string of the file in the returned object.\n */\n base64?: boolean;\n};\n\n// @needsAudit\nexport type FilePrintResult = {\n /**\n * A URI to the printed PDF file.\n */\n uri: string;\n /**\n * Number of pages that were needed to render given content.\n */\n numberOfPages: number;\n /**\n * Base64 encoded string containing the data of the PDF file. **Available only if `base64`\n * option is truthy**. It doesn't include data URI prefix `data:application/pdf;base64,`.\n */\n base64?: string;\n};\n"]}
@@ -178,6 +178,7 @@ EX_EXPORT_METHOD_AS(printToFileAsync,
178
178
  __block EXWKPDFRenderer *renderTask;
179
179
  NSString *htmlString = options[@"html"] ?: @"";
180
180
  CGSize paperSize = [self _paperSizeFromOptions:options];
181
+ UIEdgeInsets pageMargins = [self _pageMarginsFromOptions:options];
181
182
 
182
183
  void (^completionHandler)(NSError * _Nullable, NSData * _Nullable, int) =
183
184
  ^(NSError * _Nullable error, NSData * _Nullable pdfData, int pagesCount) {
@@ -221,7 +222,7 @@ EX_EXPORT_METHOD_AS(printToFileAsync,
221
222
  [self pdfWithHtmlMarkupFormatter:htmlString pageSize:paperSize completionHandler:completionHandler];
222
223
  } else {
223
224
  renderTask = [EXWKPDFRenderer new];
224
- [renderTask PDFWithHtml:htmlString pageSize:paperSize completionHandler:completionHandler];
225
+ [renderTask PDFWithHtml:htmlString pageSize:paperSize pageMargins:pageMargins completionHandler:completionHandler];
225
226
  }
226
227
  }
227
228
 
@@ -307,7 +308,8 @@ EX_EXPORT_METHOD_AS(printToFileAsync,
307
308
 
308
309
  NSString *htmlString = options[@"html"] ?: @"";
309
310
  CGSize paperSize = [self _paperSizeFromOptions:options];
310
- [renderTask PDFWithHtml:htmlString pageSize:paperSize completionHandler:^(NSError * _Nullable error, NSData * _Nullable pdfData, int pagesCount) {
311
+ UIEdgeInsets pageMargins = [self _pageMarginsFromOptions:options];
312
+ [renderTask PDFWithHtml:htmlString pageSize:paperSize pageMargins:pageMargins completionHandler:^(NSError * _Nullable error, NSData * _Nullable pdfData, int pagesCount) {
311
313
  if (pdfData != nil) {
312
314
  callback(pdfData, nil);
313
315
  } else {
@@ -357,6 +359,21 @@ EX_EXPORT_METHOD_AS(printToFileAsync,
357
359
  return paperSize;
358
360
  }
359
361
 
362
+ - (UIEdgeInsets)_pageMarginsFromOptions:(NSDictionary *)options
363
+ {
364
+ UIEdgeInsets pageMargins = UIEdgeInsetsZero;
365
+
366
+ if (options[@"margins"]) {
367
+ NSDictionary* margins = options[@"margins"];
368
+ pageMargins.left = [margins[@"left"] floatValue];
369
+ pageMargins.top = [margins[@"top"] floatValue];
370
+ pageMargins.bottom = [margins[@"bottom"] floatValue];
371
+ pageMargins.right = [margins[@"right"] floatValue];
372
+ }
373
+
374
+ return pageMargins;
375
+ }
376
+
360
377
  - (NSString *)_generatePath
361
378
  {
362
379
  id<EXFileSystemInterface> fileSystem = [_moduleRegistry getModuleImplementingProtocol:@protocol(EXFileSystemInterface)];
@@ -13,7 +13,7 @@ NS_ASSUME_NONNULL_BEGIN
13
13
 
14
14
  @interface EXWKPDFRenderer : NSObject
15
15
 
16
- - (void)PDFWithHtml:(NSString *)htmlString pageSize:(CGSize)pageSize completionHandler:(void(^_Nullable)(NSError * _Nullable, NSData * _Nullable, int))handler;
16
+ - (void)PDFWithHtml:(NSString *)htmlString pageSize:(CGSize)pageSize pageMargins:(UIEdgeInsets)pageMargins completionHandler:(void(^_Nullable)(NSError * _Nullable, NSData * _Nullable, int))handler;
17
17
 
18
18
  @end
19
19
 
@@ -2,11 +2,12 @@
2
2
 
3
3
  #import <EXPrint/EXWKPDFRenderer.h>
4
4
  #import <ExpoModulesCore/EXDefines.h>
5
- #import <EXPrint/EXWKSnapshotPDFRenderer.h>
5
+ #import <EXPrint/EXWKViewPrintPDFRenderer.h>
6
6
 
7
7
  @interface EXWKPDFRenderer () <WKNavigationDelegate>
8
8
 
9
9
  @property (nonatomic, assign) CGSize pageSize;
10
+ @property (nonatomic, assign) UIEdgeInsets pageMargins;
10
11
  @property (nonatomic, strong) WKWebView *webView;
11
12
  @property (nonatomic, strong) id<EXPDFRenderer> renderer;
12
13
  @property (nonatomic, strong) WKNavigation *htmlNavigation;
@@ -16,13 +17,14 @@
16
17
 
17
18
  @implementation EXWKPDFRenderer
18
19
 
19
- - (void)PDFWithHtml:(NSString *)htmlString pageSize:(CGSize)pageSize completionHandler:(void (^)(NSError * _Nullable, NSData * _Nullable, int))handler
20
+ - (void)PDFWithHtml:(NSString *)htmlString pageSize:(CGSize)pageSize pageMargins:(UIEdgeInsets)pageMargins completionHandler:(void (^)(NSError * _Nullable, NSData * _Nullable, int))handler
20
21
  {
21
22
  _pageSize = pageSize;
23
+ _pageMargins = pageMargins;
22
24
  _onRenderingFinished = handler;
23
25
  _webView = [self createWebView];
24
- _renderer = [[EXWKSnapshotPDFRenderer alloc] init];
25
- _htmlNavigation = [_webView loadHTMLString:htmlString baseURL:nil];
26
+ _renderer = [[EXWKViewPrintPDFRenderer alloc] initWithPageSize:pageSize pageMargins:pageMargins];
27
+ _htmlNavigation = [_webView loadHTMLString:htmlString baseURL:[[NSBundle mainBundle] resourceURL]];
26
28
  }
27
29
 
28
30
  #pragma mark - UIWebViewDelegate
@@ -1,4 +1,4 @@
1
- // Copyright 2015-present 650 Industries. All rights reserved.
1
+ // Copyright 2021-present 650 Industries. All rights reserved.
2
2
 
3
3
  #import <Foundation/Foundation.h>
4
4
  #import <WebKit/WebKit.h>
@@ -6,9 +6,11 @@
6
6
 
7
7
  NS_ASSUME_NONNULL_BEGIN
8
8
 
9
- @interface EXWKSnapshotPDFRenderer : NSObject <EXPDFRenderer>
9
+ @interface EXWKViewPrintPDFRenderer : NSObject <EXPDFRenderer>
10
10
 
11
- - (void)PDFFromWebView:(WKWebView *)webView completionHandler:(void(^_Nullable)(NSError * _Nullable, NSData * _Nullable, int))handler;
11
+ - (instancetype)initWithPageSize:(CGSize)pageSize pageMargins:(UIEdgeInsets)pageMargins;
12
+
13
+ - (void)PDFFromWebView:(WKWebView *)webView completionHandler:(void(^_Nullable)(NSError * _Nullable, NSData * _Nullable, int))handler API_AVAILABLE(ios(8.0));
12
14
 
13
15
  @end
14
16
 
@@ -0,0 +1,51 @@
1
+ // Copyright 2021-present 650 Industries. All rights reserved.
2
+
3
+ #import <EXPrint/EXWKViewPrintPDFRenderer.h>
4
+ #import <ExpoModulesCore/EXDefines.h>
5
+
6
+ @interface EXWKViewPrintPDFRenderer ()
7
+
8
+ @property (nonatomic, assign) CGSize pageSize;
9
+ @property (nonatomic, assign) UIEdgeInsets pageMargins;
10
+
11
+ @end
12
+
13
+ @implementation EXWKViewPrintPDFRenderer
14
+
15
+ - (instancetype)initWithPageSize:(CGSize)pageSize pageMargins:(UIEdgeInsets)pageMargins
16
+ {
17
+ if (self = [super init]) {
18
+ _pageSize = pageSize;
19
+ _pageMargins = pageMargins;
20
+ }
21
+ return self;
22
+ }
23
+
24
+ - (void)PDFFromWebView:(WKWebView *)webView completionHandler:(void (^)(NSError * _Nullable, NSData * _Nullable, int))handler
25
+ {
26
+ EX_WEAKIFY(self);
27
+ [webView evaluateJavaScript:@"document.body.scrollHeight;" completionHandler:^(id jsValue, NSError * _Nullable error) {
28
+ EX_ENSURE_STRONGIFY(self);
29
+
30
+ UIPrintPageRenderer *renderer = [[UIPrintPageRenderer alloc] init];
31
+ [renderer addPrintFormatter:webView.viewPrintFormatter startingAtPageAtIndex:0];
32
+
33
+ CGRect paperRect = CGRectMake(0, 0, self.pageSize.width, self.pageSize.height);
34
+ [renderer setValue:[NSValue valueWithCGRect:paperRect] forKey:@"paperRect"];
35
+ CGRect printableRect = CGRectMake(self.pageMargins.left, self.pageMargins.top, paperRect.size.width - self.pageMargins.left - self.pageMargins.right, paperRect.size.height - self.pageMargins.top - self.pageMargins.bottom);
36
+ [renderer setValue:[NSValue valueWithCGRect:printableRect] forKey:@"printableRect"];
37
+
38
+ NSMutableData* data = [[NSMutableData alloc] init];
39
+ UIGraphicsBeginPDFContextToData(data, CGRectZero /* paperRect */, nil);
40
+ [renderer prepareForDrawingPages: NSMakeRange(0, renderer.numberOfPages)];
41
+ for (int i = 0; i < renderer.numberOfPages; i++) {
42
+ UIGraphicsBeginPDFPage();
43
+ [renderer drawPageAtIndex:i inRect: UIGraphicsGetPDFContextBounds()];
44
+ }
45
+ UIGraphicsEndPDFContext();
46
+
47
+ handler(nil, data, (int)renderer.numberOfPages);
48
+ }];
49
+ }
50
+
51
+ @end
@@ -6,30 +6,30 @@
6
6
  <array>
7
7
  <dict>
8
8
  <key>LibraryIdentifier</key>
9
- <string>ios-arm64</string>
9
+ <string>ios-arm64_x86_64-simulator</string>
10
10
  <key>LibraryPath</key>
11
11
  <string>EXPrint.framework</string>
12
12
  <key>SupportedArchitectures</key>
13
13
  <array>
14
14
  <string>arm64</string>
15
+ <string>x86_64</string>
15
16
  </array>
16
17
  <key>SupportedPlatform</key>
17
18
  <string>ios</string>
19
+ <key>SupportedPlatformVariant</key>
20
+ <string>simulator</string>
18
21
  </dict>
19
22
  <dict>
20
23
  <key>LibraryIdentifier</key>
21
- <string>ios-arm64_x86_64-simulator</string>
24
+ <string>ios-arm64</string>
22
25
  <key>LibraryPath</key>
23
26
  <string>EXPrint.framework</string>
24
27
  <key>SupportedArchitectures</key>
25
28
  <array>
26
29
  <string>arm64</string>
27
- <string>x86_64</string>
28
30
  </array>
29
31
  <key>SupportedPlatform</key>
30
32
  <string>ios</string>
31
- <key>SupportedPlatformVariant</key>
32
- <string>simulator</string>
33
33
  </dict>
34
34
  </array>
35
35
  <key>CFBundlePackageType</key>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "expo-print",
3
- "version": "11.0.3",
3
+ "version": "11.0.4",
4
4
  "description": "Provides an API for iOS (AirPrint) and Android printing functionality.",
5
5
  "main": "build/Print.js",
6
6
  "types": "build/Print.d.ts",
@@ -34,10 +34,10 @@
34
34
  "preset": "expo-module-scripts/ios"
35
35
  },
36
36
  "dependencies": {
37
- "expo-modules-core": "~0.4.4"
37
+ "expo-modules-core": "~0.4.7"
38
38
  },
39
39
  "devDependencies": {
40
40
  "expo-module-scripts": "^2.0.0"
41
41
  },
42
- "gitHead": "4fa0497a180ae707fa860cb03858630ab7af19f4"
42
+ "gitHead": "74665a05e2bc8c20c23c07e1b3a8b92b2ed5d875"
43
43
  }
@@ -40,6 +40,10 @@ export type PrintOptions = {
40
40
  * or `Print.Orientation.landscape`.
41
41
  */
42
42
  orientation?: OrientationType['portrait'] | OrientationType['landscape'];
43
+ /**
44
+ * **Available on iOS only.** Page margins for the printed document.
45
+ */
46
+ margins?: PageMargins;
43
47
  };
44
48
 
45
49
  // @needsAudit
@@ -63,6 +67,14 @@ export interface OrientationType {
63
67
  landscape: string;
64
68
  }
65
69
 
70
+ // @needsAudit
71
+ export type PageMargins = {
72
+ top: number;
73
+ right: number;
74
+ bottom: number;
75
+ left: number;
76
+ };
77
+
66
78
  // @docsMissing
67
79
  export type FilePrintOptions = {
68
80
  /**
@@ -85,23 +97,15 @@ export type FilePrintOptions = {
85
97
  */
86
98
  height?: number;
87
99
  /**
88
- * Padding for the printed document.
100
+ * **Available on iOS only.** Page margins for the printed document.
89
101
  */
90
- padding?: FilePrintPadding;
102
+ margins?: PageMargins;
91
103
  /**
92
104
  * Whether to include base64 encoded string of the file in the returned object.
93
105
  */
94
106
  base64?: boolean;
95
107
  };
96
108
 
97
- // @needsAudit
98
- export type FilePrintPadding = {
99
- top: number;
100
- right: number;
101
- bottom: number;
102
- left: number;
103
- };
104
-
105
109
  // @needsAudit
106
110
  export type FilePrintResult = {
107
111
  /**
@@ -1,61 +0,0 @@
1
- // Copyright 2015-present 650 Industries. All rights reserved.
2
-
3
- #import <EXPrint/EXWKSnapshotPDFRenderer.h>
4
- #import <ExpoModulesCore/EXDefines.h>
5
-
6
- @interface EXWKSnapshotPDFRenderer ()
7
-
8
- @end
9
-
10
- @implementation EXWKSnapshotPDFRenderer
11
-
12
- - (void)PDFFromWebView:(WKWebView *)webView completionHandler:(void (^)(NSError * _Nullable, NSData * _Nullable, int))handler
13
- {
14
- EX_WEAKIFY(self);
15
- [webView evaluateJavaScript:@"window.innerHeight + ' ' + document.documentElement.scrollHeight" completionHandler:^(id jsResult, NSError * _Nullable error) {
16
- EX_ENSURE_STRONGIFY(self);
17
- NSString *jsResultString = jsResult;
18
- NSArray *items = [jsResultString componentsSeparatedByString:@" "];
19
- CGFloat pageHeight = [items[0] doubleValue];
20
- CGFloat scrollHeight = [items[1] doubleValue];
21
- int numberOfPages = ceil(scrollHeight / pageHeight);
22
-
23
- // Ensure all content is loaded by scrolling to the end of webpage
24
- [webView.scrollView setContentOffset:CGPointMake(0, scrollHeight - pageHeight) animated:NO];
25
-
26
- NSMutableData *pdfData = [NSMutableData data];
27
- UIGraphicsBeginPDFContextToData(pdfData, webView.bounds, nil);
28
- [self takeSnapshotForPage:0 ofPages:numberOfPages ofWebView:webView withCompletionHandler:^(NSError * _Nullable error) {
29
- UIGraphicsEndPDFContext();
30
- if (error) {
31
- handler(error, nil, 0);
32
- } else {
33
- handler(nil, pdfData, numberOfPages);
34
- }
35
- }];
36
- }];
37
- }
38
-
39
- - (void)takeSnapshotForPage:(int)pageIndex ofPages:(int)pagesCount ofWebView:(WKWebView *)webView withCompletionHandler:(void (^ _Nullable)(NSError * _Nullable error))completionHandler
40
- {
41
- if (pageIndex >= pagesCount) {
42
- completionHandler(nil);
43
- return;
44
- }
45
-
46
- CGFloat pageHeight = webView.bounds.size.height;
47
-
48
- [webView.scrollView setContentOffset:CGPointMake(0, pageHeight * pageIndex) animated:NO];
49
- [webView takeSnapshotWithConfiguration:nil completionHandler:^(UIImage * _Nullable snapshotImage, NSError * _Nullable error) {
50
- if (snapshotImage) {
51
- CGRect printRect = UIGraphicsGetPDFContextBounds();
52
- UIGraphicsBeginPDFPage();
53
- [snapshotImage drawInRect:printRect];
54
- [self takeSnapshotForPage:(pageIndex + 1) ofPages:pagesCount ofWebView:webView withCompletionHandler:completionHandler];
55
- } else {
56
- completionHandler(error);
57
- }
58
- }];
59
- }
60
-
61
- @end