1

I have been designing an app that analyzes lines of text, and I want to use SVProgressHUD to show progress of it.

This is my code:

let total = text.count
for line in text{
    count = count + 1
    DispatchQueue.global(pos: .background).async{
        //Analyzing line
        DispatchQueue.main.async{
            SVProgressHUD.showProgress(count/total)
        }
    }
}

The analyzing works, and the HUD shows properly, when the count reaches total, the process gets stuck, and SVProgressHUD stops at max status, and the program stops. What is the issue with the program?

Am I using Dispatchqueue wrong? Do I have to call something other to free the background process or something?

I have tried exchanging //Analyzing line and SVProgressHUD.show..., but it still doesn't work. I initially used SVProgress within the loop without the dispatchqueue, but then the progress hud moves only after the analyzation(full loop) has been completed, which is a problem.

Any help would be appreciated.

Thank you.

Mininny
  • 85
  • 6

2 Answers2

1

Use the below string extension to analyse your string. It has a completion block which will return progress as well as status of completion.

extension String {
func analyseString(completion: @escaping (Bool, Float) -> ()) {
    let totalCountOfString = self.count
    for (index, _) in self.enumerated() {
        if index == totalCountOfString - 1 {
            completion(true, Float(index)/Float(totalCountOfString))
        } else {
            completion(false, Float(index)/Float(totalCountOfString))
        }
    }
  }
}

You can call the above method to show your progress as below (maybe on a button click). self.yourString is your input string that you need to analyse.

@IBAction func clicked(_ sender: UIButton) {
    DispatchQueue.main.async {
        self.yourString.analyseString { (isCompleted, progress) in
            if isCompleted {
                SVProgressHUD.dismiss()
                print("Ending")
            } else {
                SVProgressHUD.showProgress(progress, status: "Analysing (\(progress)%)")
            }
        }
    }
}
Vineet Ravi
  • 1,457
  • 2
  • 12
  • 26
  • Or try this in your code: SVProgressHUD.showProgress(Float(count)/Float(total)) – Vineet Ravi Sep 18 '18 at 08:36
  • I tried your code, and the calculation and HUD displaying code works together(I tried putting print statement), but the HUD progress does not appear until the calculation is finished. The SVProgressHUD.showProgress line runs, but it does not actually show up. – Mininny Sep 18 '18 at 13:07
  • @Mininny Try to input large string (maybe 1000 char long) to see distinguishable progress. – Vineet Ravi Sep 20 '18 at 10:29
  • I'm using it with a text that has ~10K lines of string, which are quite long. and I think there's something wrong with the background processing but I'm not sure why the HUD wouldn't show up. – Mininny Sep 20 '18 at 10:56
1

Try using this code. It does not use loop but implements recursive calls to a function for processing your string data.

func processLines() {
    SVProgressHUD.showProgress(0)

    // sample data
    var text = Array("abcdefghijklmnop")
    var lines : [Line] = []
    let count : [Int] = Array(0..<text.count)
    count.forEach({ pos in lines.append(Line(char: text[pos])) })
    var currentIndex : Int = 0

    func processLine(at index: Int) {

        DispatchQueue.global(qos: .background).async{
            //Analyzing line
            let line = lines[index]
            print("Processing Line CHAR: \(line.char)")

            DispatchQueue.main.async{
                DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
                    guard currentIndex < lines.count-1 else {
                        SVProgressHUD.showProgress(1)
                        return
                    }
                    currentIndex += 1
                    startLineProces(at: currentIndex)
                }
            }
        }

    }

    func startLineProces(at index: Int) {
        processLine(at: index)
        SVProgressHUD.showProgress(Float(index) / Float(lines.count))
    }


    DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
        startLineProces(at: currentIndex)
    }
}

struct Line {
   var char: Character
   init(char: Character) {
     self.char = char
   }
}
ReyJenald
  • 220
  • 1
  • 7