-1

i am working an app in which data is downloaded from server in JSON format. but if Image value is nill then app crashed. i also set a default picture but cursor did not enter in else statement. Kindly guide me how i do my task correctly. Here is my code

func downloadUsersData(){

    let email = UserDefaults.standard.value(forKey: "userEmail")

    var urlString = "http://nexusvision.net/zeroone/selectuserbasic.php"
    urlString.append("?")
    urlString.append("id=\(email!)")

    print("This is URL : \(urlString)")

    let url = URL(string: urlString)
    var request = URLRequest(url: url!)

    request.httpMethod = "GET"

    let task = URLSession.shared.dataTask(with: request) { data, response, error in

        if error != nil{
            print(error?.localizedDescription)

        }

        let data = data

        if let httpStatus = response as? HTTPURLResponse, httpStatus.statusCode != 200 {           // check for http errors
            print("statusCode should be 200, but is \(httpStatus.statusCode)")
            print("response = \(response)")
        }

        let responseString = String(data: data!, encoding: .utf8)
        print("all Countary responseString = \(responseString)")

        let responseData = responseString


        do {

            let jsonValue = try JSONSerialization.jsonObject(with: data!, options: .allowFragments) as! NSDictionary

            print("This is Json : \(jsonValue.value(forKey: "product"))")

            if let profile = jsonValue.value(forKey: "product") as? NSArray
            {
                for profileData in profile{

                    if let dict = profileData as? NSDictionary{

                        if let firstName = dict.value(forKey: "firstname"){

                            print("Name is : \(firstName)")

                            self.defaults.set(firstName, forKey: "firstName")
                        }

                        if let lastName = dict.value(forKey: "lastname"){

                            print("Last Name : \(lastName)")
                            self.defaults.set(lastName, forKey: "lastName")

                        }

                        if let imageData = dict.value(forKey: "picture")    {

                            print("This is Image Json: \(imageData)")


                            let convertToImage = imageData

                            let decodedData : NSData = NSData(base64Encoded: convertToImage as! String, options: NSData.Base64DecodingOptions.ignoreUnknownCharacters)!

                            let decodedimage: UIImage = UIImage(data: decodedData as Data)!


                            print("Thats Decoded : \(decodedimage)")

                            self.profilePicImageShow.image = decodedimage

                        }

                        else{

                            self.profilePicImageShow.image = UIImage(named: "Empty")
                        }

                    }
                }
            }
        }
        catch let error as NSError {
            print(error)
        }
        }.resume()
}
matt
  • 515,959
  • 87
  • 875
  • 1,141
Irfan Saeed
  • 123
  • 2
  • 12

4 Answers4

0

Technically, key "picture" is not nil, its empty string according to the JSON response. So when you execute the code, it will go into the if statement and finally crash at let decodedimage: UIImage = UIImage(data: decodedData as Data)! as decodedData is nil.

Answer: Modify the your if statement as below

if let imageData = dict.value(forKey: "picture"), (imageData as! String) != ""   {

This should fix your crash problem.

dRAGONAIR
  • 1,181
  • 6
  • 8
0

Replace

if let imageData = dict.value(forKey: "picture") {
    print("This is Image Json: \(imageData)")
    let convertToImage = imageData
    let decodedData : NSData = NSData(base64Encoded: convertToImage as! String, options: NSData.Base64DecodingOptions.ignoreUnknownCharacters)!
    let decodedimage: UIImage = UIImage(data: decodedData as Data)!
    print("Thats Decoded : \(decodedimage)")
    self.profilePicImageShow.image = decodedimage
} else {
    self.profilePicImageShow.image = UIImage(named: "Empty")
}

with

let imageData = dict["picture"] as? NSData ?? UIImageJPEGRepresentation(UIImage(named: "Empty")!, 1.0)
self.profilePicImageShow.image = UIImage(data: imageData!)

Also, make sure that the key "picture" actually contains nil

Malik
  • 3,763
  • 1
  • 22
  • 35
0

You could add guard statements as follow:

guard let decodedData = NSData(base64Encoded: convertToImage as! String, options: NSData.Base64DecodingOptions.ignoreUnknownCharacters) else {
   return
}


guard let decodedimage: UIImage = UIImage(data: decodedData as Data) else {
   return
}

Since you are forcing an unwrap, if it fails to create an image from the data, your app will crash.

As a side note, you could use this and this, those are really great libs to work with HTTP Requests.

Nixsm
  • 37
  • 3
0

In my case I'll get URL from JSON and then download image with URL; So if url is nil then I'll add dummy image else I'll download Image from URL. Here is My Stuff :

var news = respone.result.value as! Dictionary<String,Any>
if let result:NSArray = news["stories"] as? NSArray
{
    for i in 0..<result.count
    {
        let str = (((result[i] as! NSDictionary).value(forKey: "ximg") as! NSDictionary).value(forKey: "ipath") as? String)

        if str == nil
        {
            self.news_url.append("nil")
        }
        else
        {
            self.news_url.append(str!)
        }
    }
}
self.tableview.reloadData()
pkamb
  • 33,281
  • 23
  • 160
  • 191
Rohan Dave
  • 251
  • 1
  • 7