0

I am fetching the labels, text and image through API. When API has data , it shows without error. But when the API is nil, it throws error as:

Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArray0 objectAtIndex:]: index 0 beyond bounds for empty NSArray'.

I need it to show null if API provides nil value but prevent from crash. Anyone out there please help to solve this issue in Swift 3. The code is given below:

import UIKit
import Alamofire

class Instructors: UIViewController {

    @IBOutlet var fullName: UILabel!
    @IBOutlet var post: UILabel!
    @IBOutlet var descriptionName: UITextView!
    @IBOutlet var instructorImage: UIImageView!

    var dictDataContent:NSDictionary = NSDictionary()
    var dictData:NSArray = NSArray()
    var dictprofile:NSDictionary = NSDictionary()

    override func viewDidLoad() {
        super.viewDidLoad()
        self.dictData = (dictDataContent.value(forKey: "instructors") as AnyObject) as! NSArray
        self.dictprofile = (dictData.object(at: 0) as AnyObject) as! NSDictionary
        let url:URL = URL(string: (self.dictprofile.value(forKey: "profile_image")) as! String)!
        SDWebImageManager.shared().downloadImage(with: url, options: [],progress: nil, completed: {[weak self] (image, error, cached, finished, url) in
            if self != nil {
              self?.instructorImage.image = image
            }
        })

        self.fullName.text = dictprofile.value(forKey: "full_name") as! String?
        self.post.text = dictprofile.value(forKey: "designation") as! String?
        self.descriptionName.text = dictprofile.value(forKey: "description") as! String?
    }

}
Anh Pham
  • 2,108
  • 9
  • 18
  • 29
Tamannah
  • 127
  • 2
  • 13
  • The error msg it self the reason, check the array count then access the object from the array. Your 'dictDataContent' doesn't have any value or check the key 'instructors' – Vineesh TP Jul 13 '17 at 04:14
  • i have given all my codes down there. I checked condition for dictDataContent and it still throws same error and when I check for dictData it returns nil for all. I am beginner in swift. Please can you elaborate in detail ?? plz.. – Tamannah Jul 13 '17 at 04:44
  • @Tamannah why don't just check if dictData.count > 0 and then do what are you doing? – Reinier Melian Jul 13 '17 at 04:57
  • When i check dictate.count > 0 , it shows null for all given values also. – Tamannah Jul 13 '17 at 05:02

1 Answers1

0

So what I understand from your problem is your API might have data and sometimes no data. This is the behavior of Optionals in swift. So you need to have optional variables for storing your data.

Changing your NSDictionary and NSArray variables to optional might help. Try the code below:

class Instructors: UIViewController {
    @IBOutlet var fullName: UILabel!
    @IBOutlet var post: UILabel!
    @IBOutlet var descriptionName: UITextView!
    @IBOutlet var instructorImage: UIImageView!

    var dictDataContent:NSDictionary?
    var dictData:NSArray?
    var dictprofile:NSDictionary?
    override func viewDidLoad() {
        super.viewDidLoad()
        dictData = dictDataContent?.value(forKey: "instructors") as? NSArray
        if let count = dictData?.count, count > 0 {
            dictprofile = dictData?.object(at: 0) as? NSDictionary
        }
        if let urlString = dictprofile?.value(forKey: "profile_image") as? String {
            if let url = URL(string: urlString) {
                SDWebImageManager.shared().downloadImage(with: url, options: [],progress: nil, completed: {[weak self] (image, error, cached, finished, url) in
                    if self != nil {
                        self?.instructorImage.image = image
                    }
                })
            }
        }
        fullName.text = dictprofile?.value(forKey: "full_name") as? String
        post.text = dictprofile?.value(forKey: "designation") as? String
        descriptionName.text = dictprofile?.value(forKey: "description") as? String
    }
}
nayem
  • 7,285
  • 1
  • 33
  • 51
  • I tried it earlier.. It force me to delete optionals. Error as "Fix-it Delete "?"" @nayem – Tamannah Jul 13 '17 at 04:54
  • On which line do you get this "Fix-it"? – nayem Jul 13 '17 at 04:55
  • For every lines where i put "?" as your given codes above. – Tamannah Jul 13 '17 at 04:56
  • Okay you might have put `?` by yourself, right? Let's copy my whole code and paste it to your editor. – nayem Jul 13 '17 at 04:57
  • Error as:Cannot use optional chaining on non-optional value of type 'NSArray' and Cannot use optional chaining on non-optional value of type 'NSDictionary' – Tamannah Jul 13 '17 at 04:57
  • You haven't made your variable declarations `optional`. Like: `var dictData:NSArray?`. That's why it isn't letting you to use `?` inside your viewDidLoad(). – nayem Jul 13 '17 at 04:59
  • now all errors are cleared, i copied your codes. But again shows error as *** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArray0 objectAtIndex:]: index 0 beyond bounds for empty NSArray' – Tamannah Jul 13 '17 at 05:01
  • It shows error at ,, let url = URL(string: dictprofile?.value(forKey: "profile_image") as! String) as Error: Thread 1: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP,subcode=0*0) – Tamannah Jul 13 '17 at 05:22
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/149069/discussion-between-nayem-and-tamannah). – nayem Jul 13 '17 at 05:26