Как вывести предупреждение после того, как контроллер представления был отклонен - PullRequest
0 голосов
/ 06 мая 2019

У меня есть приложение, в котором пользователь загружает файл в фоновом режиме, что обычно занимает пару секунд.Загрузка начинается, когда они нажимают кнопку «Готово», и это также отклоняет контроллер представления.Я хотел бы, чтобы по окончании загрузки появилось предупреждение.Я думал, что просто добавлю приведенный ниже код в функцию загрузки, но она не работает.Как отобразить окно с предупреждением о том, что загрузка прошла успешно?

@IBAction func tapDone(_ sender: Any) {
    self.dismiss(animated: true, completion: nil)
    if let image = newImage {
        submit2Parse(image: image)
    }
}

func submit2Parse (image: UIImage) {
    if let pfImage = image2PFFile(image: image) {
        // Insert PFFile into parse server
        let submittedImage = PFObject(className: "Images")
        submittedImage["imageFile"] = pfImage
        submittedImage["type"] = "submittedFromUserHome"
        submittedImage["bride"] = brideSwitch.isOn
        submittedImage["groom"] = groomSwitch.isOn
        submittedImage["user"] = userSwitch.isOn
        submittedImage["picturePeriod"] = pickerSelected
        submittedImage["uploadedByUserId"] = PFUser.current()?.objectId ?? ""            submittedImage["uploadedByUserName"] = PFUser.current()?.username ?? ""
        if !txtIsPlaceHolder { submittedImage["description"] = imageDescription.text }

        submittedImage.saveInBackground { (success, error) in
            if success {
                let message = "Save in bg worked"
                print(message)
                let alert = UIAlertController(title: title, message: message, preferredStyle: UIAlertController.Style.alert)
                alert.addAction(UIAlertAction(title: "Ok", style: UIAlertAction.Style.default, handler: {
                    (action) in
                    self.dismiss(animated: true, completion: nil)
                }))
                self.present(alert,animated: true, completion: nil)

            } else {
                print(error?.localizedDescription ?? "")
            }
        }
    }
}

Код дает мне эту ошибку сборки:

Неявное использование «self» взакрытие;используйте «я».сделать семантику захвата явной

Ответы [ 4 ]

1 голос
/ 06 мая 2019

В вашем tapDone методе вы должны использовать completion увольнения вашего контроллера, например так:

self.dismiss(animated: true) {
    if let image = newImage {
        self.submit2Parse(image: image)
    }
}

Это только означает, что self.submit2Parse(image: image) будет выполняться ТОЛЬКО после того, как вы отключите контроллер. Дополнительно ошибка

Неявное использование «я» в закрытии; используйте «я». сделать захват семантика явная

означает только то, что вам нужно использовать self. для явного вызова переменной или метода, когда вы находитесь внутри замыкания. Итак, ваш submit2Parse... теперь будет выглядеть так:

self.submit2Parse(image: image).

0 голосов
/ 11 мая 2019

Когда вы помещаете нижеприведенную функцию в viewController, который инициирует загрузку данных в фоновом режиме, а затем вызываете эту функцию в замыкании, которое срабатывает после завершения отправки, она может успешно создать предупреждение, даже если первоначальный контроллер представления былотклонено (или длительно отклонено, если это была длительная загрузка).

// This is the function that performs my background upload
    func submit2Parse (image: UIImage) {
        if let pfImage = image2PFFile(image: image) {
            // Insert PFFile into parse server
            let submittedImage = PFObject(className: "Images")
            submittedImage["imageFile"] = pfImage
            submittedImage["imageCreateDt"] = newImageCreateDate
            submittedImage["type"] = "submittedFromUserHome"
            submittedImage["bride"] = brideSwitch.isOn
            submittedImage["groom"] = groomSwitch.isOn
            submittedImage["user"] = userSwitch.isOn
            submittedImage["picturePeriod"] = pickerSelected
            submittedImage["uploadedByUserId"] = PFUser.current()?.objectId ?? ""
            submittedImage["uploadedByUserName"] = PFUser.current()?.username ?? ""
            if !txtIsPlaceHolder { submittedImage["description"] = imageDescription.text }
            // Get the image timestamp, every photo has one
            // How do you get the thumbnail image too?

            submittedImage.saveInBackground { (success, error) in
                if success {
                    let message = "Save in bg worked"
                    print(message)
                    self.showAlertFromAppDelegates()
                } else {
                    print(error?.localizedDescription ?? "")
                }
            }
        }
    }

