SRGSSR / srgdataprovider-apple

A library to retrieve SRG SSR unified metadata
MIT License
0 stars 1 forks source link

Development assets #26

Closed defagos closed 4 years ago

defagos commented 4 years ago

Xcode 11 provides a new feature called development assets. This is most notably useful for SwiftUI preview generation, and SRG Data Provider should thus provide a dedicated package with all kinds of data we have (SRGMedia, SRGShow, etc.).

We need some packaging script which will download the metadata. I do not recommend committing the development asset package so that users can generate fresh recent data when they need.

defagos commented 4 years ago

Some ideas:

An idea would be to implement request recorder (or to reuse one, like VCR), storing and reading assets from a development asset catalog. This would make easy to use mocked data for reliable screenshot generation via UIAutomation.

We should test that async requests can be made synchronous (e.g. with a dispatch group) so that the returned object lists can be supplied to SwiftUI previews.

defagos commented 4 years ago

It is better to start small and then expand. We need to be able to retrieve arrays of the following objects for display:

We should simply dump JSONs from associated requests, store them in development assets and parse them from there.

We should then use this for a while and see if this suffices. There is still one question, though: How should we deal with images?

defagos commented 4 years ago

No need for development assets. It suffices to perform requests synchronously for preview purposes. SwiftUI executes preview code for 5 seconds, which is enough to get the data to display. Something like:

struct MediaCell_Previews: PreviewProvider {
    static var sampleMedias: [SRGMedia] = {
        let dataProvider = SRGDataProvider(serviceURL: SRGIntegrationLayerProductionServiceURL())
        var sampleMedias: [SRGMedia] = []

        let group = DispatchGroup()
        group.enter()
        dataProvider.tvLatestMedias(for: .SRF) { (medias, _, _, _, _) in
            sampleMedias = medias ?? []
            group.leave()
        }.withOptions(.backgroundCompletionEnabled).resume()
        group.wait()
        return sampleMedias
    }()

    static var previews: some View {
        List(sampleMedias, id: \.uid) { media in
            MediaCell(media: media)
        }
    }
}

Here it is important to dispatch the work to a background thread to avoid a deadlock. There is maybe a way to reduce the associated boilerplate, but this approach provides full flexibility over the kind of sample data we want to use (we can even generate several previews for different BUs if we want, or for radio / TV content).

For this reason, I think we can close this issue. We'll reopen a new one if we have an idea about how we could eliminate this boilerplate.

defagos commented 4 years ago

One final remark: I tried development assets, which also can be associated with framework targets. Only problem is that they are discarded when archiving the framework and thus would have been supplied separately if we had used them. But this approach would have failed anyway when we perform the move to SPM.

defagos commented 3 years ago

Another approach, app-level: Use protocol-oriented programming to define the data interface to views, and mock the data with development assets.