GetStream / stream-swift

Swift client for Stream API
https://getstream.io
BSD 3-Clause "New" or "Revised" License
35 stars 26 forks source link

JSON decoding error #29

Closed rissicay closed 4 years ago

rissicay commented 4 years ago

I am trying to fetch the activity feed with the below code:

               self.timeline = Client.shared.flatFeed(feedSlug: "timeline")

                if let timeline = self.timeline {
                    print(timeline)
                    timeline.get(typeOf: FeedItem.self, enrich: false, pagination: .limit(50)) { r in
                        print("WHY!")
                        print(try! r.get().results)
                    }
                }

My FeedItem class looks like:

import GetStream

struct Data: Codable {
    var source: String
    var externalId: String
    var title: String
    var excerpt: String
    var image: String?
    var url: String
    var published: String
}

final public class FeedItem : EnrichedActivity<User, String, DefaultReaction> { 

    private enum CodingKeys: String, CodingKey {
        case data
    }

    var data: Data

    required init(from decoder: Decoder) throws {

        print("Decoding")
        let container = try decoder.container(keyedBy: CodingKeys.self)
        data = try container.decode(Data.self, forKey: .data)
        print(data)

        print("DONE")
        try super.init(from: decoder)
        print("Finished")
    }

    required init(actor: ActorType, verb: Verb, object: ObjectType, foreignId: String? = nil, time: Date? = nil, feedIds: FeedIds? = nil, originFeedId: FeedId? = nil) {
        fatalError("init(actor:verb:object:foreignId:time:feedIds:originFeedId:) has not been implemented")
    }

    override public func encode(to encoder: Encoder) throws {
        var container = encoder.container(keyedBy: CodingKeys.self)
        try container.encode(data, forKey: .data)

        try super.encode(to: encoder)
    }
}

The error I am getting:

Fatal error: 'try!' expression unexpectedly raised an error: JSON decoding error: The data couldn’t be read because it isn’t in the correct format.. Data: 39648 bytes: file

GetStream version: 2.2.3 Xcode version: 11.6 Swift version: 5

rissicay commented 4 years ago

When I use the javascript library, getting the feed works fine.

const feedClient = stream.connect(apiKey, apiSecret, apiId)
const random = feedClient.feed('timeline', userId);

// Add an Activity; message is a custom field - tip: you can add unlimited custom fields!
(async () => {
    try {
        const res = await random.get({ limit: 10 })

        console.log(res);
    } catch (e) {
        // Deal with the fact the chain failed
    }
})();
buh commented 4 years ago

Hi @rissicay

  1. It would be great if you wrap your try! into do { try ... } catch { print(error) } and print the error.
  2. Additionally will be useful if you could show logs. You can enable logs for the client:
    Client.config = .init(apiKey: "<#ApiKey#>", appId: "<#AppId#>",  logsEnabled: true)
  3. You setup FeedItem as EnrichedActivity<User, String, DefaultReaction> which mean you need to enrich your activity FeedItem with a user, so I think you can try this:
    timeline.get(typeOf: FeedItem.self, pagination: .limit(50)) { ... } // `enrich` is true by default

I think you can quickly find the issue if you'll check JSON in logs and compare it with decoding error.

rissicay commented 4 years ago

i found the issue. This fixed it:

final public class FeedItem : EnrichedActivity<String, String, DefaultReaction> {

So yes, user was the issue (we store user in our database). Thanks for the log tip.