0

I have a view that has custom cells like shown, when I hit a button in the cell, the entire app freezes and I have to force close it and restart it. Nothing is shown in the console when the app freezes and I have no idea how to debug this. I've also tried using non custom buttons.

Before hitting button

Frozen Screen

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//delete button

@IBAction func deleteButton(sender: AnyObject) {

if phonee == "0"{
   let URL = "BLURRED FOR PRIVACY"

    var url : NSString = URL
    var urlStr : NSString = url.stringByAddingPercentEscapesUsingEncoding(NSUTF8StringEncoding)!
    var searchURL : NSURL = NSURL(string: urlStr as String)!
    print (searchURL)
    let task = NSURLSession.sharedSession().dataTaskWithURL(searchURL, completionHandler: { (data, response, error) -> Void in
        var urlContent = NSString(data: data!, encoding: NSASCIIStringEncoding) as NSString!
        print(urlContent)

        if urlContent.localizedStandardContainsString("Removed event with ID") {
          dispatch_sync(dispatch_get_main_queue()) {
            var settings = Modal.Settings()
            settings.bodyColor = .whiteColor()
            Modal(title: "Success", body: "Task deleted, refresh the page.", status: .Success, settings: settings).show()
            }

            }else{
            dispatch_sync(dispatch_get_main_queue()) {
            var settings = Modal.Settings()
            settings.bodyColor = .whiteColor()
            Modal(title: "Error", body: "Are you connected to the internet?", status: .Error, settings: settings).show()
            }
        }
    })
    task.resume()

}else{
    dispatch_sync(dispatch_get_main_queue()) {
    var settings = Modal.Settings()
    settings.bodyColor = .whiteColor()
    Modal(title: "Error", body: "You can't delete an accepted task", status: .Error, settings: settings).show()
    }
    }
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //pay button

@IBAction func payButton(sender: AnyObject) {

    if phonee == "0"{

        dispatch_sync(dispatch_get_main_queue()) {
        var settings = Modal.Settings()
        settings.bodyColor = .whiteColor()
        Modal(title: "Error", body: "Please wait for the task to be accepted", status: .Error, settings: settings).show()
        }
        }else{

        url = url + userID + "&event_id=" + eventID
        let myURL = NSURL(string: url)!

        print (myURL)

        let task = NSURLSession.sharedSession().dataTaskWithURL(myURL, completionHandler: { (data, response, error) -> Void in
            var urlContent = NSString(data: data!, encoding: NSASCIIStringEncoding) as NSString!
            print(urlContent)
        })
        task.resume()

        progressBar.progress = 1.0
        complete1.textColor = UIColor(red: 43/255.0, green: 192/255.0, blue: 228/255.0, alpha: 1.0)
        accepted1.textColor = UIColor.blackColor()

        reportButton.userInteractionEnabled = false
        deleteButton.userInteractionEnabled = false
        contactButton.userInteractionEnabled = false
        payButton.userInteractionEnabled = false
        priceLabel.textColor = UIColor(red: 170/255, green: 170/255, blue: 170/255, alpha: 1.0)
        self.deleteButton.backgroundColor = UIColor(red: 170/255, green: 170/255, blue: 170/255, alpha: 1.0)
        self.contactButton.backgroundColor = UIColor(red: 170/255, green: 170/255, blue: 170/255, alpha: 1.0)
        self.payButton.backgroundColor = UIColor(red: 170/255, green: 170/255, blue: 170/255, alpha: 1.0)
        priceLabel.textColor = UIColor(red: 170/255, green: 170/255, blue: 170/255, alpha: 1.0)
        reportButton.setImage(UIImage(named: "nation2.png"), forState: UIControlState.Normal)


        }
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //contact button

@IBAction func contactButton(sender: AnyObject) {

    if phonee == "0"{
        dispatch_sync(dispatch_get_main_queue()) {
        var settings = Modal.Settings()
        settings.bodyColor = .whiteColor()
        Modal(title: "Error", body: "Please wait for the task to be accepted", status: .Error, settings: settings).show()
        }
    }else{

        if let url = NSURL(string: "tel://\(phonee)") {
            UIApplication.sharedApplication().openURL(url)
        }
    }
}
user3015221
  • 125
  • 1
  • 6
  • Well, what does pressing the button do? What sort of code is executed? Have any more details? – Acey Jun 03 '16 at 23:36
  • Pushing the button either prompts maps to open, a phone number to dial, or a get request depending not the button. I have another view like this and this never happens. – user3015221 Jun 03 '16 at 23:38
  • Without showing the code that gets executed when the button is pressed, or showing how the button's target action or gesture recognizer is added to the button, it'll be very difficult for someone to help. I suggest you post some relevant code. – Acey Jun 03 '16 at 23:40
  • added all the button code, all the connections look fine to me – user3015221 Jun 03 '16 at 23:44

1 Answers1

0

You are calling dispatch_sync(dispatch_get_main_queue()) from the main thread which results in a deadlock. IBActions are always called on the main thread (unless you are manually calling them from another thread) because all user input is handled on the main thread so this is not needed.

Acey
  • 8,048
  • 4
  • 30
  • 46
  • A better explanation of why this occurs http://stackoverflow.com/questions/12379059/why-is-this-dispatch-sync-call-freezing – Acey Jun 03 '16 at 23:48
  • Thank you very much, I don't understand threading very well yet – user3015221 Jun 03 '16 at 23:52
  • You will still need to get and dispatch to the main queue within your NSURLSession task completionHandler though. If you're starting out with threading, it's probably safer to stick with dispatch_async vs dispatch_sync. You can avoid deadlocks that way. Doing `dispatch_async(dispatch_get_main_queue(),...` won't ever deadlock, but it's just not necessary for all other areas of your code besides when you are doing UI updates within your callback. – Acey Jun 04 '16 at 00:01