Code Monkey home page Code Monkey logo

cmhealthsdk-ios's People

Contributors

apbendi avatar geoffrey-young avatar marcweil avatar pcmantz avatar wjoshraymond avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

cmhealthsdk-ios's Issues

Password Reset

Expose and pass through password reset requests to the CloudMine SDK

Improved Error Generation in Data Calls

  • Review how errors are handled and generated in the cmh_save method. Get some more info from the CM team and think about the best parameters to include in the callback to the user for both happy path and errors
  • Expand this to the cmh_fetch method, where we currently don't handle errors at all, or even check for a nil block

Validate Consent on Signup and Throw and Error if Invalid

When the SDK-user attempts to sign the participant up, we should confirm the ORKTaskResult they provide contains a consent step, and that consent step is valid, before continuing. If it doesn't, we should return a useful error message in the block callback.

Support multiple studies in the same app

API Design

Each app on the CloudMine backend designed to work with CMHealth would have an
application level object CMHStudyList:

{
  "__class__" : "CMHStudyList",
  "studies"   : [
    {
      "__class__" : "CMHStudy",
      "identifier": "CMExampleAsthmaStudy",
      "startDate" : 1455807671,
      "endDate"   : 1456412471
    },
    {
      "__class__" : "CMHStudy",
      "identifier": "CMHExampleGlucoseStudy",
      "startDate" : 1455807671,
      "endDate"   : 1457906672
    }
  ]
}

This object would have to be configured before attempting to use the CMHealthSDK.

Participants can "sign up" with only a username and password:

[CMHUser signupWithEmail:@"[email protected]" andPassword:@"password1"];

Question: Do we require providing a given and family name?

Participants can be added to studies by submitting a valid consent result:

[CMHUser registerForStudyWithIdentifier:@"CMExampleAsthmaStudy"
                                consent:(ORKTaskResult *)consentResult];

A convenience method could be added that rolled signup and registration for a
given study into one step.

Question: Family and given name will be collected with each consent. Do we
require these be equal to ones already on file? Or do we update what is on file
if the user provides something different? Or do we ignore the name users provide
during signup?

Studies for which participants have consented will be stored on the user record:

{
  "__id__": "8ef196sddccd43bdb70d0cdd9cc334b3",
  "services": null,
  "__class__": "CMHInternalUser",
  "email": "[email protected]",
  "familyName": "Smith",
  "givenName": "Jane",
  "__type__": "user",
  "__account__": {
    "email": "[email protected]"
  },
  "consentedStudies" : ["CMExampleAsthmaStudy"]
}

Submitting a result would require including a study identifier:

// `surveyResult` could be any subclass of `ORKResult`

[surveyResult cmh_saveToStudyWithIdentifier:@"CMExampleAsthmaStudy"
                                 completion:^(NSString * _Nullable uploadStatus, NSError * _Nullable error) {
  // Saving to a study when the user does not have a valid consent on file for
  // that study would result in an error in the callback
}];

Fetching would similarly require an identifier:

[ORKTaskResult cmh_fetchUserResultsForStudyWithIdentifier:@"CMExampleAsthmaStudy"
                                               completion:^(NSArray * _Nullable results, NSError * _Nullable error) {
  // This call would also result in a callback error if the user is not registered
  // for the study provided
}];

Convenience methods without an identifier could also exist. In this case, the
SDK user would have to set a global identifier via a method call. This could be
done in the app delegate, for example:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
  [CMHealth setAppIdentifier:CMExampleAppIdentifier appSecret:CMExampleAppSecret];
  [CMHealth setGlobalStudyIdentifier:@"CMExampleAsthmaStudy"];
}

Internal Implementation Details

Before any study level request could be made, the study identifier has to be
validated: does it exist and is it active but, this data is not
available to the SDK until it has been fetched from the CloudMine backend

Options:

  • Implement some checking using backend code on CloudMine- this would have to
    be "installed" for every app (yuck)
  • Wrap every internal network request in a callback that fetches the study
    data and subsequently retains it for future calls. This is a bit of a pain
    for our internals but probably the best experience for the SDK user
    • One side effect is that the data is now cached until the app restarts.
      Updates on the backend would be missed. This could be mitigated by
      providing the SDK consumer with a method that manually refreshes the
      data, and/or automatically refreshing it internally if it reaches some
      level of staleness (last fetched an hour ago, or a day ago, for example)

Date Question results not Serializing correctly

Result to this question generates an error in the base SDK:

ORKQuestionStep(identifier: "SwiftyHealthBirthQuestion", title: "When were you born?", answer: ORKAnswerFormat.dateAnswerFormat())

