-3

I'm trying to get the readme data for a selected repository from the GitHub api. So, the "content" is the content of the readme file, but is a base64 type. I tried to convert it but when I'm running the app, I get a fatal error "Fatal error: Unexpectedly found nil while unwrapping an Optional value "

Code:

class DetailsViewController: UIViewController {
    var details: Item?
    var read: Readm?
    @IBOutlet weak var forksLabel: UILabel!
    @IBOutlet weak var starLabel: UILabel!
    @IBOutlet weak var readMeLabel: UILabel!
    override func viewDidLoad() {
        super.viewDidLoad()
        
        forksLabel.text = "\(details!.forks_count)"
        starLabel.text = "\(details!.stargazers_count)"
        downloadJSON {
            return
        }
        readMeLabel.text = decodeBase64(word: read!.content) // <- here is the error
        
    }
    func downloadJSON (completed: @escaping () -> ()) {
        
        let url = URL (string: "https://api.github.com/repos/\(details!.full_name)/readme")
        URLSession.shared.dataTask(with: url!) { (data, response, error) in
            
            if error == nil {
                do {
                    print("ceva")
                    self.read = try JSONDecoder().decode(Readm.self, from: data!)
                    DispatchQueue.main.async {
                        completed()
                    }
                }catch {
                    print (error)
                }
                
            }
        }.resume()
        
    }
    
    func decodeBase64(word: String) -> String {
        let base64Decoded = Data(base64Encoded: word)!
        let decodedString = String(data: base64Decoded, encoding: .utf8)!
        return decodedString
    }
    
    
}

This is where the error is :

 readMeLabel.text = decodeBase64(word: read!.content)

EDITED:

super.viewDidLoad()
        
        forksLabel.text = "\(details!.forks_count)"
        starLabel.text = "\(details!.stargazers_count)"
        downloadJSON {
            if let content = self.read?.content {
                self.readMeLabel.text = self.base64Decoded(word: content)
                print(self.base64Decoded(word: content))
                
            }
            
        }
        
        
    }
    
    
    func base64Decoded(word: String) -> String? {
        guard let base64Data = Data(base64Encoded: word) else { return nil}
        let decodedData = String(data: base64Data, encoding: .utf8)
        return decodedData
    }

I have managed how to unwrap things, but now, my label is empty, I made a print statement and is nil. Anyone know why ?

Vasile
  • 59
  • 6
  • That’s because the faulty code gets called before the download is done so `read` is nil. Your downloadJSON method takes a completion handler as an argument, use it. – Joakim Danielson Apr 30 '21 at 20:17
  • Does this answer your question? [What does "Fatal error: Unexpectedly found nil while unwrapping an Optional value" mean?](https://stackoverflow.com/questions/32170456/what-does-fatal-error-unexpectedly-found-nil-while-unwrapping-an-optional-valu). Also a duplicate of [Returning data from async call](https://stackoverflow.com/questions/25203556/returning-data-from-async-call-in-swift-function) – Joakim Danielson Apr 30 '21 at 20:18
  • 1
    See all those exclamation marks? Every one of them means "crash me". You can hardly complain when the runtime does exactly what you said to do. – matt Apr 30 '21 at 20:28
  • I have edited my question, can you check now please ? @matt – Vasile Apr 30 '21 at 21:48

1 Answers1

1

As you have already an asynchronous completion handler use it!.

A single return statement is pretty pointless, move the line to assign the text into the closure.

And unwrap the value always safely, because an error could occur

downloadJSON {
    if let content = self.read?.content {
        self.readMeLabel.text = self.decodeBase64(word: content)
    }
}
vadian
  • 274,689
  • 30
  • 353
  • 361
  • Thank you for your answer, now im getting an error here let base64Decoded = Data(base64Encoded: word)! , into decodeBase64 function, found nil while unwrapping optional – Vasile Apr 30 '21 at 20:25
  • Don't force unwrap optionals unless you can guarantee that they have a value. Optional bind the values and return an empty string or show an error. – vadian Apr 30 '21 at 20:27
  • I have edited my question, can you check now please ? – Vasile Apr 30 '21 at 21:47
  • Of course now you avoid the crash but the main issue remains that `content ` is apparently not base64 encoded or there is a bug in your code. Please use the debugger. – vadian May 01 '21 at 04:39