Cannot force unwrap value of non-optional type but prints with "optional"

First off before anybody puts a cheeky "duplicate question" post. I have gone through EVERY single one on stack and then some. The similar posts have either been inapplicable or haven't worked for me.

Background:

I am trying to build an app to communicate with a website (server down the road, one step at a time.) I have established communication and verified that it works. Long and the short of it, the data coming in when printed has an "optional" in front of it.

My website is very barebones and is made up of an html and js file. The js is linked to my html via <"script"> command. I am trying to us a JSONdecode in swift but am prompted with a "not valid JSON" error. When I investigated further I am getting the previously mentioned "optional" in my data. I tried using "!" to force unwrap my incoming data but am prompted with "cannot force unwrap value of non-optional type"??? When I try my swift code with a known JSON website (something I found on youtube) it works fine.

Obviously my question isn't exclusive to "force unwrap." The solution provided may change what is necessary to rectify this ie. change what the question "should have been." I am open to any and all solutions but maybe we'll just start with how can I force unwrap this?

Thank you in advance.

XCODE (Swift)

super.viewDidLoad()

let url = URL(string: "https://*****for my eyes only*****.com/script.js")!              

var request = URLRequest(url: url)
request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
request.httpMethod = "POST"


let task = URLSession.shared.dataTask(with: request) { data, response, error in
     guard let data = data,
     let response = response as? HTTPURLResponse,
     error == nil else 
           {                                           
              print("error", error ?? "Unknown error")
                       return
           }

     guard (200 ... 299) ~= response.statusCode else 
           {               
              print("statusCode should be 2xx, but is \(response.statusCode)")
              print("response = \(response)")
                       return
           }


//shows data printed w/ optional in front of data                   
let htmlcontent = NSString(data: data, encoding: String.Encoding.utf8.rawValue)

print(htmlcontent)


//data is the portion I am trying to force unwrap 
//currently produces error "not valid JSON"      
let decoder = JSONDecoder()
let classes = try! decoder.decode([Class].self, from: data)

HTML Code

<html>
<body>
  <script src="script.js"></script>
</body>
</html>

JS Code (Taken from internet - Not Mine)

{
    "mothmap": {
        "value": [
            {
                "longitude": -0.13025200000004133,
                "latitude": 51.4596619
            },
            {
                "longitude": -2.707384100000013,
                "latitude": 53.7613383
            }
        ]
    }
}

1 answer

  • answered 2020-01-18 02:09 Lou Franco

    The error says

    Expected to decode Array but found a dictionary instead.

    This is true. Your JSON is not an array, but you passed an array type [Class] to the decoder. You need to match the type to the JSON.

    Try

    let classes = try! decoder.decode(Class.self, from: data)
    

    Or edit the JSON to put the class in []

    [{
        "mothmap": {
            "value": [
                {
                    "longitude": -0.13025200000004133,
                    "latitude": 51.4596619
                },
                {
                    "longitude": -2.707384100000013,
                    "latitude": 53.7613383
                }
            ]
        }
    }]