0

Just started using PromiseKit 6 with Swift. I've checked some examples and read the documentation. I have a scenario that seems trivial but I can't get around it. I have the following scenario:

func addModel(_ model: Model, image: UIImage?, completion: @escaping (Error?) -> Void) {
   var modelToSet = model
   var id = ""

   firstly {
        serviceWrapper.setImage(image!)     
   }.map { path in
        modelToSet.imagePath = path
   }.then { [serviceWrapper]
        serviceWrapper.setModel(modelToSet)
   }.map { documentId in
        id = documentId
   }.then {
        CLLocationManager.promise()
   }.done { [serviceWrapper] location in
        serviceWrapper.setLocation(GeoPoint(latitude: location.lat, longitude: location.long), id: id)
   }.catch { error in
        completion(error)
   }
} 

As you can see, in this pseudo code I am force unwrapping the image. Any ideas how I can start the chain with the setImage method only if there is an image passed? Otherwise start from setModel directly. Or probably just return empty string if there is no image? What am I missing here?

halfer
  • 19,824
  • 17
  • 99
  • 186
Vasil Garov
  • 4,851
  • 1
  • 26
  • 37

2 Answers2

1

After asking the PromiseKit community, I got what I needed. So this is how you can go with solving it with a local function:

func addModel(_ model: Model, image: UIImage?, completion: @escaping (Error?) -> Void) {
    var modelToSet = model
    var id = ""

    func start() -> Promise<Void> {
        guard let image = image else {
            return Promise()
        }
        return serviceWrapper.uploadImage(image).map { path in
            dishToSet.imagePath = path
        }
    }

    firstly {
        start()
    }.then { [serviceWrapper]
        serviceWrapper.setModel(modelToSet)
    }.map { documentId in
        id = documentId
    }.then {
        CLLocationManager.promise()
    }.done { [serviceWrapper] location in
        serviceWrapper.setLocation(GeoPoint(latitude: location.lat, longitude: location.long), id: id)
    }.catch { error in
        completion(error)
    }
}
Vasil Garov
  • 4,851
  • 1
  • 26
  • 37
0

Any ideas how I can start the chain with the setImage method only if there is an image passed?

You can use a guard statement to check the image is nil or not. If it is nil, execute the code needed to return. If not, continue the flow with a warpped image.

func addModel(_ model: Model, image: UIImage?, completion: @escaping (Error?) -> Void) {
   var modelToSet = model
   var id = ""

   guard let image = image else {
       // insert code to return if needed
       return
   }

   firstly {
        serviceWrapper.setImage(image)     
   }.map { path in
        modelToSet.imagePath = path
   }.then { [serviceWrapper]
        serviceWrapper.setModel(modelToSet)
   }.map { documentId in
        id = documentId
   }.then {
        CLLocationManager.promise()
   }.done { [serviceWrapper] location in
        serviceWrapper.setLocation(GeoPoint(latitude: location.lat, longitude: location.long), id: id)
   }.catch { error in
        completion(error)
   }
} 
  • Hey, thanks for the answer. You misunderstood me, I don’t want the whole chain to fail if there is no image. If there is no image I want to skip the first operator. If that’s not possible, just pass forward an empty string. Is that doable? – Vasil Garov May 27 '18 at 09:28
  • This does work, but what if you want to be able to handle the image being nil in the .catch ? – iCediCe Nov 03 '20 at 12:19