Как получить значение из обработчика завершения iOS Swift 3
Может ли кто-нибудь, пожалуйста, предложить или руководство, как я могу вернуть ProfileImage
получено в Location 1
в приведенном ниже коде и вернуть его в Location 2
, Буду очень признателен за вашу помощь. Я прошел другие вопросы, но ни один из них не помог мне.
static var profileImage : UIImage{
get{
let defaults = UserDefaults.standard
guard let imageData = defaults.object(forKey: "profileImage") as? NSData else{
downloadAndSetProfileImage(completionHandler: { (profileImage) in
// LOCATION 1:
// PLEASE ADVISE HOW I CAN RETURN THE OBTAINED PROFILE IMAGE BELOW at LOCATION 2
})
}
// LOCATION 2:
// I would like to return the profileImage Here i.e. return profileImage
}
set (image){
let defaults = UserDefaults.standard
let imageData : NSData = UIImagePNGRepresentation(image)! as NSData
defaults.set(imageData, forKey: "profileImage")
}
}
3 ответа
Вы не должны ставить асинхронные задачи в ваш геттер. Вместо этого вы можете использовать ваш необязательный profileImage
вычисляемое свойство только для получения изображения от пользователя по умолчанию и создания другой асинхронной функции для получения профиля пользователя, который будет возвращать изображение по умолчанию, если оно не равно нулю, в противном случае он попытается загрузить его. Как это:
static var profileImage : UIImage? {
get {
let defaults = UserDefaults.standard
guard let imageData = defaults.object(forKey: "profileImage") as? NSData else {
return nil
}
return UIImage(data: Data(referencing: imageData))
}
set {
let defaults = UserDefaults.standard
guard newValue != nil else {
defaults.removeObject(forKey: "profileImage")
return
}
let imageData = NSData(data: UIImagePNGRepresentation(newValue!)!)
defaults.set(imageData, forKey: "profileImage")
}
}
// Async function to retrieve profile image
func getProfileImage(completion: (_ image: UIImage?) -> ()) {
guard ProfileAPI.profileImage == nil else {
completion(ViewController.profileImage!)
return
}
// Your image dowload funciton
SomeImageDownloader.downloadImage("imagePath") { downloadedImage in
completion(downloadedImage) // assuming downloadedImage can be nil
}
}
Чтобы получить изображение вашего профиля вы звоните:
getProfileImage { (image) in
if let profileIage = image {
// do something with it
}
}
В примере getProfileImage
объединяет profileImage
собственность с downloadImage
, Если getProfileImage
имеет значение, оно передаст его немедленно с закрытием завершения, иначе это вызовет downloadImage
и передаст результат, когда задача закончена. В итоге у вас есть ситуация, когда требуется асинхронная задача, так что, так или иначе, вам нужен какой-то обработчик завершения, такой как в моем примере.
static var profileImage : UIImage{
get{
let defaults = UserDefaults.standard
guard let imageData = defaults.object(forKey: "profileImage") as? NSData else{
downloadAndSetProfileImage(completionHandler: { (profileImage) in
// LOCATION 1:
return profileImage
})
}
// LOCATION 2:
return UIImage(data: (imageData as! NSData) as Data)
}
set (image){
let defaults = UserDefaults.standard
let imageData : NSData = UIImagePNGRepresentation(image)! as NSData
defaults.set(imageData, forKey: "profileImage")
}
}
Вы можете использовать оператор возврата
get{
let defaults = UserDefaults.standard
guard let imageData = defaults.object(forKey: "profileImage") as? NSData else{
downloadAndSetProfileImage(completionHandler: { (profileImage) in
return profileImage
})
}
return UIImage(data: (imageData as! NSData) as Data)
}
Если вы получаете тип значения Data в вашем завершении Handler, вы должны использовать метод UIImage(data: profileImage)