2016-12-15 2 views
1

У меня есть поле и кнопка, когда вы заполните поле с содержанием, и нажмите кнопку:Swift 3 - задержка индикатор активности или не отвечает

@IBAction func dpSomething(_ sender: UIButton) { 
    activityIndicator.startAnimating() 
    activityIndicator.isHidden = false 
    field.isHidden = true 
    send.isHidden = true 
    let url = "http://urlwithjson" 
    let session = URLSession.shared 
    DispatchQueue.main.async { [unowned self] in 
     let task = session.dataTask(with: URL(string: url)!) { (data, response, error) in 
      if(error==nil){ 
         do { 
          let jsonData = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as! NSDictionary 
           if((jsonData["response"] as! Int) == 0){ 
            self.responseL.text = "no results" 
           } 
          self.activityIndicator.stopAnimating() 
          self.responseL.isHidden = false 
         } catch _ {} 
      } 
     } 
     task.resume() 
    } 

} 

при использовании печати он печатает меня почти сразу на JSON, но активности индикатору требуется 10-20 секунд, чтобы исчезнуть, или иногда он не исчезает. Может кто-нибудь мне подскажет почему? А также, когда я меняю текст на этикетке, я получаю сообщение об ошибке в консоли:

Это приложение модифицирует механизм автозапуска из фоновой темы, что может привести к повреждению двигателя и странным сбоям. Это приведет к исключению в будущей версии.

Почему это происходит?

+0

кажется ваш запрос работает сеть на главном потоке, не поощряются –

+0

вместо того, чтобы попытаться 'DispatchQueue.main.async { self.activityIndicator.stopAnimating() self.responseL.isHidden = ложный }' –

ответ

4

Прежде всего Добавьте следующий код после activityIndicator.startAnimating(), этот код будет скрыть индикатор активности те, которые вы звоните self.activityIndicator.stopAnimating():

activityIndicator.hidesWhenStopped = true 

Также вы только скрывает индикатор активности, если ответ удалось, так вам может потребоваться скрыть индикатор, если в блоке catch есть ошибка, а в противном случае вы получите ошибку из ответа api.

Еще один момент, когда вы делаете свой запрос, он не должен находиться в главном threa d, только в фоновом режиме, а затем, когда вам необходимо обновить пользовательский интерфейс, то ли использовать основной поток, так что, наконец, вот полный код, возможно, потребуется:

@IBAction func dpSomething(_ sender: UIButton) { 
    activityIndicator.startAnimating() 
    activityIndicator.isHidden = false 
    activityIndicator.hidesWhenStopped = true 
    field.isHidden = true 
    send.isHidden = true 
    let url = "http://urlwithjson" 
    let session = URLSession.shared 
    let task = session.dataTask(with: URL(string: url)!) { (data, response, error) in 
      if(error==nil){ 
       do { 
        let jsonData = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as! NSDictionary 
        if((jsonData["response"] as! Int) == 0){ 
         DispatchQueue.main.async { 
         //Update your UI here 


         self.responseL.text = "no results" 
         } 
       } 

        DispatchQueue.main.async { 
         //Update your UI here 
         self.activityIndicator.stopAnimating() 
         self.responseL.isHidden = false 
        } 

       } catch _ { 

        // JSONSerialization error might happen so hide the indicator 
        DispatchQueue.main.async { 
         //Update your UI here 
         self.activityIndicator.stopAnimating() 
         self.responseL.isHidden = false 
        } 

       } 
      }else { 
       // api response error might happen so hide the indicator 
       DispatchQueue.main.async { 
        //Update your UI here 
        self.activityIndicator.stopAnimating() 
        self.responseL.isHidden = false 
       } 

      } 
     } 
     task.resume() 

} 
+0

теперь его сразу работает, но ответ метка меняется через 10 секунд: D, и я все еще получаю: это приложение модифицирует механизм автоотключения из фонового потока после того, как движок был доступен из основного t hread. Это может привести к повреждению двигателя и странным сбоям. –

+1

@BogdanBogdanov Я отредактировал свой ответ, ярлык должен быть также обновлен из основного потока! Дайте мне знать, если это сработает – AaoIi

+1

приятно сейчас, теперь его рабочие благодарности ...: D –

2

Вы должны сделать только UI изменений на main нить никогда не вызывать вызов Async API в основной теме.

let task = session.dataTask(with: URL(string: url)!) { (data, response, error) in 
     if(error==nil){ 
        do { 
         let jsonData = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as! NSDictionary 
          if((jsonData["response"] as! Int) == 0){ 
           self.responseL.text = "no results" 
          } 
         DispatchQueue.main.async { 
          self.activityIndicator.stopAnimating() 
          self.activityIndicator.isHidden = true 
          self.responseL.isHidden = false 
         } 
        } catch _ {} 
     } 
    } 
    task.resume() 
+1

Большая работа @Nirav D –

+0

@Ashok Благодаря мате :) –

Смежные вопросы