0

I am a relatively new iOS programmer, and I'm working on developing a barcode scanner that uses a function to get the name of a product from a URL using JSON. For simplicity, I have placed everything on one view controller because I hope to implement everything onto one view eventually. However, I am currently stuck on this issue. When I make the function call, the println()'s within the function appear to execute after my viewDidLoad() function is done. Heres my view controller code:

import UIKit

var productName = ""

class ViewController: UIViewController {

  override func viewDidLoad() {
    super.viewDidLoad()

    var sendBarcode = "0068274346613"

    productName = getProductName(sendBarcode)

    println("Product Name2: " + productName)

    }

    func getProductName(barcode: String) -> String{
        // Now escape anything else that isn't URL-friendly

        var prodName = ""
        var barcodeID = barcode

        if let escapedSearchTerm = barcodeID.stringByAddingPercentEscapesUsingEncoding(NSUTF8StringEncoding) {
            let urlPath = "https://www.outpan.com/api/get-product.php?barcode=" + escapedSearchTerm + "&apikey=600abe49c13da26c61ae2cb92300b3dc"
        let url = NSURL(string: urlPath)
        let session = NSURLSession.sharedSession()
        let task = session.dataTaskWithURL(url!, completionHandler: {data, response, error -> Void in
            println("Task completed")
            if(error != nil) {
                // If there is an error in the web request, print it to the console
                println(error.localizedDescription)
            }
            var err: NSError?
            if let jsonResult = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: &err) as? NSDictionary {
                if(err != nil) {
                    // If there is an error parsing JSON, print it to the console
                    println("JSON Error \(err!.localizedDescription)")
                }
                if let prodNameRes = jsonResult["name"] as? String {
                    dispatch_async(dispatch_get_main_queue(), {
                        productName = prodNameRes
                        println("Product Name: " + productName)
                    })
                }
            }
        })

        // The task is just an object with all these properties set
        // In order to actually make the web request, we need to "resume"
        task.resume()

    }

    return productName
}

}

The output for the code is:

Product Name2: 
Task completed
Product Name: Nestle Pure Life:  Purified Water, 1 Gal

Based on my previous programming knowledge, I assumed "Product Name: ..." would print out first because I call it's function first, followed by "Task completed" because the JSON data was received, followed by "Product Name2: ...".

Am I doing something wrong? Or is my understanding of how the code is executed incorrect?

Thank you very much for the help.

  • Please lookup the documentation. `dataTaskWithURL()` performs *asynchronously*. You'll find many similar questions (with answers) here on SO. – Martin R Jun 20 '15 at 21:51
  • Why would you think "Product Name:" would be called first? Not only is it after the other two statements in code, but you call it asynchronously with `dispatch_async`, which means it won't run until the main queue executes everything already on the queue at that point. – Jon Shier Jun 20 '15 at 21:51
  • Thank you Martin R, I apologize for possibly posting a duplicate question, I will read into it. Jon Shier, I thought it would print "Product Name:.." first because I call the function getProductName(sendBarcode). I will look into dispatch_async for better understanding. – sjsharksfan920 Jun 20 '15 at 21:58

0 Answers0