Isuues с передачей изображения контроллеру представления, который будет использоваться для сетевого запроса POST - PullRequest
0 голосов
/ 26 мая 2020

У меня вопрос. Я пытаюсь создать небольшое приложение, в котором я отправляю запрос POST с изображением в API. Я поместил все свои сетевые logi c в отдельный быстрый класс, и у меня есть главный контроллер представления. Проблема, с которой я столкнулся, заключается в том, что мне нужно получить изображение из моего основного контроллера просмотра и отправить его в отдельный сетевой класс, чтобы его можно было отправить с помощью POST REQUEST, но у меня возникли проблемы с этим, поскольку значение изображения возвращает ноль при передаче в сетевой класс. Я пробовал использовать замыкания, делегаты, свойства, чтобы попытаться передать это изображение, но безуспешно. Если я делаю всю сеть в своем основном контроллере просмотра, все работает нормально, но я хотел бы отделить сетевой лог c. Я занимаюсь этим в течение двух дней, ПОЖАЛУЙСТА, помогите подсказать, что мне не хватает, или лучший способ go об этом.

import UIKit
import YPImagePicker


class NewViewController: UIViewController {
static let instance = NewViewController()

var config = YPImagePickerConfiguration()
    override func viewDidLoad() {
        super.viewDidLoad()

        config.isScrollToChangeModesEnabled = true
        config.onlySquareImagesFromCamera = true
        config.usesFrontCamera = false
        config.showsPhotoFilters = false
        config.showsVideoTrimmer = true
        config.shouldSaveNewPicturesToAlbum = true
        config.albumName = "DefaultYPImagePickerAlbumName"
        config.startOnScreen = YPPickerScreen.photo
        config.screens = [.library, .photo]
        config.showsCrop = .none
        config.targetImageSize = YPImageSize.original
        config.overlayView = UIView()
        config.hidesStatusBar = true
        config.hidesBottomBar = false
        config.preferredStatusBarStyle = UIStatusBarStyle.default
        config.bottomMenuItemSelectedTextColour = UIColor()
       config.bottomMenuItemUnSelectedTextColour = UIColor()
       // config.filters = [DefaultYPFilters...]
        config.maxCameraZoomFactor = 1.0

        // Do any additional setup after loading the view.
    }


    @IBOutlet weak var imageView: UIImageView!


    @IBAction func sendBtn(_ sender: UIButton) {
        NetworkServices.instance.userChoice { (Age) in
                   print(Age)
               }
    }

    @IBAction func imageBtn(_ sender: UIButton) {

    let picker = YPImagePicker(configuration: config)
    picker.didFinishPicking { [unowned picker] items, _ in
        if let photo = items.singlePhoto {
            self.imageView.contentMode = .scaleToFill
            self.imageView.image = photo.originalImage


        }
        picker.dismiss(animated: true, completion: nil)
    }



    present(picker, animated: true, completion: nil)





}

    func getimages(completion: @escaping(UIImage) -> ()) {
        completion(imageView.image!) // THIS IS WHERE I USED CLOSURES TO SEND MY IMAGE.
    }


}

// Ниже приведен мой сетевой класс, который использует метод POST, метод post работает, но этот класс // никогда не получает изображение из основного класса контроллера просмотра.

import UIKit
typealias Parameters = [String: String]
class NetworkServices {



    static let instance = NetworkServices()

    func userChoice(completion: @escaping (Float) -> ()) {

       NewViewController.instance.getimages { (image) in

            guard let mediaImage = Media(withImage: image , forKey: "inputFile") else { return } //This is where you manually change things, insert your image and the key

                                         guard let url = URL(string: "https://api.cloudmersive.com/image/face/detect-age") else { return }
                                         var request = URLRequest(url: url)
                                         request.httpMethod = "POST"

                        let boundary = self.generateBoundary()

                                         request.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")
                                         request.addValue("f6-4e94-8b-e4f1", forHTTPHeaderField: "Apikey")

                        let dataBody = self.createDataBody(withParameters: nil, media: [mediaImage], boundary: boundary)
                                         request.httpBody = dataBody

                                        let task = URLSession.shared.dataTask(with: request) { (data, response, error) in
                                        if error != nil{
                                            debugPrint("Errors were found")
                                            return
                                        }

                                             guard let data = data else{ return }

                                            do {
                                                 guard let json = try JSONSerialization.jsonObject(with: data, options: [.allowFragments]) as? [String: Any] else { return }

                                              guard let outputs = json["PeopleWithAge"] as? [[String: Any]] else { return }

                                                 var requiredAge = [Float]()

                                                 for ages in outputs {
                                                     let age = ages["Age"] as? Float ?? 0.0
                                                    requiredAge.append(age)


                                                    DispatchQueue.main.async {
                                                        completion(age)
                                                    }



                                                 }



                                             } catch {
                                                 debugPrint("JSON error: \(error.localizedDescription)")
                                             }
                                             }
                                       task.resume()

        }

    }




    //MARK: - Post Methods

    func generateBoundary() -> String {
        return "Boundary-\(NSUUID().uuidString)"
    }

    func createDataBody(withParameters params: Parameters?, media: [Media]?, boundary: String) -> Data {

        let lineBreak = "\r\n" //this is required in converting my file into data
        var body = Data()

        if let parameters = params {
            for (key, value) in parameters {
                body.append("--\(boundary + lineBreak)")
                body.append("Content-Disposition: form-data; name=\"\(key)\"\(lineBreak + lineBreak)")
                body.append("\(value + lineBreak)")
            }
        }

        if let media = media {// put in your filename here from media class
            for photo in media {
                body.append("--\(boundary + lineBreak)")
                body.append("Content-Disposition: form-data; name=\"\(photo.key)\"; filename=\"\(photo.filename)\"\(lineBreak)")
                body.append("Content-Type: \(photo.mimeType + lineBreak + lineBreak)")
                body.append(photo.data)// append actual image from Media class when you initialise Media class
                body.append(lineBreak)
            }
        }

        body.append("--\(boundary)--\(lineBreak)")

        return body
    }


}

extension Data {
    mutating func append(_ string: String) { // i will use this to append all my files.
        if let data = string.data(using: .utf8) {
            append(data)
        }
    }
}
...