PoolHallJunkie PoolHallJunkie - 2 months ago 6
Swift Question

Loading data from API pattern issue

I am building an app that populates data in a

collectionView
. The data come from API calls. When the screen first loads I get the products and store them locally in my
ViewController
.

My question is when should I get the products again and how to handle screen changing. My data will change when the app is running (sensitive attributes like prices) , but I don't find ideal solution to make the API call each time
viewWillAppear
is being called.

Can anybody please tell me what is the best pattern to handle this situation. My first though was to check if
[CustomObject].isEmpty
on
viewWillAppear
and then make the call. Including a timer that check again every 10-15 minutes for example.

Thank you for your input.

Answer

There is no set pattern but it is advisable not to send repeated network requests to increase energy efficiency (link). You can check the time interval in ViewWillApear and send the network requests after certain gap or can use timer to send requests at time intervals. First method would be better as it sends request only when user is on that screen. You can try following code snippet to get the idea

class ViewController: UIViewController {

    let time = "startTime"
    let collectionView: UICollectionView!

    override func viewDidLoad() {
        super.viewDidLoad()
    }

    override func viewWillAppear(animated: Bool) {
        super.viewWillAppear(animated)
        update()
    }

    private func update() {
        if let startDateTime = NSUserDefaults.standardUserDefaults().objectForKey(time) as? NSDate {
            let interval = NSDate().timeIntervalSinceDate(startDateTime)
            let elapsedTime = Int(interval)
            if elapsedTime >= 3600 {
                makeNetworkRequest()
                NSUserDefaults.standardUserDefaults().setObject(startDateTime, forKey: time)
            }
        } else {
            makeNetworkRequest()
            NSUserDefaults.standardUserDefaults().setObject(NSDate(), forKey: time)
        }
    }

    func makeNetworkRequest() {

        //Network Request to fetch data and update collectionView
        let urlPath = "http://MyServer.com/api/data.json"
        guard let endpoint = NSURL(string: urlPath) else {
            print("Error creating endpoint")
            return
        }
        let request = NSMutableURLRequest(URL:endpoint)
        NSURLSession.sharedSession().dataTaskWithRequest(request) { (data, response, error) in
            do {
                guard let data = data else {
                    return
                }
                guard let json = try NSJSONSerialization.JSONObjectWithData(data, options: []) as? [String: AnyObject] else {
                   print("Error in json parsing")
                   return
                }
                self.collectionView.reloadData()
            } catch let error as NSError {
                print(error.debugDescription)
            }
        }.resume()
    }