Code Monkey home page Code Monkey logo

appcore's Introduction

AppCore

AppCore is a layer built on top of ResearchKit which forms the core of the five initial ResearchKit apps.

It includes some of the key features of those initial ResearchKit apps, including:

  • Dashboard with progress graphs
  • Data storage back end
  • JSON serialization and deserialization
  • Integration with Sage Bionetworks' Bridge service

We are excited about how helpful AppCore has been in the development of several ResearchKit apps. In order to help the ResearchKit community derive the most utility from the individual components in AppCore, we’re working hard with many developers to transition components of AppCore into the main ResearchKit repo. As a result, we will only be accepting bug fixes to AppCore moving forward and hope you’ll continue giving feature and UI enhancements once the pieces are fully integrated into ResearchKit’s repo.

We posted AppCore at the time the ResearchKit was released as a way to provide functionality that the ResearchKit framework did not have at the time. Since then, there have been many improvements to ResearchKit which make it no longer necessary to use AppCore.

Before you decide to use AppCore, consider these ResearchKit alternatives for AppCore’s components:

Also take a look the ResearchKit sample app (ORKSample) to see how to use the latest ResearchKit capabilities. https://github.com/ResearchKit/ResearchKit/tree/master/samples/ORKSample/ORKSample

Building AppCore

AppCore does not build stand-alone, but rather is built as part of other projects. To build it, go to one of the projects that uses it, such as Share the Journey.

OpenSSL

This version of AppCore differs from the version in the shipping apps because it does not include OpenSSL, which is used in the shipping apps for Cryptographic Message Syntax (CMS) encryption support.

CMS is used by the apps in order to protect sensitive data stored temporarily on the phone, and while in transit. It helps reduce requirements on back-ends, so that HTTPS endpoints can safely be terminated earlier than the final hop, because data encryption and decryption occurs at the application layer.

To re-enable OpenSSL, build OpenSSL as an iOS static library, add it to the AppCore library target, and then switch the CMS code to use OpenSSL by removing APCCMS_NoEncryption_JustAStub.m from the target and adding APCCMS_UsingOpenSSL.m instead.

License

The source in the AppCore repository is made available under the following license unless another license is explicitly identified:

Copyright (c) 2015, Apple Inc. All rights reserved.

Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:

1.  Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.

2.  Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.

3. Neither the name of the copyright holder(s) nor the names of any contributors
may be used to endorse or promote products derived from this software without
specific prior written permission. No license is granted to the trademarks of
the copyright holders even if such marks are included in this software.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

appcore's People

Contributors

chrisinsfo avatar erin-mounts avatar jwe-apple avatar lucianoturrini avatar p2 avatar peculiar avatar ramshandilya avatar wooster avatar yuanzhu-apple avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  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  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

appcore's Issues

APCSignUpPermissionsType enum is not nice to use from Swift

The enum APCSignUpPermissionsType defines cases named like kSignUpPermissionsTypeXY, omitting the "APC" at the beginning.

There is a similar issue with APCUserInfoItemType, which defines cases with 2 different trunks:

  • kAPCUserInfoItemTypeXY
  • kAPCSettingsItemTypeXY

The latter would require creating a new enum, which might cause problems if the types should be mixable.

AutoLayout issues in onboarding screens

There are several auto layout conflicts in the onboarding screens, mostly labels that want to be centered, want a given width and have a fixed width from one of the edges. While the fixed width makes some sense to have English text nicely wrapped onto two lines, the fixed distance to the edge is unnecessary and creates a conflict on different screen sizes.

Audit threading for data collectors

Data collection appears to run on a non-serial dispatch queue, but there doesn't appear to be any thread safety built into any of the collectors. Perform an audit for thread safety.

kLastUsedTimeKey is defined twice

To keep track of last time the app was used, the app delegate sets kLastUsedTimeKey on termination/moving to background. APCTabBarViewController does the same – with the same key that it defines itself – when PIN entry succeeds.

It seems the tab controllers implementation can be removed entirely. If not it should probably be moved to the delegate method that the app delegate implements and the define should be removed.

Crash when running observer query

In the Asthma app we've observed crashes when responding to a HealthKit observer query.

It looks like the consentDate could be nil at APCAppDelegate.m lines 730ff:

                    NSUInteger anchorForSampleType = [[NSUserDefaults standardUserDefaults] integerForKey:sampleType.identifier];
                    NSPredicate *predicate = nil;
                    NSDate *consentDate = self.dataSubstrate.currentUser.consentSignatureDate;

                    if (anchorForSampleType == 0) {
                        predicate = [NSPredicate predicateWithFormat:@"%K >= %@",
                                     HKPredicateKeyPathStartDate,
                                     [consentDate startOfDay]];
                    }

Which would lead to an invalid predicate on the anchored object query.

Add documentation for AppCore

Are there plans to include documentation on how to integrate AppCore into a fresh project—or perhaps a demo app similar in purpose to ORKCatalog, showcasing a generic app using AppCore?

Consolidate dictionary generation code in one place for KeyChain access

