Получение файла образа в параметре body

Я пытаюсь загрузить файл на сервер. Я использую SlimFramework и PHP в своем внутреннем коде, и он находится в форме RESTful. Загрузка изображений работает очень хорошо, если я загружаю его через Postman, но я не могу заставить его работать с помощью библиотеки Swift и Alamofire.

В маршруте, который у меня есть в бэкэнд, я получаю файл, как это, из параметра body:

$image = $request->getUploadedFiles();

и для загрузки я использую:

$image->moveTo("myPath");

В Swift у меня есть маршрутизатор, который дает метод .post и URL маршрута, и я пробовал вот так:

func uploadImage(user_id: Int, image: Data, completion: @escaping (_ error: Error?, _ success: Bool)->Void) {
        let parameters = [
            "user_id": user_id,
            "newFile": image
        ] as [String : Any]

        Alamofire.request(Router.imageUplaod(parameters: parameters))
            .validate(statusCode: 200..<300)
            .responseJSON { response in

                switch response.result{

                case .failure(let error):
                    completion(error, false)

                    print(error)

                case .success(let value):
                    //Registered sucesfully! let json = JSON(value)
                    completion(nil, true)

                }//Switch case
        }//Alamofire
    }

И я называю это следующим образом:

func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
        let chosenProfileImage = info[UIImagePickerControllerEditedImage] as! UIImage
        let imageData = UIImageJPEGRepresentation(chosenProfileImage, 0.2)
        profileImageView.image = chosenProfileImage

        dismiss(animated: true) { 
            API.uploadImage(user_id: User.sharedInstance.user_id, image: imageData!) { (error, success) in

                if success{
                    print("IMAGE UPLOADDED")
                }
            }
        }
    }

Это мой бэкэнд-маршрут:

 $this->post('/image/upload', function($request, $response, $args){
    global $database;
    $data = $request->getParsedBody();
    $user_id = $data['user_id'];

    $files = $request->getUploadedFiles();
    if (empty($files['newfile'])) {
        throw new Exception('Expected a newfile');
    }

    $newfile = $files['newfile'];

    if ($newfile->getError() === UPLOAD_ERR_OK) {
    $uploadFileName = "profileImage".$user_id.".jpg";
    $newfile->moveTo("/path/to/image/$uploadFileName");
    }

    $database->query("UPDATE `users` SET `profile_image_url` = :image WHERE user_id = :user_id");
    $database->bind(':image', $uploadFileName);
    $database->bind(':user_id', $user_id);
    $database->execute();


    $Jsonarray['status'] = "true";
    $Jsonarray['message'] = "Image Uploaded Successfully";
    return $response->withStatus(200)->withHeader('Content-Type', 'application/json')->write(json_encode($Jsonarray));

    });

Странно, что Alamofire выводит статусный код 500, но сервер ничего мне не говорит. Проблема должна быть в Swift. Поэтому я даже не знаю, как его отладить.

Как мне решить проблему?

Ответ 1

Я решил проблему. Я перестроил его таким образом:

  • Преобразование изображения в Base64 String на клиенте
  • Декодирование изображения на бэкэнд
  • Загрузить его

Итак, в Swift я Преобразуем его следующим образом:

let chosenProfileImage = info[UIImagePickerControllerEditedImage] as! UIImage
let imageData = UIImageJPEGRepresentation(chosenProfileImage, 0.2)
profileImageView.image = chosenProfileImage

let base64String = imageData?.base64EncodedString(options: .lineLength64Characters)

И бэкэнд почти такой же, просто преобразовал его обратно в файл с помощью base64_decode(); и использовал функцию file_put_contents();, чтобы переместить его на сервер.