0
votes

I am using response from API and parsing it as a JSON.

        var readableJSON = try JSONSerialization.jsonObject(with: JSONData, options: .mutableContainers) as! [String: AnyObject]
        let status = readableJSON["status"] as! String

        if status == "success" {
            if let profileInfo = readableJSON["profile_info"] {

                let stb = UIStoryboard(name: "Main", bundle: nil)
                let vcVerifyOTP = stb.instantiateViewController(withIdentifier: "verify_otp") as! VCVerifyOTP
                vcVerifyOTP.sessionID = readableJSON["otp_session_id"] as! String
                vcVerifyOTP.userID = readableJSON["customer_id"] as! String
                vcVerifyOTP.first_name = profileInfo["firstname"] as! String
                vcVerifyOTP.last_name = profileInfo["lastname"] as! String
                vcVerifyOTP.email_id = profileInfo["email"] as! String
                vcVerifyOTP.phone_number = profileInfo["mobile"] as! String

                let scores = profileInfo["scores"] as! [String: AnyObject]

                vcVerifyOTP.gmat = scores["gmat"] as! String
                vcVerifyOTP.gre = scores["gre"] as! String
                vcVerifyOTP.ielts = scores["ielts"] as! String
                vcVerifyOTP.tofel = scores["tofel"] as! String

                self.present(vcVerifyOTP, animated: true, completion: nil)
            }
        } else {
            let alert = UIAlertController(title: "Error", message: "Login Unsuccessful.", preferredStyle: UIAlertControllerStyle.alert)
            alert.addAction(UIAlertAction(title: "Ok", style: UIAlertActionStyle.default, handler: nil))
            self.present(alert, animated: true, completion: nil)
        }

This above code works fine if 'scores' JSONObject contains any data, but if it is a blank app crashes.

IF 'scores' CONTAINS DATA (RESPONSE IS) { "status":"success", "otp_session_id":"somevalue", "customer_id":"somevalue", "profile_info": { "firstname":"somevalue", "lastname":"somevalue", "email":"somevalue", "mobile":"somevalue", "scores": { "gmat":"somevalue", "gre":"somevalue", "ielts":"somevalue", "tofel":"somevalue" } } }

IF 'scores' DOES NOT CONTAINS DATA (RESPONSE IS) (GIVING ERROR) { "status":"success", "otp_session_id":"somevalue", "customer_id":"somevalue", "profile_info": { "firstname":"somevalue", "lastname":"somevalue", "email":"somevalue", "mobile":"somevalue", "scores":[0] } }

What happening is if there is data inside 'scores' then it comes as JSONObject and if there is no data inside 'scores' then it comes as JSONArray

Now if array comes it crashes. I tried many things but I cant catch this exception. I even tried to check if value is JSONObject or JSONArray but still no success. Please Help.

1
instead of handling all of it yourself. Why not use some library like ObjectMapper or SwiftyJson ? - Umair Afzal
So first you need to check Score contains data(Key,value) or not if yes then go ahead - Bhupat Bheda
Yes that would be easier but problem is there is compatibility issue in some of my other used libraries so I am trying to avoid new library. - xSHERU
@BhupatBheda Yes exactly but I can't figure out how to do that... In same Android app I have done the same thing but I cant do that in iOS - xSHERU
Can You show me the response of Score Json object? - Bhupat Bheda

1 Answers

2
votes

As your scores object can change its format you should use implicit unwrap(!), as this directs the compiler that the object is necessarily in the same format. Instead use optional typecasting with if let , in this case you app will not crash.

You try this :

if let scores = profileInfo["scores"] as? [String: AnyObject]{   vcVerifyOTP.gmat = scores["gmat"] as! String
                vcVerifyOTP.gre = scores["gre"] as! String
                vcVerifyOTP.ielts = scores["ielts"] as! String
                vcVerifyOTP.tofel = scores["tofel"] as! String

}

else {  scores = profileInfo["scores"] as? [Int] }

Hope this helps you out!