Something along the lines:

static NSMutableDictionary* NSMutableDictionary createQuery(id class, id service, id account) {
    ...
}

Providing we cover all the parameters for all the methods, such as kSecReturnData, kSecReturnAttributes, kSecMatchLimit, kSecAttrAccessGroup and not constrain the query.

`initializationOptions` dictionary should be broken apart (and is strange to use from Swift)

The app delegate's initializationOptions dictionary contains a lot of different settings pertaining to different areas, it would be nice to delegate those responsibilities out to a controller object belonging to the "module" in question, as discussed in #41.

Also, some arrays in the dictionary, such as kAppProfileElementsListKey, rely on an NSNumber representation of enum values. This is weird to use from Swift, where you need to wrap those in something like

NSNumber(unsignedLong: enumCase.rawValue)

Issues like these could be solved more elegantly from a "module" controller.

Conflicting layout constraints

I'm getting layout constraint warnings like below (APCStudyOverviewCollectionViewController) for many AppCore view controllers out of the box. That is with no changes on my part.

Has anyone else seen these?


2015-07-22 15:18:00.452 myApp[3046:271833] Unable to simultaneously satisfy constraints.
Probably at least one of the constraints in the following list is one you don't want. Try this: (1) look at each constraint and try to figure out which you don't expect; (2) find the code that added the unwanted constraint or constraints and fix it. (Note: If you're seeing NSAutoresizingMaskLayoutConstraints that you don't understand, refer to the documentation for the UIView property translatesAutoresizingMaskIntoConstraints)
(
"<NSLayoutConstraint:0x7fa546014d30 V:[UIView:0x7fa546012cd0(343)]>",
"<NSLayoutConstraint:0x7fa5460153e0 UIView:0x7fa546012cd0.top == UIView:0x7fa546012bc0.topMargin - 8>",
"<NSLayoutConstraint:0x7fa546015480 UIView:0x7fa546012bc0.bottomMargin == UIView:0x7fa546012cd0.bottom - 8>",
"<NSAutoresizingMaskLayoutConstraint:0x7fa546018090 h=--& v=--& V:[UIView:0x7fa546012bc0(50)]>"
)

Will attempt to recover by breaking constraint
<NSLayoutConstraint:0x7fa546014d30 V:[UIView:0x7fa546012cd0(343)]>

Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger.
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKit/UIView.h> may also be helpful.

APCScoring fails for Sleep Analysis metric

APCScoring fails with an 'incompatible unit' error, when I query for the Sleep Analysis metric. This is likely because Sleep Analysis us unit-less. But the method seems to require an HKUnity parameter.

Refactor APCDataSubstrate and APCUser to make them modular

As mentioned in #41, the data substrate and especially APCUser are tightly coupled to various parts of AppCore and the Bridge SDK. It would be nice to have these as protocols but keep the existing code as implementations of those protocols. Additionally, APCDataSubstrate (as-is) should take care of the stack initialization, not the app delegate.

New project with RK, AppCore and BridgeSDK has build error

Hi,
When I create a new iOS project using latest of ResearchKit framework, AppCore and BridgeSDK has build errors and can't be built.

/AppCore/APCAppCore/APCAppCore/DataSubstrate/Model/APCSmartSurveyTask.m:99:68: Property 'questions' not found on object of type 'SBBSurvey *'

/AppCore/APCAppCore/APCAppCore/DataSubstrate/Model/APCSmartSurveyTask.m:438:18: Property 'detail' not found on object of type 'SBBSurveyQuestion *'

/AppCore/APCAppCore/APCAppCore/DataSubstrate/Model/APCSmartSurveyTask.m:439:33: Property 'detail' not found on object of type 'SBBSurveyQuestion *'

/AppCore/APCAppCore/APCAppCore/Startup/APCAppDelegate.m:90:31: Unknown type name 'APCDemographicUploader'

/AppCore/APCAppCore/APCAppCore/Startup/APCAppDelegate.m:90:1: Property with 'retain (or strong)' attribute must be of object type

/AppCore/APCAppCore/APCAppCore/DataSubstrate/Model/APCSmartSurveyTask.m:572:50: No known class method for selector 'scaleAnswerFormatWithMaxValue:minValue:step:defaultValue:'

Some APCApcoreTests fail

APCScheduleExpressionParserTests's testListParsing, testNumberParsing, and APCScheduleExpressionPointSelectorTests's testPointSelector seem to fail.

Move onboarding configuration to an onboarding manager

Similar to #47, code used to setup and configure onboarding could be moved to a onboarding manager class. This would free up the app delegate and allow for easy customization by subclassing. For simple tie in to the app, AppCore may ask the app delegate, via protocol, for the onboarding manager.

I'm not sure if onboarding should be rolled into consenting or stay separate. It seems to me keeping them separate is desirable so as to not create a huge manager class with slightly different responsibilities.

Also cf. #41

Move consenting setup to a consent manager

