Отправьте запрос POST, получите PDF-файл взамен и сохраните его в файловой системе в NativeScript - PullRequest
0 голосов
/ 10 марта 2020

Я хочу отправить запрос POST, содержащий JSON, на сервер для обработки. Затем сервер вернет PDF-файл, который я хочу получить, сохранить в файловой системе и отобразить с помощью nativescript-pdf-view . Однако File.writeSync() не примет ArrayBuffer , полученный от ответа сервера. Вместо этого он ожидает собственные варианты NSData (iOS) и ByteArray (Android). Как я могу преобразовать ArrayBuffer в собственные байтовые массивы?

1 Ответ

0 голосов
/ 10 марта 2020

Отправка запроса POST

Как указано в официальной документации, запрос POST можно отправить с помощью функции getBinary():

import { getBinary } from 'tns-core-modules/http'

getBinary({
  url: 'https://example.com/foo/bar/generate-pdf',
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  content: JSON.stringify(someObject),
})

Здесь, someObject - это объект, который вы хотите преобразовать в JSON и отправить на сервер.

Получение, преобразование и сохранение файла / PDF

Ответ будет содержать PDF или любой другой файл как ArrayBuffer . Как уже упоминалось в вопросе, метод File.writeSync() ожидает NSData (iOS) и ByteArray (Android). Итак, нам нужно получить обработчик файла, преобразовать наш файл и сохранить его в файловой системе.

import { getBinary } from 'tns-core-modules/http'
import { isAndroid } from 'tns-core-modules/platform'
import { File, knownFolders, path } from 'tns-core-modules/file-system'

getBinary({
  url: 'https://example.com/foo/bar/generate-pdf',
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  content: JSON.stringify(someObject),
}).then((buffer) => {

  // Get file handler
  const documentsFolder = knownFolders.documents()
  const destination = path.join(documentsFolder.path, 'result.pdf')
  const file = File.fromPath(destination)

  // Convert buffer to byte array
  let byteArray
  if (isAndroid) {
    byteArray = Array.create('byte', buffer.byteLength)
    for (let i = 0; i < buffer.length; i++) {
      byteArray[i] = new java.lang.Byte(buffer[i])
    }
  } else {
    byteArray = NSData.dataWithBytesLength(buffer, buffer.byteLength)
  }

  // Save file
  file.writeSync(byteArray, (error) => {
    console.log(error)
  });
})

Почему метод File.writeSync() не конвертирует это автоматически, это чудо мне. Может быть, кто-то еще может объяснить!

Отображение PDF

Чтобы отобразить PDF, вы можете использовать nativescript-pdf-view . Просто используйте обработчик файлов, чтобы получить путь file.path или переменную destination и передать его в свойство src компонента PDFView. Это может выглядеть так:

<template>
  <Page>
    <ActionBar title="PDF" />
    <GridLayout rows="*" columns="*">
      <PDFView :src="path" row="0" col="0" />
    </GridLayout>
  </Page>
</template>

<script lang="ts">
export default {
  name: 'PdfViewer',
  props: {
    path: {
      type: String,
      required: true,
    },
  },
}
</script>

Обязательно установите плагин и, конечно, добавьте элемент в Vue. js, сначала:

// main.ts

Vue.registerElement('PDFView', () => require('nativescript-pdf-view').PDFView)
...