적당한 고통은 희열이다

- 댄 브라운 '다빈치 코드' 중에서

Swift iOS 앱 개발/실전 Swift

[Swift] Multiple asynchronous tasks 비동기로 여러 파일 다운로드 실행하기

hongssup_ 2021. 1. 4. 13:58
반응형

 

Firebase Storage에서 폴더 리스트를 받아온 컬렉션 뷰에서 해당 셀을 터치하면

해당 폴더 내 파일들의 리스트를 받아와 각 파일의 경로(StorageReference)를 리스트[]로 저장하고

DispatchGroup()을 통해 각 파일들을 비동기 다운로드하여 localURL에 저장하고,

파일들이 다 다운이 되었을 때 UINavigationController를 사용하여 새 화면으로 넘어가는 코드를 구현해보았다.

override func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
        print(files[indexPath.item])
        let listRef = ref.child(files[indexPath.item])
        listRef.listAll (completion: { (result, error) in
            var meshRef:StorageReference?
            var textureRef:StorageReference?
            var propRef:StorageReference?
            for i in result.items {
                if i.name.contains("DATA") == true {
                    meshRef = i
                } else if i.name.contains("VIDEO") == true {
                    textureRef = i
                } else if i.name.contains("PROP") == true {
                    propRef = i
                }
            }
            //print("meshRef \(meshRef)")
            
            let cases = [meshRef, textureRef, propRef]
            // meshRef, textureRef null인지 아닌지 확인
            if let meshRef = meshRef, let textureRef = textureRef {
                // 로컬 파일로 다운로드
                let localURL = FileManager.default.temporaryDirectory.appendingPathComponent("storage")
                //print("localURL \(localURL)")
                
                let group = DispatchGroup()
                cases.forEach { Ref in
                    print(Ref)
                    if let Ref = Ref {
                        group.enter()
                        Ref.write(toFile: localURL) { url, error in
                            if let error = error {
                                print("Download Fail \(error)")
                            } else {
                                print("\(Ref) Download Clear")
                            }
                            group.leave()
                        }
                    }                                    
                }
                
                group.notify(queue: .main) {
                    print("All tasks are done")
                    let viewController = PlayerViewController(localURL)
                    self.navigationController?.pushViewController(viewController, animated: true)
                }
                            } else {
                return
            }
        })
    }
}

DispatchGroup()으로 파일 여러개 동시 다운로드하기 

세 개의 파일을 다운받기 위해 우선 

let cases = [meshRef, textureRef, propRef]

로 리스트에 세 가지 경우를 추가해준다. 

let group = DispatchGroup()

cases.forEach { Ref in
	group.enter()
	Ref.write(toFile: localURL) { url, error in
    	// 실행할 task
		group.leave()
	}
}         
// notify the main thread when all task are completed
group.notify(queue: .main) {
	print("All tasks are done")
	// tasks 완료 후 작동될 코드
}                    

먼저 DispatchGroup을 생성하고

cases 에 들어있는 url들을 반복문으로 그룹에 넣어 localURL에 저장해준 후 그룹을 나간다. 

이는 비동기로 실행되기 때문에 동시에 한꺼번에 다운을 받을 수 있고,

모든 task들이 완료되었을 경우 .notify 속에 있는 코드가 실행된다.

 

 

728x90
반응형