Search code examples
iosswiftswift2alamofireappdelegate

Unable to load HTTP POST response data in array in AppDelegate application method. How to solve this issue?


Please find the following code snippet within AppDelegate.swift What I want to achieve is to be able to populate 'images' array with image urls I receive using my own API, and further migrate this images array to a view controller (which can be done using delegate). I do get the list of image urls at "print(self.images[index])", however " images.isEmpty" returns true. Where am I going wrong?

Sample console output:
true
2016-01-03 19:28:48.767 Mobblr[22372:1347546] Unknown class ContentViewContr in Interface Builder file.
list of image URLs displayed here

var images = [String]()    
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {

    preloadData()
    print(images.isEmpty)

    var pageControl = UIPageControl.appearance()
    pageControl.pageIndicatorTintColor = UIColor.lightGrayColor()
    pageControl.currentPageIndicatorTintColor = UIColor.blackColor()
    pageControl.backgroundColor = UIColor.whiteColor()
    return true
}

func preloadData() {
    let parameters = ["count": 100]
    Alamofire.request(.POST, <My API>, parameters: parameters, encoding: .JSON)
        .responseJSON { response in
            if let value: AnyObject = response.result.value {

                let posts = JSON(value)
                //print(posts)
                for index in 0..<posts.count {
                    //print(posts[index]["image_url"])
                    if let image = posts[index]["image_url"].string {
                        self.images += [image]
                        print(self.images[index])

                    } else {
                        self.images += [""]
                    }
                }

    }

}

Solution

  • You say that "images.isEmpty returns true". Where/when are you checking that?

    This request runs asynchronously (and it should, as you don't want to block your app while the image URLs are retrieved), so it's quite possible that the view controller that wants to use images is checking before the request is done. So the question is how do you notify the view controller (or whatever is waiting for images to be populated) when the images is successfully retrieved.

    You could use a notification for this. So, the responseJSON completion block can post a notification:

    Alamofire.request(.POST, <My API>, parameters: parameters, encoding: .JSON)
        .responseJSON { response in
            // process the response here
    
            // now post notification
    
            NSNotificationCenter.defaultCenter().postNotificationName(imagesNotificationKey, object: nil)
    }
    

    This assumes you have some global that is the key for this notification:

    let imagesNotificationKey = "..."
    

    And whatever view controllers that want to take some action upon receiving this notification can add themselves as observers:

    class ViewController: UIViewController {
    
        var observer: NSObjectProtocol?
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            observer = NSNotificationCenter.defaultCenter().addObserverForName(imagesNotificationKey, object: nil, queue: NSOperationQueue.mainQueue()) { notification in
                // do something (e.g. reload table or what have you)
            }
        }
    
        deinit {
            NSNotificationCenter.defaultCenter().removeObserver(observer!)
        }
    
    }