Search code examples
iosswiftanimationtimeout

How to properly set a network timeout before showing an animation on iOS?


as the title says I have a problem with my app. Let me explain a little more in detail what I'm trying to achieve using a bulleted list:

  • The app loads the main menù and connect to firebase in order to see if there's some product to show
  • Download the product image
  • Animate the content in order to show the product info and image

I created functions to handle the case the connection doesn't work or the product doesn't exist. The problem is when the connection is too slow to load the image before the animation starts (about 2 seconds). In this case, the app stuck a little and the product will be shown before the animation ends.

Load code

override func viewDidLoad() {
    super.viewDidLoad()

    // The view where the product will be shown
    self.productView.alpha = 0.0 

    // Checks the internet connection
    if (ConnectionService.isConnectedToNetwork()) {
        fetchDataFromDatabase(downloadCompleted: { (productToShow) in
            self.fillPromoView(usingProduct: productToShow)
        })
    } else {
        fillPromoView(nil)
    }
}

Appear code

override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)

    UIView.animate(withDuration: 0.5, delay: 2.0, options: UIViewAnimationOptions.curveEaseInOut, animations: {
          ...
    }
}

Here the code to download the product image:

func fetchDataFromDatabase(downloadCompleted: @escaping ((Product?) -> Void)) {
    FirebaseService.instance.getProductList { (productList) in
        if (productList.count != 0) {
            do {
                let productImage = try Data(contentsOf: productList.productImage as URL)

                // Fill the IBOutlet with the downloaded image
                self.promoProductImg.image = UIImage(data: productImage)

                downloadCompleted(productList)
            } catch {
                downloadCompleted(nil)
            }
        } else {
            downloadCompleted(nil)
        }
    }
}

My aim is to launch the animation once I have a response from the download status or because the connection takes more than 2 seconds to download the image. Any advice?


Solution

  • Your code in viewDidAppear will fire irregardless of whether you have a response from FireBase.

    At an abstract level you need to allow your application to know when you have loaded data (or not)

    The simpliest way of doing this would be;

    1. Have a "skeleton" template for the product details page (here is an example of Facebooks version of it, see the first gif)
    2. Move your view animation code out of viewDidAppear and into its own dedicated function.
    3. Call this function via NSNotificationCenter inside the success portion offetchDataFromDatabase (via this notification paradigm, you will "fire" a notification in your fetchDataFromDatabase function, and your viewController will "listen" for this notification and respond accordingly (in this instance, by animating and presenting the data in a view"))