I am downloading files (.pdf, .JPG, .PNG etc.) from remote server. "fullFileURLString" is provide file Path URL in String.
When user click on filename from collection view, I need to give option of saving files in user's own device. For That i am using UIDocumentInteractionController(). I am planing to give this functionality to users.
This functionality is working properly. This process take some times to do it. I want to show Activity Indicator while this process is happening. But Activity Indicator is not animating or not displaying on view.
How to show Activity Indicator when this process is happening & hide activity indicator when documentInteractionController present?
I had try below code
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier:"showUplodedMediaCellCollectionViewCell", for: indexPath) as! showUplodedMediaCellCollectionViewCell;
if let bytes = Memory().deviceRemainingFreeSpaceInBytes() {
let twoHundresMb:Int64 = 283115520
if bytes < twoHundresMb {
Alert.showAlertView(on: self, message: "There is not enough available storage to download.")
}
else {
let activityIndicatior:UIActivityIndicatorView = UIActivityIndicatorView()
activityIndicatior.center = self.view.center
activityIndicatior.hidesWhenStopped = true
activityIndicatior.style = .gray
view.addSubview(activityIndicatior)
activityIndicatior.startAnimating()
let mediaDetails = MediaFiles?[indexPath.row]
if let path = mediaDetails?.folderPath {
if let Filename = mediaDetails?.name {
let fullFileURLString = "\(baseURL)"+"\(path)"+"\(Filename)"
if let FileUrl = URL(string: fullFileURLString) {
let Filedata = try? Data(contentsOf: FileUrl)
let documentDirectoryPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0] as String
let documentDirectoryPath2 = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0] as NSString
let documentDirectoryPathURL = NSURL(fileURLWithPath: documentDirectoryPath)
if let pathComponent = documentDirectoryPathURL.appendingPathComponent(Filename) {
let fileManager = FileManager.default
let filePath = pathComponent.path
if fileManager.fileExists(atPath: filePath) {
print("Already Have:",Filename)
}
else {
print("No available",Filename)
let fileManager = FileManager.default
let fileManagerPath = documentDirectoryPath2.appendingPathComponent(Filename)
fileManager.createFile(atPath: fileManagerPath, contents: Filedata, attributes: nil)
print("path:- \(fileManagerPath)")
}
}
let destinationPath = documentDirectoryPath2.appendingPathComponent(Filename)
let destinationURL = URL(fileURLWithPath: destinationPath)
let dowanloadedMediaDocumentDirectoryPathURL = NSURL(fileURLWithPath: documentDirectoryPath)
if let pathComponent = dowanloadedMediaDocumentDirectoryPathURL.appendingPathComponent(Filename) {
let fileManager = FileManager.default
let filePath = pathComponent.path
if fileManager.fileExists(atPath: filePath) {
activityIndicatior.stopAnimating()
var documentInteractionController = UIDocumentInteractionController()
documentInteractionController.url = destinationURL
if !documentInteractionController.presentOpenInMenu(from: cell.bounds, in: view, animated: true) {
print("You don't have an app installed that can handle ePub files.")
}
}
else {
Alert.showAlertView(on: self, message: "Unable to download file from remote server.")
}
}
}
}
}
}
}
else {
Alert.showAlertView(on: self, message: "There is not enough available storage to download.")
}
}
I expect the ActivityIndicator will animating until documentInteractionController will not present.
You should put all the downloading file process in a background thread.
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
// Some code here
DispatchQueue.main.async {
activityIndicatior.startAnimating()
}
DispatchQueue.global(qos: .userInitiated).async {
// Download file or perform expensive task
DispatchQueue.main.async {
activityIndicator.stopAnimating()
}
}
}
Split your code into functions with a single responsibility, it will make your code easier to debug.