Отправка изображения XFile в API с помощью многоступенчатого флаттера

#android #react-native #flutter #dart #multipartform-data

Вопрос:

У меня есть приложение, предназначенное для Интернета, Android и ios. Я реализовал пакеты ниже

https://pub.dev/packages/image_picker/example

  • image_picker: ^0.8.2
  • image_picker_for_web: ^2.1.1

Задачи:

  1. Пользователю необходимо выбрать несколько изображений (при отладке через Android я иногда получаю сообщение о подключении к websocket, и приложение выходит без какого-либо сообщения об ошибке. Бонус, если вы также можете предоставить некоторые соображения по этому вопросу)
  2. Нажмите отправить, чтобы загрузить изображения (XFile) в API
 class UserAttachments {
  List<XFile>? attachments = [];
  int userID = 0;
}

Future<String> submitImage(UserAttachments ua) async {
  http.MultipartRequest request =
      new http.MultipartRequest("POST", Uri.parse(kAttachmentsURI));

  Map<String, String> headers = {"Content-Type": "application/json"};

  ua.attachments!.forEach((element) async {
    var bytes = element.readAsBytes();
    request.files.add(new http.MultipartFile.fromBytes('file', await bytes));
  });

  request.headers.addAll(headers);
  request.fields['userID'] = '23';

  http.StreamedResponse responseAttachmentSTR = await request.send();

  print(responseAttachmentSTR.statusCode);
  return "SENT"; //   "  - Respomse:  "   map.toString();
}

 

Приведенный выше код, похоже, не работает. Есть решения, которые подходят для Интернета/android/ios?

Комментарии:

1. Привет, тебе нужно быть более конкретным в своем вопросе. В чем именно здесь проблема?

2. Привет, кажется, я не могу передать файл в api, возвращает мне общую ошибку 500.

Ответ №1:

Вы не можете использовать асинхронность в forEach, потому что это просто вернет массив обещаний и не будет их ждать. Чтобы исправить это, вы можете использовать a for loop для асинхронных функций.

 for(var i = 0; i < ua.attachments!.length; i  ) {
  var element = ua.attachments[i];
  var bytes = element.readAsBytes();
  request.files.add(new http.MultipartFile.fromBytes('file', await bytes));
}
 

И вы можете оптимизировать этот код, используя Future.wait

 Future<String> submitImage(UserAttachments ua) async {
      http.MultipartRequest request =
          new http.MultipartRequest("POST", Uri.parse(kAttachmentsURI));
    
      Map<String, String> headers = {"Content-Type": "application/json"};
    
      var bytes = await Future.wait(ua.attachments!.map((el) => el.readAsBytes()));
      request.files.addAll(bytes.map((b) => new http.MultipartFile.fromBytes('file', b)));
    
      request.headers.addAll(headers);
      request.fields['userID'] = '23';
    
      http.StreamedResponse responseAttachmentSTR = await request.send();
    
      print(responseAttachmentSTR.statusCode);
      return "SENT";
}
 

Комментарии:

1. Получено 500 от API, я проверил URL — адрес для локального хоста изображения:59934/47aab53a-2889-4d65-9793-216693a248b8 может ли это вызвать проблему?