Contentful logo

Contentful Community

Optional Unwrapping Error On fetchMappedEntries

#1

Hello,

I am calling the function fetchMappedEntries on my Client, and getting an Unexpectedly Unwrapped Optional on the Contentful extension of Decoder.

The following picture contains the crash itself. I can not log the contents of userInfo at this point

The only immediate thing that comes to mind is that I am not properly mapping my Contentful Content Model to my EntryDecodable class.

Here is my EntryDecodable class

import Contentful
import Interstellar

final class Article: EntryDecodable, ResourceQueryable {
    
    static let contentTypeId: String = Constants.CONTENT_TYPE_ARTICLE
    
    let sys: Sys
    
    let title: String?
    let shortDescription: String?
    let dateAndTime: Date
    let eventInfo: String?
    let significance: String?
//    let photos: [Link]?
    let category: String?
    let ranking: Int16

    
    public required init(from decoder: Decoder) throws {
        sys             = try decoder.sys()
        let fields      = try decoder.contentfulFieldsContainer(keyedBy: Article.Fields.self)
        
        self.title      = try fields.decodeIfPresent(String.self, forKey: .title)
        
        self.shortDescription = try fields.decodeIfPresent(String.self, forKey: .shortDescription)
        
        self.dateAndTime = (try fields.decodeIfPresent(Date.self, forKey: .dateAndTime))!
        
        self.eventInfo = try fields.decodeIfPresent(String.self, forKey: .eventInfo)
        
        self.significance = try fields.decodeIfPresent(String.self, forKey: .significance)
        
//        self.photos = try fields.decodeIfPresent(Array<Link>.self, forKey: .photos)
        
        self.category = try fields.decodeIfPresent(String.self, forKey: .category)
        
        self.ranking = (try fields.decodeIfPresent(Int16.self, forKey: .ranking))!
        
    }
    
    enum Fields: String, CodingKey {
        case title, shortDescription, dateAndTime, eventInfo, significance, photos, category, ranking
    }
}

This is my Content Model on Contentful:

I am aware that the photos is missing from the model, I tried to temporarily remove it to fix the problem to no avail.

If you have any ideas on how to fix this problem, either by helping me understand how the model in Swift maps to the model on Contentful better, or another means, please let me know.

Thanks!

0 Likes

#2

Hey,

since a lot of us are on vacation, let me be your rubber duck:

While pattern matching the code you shared, I saw a photos still in the Fields enum. Can you try and remove it?

:christmas_tree:Greetings from the Android Developer

0 Likes

#3

Wow,

Thanks for catching that, sorry about that.

Sadly, it did not fix the crash :confused:

0 Likes

#4

Hello,

I am getting the same error but can’t work out what the issue is. Did you find a fix for it?

I have tried to simplify the model down to a single field but the issue remains.

My simple model is:

class W2: EntryModellable, ResourceQueryable, Resource {

 var sys: Sys

 static let contentTypeId: ContentTypeId = "testmodel"

 var name: String

 enum Fields: String, CodingKey {
    case name
 }

 public required init(from decoder: Decoder) throws {

    sys = try decoder.sys()
    
    let container = try decoder.contentfulFieldsContainer(keyedBy: Fields.self)
    
    name = try container.decode(String.self, forKey: .name)
    
 }

}

Calling the api with:

let featuredQuery = QueryOn<W2>.where(field: .name, .includes(["test"]))

    client.fetchMappedEntries(matching: featuredQuery) {
        result in

        switch result {
        case .success(let arrayResponse):
            print("Featured arrayResponse")
            print(arrayResponse.items.map { $0.name })
        case .error(let error):
            print("Featured error")
            print(error.localizedDescription)



        }
    }
0 Likes

#5

Hey all, sorry for the delayed response.

The reason for the crash is that the SDK is not yet aware of the model classes you’ve created that conform to EntryDecodable. The fix is to pass in these classes as an array into the Client initializer like so:

let contentTypeClasses: [EntryDecodable.Type] = [
    W2.self,
    OtherType.self,
]

self.client = Client(spaceId: spaceId,
                     accessToken: deliveryAPIAccessToken,
                     contentTypeClasses: contentTypeClasses)
1 Like

#6

Was running into the same problem. I was looking everywhere in my code and randomly ended up in this topic. Added this in and everything worked. Support is on point at Contentful! Thanks!

1 Like