Search code examples
iosswiftmobile-application

How to show Activity Indicator in UI, while creating file Using File Manger


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.


Solution

  • 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.