UPGRADE YOUR SKILLS: Learn advanced Swift and SwiftUI on Hacking with Swift+! >>

SOLVED: Question: Project9 -> challenge 2

Forums > 100 Days of Swift

@Haibo  

This challenge is to modify project 8 to involves GCD.

The problem is when I put background queue directly inside function itself, then cluesString, answers label are empty when app is launched. Also letter buttons are default valued "WWW".

func loadLevel() {
      var clueString = ""
      var solutionString = ""
      var letterBits = [String]()

      DispatchQueue.global(qos: .userInitiated).async { [weak self] in
        // code to load and parse the level.
      }

      letterBits.shuffle()

      // Project9 challenge 2
      DispatchQueue.main.async { [weak self] in
          // Configure buttons and labels
          self?.cluesLabel.text = clueString.trimmingCharacters(in: .whitespacesAndNewlines)
          self?.answersLabel.text = solutionString.trimmingCharacters(in: .whitespacesAndNewlines)

          if letterBits.count == self?.letterButtons.count {
              if let letterButtons = self?.letterButtons {
                  for i in 0..<letterButtons.count {
                      self?.letterButtons[i].setTitle(letterBits[i], for: .normal)
                  }
              }
          }
      }
   }

If I put loadLevel() in background queue from viewDidLoad(), it works fine. So what is the different of this two way?

    override func viewDidLoad() {
        super.viewDidLoad()

        DispatchQueue.global(qos: .userInitiated).async { [weak self] in
            self?.loadLevel()
        }
    }

3      

@Haibo  

I found the issue, it is not related with GCD actually. This issue is in line Bundle.main.url(forResource: "level\(self?.level)", which produces a String interpolation warning. And result resource load get nil I guess.

As I used weak reference [weak self] as capture list here, I need to put self? before the global variable level in case to use it in closure. If I give it a default value like \(self?.level ?? 0), then this issue is fixed.

But is it that the property way to deal with this String interpolation here? Or some better approach should be involved here?

override func viewDidLoad() {
      super.viewDidLoad()

      // 1. call loadLevel
      loadLevel()
    }

    func loadLevel() {
      var clueString = ""
      var solutionString = ""
      var letterBits = [String]()

      DispatchQueue.global().async { [weak self] in
        if let levelFileURL = Bundle.main.url(forResource: "level\(self?.level)", withExtension: "txt") {
            if let levelContents = try? String(contentsOf: levelFileURL) {
                var lines = levelContents.components(separatedBy: "\n")
                lines.shuffle()
                self?.correctGuess = 0
                print("AAA")

                for (index, line) in lines.enumerated() {
                    let parts = line.components(separatedBy: ": ")
                    let answer = parts[0]
                    let clue = parts[1]

                    clueString += "\(index + 1). \(clue)\n"

                    let solutionWord = answer.replacingOccurrences(of: "|", with: "")
                    solutionString += "\(solutionWord.count) letters\n"
                    self?.solutions.append(solutionWord)

                    let bits = answer.components(separatedBy: "|")
                    letterBits += bits
                    print("ABC")
                }
            }
        }

        DispatchQueue.main.async {
          // 3. push UI code back to main thread
        }
      }
    }

3      

TAKE YOUR SKILLS TO THE NEXT LEVEL If you like Hacking with Swift, you'll love Hacking with Swift+ – it's my premium service where you can learn advanced Swift and SwiftUI, functional programming, algorithms, and more. Plus it comes with stacks of benefits, including monthly live streams, downloadable projects, a 20% discount on all books, and free gifts!

Find out more

Sponsor Hacking with Swift and reach the world's largest Swift community!

Archived topic

This topic has been closed due to inactivity, so you can't reply. Please create a new topic if you need to.

All interactions here are governed by our code of conduct.

 
Unknown user

You are not logged in

Log in or create account
 

Link copied to your pasteboard.