mardi 28 juin 2016

Handling common data between framework and app

I have designed myself in a bit of a pickle here. My workspace contains the following projects:

  • App. The UI of the app itself, containing the launch target.
  • API. The API project, which builds the API framework used in the App project.
  • Shared. The shared project, which builds a framework with commonly used code in both the API and the App.
  • Pods. The cocoapods project.

When the app needs data from the api, it will call the API.framework's corresponding data provider, which in its turn will use the APIManager class to make the GET/POST/DELETE ect. call and return the data to the dataprovider, whom in its turn will return the appropriate answer to the requester.

The App project withholds a class called EventManager which job it is to log data to Mixpanel, AppsFlyer, Google ect.

Now, my problem is the following: The external API will start returning an extra data object which I need to send on towards Google Tag Manager from the app side. The problem is that none of the solutions I come up with seem perfect to me.

The solutions I came to think of are (in order of worst to best):

  • Let every request to the data providers check themselves wether there is a GTM object and then log it.
    • Pro: least amount of work in the API framework
    • Con:
      • It is anything but DRY. Every request would have to check for the GTM object, or let another method check the JSON and log it.
      • If any method "forgets" this, GTM data might be lost.
      • Make the code and process harder to read.
  • Let the API framework check wether there is an item called GTM in the returned data and send that as a seperate object to the dataprovider, whom in its turn sends it to the requester, whom in its turn logs this to the EventManager.
    • Pro:
      • Better readability
      • Less likelihood of forgetting to handle the GTM data
    • Cons:
      • There is still a likelyhood of forgetting something
      • Still not fully DRY, every request will have to handle the check of GTM callback.
  • Change the APIManager into a singleton. Add a protocol called APIManagerDelegate with function didRecieveGTMData(gtmData: AnyObject). Let the APIManager check the result of the request for GTM data, if any exist, send it to the delegate. Subscribe to the delegate in (e.g.) AppDelegate and if data is returned from the didRecieveGTMData() call, handle it and send it to the EventManager. An alternative to using protocol/delegates is to use a closure variable instead, and subscribe to that one on AppDelegate.
    • Pro:
      • This is by far the best solution I came to think of. It is DRY and doesn't require anything more from the data providers.
      • No possibility for it to be "forgotten" to log.
    • Con:

The reason for not having the API send the data directly to Google would be because the API itself should not have a dependency towards an external service. Would I later like to implement the API in another app (TVOS, Apple watch, macOS), I would not have to worry about setting up a google account for it.

I would like to know wether there is another alternative that I haven't thought off or practice when working with frameworks and common data.

Aucun commentaire:

Enregistrer un commentaire