ACLs

Placeholder: we know something needs to happen with ACLs but exactly what is TBD

Handle case where uploading user consent fails after account creation

Uploading the user consent data may fail after creating the account succeeded. Currently, we return an error through the block, however the user account is still created and logged in. This account could be used to sign in and participate in the study, but the consent docs are not on file. Somehow, we need to handle this state, and at minimum throw an error when such a user attempts to authenticate.

Add Study Identifier to ORK Results

The developer should (optionally) provide a study identifier string when uploading or fetching ORK data. Internally, the wrapper class should be able to add this as a field to the ORK data, but it's presence will be transparent to the developer. The methods should still work with, and produce, regular ORK objects.

Consider: User extensibility

Should we provide a method for developers to add additional properties to the user profile? How would we do this? Expose the user profile object and allow it to be extended? This is not necessarily a requirement for a Beta, or even 1.0 release.

Separate Account Creation from Consent Submission

User's should be able to create an account with email and password. In a separate step, user's should be able to upload a consent object. The family and given name will be extracted from the family name and added to the user object, if not already present. If the user object already has these fields set, they will be ignored.

Add Study Identifier Field to User Consent

The user consent object should also include a field for study identifier. The developer should provide this field when uploading consent. The developer should be able to fetch user consent based on the identifier.

Kill Dynamically Generated Wrapper Classes, make it explicit

The CM SDK keeps a dynamic registry of classes that implement CMCoding or subclass from CMObject. By dynamically generating wrapper classes that pretended to be vanilla ORKResult objects (and subclasses) to the CM SDK, we introduced the opportunity for a runtime error based on the order of actions. If the user tries serialize a regular old ORKResult object (such as part of uploading consent) first, then the key-values stored in the runtime registry will be different.

The solution is to give up on faking out the CM SDK, and actually just wrap ORKResults in an explicit class (say, CMHResult) that inherits from CMObject. This wrapper class can still be transparent to the user of the iOS SDK, (used only internally) but will have to be accounted for by other consumers of the data stored on the CloudMine backend. That is, to get at the actual ORKResult object, someone interacting with the CloudMine backend would have to follow a property to that object, (say rkResult or the like).

saveStudyWithDescriptor

This is always returning a created status even though it has the same descriptor, shouldn't it be updated if its with the same descriptor name

Convenience Fetch Method with RK Identifier

Research Kit objects all have an identifier that is provided by the user. This method would allow sdk-users to fetch all ORKResults of a given subclass with a provided identifier, without having to write a query string to do so.

Time of Day Question Not Serializing

The ORKTimeOfDayAnswerFormat produces an ORKTimeOfDayQuestionResult object, which does not properly serialize due to the non-primitive NSDateComponents property. As reported by @kothapas

Public userData property not persisted when app restarts

While the user profile object is fetched on signup and login, the logged in user's session may persist between an app's lifecycle, in which case the profile data is removed from memory and not available to the CMHUser class to expose.

Include Pre-Built Signup Screen

Provide a view controller the user can instantiate and present, with delegate callbacks, to collect and validate user email and password.

Swift Audit

Spike out a project in Swift that uses the API and ensure that it feels "Swifty enough". Look for any sharp edges that could be smoothed easily.

Support Multiple Studies: Take 2

Simplifying the scope of the SDK's responsibilities also simplifies the scope of supporting multiple studies.

  • We will not ensure the participant has consent for a given study. We will simply support uploading and fetching consent objects. The developer is responsible for ensuring the user has consented.
  • We will not validate that a given study exists, or that a user is participating in it. Instead, all objects must simply be tagged with a study identifier string the developer supplies to calls. This field is simply added to the tagged objects.

With these assumptions in place we need to:

  • Separate user account creation/authentication from user consent
  • Add a study identifier field to the user consent object; add methods to push/fetch consent with the identifier
  • Add a study identifier field to serialized ORK data; add methods to push/fetch ORK data with the identifier
  • Add convenience methods that allow you to ignore the study identifier if you don't want to support multiple studies in your app.
  • Consider: Should we provide a method to set a global study identifier, for developer convenience?

Handle Upload of Consent Signature

Need to determine the best way to handle uploading the signature image when the user consent and subsequently attempts to authenticate. Possible options include:

  • Uploading the image inline with the signup call; this would add a third nested network request that must be completed (after account creation and consent data upload) that must be completed before a user is signed up
  • Create a queue system to upload the image in the background eventually; if it fails, the user could continue, and the app would attempt to upload at a later point automatically; is this actually acceptable from a data integrity standpoint? We know the user consented but might not immediately have their signature image on file

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.