-1

I am trying to take a string I have queried (in a function) from parse and return it to a button action which sends the returned string as a URL.

Before, I was querying inside the Viewdidload, but since the scope is too small I placed in a new function outside the Viewdidload. The new function should return a string which I can then use inside a button action as a URL (the string I am returning is a URL).

I tried declaring the variable at the top of the view class, but it did not register inside the function "Q3".

With my current code, if I press the button, it crashes the app.

Here is my code:

class ViewController: UIViewController {

    @IBAction func gridButtonURL(sender: AnyObject) {
        let gridurl = Q3()
        UIApplication.sharedApplication().openURL(NSURL(string: "http://\(gridurl)")!)
    }

    override func viewDidLoad() {

        super.viewDidLoad()

        var query3 = PFQuery(className:"TestObject")
        query3.getObjectInBackgroundWithId("XXXXXXXXXX") {
            (gridExplain: PFObject?, error: NSError?) -> Void in
            if error == nil && gridExplain != nil {
                print(gridExplain)
                self.gridExplain.text = gridExplain!.objectForKey("text") as! String
            } else {
                print(error)
            }
        }

        var test = Q3()
        print("---------",test);
        //"test" is blank

    }
    //End of viewdidload

    func Q3 () -> String {
        var getGridURL = String()
        var query4 = PFQuery(className:"TestObject")
        print("enterQ3")
        query4.getObjectInBackgroundWithId("XXXXXXXXXX") {
            (gridURL: PFObject?, error: NSError?) -> Void in
            if error == nil && gridURL != nil {
                getGridURL = gridURL!.objectForKey("text") as! String
                print("f3") //it prints "f3"
                print(getGridURL)
                //it prints getGridUrl
            } else { 
                print("errorQ3") 
            } 
        }
        return getGridURL
        //doesn't  get here though because it's nil
    }

}

The "query3" variable and its entourage works perfectly inside the Viewdidload and prints to a uiLabel called "gridExplain" without errors.

In the output bar at the bottom of Xcode it prints "print(getGridURL)" in the middle of the "Q3" function which in this case is http://www.instagram.com/.

BUT, At this:

print("---------",test);

It prints the dashes but not "test", as it is blank, except I don't understand why. It seems like "Q3" isn't returning the string "getGridURL".

I can't tell if my problem is scope or the returning bit. It may also be the-

var getGridURL = String()

-initialization part.

I need to know how to return the string "var getGridURL" as "Q3" into the button action at the top of the class, which in turn would chnage the "let gridurl" inside the action.

rmaddy
  • 314,917
  • 42
  • 532
  • 579
Ezio L.
  • 3
  • 5

1 Answers1

0

Try something like this:

@IBAction func gridButtonURL(sender: AnyObject) {
    var query4 = PFQuery(className:"TestObject")
    query4.getObjectInBackgroundWithId("XXXXXXXXXX") { (gridURL: PFObject?, error: NSError?) in
        if error == nil && gridURL != nil {
            getGridURL = gridURL!.objectForKey("text") as! String
            UIApplication.sharedApplication().openURL(NSURL(string: "http://\(getGridURL)"))
        } else { 
            print("errorQ3") 
        } 
    }
}

Your issue is that your PF Query is run in the background and not in the main thread. You need to make sure that you use and/or return the string inside the closure or better yet pass it another "completion closure" to execute.

Note: Using getObjectWithId instead of getObjectInBackgroundWithId will probably solve most of your issues if you don't understand asynchronicity. However this will block the main thread until your data is returned and that is not best practice.

Adam Campbell
  • 646
  • 5
  • 13