0

guys! Once again my app is crashing and I don't have a clue to what to do. Does anyone could help out?! By the way, I'm beginner.. I'm learning. Please, be kind.

AF.request(URL_USER_ADD, method: .post, parameters: body, encoding: JSONEncoding.default, headers: header).responseJSON { (response) in

        switch response.result {
              case .success(let result):
                 if let json = result as? Data {
                    guard let data = response.data else { return }
                    let json = JSON(data: data)
                    let id = json["_id"].stringValue
                    let color = json["avatarColor"].stringValue
                    let avatarName = json["avatarName"].stringValue
                    let email = json["email"].stringValue
                    let name = json["name"].stringValue
                    
                    UserDataService.instance.setUserData(id: id, color: color, avatarName: avatarName, email: email, name: name)
                    completion(true)
                 
                 } else {
                    completion(false)
                    debugPrint(response.result as Any)

Check it out the image of the error!

Thanks!

enter image description here

goat23
  • 3
  • 1
  • 3

2 Answers2

2

Your app isn't crashing. It's failing to compile.

"switch must be exhaustive" indicates that you're not handling all of the possible cases of response.result. Because your code snippet doesn't include the context, I'll just have to guess based on my own experience and the code you do provide that response.result is a Swift Result<Data, Error>. In that case in addition to .success(_) you also have to handle .failure(_)

switch response.result
{
    case .success(let result):
        // The code you already have - more on that in a bit

    // The thing that's missing
    case .failure (let error):
        // Do something with error here that makes sense for your app
}

So that's the first thing, but you also have the error that JSON isn't defined. Indeed I don't see a definition for it in your screenshot or in the code snippet, but maybe it (or something similar that you meant to refer to) is defined outside of what I can see.

If it's in a framework (or Swift Package) that you're using, make sure you import that framework at the top of the file. Or did you intend to use Foundation JSON conversion facilities (JSONSerialization or JSONDecoder)?

Addendum

Based on conversation in comments, I think this is what you're trying to do:

switch response.result
{
    case .success(let result):
        guard let json = try? JSON(data: result) else { fallthrough }
        let id = json["_id"].stringValue
        let color = json["avatarColor"].stringValue
        let avatarName = json["avatarName"].stringValue
        let email = json["email"].stringValue
        let name = json["name"].stringValue

        UserDataService.instance.setUserData(id: id, color: color, avatarName: avatarName, email: email, name: name)
        completion(true)

    case .failure(let error)
         completion(false)
         debugPrint(response.result as Any)
}
Chip Jarred
  • 2,600
  • 7
  • 12
  • got it. So switch must be more than just one failure or success, it must be both. ok! As I'm watching online courses and the teacher said the we data because what JSON does is it creates an object out of the response data. let json = JSON(data: data) JSON suppose to be an initialiser and use ' import SwiftyJSON' but still failling. – goat23 Apr 02 '21 at 01:14
  • In general a `switch` must handle all possible cases of whatever it's switching on. For `enum` types, which `Result` is, that generally means handling each case explicitly, but for some things like `String`, you often have to include a `default` case. – Chip Jarred Apr 02 '21 at 01:18
  • Is it failing with the same error as before? Or something different? – Chip Jarred Apr 02 '21 at 01:18
  • no is different, it says: let json = JSON(data: data) XCall can throw, but it is not marked with 'try' and the error is not handled – goat23 Apr 02 '21 at 01:21
  • Ah... different error = progress. you'd need to do `let json = try JSON(data: data)`, **but** the function it's in must be marked as `throws` or you have to enclose it in `do { ... } catch { ...}` to handle the error it might throw. Since you already have a `guard` statement above it, do this the same way `guard let json = try? JSON(data: data) else { return }` – Chip Jarred Apr 02 '21 at 01:26
  • `try` requires a `do...catch` block, or for the surrounding function to be marked `throws`. `try?` will return `nil` if the thing that can throw does throw. `try!` just ignores the possibility that an error might be thrown, and crashes if it does. – Chip Jarred Apr 02 '21 at 01:28
  • I just updated my answer to reflect the progress and what I think you're trying to do based on the new screenshots. – Chip Jarred Apr 02 '21 at 01:40
  • 1
    i'm in shock.. haha no error! It worked! thank you very much. That was a good lesson! – goat23 Apr 02 '21 at 01:41
  • Glad it helped. Hopefully the code works as expected... after all getting it to compile is just the first step. – Chip Jarred Apr 02 '21 at 01:42
  • I should mention that for handling the error in a class project, `debugPrint` might be ok. However, for a real app, you'd want to do something else... what that is depends on the kind of app and kind of error. For a command line tool, you'd want to write to `FileHandle.standardError`. For a graphical app, you might display an alert so the user knows something went wrong, or maybe you can recover by re-trying a network request. For a server side app you'd want to log the error and maybe send an error notification to the user. – Chip Jarred Apr 02 '21 at 01:54
0

first screeshot is the teacher code: enter image description here

Second is mine as I refused to bring error as an attribute of response: enter image description here

goat23
  • 3
  • 1
  • 3