Функция всегда возвращает ноль из-за неправильного размещения операторов, присваивающих значения - PullRequest
1 голос
/ 03 апреля 2019

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

func getImagesDownloaded(reference: StorageReference) -> UIImage {
    var imagePassedIn : UIImage?
    reference.getData(maxSize: 10*1024*1024) { (data, error) in

        guard let imageObject = UIImage(data: data!) else {print("Error has occurred: \(String(describing: error?.localizedDescription))"); return}
        imagePassedIn = imageObject
    }
    if imagePassedIn == nil {
        print("Error, getImagesDownloaded is not working")
    }
    return imagePassedIn!
}

Ответы [ 3 ]

3 голосов
/ 03 апреля 2019

Проблема в том, что StorageReference.getData является асинхронной функцией, но вы пытаетесь синхронно вернуть значение. Вам нужно использовать обработчик завершения для возврата асинхронно полученного значения.

func getImagesDownloaded(reference: StorageReference, completion: (UIImage?,Error?)->()) {
    reference.getData(maxSize: 10*1024*1024) { (data, error) in
        guard error == nil, let data = data else {
            completion(nil,error)
            return
        }
        guard let image = UIImage(data: data) else {
            completion(nil, FirebaseErrors.expectedImage)
            return
        }
        completion(image,nil)
    }
}

enum FirebaseErrors: Error {
    case expectedImage
}

Тогда вам нужно использовать это так:

getImagesDownloaded(reference: yourStorageReference, completion: { image, error in
    guard let image = image, error == nil else {
        print(error)
        return
    }
    // Assign your image to a UIImageView or do anything else with it inside the closure (before the ending `}`)
    yourImageView.image = image
})
0 голосов
/ 03 апреля 2019

Вы устанавливаете imagePassedIn внутри блока завершения.Это означает, что когда вы готовы установить его, вы уже перенастроили его.

В нескольких словах, при использовании блоков завершения код, приведенный ниже, не будет ждать его завершения для выполнения..

Обновите ваши функции следующим образом:

func getImagesDownloaded(reference: StorageReference, _ completion: (UIImage) -> ()) {
    reference.getData(maxSize: 10*1024*1024) { (data, error) in

        guard let data = data, let imageObject = UIImage(data: data) else {print("Error has occurred: \(String(describing: error?.localizedDescription))"); return}
        completion(imageObject)
    } else {
        print("Error, getImagesDownloaded is not working")
    }
}
0 голосов
/ 03 апреля 2019

Вы используете замыкание, и imageObject, вероятно, не возвращается, когда вы выполняете проверку на ноль.Swift выполняется построчно, и когда у вас есть асинхронный код, он выполняет следующую строку и не ждет результата.

Вы должны переместить чек imagePassedIn в закрытие.

...