Code used to setup and configure consenting could be moved to a new consent manager class. This would free up the app delegate and allow for easy customization by subclassing. For simple tie in to the app, AppCore may ask the app delegate, which should be adhering to a new consent manager provider protocol, for the consent manager.

cf. #41

APCKeychainStore.stringForKey randomly returning empty values

I'm seeing unpredictable behavior with APCKeychain, where APCKeychainStore.stringForKey incorrectly returns an empty value about 1/3 of the time. Where APCKeychainStore incorrectly returns empty values, I can force-close the app and see the correct values returned on subsequent queries.

I'm getting and setting keychain values via Swift, like this:

var email : String {
    get {
        if let value = APCKeychainStore.stringForKey(kEmailPropertyName) {
            return value
        }
        return ""
    }
    set {
        APCKeychainStore.setString(newValue, forKey: kEmailPropertyName)
    }
}

var password : String {
    get {
        if let value = APCKeychainStore.stringForKey(kPasswordPropertyName) {
            return value
        }
        return ""
    }
    set {
        APCKeychainStore.setString(newValue, forKey: kPasswordPropertyName)
    }
}

Refactoring: High Level Overview

To make AppCore useable without needing to link the whole AppCore framework and with one's own AppDelegate, not a subclass of APCAppDelegate, some refactoring has to happen. Before I dig myself in I wanted to note a few ideas and see if it's a good way to go. I'll raise additional issues for specific things, hoping to collect some thoughts on the general refactoring direction here.

Untangle App Delegate

Ties to the specific implementation of APCAppDelegate is everywhere, often for sensible things like getting ahold of the data substrate instance, but not always. A possible way would be to create controller classes for the individual AppCore "modules", APCOnboarding and APCDataSubstrate are a start already. App delegates would have to implement a protocol so that they can return the controller instance to be used in the app. This would help modularizing and at the same time allow to clean up the initializationOptions dictionary.

The modules I currently see are:

  • Data Substrate (with the current user, see below)
  • Onboarding & Consenting
  • Scheduling
  • Data Collection

Untangle APCUser

The current implementation of the class representing the study subject, APCUser, is strongly tied to the Bridge SDK. In fact its sign-up and withdraw methods are only defined in the user's Bridge category. The current CoreData stack is likely to be of use to many ResearchKit developers, but still there will be studies with minimal on-device data that only need a name and the date of consent stored on device, possibly in the keychain.

I think the nicest way would be to convert APCDataSubstrate and APCUser into categories and make the current models implementations of those, for those who want to use them out of the box. The Bridge extended user should be a subclass of the current APCUser class, not being able to use methods not defined in the superclass/protocol.

userProfileElements property on APCPermissionsManager is not a permission type

APCPermissionsManager is effectively a global variable holding a representation of the configuration of permissions, returning the state of permissions, and requesting those permissions when necessary. While userInfoItemTypes behave like permissions, they are not actually permissions.

APCPermissionsManager has the following property in the header file:

@property (copy, nonatomic) NSArray *userInfoItemTypes;

The userInfoItemTypes are used to configure view controller elements by prepareContent() methods in APCProfileViewController, APCSignUpMedicalInfoViewController, and APCSignUpGeneralInfoViewController.

A future review of this architecture might for example, add a userInfoConfiguration object to resolve this issue. Discussion in #117 recommended that neither APCPermissionsManager or APCOnboardingManager be the home for the array of userInfoItemTypes.

APCPasscodeViewController does not reset input blobs on success

APCPasscodeViewController disappears when the PIN is entered correctly. If it is subsequently shown again the 4 input indicators are still blobs, not dashes.

This can be resolved by deallocating APCPasscodeViewController when PIN entry succeeds, however in the reference implementation in APCAppDelegate this is not the case as it's being retained (https://github.com/ResearchKit/AppCore/blob/master/APCAppCore/APCAppCore/Startup/APCAppDelegate.m#L975).

APCSignInViewController needs updating to APCOnboardingManager

The sign-in view controller still handles many onboarding tasks by itself instead of using the manager, such as posting notifications. It should be updated, especially the signInSuccess method. I would give it a shot but don't have the means to test sign-in.

Nullability warnings on APCPasscodeViewController.h

I'm getting - "Pointer is missing a nullability type specifier (__nonnull or __nullable)" - warnings on the APCPasscodeViewControllerDelegate protocol definition:

  • (void)passcodeViewControllerDidSucceed:(APCPasscodeViewController *)viewController;
  • (void)passcodeViewControllerDidFail:(APCPasscodeViewController *)viewController;

Example App using AppCore

In the ResearchKit, the Chart Module can't filter data by 5 days/ 1 week/ 1 month...
But AppCore can do this, (In APCGraphViewController.m)

So I would like Integrate AppCore into my app,
But I can't put files which relate Dashboard into my app,

My question is, Does is exist example app using AppCore framework?

Consent PDF is wider than view

Re: commit 12b4dfd (Implement onboarding manager)
#49

We see that the consent pdf is wider than the view. May be an issue with css in html file, or some problem with the storyboard.
ios simulator screen shot jul 21 2015 2 04 49 pm

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.