// This is the function that creates the alert
    func showAlertFromAppDelegates(){
        var topWindow: UIWindow? = UIWindow(frame: UIScreen.main.bounds)
        topWindow?.rootViewController = UIViewController()
        topWindow?.windowLevel = UIWindow.Level.alert + 1
        let alert: UIAlertController =  UIAlertController(title: "Upload Complete", message: "Your image was successfully submitted!", preferredStyle: .alert)
        alert.addAction(UIAlertAction.init(title: "OK", style: .default, handler: { (alertAction) in
            topWindow?.isHidden = true
            topWindow = nil
        }))
        topWindow?.makeKeyAndVisible()
        topWindow?.rootViewController?.present(alert, animated: true, completion:nil)
    }
0 голосов
/ 06 мая 2019

Если я правильно понял ваш вопрос, вы хотите отклонить ваш SecondViewController, когда пользователь нажмет на кнопку tapDone.И после этого после завершения загрузки изображения вы хотите сообщить об успешном завершении.

Но если вы dismiss нажали одну кнопку, вы не получите никакого предупреждения, потому что ваш SecondViewController больше не находится в window hierarchy, и если вы попытаетесь представить предупреждение, вы получите сообщение об ошибке в консоли, например:

Попытка представить, чье представление не находится в иерархии окон!

Чтобы решить эту проблему, вам нужно представить предупреждение от вашего первого контроллера представления, которое появится после того, как вы уволите свой второй контроллер представления, и вы можете достичь его с помощью delegate.

Рассмотрите приведенный ниже пример:

Прежде всего объявите protocol вне вашего FirstViewController:

protocol UplaodSuccessDelegate:class {
    func uploadSuccess(message: String)
}

, затем подтвердите ваш делегат того же класса:

class ViewController: FirstViewController, UplaodSuccessDelegate {

, затем вам нужно передать делегатакогда вы представляете SecondViewController:

let vc = self.storyboard?.instantiateViewController(withIdentifier: "SecondViewController") as! SecondViewController
vc.delegate = self. //Pass delegate
self.present(vc, animated: true, completion: nil)

и добавляете метод делегата к тому же классу:

func uploadSuccess(message: String) {

    let message = "Save in bg worked"
    print(message)
    let alert = UIAlertController(title: "title", message: message, preferredStyle: UIAlertController.Style.alert)
    alert.addAction(UIAlertAction(title: "Ok", style: UIAlertAction.Style.default, handler: {
        (action) in

    }))
    self.present(alert,animated: true, completion: nil)
}

теперь в вашем SecondViewController вам нужно добавить

weak var delegate: UplaodSuccessDelegate?

и в вашем методе tapDone замените код на:

self.dismiss(animated: true) {
    if let image = newImage {
        submit2Parse(image: image)
    }
}

и после завершения загрузки необходимо вызвать метод делегата (после завершения загрузки), например:

self.delegate?.uploadSuccess(message: "your message")

Это вызовет метод делегата с FirstViewController.

0 голосов
/ 06 мая 2019

Вы удалили self.dismiss(animated: true, completion: nil) из

@IBAction func tapDone(_ sender: Any) {
    if let image = newImage {
        submit2Parse(image: image)
    }
}

или используете

@IBAction func tapDone(_ sender: Any) {
    if let image = newImage {
        submit2Parse(image: image)
    }
    else
     {
        self.dismiss(animated: true, completion: nil)
     }
}

Поскольку viewController рано dismissed, а compiler не получилviewController для self.

...