3
\$\begingroup\$

In my solution I've implemented transaction-like methods of uploading posts media. For example I'm adding new post with photo. I want to have 700x700, 200x200, 70x70, 10x10 px sizes in my storage and original in device album. And when all images are uploaded, then save new post info to database. But this code is not beautiful at all. How can I improve it?

// MARK: - Christmas tree
// Like transaction :)
// Bad view actually
static func uploadVideoForPost(with videoURL: URL, for postForUpdate: PostItem,
                              screenShot: UIImage,
                              completion: @escaping (_ hasFinished: Bool, _ postWithRefs: PostItem?) -> Void) {
  var post = postForUpdate // we will insert refs to media to this object
  // upload screenshots
  upload(screenShot, for: post, withSize: 700.0)
  { (hasFinishedSuccessfully, url) in

     if hasFinishedSuccessfully {
        post.mediaRef700 = url

        upload(screenShot, for: post, withSize: 200.0)
        { (hasFinishedSuccessfully, url) in

           if hasFinishedSuccessfully {
              post.mediaRef200 = url

              upload(screenShot, for: post, withSize: 70.0)
              { (hasFinishedSuccessfully, url) in

                 if hasFinishedSuccessfully {
                    post.mediaRef70 = url

                    upload(screenShot, for: post, withSize: 10.0)
                    { (hasFinishedSuccessfully, url) in

                       if hasFinishedSuccessfully {
                          post.mediaRef10 = url

                          // upload video
                          upload(with: videoURL, for: post)
                          { (hasFinishedSuccessfully, url) in

                             if hasFinishedSuccessfully {
                                post.videoRef = url

                                let path = videoURL.path

                                if UIVideoAtPathIsCompatibleWithSavedPhotosAlbum(path) {
                                   UISaveVideoAtPathToSavedPhotosAlbum(path, nil, nil, nil)
                                }
                                completion(true, post) // after this func i will save post data to db in other func.
                             } else {
                                completion(false, nil)
                             }
                          }
                       }else {
                          completion(false, nil)
                       }
                    }
                 } else {
                    completion(false, nil)
                 }
              }
           } else {
              completion(false, nil)
           }
        }
     } else {
        completion(false, nil)
     }
   }
}

Upload func is just a func of uploading with completion handler.

\$\endgroup\$
  • \$\begingroup\$ Just drop those abundant if-else statements. You are better off turning your upload() into a method that works with an array of images, and not just one image at a time. \$\endgroup\$ – Mr. Xcoder Jun 20 '17 at 11:29
3
\$\begingroup\$

You can chain those async methods using Promises. So the code will look like this:

fetchUsers()
.then({ users in
    return users[0]
})
.then({ firstUser in
    return fetchFollowers(of: firstUser)
})
.then({ followers in
    self.followers = followers
})
.catch({ error in
    displayError(error)
})

Take a look at those projects:

https://github.com/khanlou/Promise

https://github.com/mxcl/PromiseKit

\$\endgroup\$
3
\$\begingroup\$

If Nesting

You are nesting if's too much which quickly becomes ugly. I don't know your language but if at all possible negate the the conditions and return the result for example:

do:

if not HasCompleted {

return(or equivalent) completion(false, nil)

}

instead of:

if HasCompleted {
...
}
else
{
completion(false, nil)
}
\$\endgroup\$
  • \$\begingroup\$ I ll use Yakiv answer. Anyway thx. Upvoted:) \$\endgroup\$ – Vlad Pulichev Jun 28 '17 at 7:16

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.