Skip to content

iOS: Some files are saved with 0 KB size when IOSBackgroundTask: true #424

@eduardo-santos-tribia

Description

@eduardo-santos-tribia

Hi, I'm using react-native-blob-util in a React Native CLI app to download multiple files in parallel. The downloads work perfectly when IOSBackgroundTask is set to false, but when I set IOSBackgroundTask: true, I consistently encounter a problem: some of the downloaded files end up being 0 KB in size, and it's not always the same file. The issue appears to occur randomly.

Can someone help me understand why this is happening, and when should I set IOSBackgroundTask to true? The App I'm building has a requirement to work Offline, that's why I have to download multiple files and store them. It also need to keep downloading the files even when the App is running on background.

Environment:

Library version: react-native-blob-util@^0.19.11

React Native version: 0.76.9

Platform: iOS

Device: Simulator (tested so far)

iOS Version: e.g., iOS 17.5 (simulator)

Development machine: macOS

Steps to reproduce:

Configure the fetch call with IOSBackgroundTask: true.

Initiate multiple file downloads in parallel (e.g., 5–10).

Observe that some files are saved with 0 KB size.

Repeat test — different files result in 0 KB on each run.

Sample Code

const fetchBlob = async (
  fileName: string,
  fullFilePath: string,
) => {
  const authBearerToken = `Bearer token`
  const fullApiRoute = 'MyApiEndpoint'

  const headers = { Authorization: authBearerToken }

  return new Promise<any>((resolve, reject) => {
    ReactNativeBlobUtil.config({
      path: fullFilePath,
      fileCache: true,
      indicator: true,
      overwrite: true,
      IOSBackgroundTask: true, // works when is set to false.
    })
      .fetch('GET', fullApiRoute, headers)
      .then(async res => {
        const resStatus = res?.info ? res.info().status : 'Unknown'

        const isValidResponse = resStatus === 200 || res.data

        if (isValidResponse) {
          resolve(res)
        }
      })
      .catch(error => {
        reject(error)
      })
  })
}

// Downloading multiple files in parallel
let successCount = 0
const allPromises = await Promise.all(
  filesToFetch.map(file => {
    return fetchBlob(file.name, file.pathToDownload)
      .then(() => {
        successCount++
        return 'done'
      })
      .catch(err => {
        console.warn(`Skipping file due to error for ${file.id}:`, err)
        return 'error'
      })
  }),
)

Screenshot

Image

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions