12.1 C
London
Friday, February 16, 2024

App crashes throughout PDF comparability utilizing PDFKIT in iOS with Swift


I’m a React Native developer, and studying Swift. I’ve developed a NativeModule for my app, which, examine two PDFs and summarize the altering end result, and ship it again to the React Native Bridge. Listed below are the codes I’m utilizing, and these codes work if the PDF comprises lower than 100 pages, nevertheless, when the pages will increase the App crashes as a result of Reminiscence challenge.

Native Module (PDF Supervisor):

import Basis
import PDFKit
import SwiftDiff

@objc(PDFManager)
class PDFManager: NSObject {
  
  non-public var currentPageIndex: Int = 0
  non-public var lastProcessedIndex: Int = 0
  
  @objc
  func compareAndMerge(_ pdfPath1: String, pdfPath2: String, documentName: String, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) {
    do {
      guard let firstPdfURL = URL(string: pdfPath1),
            let secondPdfURL = URL(string: pdfPath2) else {
        reject("pdfInvalidPath", "Invalid PDF path", nil)
        return
      }
      
      guard let pdf1 = PDFDocument(url: firstPdfURL),
            let pdf2 = PDFDocument(url: secondPdfURL) else {
        reject("PDFLoadError", "Didn't load PDFs", nil)
        return
      }
      
      let abstract = attempt compareAndSummarize(doc1: pdf1, doc2: pdf2)
      let json = summarizeToJSON(abstract: abstract)
      resolve(json)
    } catch {
      print("Error merging PDFs:", error)
      reject("pdfMergeError", "Error merging PDFs", nil)
    }
  }
  
  @objc
  static func requiresMainQueueSetup() -> Bool {
    return true
  }
  
  non-public func compareAndSummarize(doc1: PDFDocument, doc2: PDFDocument) throws -> (String, Int) {
    var changesSummary = ""
    var pagesChanged = 0
    // Iterate over pages of doc1 and doc2 concurrently
    let pageCount = min(doc1.pageCount, doc2.pageCount)
    for pageIndex in 0..<pageCount {
      autoreleasepool {
        guard let page1 = doc1.web page(at: pageIndex),
              let page2 = doc2.web page(at: pageIndex) else { return }
        let page1Text = page1.string ?? ""
        let page2Text = page2.string ?? ""
        changesSummary += "Web page (pageIndex + 1):n"
        
        // Calculate variations between the textual content of the 2 pages
        let diff = diff(text1: page1Text, text2: page2Text)
        var pageChanged = false
        // Course of every change within the variations
        for change in diff {
          swap change {
          case .delete(let worth):
            pageChanged = true
            changesSummary += "- Deleted: (worth)n"
          case .insert(let worth):
            pageChanged = true
            changesSummary += "+ Inserted: (worth)n"
          case .equal( _):
            break
          }
        }
        if pageChanged {
          pagesChanged += 1
        }
      }
    }
    return (changesSummary, pagesChanged)
  }

  func summarizeToJSON(abstract: (String, Int)) -> String {
    let dictionary: [String: Any] = ["changes": summary.0, "pagesChanged": summary.0]
    let knowledge = attempt? JSONSerialization.knowledge(withJSONObject: dictionary, choices: [.prettyPrinted])
    return String(knowledge: knowledge!, encoding: .utf8) ?? ""
  }

}

React Native Codes:

import React, {useState} from 'react';
import {ActivityIndicator, NativeModules, View, useWindowDimensions} from 'react-native';
import Textual content from '../../Parts/Textual content';
import s from '../../property/kinds';
import {Button} from '../../Parts/Buttons';
import DocumentPicker from 'react-native-document-picker';
import {useSafeAreaInsets} from 'react-native-safe-area-context';

perform HomeScreen() {
  const [pdf1, setPDF1] = useState(null);
  const [pdf2, setPDF2] = useState(null);
  const [merging, setMerging] = useState(false);
  const {PDFManager} = NativeModules;
  const insets = useSafeAreaInsets();
  const {width} = useWindowDimensions();
  const buttonWidth = width / 2 - 25;

  const selectFirstPDF = async () => {
    attempt {
      const end result = await DocumentPicker.pickSingle({
        kind: DocumentPicker.sorts.pdf,
        copyTo: 'cachesDirectory',
      });
      if (!end result?.fileCopyUri) {
        return;
      }
      setPDF1(end result);
    } catch (error) {}
  };

  const selectSecondPDF = async () => {
    attempt {
      const end result = await DocumentPicker.pickSingle({
        kind: DocumentPicker.sorts.pdf,
        copyTo: 'cachesDirectory',
      });
      if (!end result?.fileCopyUri) {
        return;
      }
      setPDF2(end result);
    } catch (error) {}
  };

  const updateManuals = async () => {
    setMerging(true);
    attempt {
      const end result = await PDFManager.compareAndMerge(
        pdf1?.fileCopyUri,
        pdf2?.fileCopyUri,
        `${pdf2?.title}_Autopilot3.pdf`,
      );
      setMerging(false);
      if (end result) {
        const json = JSON.parse(end result);
        console.log('json -> ', json);
      }
    } catch (error) {
      console.log('Error -> ', error);
    } lastly {
      setMerging(false);
    }
  };

  return (
    <View type={[s.flex1, {paddingTop: insets.top}, s.jcac]}>
      <View type={[s.mHor10]}>
        <Textual content type={[s.f30, s.ls2, s.fontBlack, s.textCenter, s.as]}>
          Maintain Highlights
        </Textual content>
        <Textual content type={[s.fontSemiBold, s.mVer10]}>
          Effortlessly examine your PDF manuals and maintain your highlights
          up to date. Recordsdata are in contrast domestically and your knowledge at all times stay
          confidential.
        </Textual content>
        <View type={[s.flexRow, s.aic, s.jsb, s.mVer10]}>
          <Button
            title={pdf1?.title ? pdf1?.title : 'Highlighted PDF'}
            type={[s.bgPurple, s.br30, {width: buttonWidth}, s.me10]}
            textStyle={[s.fontMedium, s.f14, s.textWhite]}
            onPress={selectFirstPDF}
          />
          <Button
            title={pdf2?.title ? pdf2?.title : 'Up to date handbook'}
            onPress={selectSecondPDF}
            textStyle={[s.fontMedium, s.f14, s.textWhite]}
            type={[s.br30, {width: buttonWidth}]}
          />
        </View>
        <Button
          title={'Get up to date handbook'}
          isDisabled=
          onPress={updateManuals}
        />
        {merging && <ActivityIndicator dimension={'giant'} shade={'white'}/>}
      </View>
    </View>
  );
}

export default HomeScreen;

I attempted totally different suggestions and strategies like: autorelease.

Latest news
Related news

LEAVE A REPLY

Please enter your comment!
Please enter your name here