Swift iOS -DispatchGroup с URLSession блокирует другие части приложения, в которых оно не находится - PullRequest
0 голосов
/ 21 мая 2018

У меня есть массив до 6 изображений.Я использую цикл для просмотра всех изображений, превращаю их в метаданные, отправляю метаданные в хранилище, а затем по окончании отправляю строки url в базу данных Firebase.

Я использую DispatchGroup для управления цикломтак как URL-адрес изменен на Данные, чтобы я мог отправлять данные в Firebase Storage.

Если этот цикл происходит в tabOne, если я возвращаюсь назад и назад к tabTwo или tabThree, когда цикл заканчивается и появляется предупреждение, tabTwo временно заблокирован или tabThree временно заблокирован на 2-3 секунды.Я не могу понять, где я иду не так?

Я не уверен, если это имеет значение, но я использую пользовательское предупреждение вместо UIAlertController.Это просто некоторые UIViews и кнопка, ничего особенного, поэтому я не включил код.

var urls = [URL]()
picUUID = UUID().uuidString
dict = [String:Any]()

let myGroup = DispatchGroup()
var count = 0

for url in urls{

    myGroup.enter() // enter group here
    URLSession.shared.dataTask(with: url!, completionHandler: {
            (data, response, error) in
            guard let data = data, let _ = error else { return }

            DispatchQueue.main.async{
                self.sendDataToStorage("\(self.picUUID)_\(self.count).jpg", picData: data)
                self.count += 1
            }
     }).resume()

    // send dictionary data to firebase when loop is done
    myGroup.notify(queue: .main) {
        self.sendDataToFirebaseDatabase()
        self.count = 0
    }
}

func sendDataToStorage(_ picId: String, picData: Data?){

    dict.updateValue(picId, forKey:"picId_\(count)")

    let picRef = storageRoot.child("pics")
    picRef.putData(picData!, metadata: nil, completion: { (metadata, error) in

        if let picUrl = metadata?.downloadURL()?.absoluteString{

             self.dict.updateValue(picUrl, forKey:"picUrl_\(count)")
             self.myGroup.leave() // leave group here
        }else{
             self.myGroup.leave() // leave group if picUrl is nil
        }
    }
}

func sendDataToFirebaseDatabase(){

    let ref = dbRoot.child("myRef")
    ref.updateChildValues(dict, withCompletionBlock: { (error, ref) in
         displaySuccessAlert()
    }
}

1 Ответ

0 голосов
/ 21 мая 2018

Я мало что знаю о Firebase, но вы отправляете свой метод sendDataToFirebaseDatabase в основную очередь, что, вероятно, объясняет, почему ваш пользовательский интерфейс перестает отвечать.

Отправка sendDataToFirebaseDatabase в фоновую очередь и только отправкаваш displaySuccessAlert обратно в основную очередь.

...