Как получить значение из обработчика завершения 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)

Другие вопросы по тегам