0

As suggested by OOPer I am posting this as a separate question. This is an extension of this: JSONserialization error

I am pulling a json array from a php script that reads an sql database. The json is pretty large but should be well formed as tested using several online testers. The problem is that when I try to get the elements out of the array it returns nil. It is able to download the data and it can correctly count how many elements are in the array but when I try to access the elements it returns nil. Any suggestions?

Here is an example of an element:

{
"id":2045,
"oprettelsesdato":"09-02",
"overskrift":"etc etc etc",
"navn":"xyz xyz xyz",
"tlf":"12345678",
"email":"[email protected]",
"journal":"MJ",
"intro":"yada yada yada yada ",
"annonce":"test",
"address":"testroad"
},

The LocationModel.swift

import Foundation

class LocationModel: NSObject {

//properties

var id: String?
var oprettelsesdato: String?
var overskrift: String?
var address: String?
var intro: String?
var email: String?
var tlf: String?
var annonce: String?
var journalnr: String?


override init()
{

}


init(id: String, oprettelsesdato: String, overskrift: String, address: String, intro: String, email: String, tlf: String, annonce: String, journalnr: String) {

    self.id = id
    self.oprettelsesdato = oprettelsesdato
    self.overskrift = overskrift
    self.address = address
    self.intro = intro
    self.email = email
    self.tlf = tlf
    self.annonce = annonce
    self.journalnr = journalnr

}


override var description: String {
    return "id: \(id), oprettelsesdato: \(oprettelsesdato), overskrift: \(overskrift), address: \(address), journalnr: \(journalnr)"

}



}

And here is where the error is thrown:

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    let item: LocationModel = feedItems[indexPath.row] as! LocationModel
    let cellIdentifier: String = "BasicCell"
    let myCell: UITableViewCell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier)!
    print(feedItems[indexPath.row])


    //myCell.detailTextLabel!.text = item.oprettelsesdato
    myCell.textLabel!.text = item.overskrift
    myCell.textLabel!.leadingAnchor.constraint(equalTo: myCell.leadingAnchor).isActive = true
    myCell.textLabel!.topAnchor.constraint(equalTo: myCell.topAnchor).isActive = true
    myCell.textLabel!.heightAnchor.constraint(equalTo: myCell.heightAnchor,
                                                multiplier: 1.0).isActive = true
    myCell.textLabel!.widthAnchor.constraint(equalTo: myCell.heightAnchor,
                                                multiplier: 0.8).isActive = true


    //print(item.id)  <-returns nil
    //print(item.oprettelsesdato)  <-returns nil
    //print(item.overskrift)  <-returns nil
    extralabel!.text = item.oprettelsesdato // <-This is where the error is thrown 

}

error msg:

fatal error: unexpectedly found nil while unwrapping an Optional value

update So I narrowed it down to the following in the json parser. The if let optional is never true although all the jsonElements contain values. What is wrong?

for jsonElement in jsonResult {
        print(jsonElement["id"])  //<- these print() all return the correct values
        print(jsonElement["oprettelsesdato"])
        print(jsonElement["overskrift"])
        print(jsonElement["address"])
        print(jsonElement["intro"])
        print(jsonElement["email"])
        print(jsonElement["tlf"])
        print(jsonElement["annonce"])
        print(jsonElement["journal"])

        let location = LocationModel()
        if let id = jsonElement["id"] as? String,
            let oprettelsesdato = jsonElement["oprettelsesdato"] as? String,
            let overskrift = jsonElement["overskrift"] as? String,
            let address = jsonElement["address"] as? String,
            let intro = jsonElement["intro"] as? String,
            let email = jsonElement["email"] as? String,
            let tlf = jsonElement["tlf"] as? String,
            let annonce = jsonElement["annonce"] as? String,
            let journalnr = jsonElement["journal"] as? String
        { //this never returns true and location. is never set. Why??
            location.id = id
            location.oprettelsesdato = oprettelsesdato
            location.overskrift = overskrift
            location.address = address
            location.intro = intro
            location.email = email
            location.tlf = tlf
            location.annonce = annonce
            location.journalnr = journalnr

        }

        locations.append(location)

    }

3 Answers 3

3

If the line

extralabel!.text = item.oprettelsesdato // <-This is where the error is thrown 

Is the one throwing an "unexpectedly found nil while unwrapping an Optional value" error then the cause is almost certainly that extralabel (which should be named extraLabel to follow camelCase naming conventions) is nil. Set a breakpoint at that line and check extralabel.

Sign up to request clarification or add additional context in comments.

1 Comment

yes, that is the point, extralabel is nil because item.oprettelsesdato is nil. However, item.oprettelsesdato is an item in the json array. The json array is downloaded from the php generated json array. If I print feedItems[indexPath.row] it looks like this: id: nil, oprettelsesdato: nil, overskrift: nil, address: nil, journalnr: nil
2

According to the given JSON id is clearly Int, not String

var id: Int

...

if let id = jsonElement["id"] as? Int,

Note: Don't declare properties as optional when providing a non-optional initializer or as a laziness alibi not to write an initializer. The type system of Swift encourages you to use non-optional types as much as possible. Non-optional types will never crash the app!

7 Comments

Awesome. Good call. Now, the let if returns true but it still crashes at extralabel!.text = item.oprettelsesdato. I'll update when I am a little further
Check that extralabel is not nil.
extralabel is still nil but item.oprettelsesdato is now set. Could this have something to do with item.oprettelsesdato being a date on the format dd-mm? Maybe it thinks it should be an Int. I guess I can't simply make dd-mm an Int because it will then subtract the mm from the dd (02-05 becomes -3)
If extralabel is nil it causes the crash not item.oprettelsesdato. Do not use exclamation marks carelessly.
Really appreciate your patience @vadian . I am obviously completely ignorant here, but how can extralabel!.text be nil when item.oprettelsesdato is not nil and extralabel!.text = item.oprettelsesdato?
|
2

Your var oprettelsesdato:String? variable is an optional variable .And as you no optionals says either "there is a value" or "there isn't a value at all".If you define variable as an optional ,then to get value from this variable you will have to unwrap it.And good way to force unwrap are OPTIONAL BINDING.Here is a example-:

var oprettelsesdato:String?

  oprettelsesdato = "hello swift!"

  if let value = oprettelsesdato
  { 

   println(value)

  }
else

{

println("no value")

}

TRY YOUR CODE IN THIS WAY IT WILL SOLVE YOUR ISSUE

JUST USE if let AND STORE ARRAY VALUES IN VARIABLE THEN ASSIGN THEM TO YOUR LABELS WITHIN if let CONDITION.

EXAMPLE-:

if let value =  item.oprettelsesdato
{
extralabel.text = value
}

else
{
print("no value")
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.