contentful.swift icon indicating copy to clipboard operation
contentful.swift copied to clipboard

Combine Linked custom types with concrete types

Open markst opened this issue 5 years ago • 3 comments

  • contentful.swift version number: 5.2.0
  • Xcode version number: 11.6
  • Target operating system(s) and version number(s)
    • [x] iOS:
    • [ ] tvOS:
    • [ ] watchOS:
    • [ ] macOS:
  • Package manager:
    • [ ] Carthage
    • [x] Cocoapods

My content features mostly custom types with the exception of some linked Entry's such as:

                "author": {
                    "sys": {
                        "space": {
                            "sys": {
                                "type": "Link",
                                "linkType": "Space",
                                "id": "yfwfvlr8bdv4"
                            }
                        },
                        "id": "44BDZzf5H4tTWdiPepsQas",
                        "type": "Entry",
                        "createdAt": "2020-09-02T00:17:27.469Z",
                        "updatedAt": "2020-09-02T09:40:19.821Z",
                        "environment": {
                            "sys": {
                                "id": "master",
                                "type": "Link",
                                "linkType": "Environment"
                            }
                        },
                        "revision": 3,
                        "contentType": {
                            "sys": {
                                "type": "Link",
                                "linkType": "ContentType",
                                "id": "38nK0gXXIccQ2IEosyAg6C"
                            }
                        },
                        "locale": "en-US"
                    },
                    "fields": {
                        "name": "our So Fresh Hosts <3"
                    }
                },

decodeHeterogeneousEntries will throw away content types which aren't passed as content type classes: https://github.com/contentful/contentful.swift/blob/master/Sources/Contentful/ArrayResponse.swift#L327

Since resource can be decoded:

(lldb) po entriesJSONContainer.decode(Entry.self).fields
▿ 1 element
  ▿ 0 : 2 elements
    - key : "name"
    - value : "our So Fresh Hosts <3"

Why then is it not possible to use generic Entry's as relationship links?

final class Feature: EntryDecodable, FieldKeysQueryable {

  static let contentTypeId: String = "feature"

  let id: String
  let localeCode: String?
  let updatedAt: Date?
  let createdAt: Date?

  let author: Entry?

  public required init(from decoder: Decoder) throws {
    let sys         = try decoder.sys()
    id              = sys.id
    localeCode      = sys.locale
    updatedAt       = sys.updatedAt
    createdAt       = sys.createdAt

    let fields = try decoder.contentfulFieldsContainer(keyedBy: Feature.FieldKeys.self)
    try fields.resolveLink(forKey: .author, decoder: decoder, callback: { (author) in
      self.author = author as? Entry
    })

markst avatar Sep 03 '20 06:09 markst

Not sure if I get the issue right, please correct me if I am wrong.

From what I understood you'd like to resolve Author model to a more generic Entry type. If yes, what is the purpose of that and why can't/won't you specify the Author type in the custom content types? From my perspective, if you don't want/need to use the Author custom type you could remove that property from the Feature class.

At the moment the library cannot resolve that type because heterogeneous array is designed to work with custom types that conforms to EntryDecodable. The Entry is completely different type. When you resolve those types to see the protocols they conform to you can see they differ a bit.

Author: FlatResource, EndpointAccessible, Resource, FieldKeysQueryable, Decodable

Entry: FlatResource, EndpointAccessible, Resource, ResourceQueryable, Codable

Could you elaborate more on what would you like to achieve with the property being specified as Entry?

Thanks!

tomkowz avatar Sep 05 '20 09:09 tomkowz

Thanks @tomkowz. That's correct we wish to combine the two types.

In most cases we can define the EntryDecodable models for each & works fine. However since content types can be added to the backend after app launch, it was an effort to allow future modifications to be supported.

markst avatar Sep 09 '20 00:09 markst

I don't think we'll be able to change that behaviour at the current state of the library.

tomkowz avatar Sep 21 '20 07:09 tomkowz