Q:

Need to return array from a function inside my class

I have a UIPickerView I want to fill with an array of values.  The array of values is coming from a function inside of one of my classes (using json to grab the values and then put them into an array).  The data is being grabbed successfully, and added to an array inside the function, but it's not returning for some reason.
Here's my class:
class Supplier {

    var supplierId: Int
    var supplierName: String

    init(id: Int, name: String){
        supplierId = id
        supplierName = name
    }

    static func arrayOfSupplierNames() -> [String] {
        let urlString = Constants.Urls.Suppliers.List;
        let session = NSURLSession.sharedSession();
        let url = NSURL(string: urlString)!;
        var suppliers: Array<String> = []

        session.dataTaskWithURL(url) { (data: NSData?, response:NSURLResponse?, error: NSError?) -> Void in
            if let responseData = data {

                do {
                    let json = try NSJSONSerialization.JSONObjectWithData(responseData, options: NSJSONReadingOptions.AllowFragments) as! Dictionary<String, AnyObject>;

                    if let suppliersDictionary = json["suppliers"] as? [Dictionary<String, AnyObject>] {

                        for aSupplier in suppliersDictionary {

                            if let id = aSupplier["id"] as? Int, let name = aSupplier["supplierName"] as? String {
                                let supplier = Supplier(id: id, name: name)
                                suppliers.append(supplier.supplierName)
                            }

                        }
                    }
                }catch {
                    print("Could not serialize");
                }
            }
            }.resume()

        return suppliers
    }
}

This seems to work because when I debug I can see the values being added to the array.  I have another function in my ViewController that runs this function and adds it to a local array but the array returned from the function doesn't seem to get added to the array in the view controller:
func populateSuppliersArray() {

        let sup:Array = Supplier.arrayOfSupplierNames()

        for s in sup {
            supplierArray.append(s) //supplierArray is at the top scope of view controller. 
        }
    }

I even made the class function static so I wouldn't have to initialize the class just to use the function.   I'm not sure this is the correct way.  When I look at the sup variable while debugging it has zero values. 

A:

the json data is received inside an asynchronous block. your function returns as soon as you call resume on dataTaskWithURL. you should pass a completion block as an argument to your arrayOfSupplierNames and pass the array to that completion block instead. You could modify your function like this:
// take a completion block as an argument
func arrayOfSupplierNames(completion: (([String]) -> Void)) -> Void {
    let urlString = Constants.Urls.Suppliers.List;
    let session = NSURLSession.sharedSession();
    let url = NSURL(string: urlString)!;
    var suppliers: Array<String> = []

    session.dataTaskWithURL(url) { (data: NSData?, response:NSURLResponse?, error: NSError?) -> Void in
        if let responseData = data {

            do {
                let json = try NSJSONSerialization.JSONObjectWithData(responseData, options: NSJSONReadingOptions.AllowFragments) as! Dictionary<String, AnyObject>;

                if let suppliersDictionary = json["suppliers"] as? [Dictionary<String, AnyObject>] {

                    for aSupplier in suppliersDictionary {

                        if let id = aSupplier["id"] as? Int, let name = aSupplier["supplierName"] as? String {
                            let supplier = Supplier(id: id, name: name)
                            suppliers.append(supplier.supplierName)
                        }

                    }
                    completion(suppliers) // pass the array to completion block
                }
            }catch {
                print("Could not serialize");
            }
        }
        }.resume()
}

You'll call it like this:
Supplier.arrayOfSupplierNames { (suppliers) -> Void in
    // use suppliers as appropriate
}

please note that completion block is called asynchronously (some time in future).

