Search code examples
iosjsonswiftalamofirexcode12

Call can throw, but it is not marked with 'try' and the error is not handled / Initializer for conditional binding must have Optional type, not 'JSON'


Sup, everyone... i hope you're doing good. Well, I've being coding for a short period of time and this bug came across, does anyone knows how to solve it? The intention is to have this 'file' which is a 'Auth Service', to communicate with a 'user data service' when the user present all of the information to this chat app.

The Third Image that I uploaded is what the I've being taught to to do it.*

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 }
                guard let json = JSON(data: data) else { return }
                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
             }

            case .failure(let result):
                completion(false)
                debugPrint(response.result as Any)

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

error01

error02

lesson taught


Solution

  • It would seem that the JSON initialiser throws, so the compiler is telling you you need to handle this.

    You are also trying to access local variables declare in the .success code block outside of that block, so they are unknown. You also have the wrong name for the id variable.

    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 }
                    do {
                        let json = try 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: avatarColor, avatarName: avatarName, email: email, name: name)
                        completion(true)
                    } catch {
                        print(error)
                        completion(false)
                    }
                }
    
                case .failure(let result):
                    completion(false)
                    debugPrint(response.result as Any)
                }
            }
        }
    }
    

    As a point of style, a completion handler that simply returns true or false isn't particularly useful as it doesn't provide any information on what went wrong when false is returned, but since you mention a lesson, I will assume that this isn't your design choice.