Skip to content

iOS: Correct way to send a Binary file to an IOT device with no internet connection. #411

@bcmendis

Description

@bcmendis

Hello all,

I have a piece of code using this library that works perfectly with Android, but am having issues with iOS. It looks like iOS is dropping the connection because the network that my ESP32 creates does not have internet.

If I don't remove the "file://" before wrapping it, I get a ""Failed to create request body error", and if I remove it I get a "The network connection was lost" error.

Not really sure if it's a permissions issue or the way this library expects the filePath.

Has anyone faced this before? Any suggestions would be greatly appreciated.

const sendFirmwareUpdateFile = async ({
  filePath,
  binaryFileName,
// other variables...
}: sendFirmwareUpdateFileProps) => {


  try {
      postUrl = "http://192.168.10.11/update"

    if (filePath) {

      //Checks if file is present
      const getInfo = await FileSystem.getInfoAsync(filePath, {
        size: true,
      });

      if (!getInfo.exists) {
        throw new Error("Firmware file doesn't exist!");
      }

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

////////         Where iOS fails, but Android succeeds

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

      let data;

      if (Platform.OS === "ios") {
        const cleanFilePath = filePath.replace("file://", "");
        data = ReactNativeBlobUtil.wrap(cleanFilePath);
      } else {
        data = ReactNativeBlobUtil.wrap(filePath);
      }

         if (postUrl) {
           const response = await ReactNativeBlobUtil.config({
             trusty: true,             //added for testing, no effect
             wifiOnly: true.         //added for testing, no effect
           }).fetch(
             "POST",
             postUrl,
             {
               "Content-Type": "multipart/form-data",
               networkServiceType: "wifi",            //added for testing, no effect
               allowsCellularAccess: "false",        //added for testing, no effect
             },
             [
               {
                 name: "firmware",
                 filename: binaryFileName,
                 type: "application/octet-stream",
                 data,
               },
             ]
           );


///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

           const rawResponse = (await response.text()) as string;

           if (rawResponse.includes("OK")) {
             console.log("Firmware upload successful: ", rawResponse);
             return true;
             } else { 
                 throw new Error("Firmware could not be uploaded!");
               }

        } else {
          throw new Error("Not a valid POST URL address!");
        }

    } else {
      throw new Error("No valid filepath found!");
    }
  } catch (error) {
    // Error Handling
  }
};

My app.json info.plist has these requests:

"infoPlist": {
        "NSLocalNetworkUsageDescription": "The app requires access to the local network so it can download device updates",
        "NSAllowsLocalNetworking": true,
        "NSAppTransportSecurity": {
          "NSAllowsArbitraryLoads": true,
          "NSExceptionAllowsInsecureHTTPLoads": true
        },
        "UIFileSharingEnabled": true,
        "LSSupportsOpeningDocumentsInPlace": true
      },

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