├── README.md
└── TwentyThreeAndMe
├── Assets
├── congratulations_chromosome_blue.imageset
│ ├── Contents.json
│ ├── congratulations_chromosome_blue.png
│ ├── congratulations_chromosome_blue@2x.png
│ └── congratulations_chromosome_blue@3x.png
├── failure_chromosome_purple.imageset
│ ├── Contents.json
│ ├── failure_chromosome_purple.png
│ ├── failure_chromosome_purple@2x.png
│ └── failure_chromosome_purple@3x.png
├── intro_23andMe_logo.imageset
│ ├── Contents.json
│ ├── intro_23andMe_logo.png
│ ├── intro_23andMe_logo@2x.png
│ └── intro_23andMe_logo@3x.png
├── intro_chromosome_green.imageset
│ ├── Contents.json
│ ├── intro_chromosome_green.png
│ ├── intro_chromosome_green@2x.png
│ └── intro_chromosome_green@3x.png
├── intro_chromosome_green_striped.imageset
│ ├── Contents.json
│ ├── intro_chromosome_green_striped.png
│ ├── intro_chromosome_green_striped@2x.png
│ └── intro_chromosome_green_striped@3x.png
└── intro_chromosome_pink.imageset
│ ├── Contents.json
│ ├── intro_chromosome_pink.png
│ ├── intro_chromosome_pink@2x.png
│ └── intro_chromosome_pink@3x.png
├── Common
├── ORKOrderedTask+TwentyThreeAndMe.h
├── ORKOrderedTask+TwentyThreeAndMe.m
├── ORKResult+TwentyThreeAndMe.h
├── ORKResult+TwentyThreeAndMe.m
└── ORKTwentyThreeAndMeDefines.h
├── OtherEdits.txt
├── Steps
├── Complete
│ ├── ORKTwentyThreeAndMeCompleteStep.h
│ ├── ORKTwentyThreeAndMeCompleteStep.m
│ ├── ORKTwentyThreeAndMeCompleteViewController.h
│ ├── ORKTwentyThreeAndMeCompleteViewController.m
│ ├── ORKTwentyThreeAndMeFailureViewController.h
│ ├── ORKTwentyThreeAndMeFailureViewController.m
│ ├── ORKTwentyThreeAndMeSuccessExistingViewController.h
│ ├── ORKTwentyThreeAndMeSuccessExistingViewController.m
│ ├── ORKTwentyThreeAndMeSuccessNewViewController.h
│ └── ORKTwentyThreeAndMeSuccessNewViewController.m
├── Connect
│ ├── ORKTwentyThreeAndMeConnectStep.h
│ ├── ORKTwentyThreeAndMeConnectStep.m
│ ├── ORKTwentyThreeAndMeConnectStepViewController.h
│ └── ORKTwentyThreeAndMeConnectStepViewController.m
└── Intro
│ ├── ORKTwentyThreeAndMeIntroPage1ViewController.h
│ ├── ORKTwentyThreeAndMeIntroPage1ViewController.m
│ ├── ORKTwentyThreeAndMeIntroPage2ViewController.h
│ ├── ORKTwentyThreeAndMeIntroPage2ViewController.m
│ ├── ORKTwentyThreeAndMeIntroPage3ViewController.h
│ ├── ORKTwentyThreeAndMeIntroPage3ViewController.m
│ ├── ORKTwentyThreeAndMeIntroStep.h
│ ├── ORKTwentyThreeAndMeIntroStep.m
│ ├── ORKTwentyThreeAndMeIntroViewController.h
│ └── ORKTwentyThreeAndMeIntroViewController.m
├── Tasks
├── ORKTwentyThreeAndMeConnectTaskViewController.h
└── ORKTwentyThreeAndMeConnectTaskViewController.m
└── UIHelpers
├── UIButton+T23.h
├── UIButton+T23.m
├── UILabel+T23.h
└── UILabel+T23.m
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | # 23andMe ResearchKit Module
4 | Bring genetic data to your ResearchKit-enabled research app with 23andMe.
5 |
6 | **Interested? Contact us at geneticsmodule@23andme.com**
7 |
8 | ## Introduction
9 | Seamlessly incorporate genetic data collection into your ResearchKit-enabled app. With 23andMe's ResearchKit module you can use 23andMe as a source for collecting genetic data from both existing 23andMe customers as well as other individuals who you'd like to sign up for 23andMe.
10 |
11 | 23andMe's ResearchKit module makes it easy to either:
12 | - Request that an existing 23andMe customers agree to share their genetic data with your app
13 | - Have a non-23andMe customer create a 23andMe account and profile, and agree to share their genetic data with your app, when available.
14 |
15 | ### Supported Configurations
16 | #### 23andMe Customer Types
17 | - Existing 23andMe customers only
18 |
19 | This configuration allows existing 23andMe customers to share their genotype data with your research study.
20 | - Existing and new 23andMe customers
21 |
22 | Note that this configuration requires that a researcher has a purchase agreement in place to sponsor the purchase of a 23andMe kit for participants the researcher has deemed eligible.
23 |
24 | #### Contribution of Data
25 | - Contributing genetic data required
26 | - Contributing genetic data optional
27 |
28 | #### Retreival of genetic data
29 | The module is designed to make it simple for you to gain permission to access a 23andMe customer's genetic data. While it will provide you with the credentials necessary to access a customer's data, you will need to use the 23andMe API to retreive any genetic inforamtion. **Unless you have a need for the information in your app, we recommend that you not download genomewide data directly to a participant's phone.**
30 |
31 | ## Getting Started
32 | ### Requirements
33 | - ResearchKit 1.3.0 (has not been tested against other versions)
34 | - iOS Base SDK 8.0+
35 |
36 | ### Contact 23andMe for development environment access
37 | 23andMe has created a development environment for researchers looking to include the 23andMe module in their app. Send an email to geneticsmodule@23andme.com for more information on accessing the development environment.
38 |
39 | If your app will only accept data from existing 23andMe customers, then you may not need access to the development environment. You can create a development API account [here].
40 |
41 | Note that development accounts are limited to 20 users. **You will need to request an API [upgrade] before you release your app.**
42 |
43 | ### Authenticating with the 23andMe API
44 | Once a user has gone through the 23andMe module, the app will return an authorization code that you can exchange for auth & refresh tokens using the 23andMe API. See the [documentation] for additional details.
45 |
46 | ### Retrieving genetic data via the API
47 | - See the [genomes] endpoint documentation for downloading genomewide data
48 | - See the [genotypes] endpoint documentation for retrieving data for selected SNPs
49 |
50 | ## Integrating the 23andMe Module
51 | ### 1. Add the ResearchKit framework to your app
52 |
53 | Follow the instructions posted at the [ResearchKit repo].
54 |
55 | ### 2. Add the 23andMe module to your app's project
56 |
57 | Clone the 23andMe module:
58 | ```bash
59 | git clone https://github.com/23andMe/23andMeResearchKitModule.git
60 | ```
61 | Copy the module inside your ResearchKit project. Copy the "TwentyThreeAndMe" into the ResearchKit project inside of XCode.
62 |
63 | ### 3. Update ResearchKit code
64 |
65 | See the "OtherEdits.txt" file for a summary of the required modifications.
66 |
67 | **Researchkit.h**
68 | Don't forget that when you add the following files to your project, they must have target membership set to "public"
69 | ```objc
70 | #import
71 | #import
72 | ```
73 |
74 | **Researchkit.private**
75 | Don't forget that when you add the following files to your project, they must have target membership set to "private"
76 | ```objc
77 | #import
78 | #import
79 | ```
80 |
81 | **Researchkit.strings - English**
82 | ```objc
83 | /* 23andMe connect task. */
84 | "TWENTYTHREEANDME_DECLINE_PROMPT_DETAILS" = "Are you sure you want to decline adding your genetic data to %@? Declining may impact your eligibility for this study";
85 | "TWENTYTHREEANDME_DECLINE_PROMPT_ACTION_DECLINE" = "Decline";
86 | "TWENTYTHREEANDME_DECLINE_PROMPT_ACTION_CANCEL" = "Cancel";
87 |
88 | "TWENTYTHREEANDME_INTRO_MAIN_SHARE" = "Add Genetic Data";
89 | "TWENTYTHREEANDME_INTRO_MAIN_DECLINE" = "Decline";
90 |
91 | "TWENTYTHREEANDME_INTRO_1_DESCRIPTION" = "%@ has selected 23andMe to collect genetic data for the %@ study";
92 |
93 | "TWENTYTHREEANDME_INTRO_2_TITLE" = "About this study";
94 | "TWENTYTHREEANDME_INTRO_2_ABOUT_REQUIRED" = "Contributing your genetic data is required for participation in the %@ study. You will need to authorize 23andMe to share that data with %@";
95 | "TWENTYTHREEANDME_INTRO_2_ABOUT_OPTIONAL" = "In order to contribute your genetic data to the %@ study, you will need to authorize 23andMe to share that data with %@";
96 | "TWENTYTHREEANDME_INTRO_2_ELIGIBILITY_HEADER" = "Eligibility";
97 | "TWENTYTHREEANDME_INTRO_2_ELIGIBILITY_EXISTING" = "• Existing 23andMe users";
98 | "TWENTYTHREEANDME_INTRO_2_ELIGIBILITY_NEW" = "• Individuals who agree to receive the 23andMe Personal Genome Service at no cost";
99 |
100 | "TWENTYTHREEANDME_INTRO_3_TITLE" = "About 23andMe";
101 | "TWENTYTHREEANDME_INTRO_3_MISSION" = "23andMe is a genetic service available directly to U.S. customers that includes reports that meet FDA standards for being scientifically and clinically valid. 23andMe helps people understand what’s in their DNA. The 23andMe Personal Genome Service includes more than 60 personalized genetic health, trait and ancestry reports.";
102 | "TWENTYTHREEANDME_INTRO_3_LEARN_MORE" = "Learn more about 23andMe";
103 | "TWENTYTHREEANDME_INTRO_3_QUESTIONS" = "Questions?";
104 | "TWENTYTHREEANDME_INTRO_3_CONTACT" = "Contact %@";
105 |
106 | "TWENTYTHREEANDME_COMPLETE_TITLE" = "Congratulations";
107 | "TWENTYTHREEANDME_COMPLETE_DONE_BUTTON" = "Done";
108 | "TWENTYTHREEANDME_COMPLETE_EXISTING_DETAIL" = "Congratulations, you’ve successfully enrolled in %@. %@ is now authorized to access your genetic data.";
109 | "TWENTYTHREEANDME_COMPLETE_NEW_DETAIL" = "Congratulations, you’ve successfully enrolled in %@. %@ is now authorized to access your genetic data.";
110 | "TWENTYTHREEANDME_COMPLETE_NEW_NEXT_STEP" = "Next steps";
111 | "TWENTYTHREEANDME_COMPLETE_NEW_NEXT_STEP_DETAIL" = "23andMe will mail you a saliva collection kit. Simply follow the instructions included with the kit, mail the sample back, and we will notify you when your reports are ready.";
112 |
113 | "TWENTYTHREEANDME_FAILURE_TITLE" = "Try again";
114 | "TWENTYTHREEANDME_FAILURE_DESCRIPTION" = "Sorry, we weren’t able to enroll you in the genetic component of %@. Please try again, or contact %@ if you have any questions.";
115 | "TWENTYTHREEANDME_FAILURE_CONTACT" = "Contact %@";
116 | "TWENTYTHREEANDME_FAILURE_TRY_AGAIN_BUTTON" = "Try again";
117 | "TWENTYTHREEANDME_FAILURE_DECLINE_BUTTON" = "Decline";
118 | ```
119 | ### 4. Add image assets
120 |
121 | The 23andMe module includes a series of assets used to incorporate 23andMe's look and feel. In order to include those in your app, create a "TwentyThreeAndMe" folder inside of the "Artwork.xcassets" item in your project's copy of ResearchKit. Then, copy the contents of the /Assets folder into the folder you've just created.
122 |
123 | ### 5. Present the 23andMe Connect Task
124 |
125 | In the view controller where you want to present the connect to 23andMe task and receive a user's permission to access her data, include the ResearchKit libraries and set a delegate to receive the task's response:
126 | ```objc
127 | #import
128 |
129 | @interface UIViewController ()
130 | ```
131 | Create the 23andMe task's view controller with the following method:
132 | ```objc
133 | ORKTwentyThreeAndMeConnectTaskViewController *ttamTaskVC =
134 | [ORKTwentyThreeAndMeConnectTaskViewController twentyThreeAndMeTaskViewControllerWithIdentifier:@"connectWithTTAM"
135 | allowedUserMode:ORKTwentyThreeAndMeAllowedUserModeExistingAndNew
136 | studyDependency:ORKTwentyThreeAndMeStudyDependencyRequired
137 | authClientId:@""
138 | authClientSecret:@""
139 | authScopes:@"basic genomes"
140 | investigatorDisplayName:@"name"
141 | studyDisplayName:@"study_name"
142 | studyContactEmail:@"my_email@email.com"
143 | baseURLOverride:nil];
144 | ```
145 |
146 | #### Parameters:
147 |
148 | **allowedUserMode**: Either ```ORKTwentyThreeAndMeAllowedUserModeExistingAndNew``` or ```ORKTwentyThreeAndMeAllowedUserModeExistingOnly```.
149 |
150 | **studyDependency**: Either ```ORKTwentyThreeAndMeStudyDependencyRequired``` or ```ORKTwentyThreeAndMeStudyDependencyOptional```.
151 |
152 | **authClientId**: 23andMe API OAuth client ID
153 |
154 | **authClientSecret**: 23andMe API OAuth client secret
155 |
156 | **authScopes**: Space-seperated list of scopes to request from the 23andMe API. See the list of [scopes] for details on what scopes to request.
157 |
158 | **investigatorDisplayName**: User-facing investigator name.
159 |
160 | **studyDisplayName**: User-facing study name.
161 |
162 | **studyContactEmail**: User-facing contact email address.
163 |
164 | **baseURLOverride**: Either ```nil``` or a URL to override the default 23andMe API URL. Use this override URL to access the sandbox environment. For access to the sandbox environment, contact us at geneticsmodule@23andme.com
165 |
166 | #### Set the delegate and present the 23andMe view controller:
167 | ```objc
168 | ttamTaskVC.twentyThreeAndMeConnectDelegate = self;
169 |
170 | [self presentViewController:ttamTaskVC animated:NO completion:nil];
171 | ```
172 | ### 6. Implement the delegate method to receive a response
173 |
174 | ```objc
175 | - (void)twentyThreeAndMeConnectTaskViewController:(ORKTwentyThreeAndMeConnectTaskViewController *)twentyThreeAndMeConnectTaskViewController
176 | didFinishWithResults:(NSDictionary *)results
177 | error:(nullable NSError *)error
178 | ```
179 | The ```results``` dictionary contains:
180 |
181 | **completionType**: If the user successfully auth'd (and, for new 23andMe users, created an account) this will be set to ```success```. Otherwise, this will be set to ```cancelled```.
182 |
183 | **authToken**: 23andMe Auth Token for the user's 23andMe profile. Only set if ```completionType == success```.
184 |
185 | **refreshToken**: 23andMe Refresh Token for the user's 23andMe profile. Only set if ```completionType == success```.
186 |
187 | On access and refresh tokens:
188 | >Access tokens expire after 1 day. If you need to access a user's data past that, you can request another token using the last ```refresh_token``` that you were issued. Using the refresh token means you don't have to send the user through the "Accept" screen all over again. Requesting a new token set will invalidate your old ```refresh_token```. Be sure to specify the full scope when requesting a new access token.
189 |
190 | #### 7. Use the 23andMe API to retrieve user data
191 | Once you've retrieved an access token, you can use the API to access the information that the user agreed to share with you as it is available. _Access tokens retrieved via the 23andMe ResearchKit module are only valid for individual profiles, so be sure to keep track of the profile ID that's associated with the token._
192 |
193 | ## Questions?
194 | **Questions about 23andMe, the 23andMe API, or interested in setting up a project with us?** Contact us at geneticsmodule@23andme.com.
195 |
196 | **See something in our code or documentation?** Create an issue on GitHub and we'll take a look.
197 |
198 | # License
199 | The source in the _23andMeResearchKitModule_ repository is made available under the following license unless another license is explicitly identified:
200 | ```
201 | Copyright (c) 2016, 23andMe, Inc. All rights reserved.
202 |
203 | Redistribution and use in source and binary forms, with or without modification,
204 | are permitted provided that the following conditions are met:
205 |
206 | 1. Redistributions of source code must retain the above copyright notice, this
207 | list of conditions and the following disclaimer.
208 |
209 | 2. Redistributions in binary form must reproduce the above copyright notice,
210 | this list of conditions and the following disclaimer in the documentation and/or
211 | other materials provided with the distribution.
212 |
213 | 3. Neither the name of the copyright holder(s) nor the names of any contributors
214 | may be used to endorse or promote products derived from this software without
215 | specific prior written permission. No license is granted to the trademarks of
216 | the copyright holders even if such marks are included in this software.
217 |
218 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
219 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
220 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
221 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
222 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
223 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
224 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
225 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
226 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
227 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
228 | ```
229 |
230 | [documentation]: https://api.23andme.com/docs/authentication/
231 | [genomes]: https://api.23andme.com/docs/reference/#genomes
232 | [genotypes]: https://api.23andme.com/docs/reference/#genotypes
233 | [here]: https://api.23andme.com/
234 | [upgrade]: https://api.23andme.com/overview/
235 | [ResearchKit repo]: https://github.com/researchkit/researchkit#adding-the-researchkit-framework-to-your-app
236 | [scopes]: https://api.23andme.com/docs/authentication/#scopes
237 |
--------------------------------------------------------------------------------
/TwentyThreeAndMe/Assets/congratulations_chromosome_blue.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "congratulations_chromosome_blue.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "congratulations_chromosome_blue@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "congratulations_chromosome_blue@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/TwentyThreeAndMe/Assets/congratulations_chromosome_blue.imageset/congratulations_chromosome_blue.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/23andMe/23andMeResearchKitModule/9c7a0b2be813607b83991b20616fdfcffda7083b/TwentyThreeAndMe/Assets/congratulations_chromosome_blue.imageset/congratulations_chromosome_blue.png
--------------------------------------------------------------------------------
/TwentyThreeAndMe/Assets/congratulations_chromosome_blue.imageset/congratulations_chromosome_blue@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/23andMe/23andMeResearchKitModule/9c7a0b2be813607b83991b20616fdfcffda7083b/TwentyThreeAndMe/Assets/congratulations_chromosome_blue.imageset/congratulations_chromosome_blue@2x.png
--------------------------------------------------------------------------------
/TwentyThreeAndMe/Assets/congratulations_chromosome_blue.imageset/congratulations_chromosome_blue@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/23andMe/23andMeResearchKitModule/9c7a0b2be813607b83991b20616fdfcffda7083b/TwentyThreeAndMe/Assets/congratulations_chromosome_blue.imageset/congratulations_chromosome_blue@3x.png
--------------------------------------------------------------------------------
/TwentyThreeAndMe/Assets/failure_chromosome_purple.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "failure_chromosome_purple.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "failure_chromosome_purple@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "failure_chromosome_purple@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/TwentyThreeAndMe/Assets/failure_chromosome_purple.imageset/failure_chromosome_purple.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/23andMe/23andMeResearchKitModule/9c7a0b2be813607b83991b20616fdfcffda7083b/TwentyThreeAndMe/Assets/failure_chromosome_purple.imageset/failure_chromosome_purple.png
--------------------------------------------------------------------------------
/TwentyThreeAndMe/Assets/failure_chromosome_purple.imageset/failure_chromosome_purple@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/23andMe/23andMeResearchKitModule/9c7a0b2be813607b83991b20616fdfcffda7083b/TwentyThreeAndMe/Assets/failure_chromosome_purple.imageset/failure_chromosome_purple@2x.png
--------------------------------------------------------------------------------
/TwentyThreeAndMe/Assets/failure_chromosome_purple.imageset/failure_chromosome_purple@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/23andMe/23andMeResearchKitModule/9c7a0b2be813607b83991b20616fdfcffda7083b/TwentyThreeAndMe/Assets/failure_chromosome_purple.imageset/failure_chromosome_purple@3x.png
--------------------------------------------------------------------------------
/TwentyThreeAndMe/Assets/intro_23andMe_logo.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "intro_23andMe_logo.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "intro_23andMe_logo@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "intro_23andMe_logo@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/TwentyThreeAndMe/Assets/intro_23andMe_logo.imageset/intro_23andMe_logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/23andMe/23andMeResearchKitModule/9c7a0b2be813607b83991b20616fdfcffda7083b/TwentyThreeAndMe/Assets/intro_23andMe_logo.imageset/intro_23andMe_logo.png
--------------------------------------------------------------------------------
/TwentyThreeAndMe/Assets/intro_23andMe_logo.imageset/intro_23andMe_logo@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/23andMe/23andMeResearchKitModule/9c7a0b2be813607b83991b20616fdfcffda7083b/TwentyThreeAndMe/Assets/intro_23andMe_logo.imageset/intro_23andMe_logo@2x.png
--------------------------------------------------------------------------------
/TwentyThreeAndMe/Assets/intro_23andMe_logo.imageset/intro_23andMe_logo@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/23andMe/23andMeResearchKitModule/9c7a0b2be813607b83991b20616fdfcffda7083b/TwentyThreeAndMe/Assets/intro_23andMe_logo.imageset/intro_23andMe_logo@3x.png
--------------------------------------------------------------------------------
/TwentyThreeAndMe/Assets/intro_chromosome_green.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "intro_chromosome_green.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "intro_chromosome_green@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "intro_chromosome_green@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/TwentyThreeAndMe/Assets/intro_chromosome_green.imageset/intro_chromosome_green.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/23andMe/23andMeResearchKitModule/9c7a0b2be813607b83991b20616fdfcffda7083b/TwentyThreeAndMe/Assets/intro_chromosome_green.imageset/intro_chromosome_green.png
--------------------------------------------------------------------------------
/TwentyThreeAndMe/Assets/intro_chromosome_green.imageset/intro_chromosome_green@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/23andMe/23andMeResearchKitModule/9c7a0b2be813607b83991b20616fdfcffda7083b/TwentyThreeAndMe/Assets/intro_chromosome_green.imageset/intro_chromosome_green@2x.png
--------------------------------------------------------------------------------
/TwentyThreeAndMe/Assets/intro_chromosome_green.imageset/intro_chromosome_green@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/23andMe/23andMeResearchKitModule/9c7a0b2be813607b83991b20616fdfcffda7083b/TwentyThreeAndMe/Assets/intro_chromosome_green.imageset/intro_chromosome_green@3x.png
--------------------------------------------------------------------------------
/TwentyThreeAndMe/Assets/intro_chromosome_green_striped.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "intro_chromosome_green_striped.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "intro_chromosome_green_striped@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "intro_chromosome_green_striped@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/TwentyThreeAndMe/Assets/intro_chromosome_green_striped.imageset/intro_chromosome_green_striped.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/23andMe/23andMeResearchKitModule/9c7a0b2be813607b83991b20616fdfcffda7083b/TwentyThreeAndMe/Assets/intro_chromosome_green_striped.imageset/intro_chromosome_green_striped.png
--------------------------------------------------------------------------------
/TwentyThreeAndMe/Assets/intro_chromosome_green_striped.imageset/intro_chromosome_green_striped@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/23andMe/23andMeResearchKitModule/9c7a0b2be813607b83991b20616fdfcffda7083b/TwentyThreeAndMe/Assets/intro_chromosome_green_striped.imageset/intro_chromosome_green_striped@2x.png
--------------------------------------------------------------------------------
/TwentyThreeAndMe/Assets/intro_chromosome_green_striped.imageset/intro_chromosome_green_striped@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/23andMe/23andMeResearchKitModule/9c7a0b2be813607b83991b20616fdfcffda7083b/TwentyThreeAndMe/Assets/intro_chromosome_green_striped.imageset/intro_chromosome_green_striped@3x.png
--------------------------------------------------------------------------------
/TwentyThreeAndMe/Assets/intro_chromosome_pink.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "intro_chromosome_pink.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "intro_chromosome_pink@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "intro_chromosome_pink@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/TwentyThreeAndMe/Assets/intro_chromosome_pink.imageset/intro_chromosome_pink.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/23andMe/23andMeResearchKitModule/9c7a0b2be813607b83991b20616fdfcffda7083b/TwentyThreeAndMe/Assets/intro_chromosome_pink.imageset/intro_chromosome_pink.png
--------------------------------------------------------------------------------
/TwentyThreeAndMe/Assets/intro_chromosome_pink.imageset/intro_chromosome_pink@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/23andMe/23andMeResearchKitModule/9c7a0b2be813607b83991b20616fdfcffda7083b/TwentyThreeAndMe/Assets/intro_chromosome_pink.imageset/intro_chromosome_pink@2x.png
--------------------------------------------------------------------------------
/TwentyThreeAndMe/Assets/intro_chromosome_pink.imageset/intro_chromosome_pink@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/23andMe/23andMeResearchKitModule/9c7a0b2be813607b83991b20616fdfcffda7083b/TwentyThreeAndMe/Assets/intro_chromosome_pink.imageset/intro_chromosome_pink@3x.png
--------------------------------------------------------------------------------
/TwentyThreeAndMe/Common/ORKOrderedTask+TwentyThreeAndMe.h:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2016, 23andMe, Inc. All rights reserved.
3 |
4 | Redistribution and use in source and binary forms, with or without modification,
5 | are permitted provided that the following conditions are met:
6 |
7 | 1. Redistributions of source code must retain the above copyright notice, this
8 | list of conditions and the following disclaimer.
9 |
10 | 2. Redistributions in binary form must reproduce the above copyright notice,
11 | this list of conditions and the following disclaimer in the documentation and/or
12 | other materials provided with the distribution.
13 |
14 | 3. Neither the name of the copyright holder(s) nor the names of any contributors
15 | may be used to endorse or promote products derived from this software without
16 | specific prior written permission. No license is granted to the trademarks of
17 | the copyright holders even if such marks are included in this software.
18 |
19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
23 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 | */
30 |
31 | #import
32 |
33 | NS_ASSUME_NONNULL_BEGIN
34 |
35 | @interface ORKOrderedTask (TwentyThreeAndMe)
36 |
37 | /**
38 | * Returns a predefined task that connects a participant with 23andMe
39 | *
40 | * @param identifier The task identifier to use for this task, appropriate to the study.
41 | * @param allowedUserMode Identify the type of users to allow for the module
42 | * @param studyDependency Whether the study requires the module to be succesfully completed. Changes flow/text.
43 | * @param clientId oauth client id
44 | * @param clientSecret oauth client secret
45 | * @param scopes oauth scopes string (will be url encoded)
46 | * @param investigatorDisplayName User facing investigator name
47 | * @param studyDisplayName User facing study name
48 | * @param studyContactEmail Study contact email used in module
49 | * @param baseURLOverride Optional override for connection URL.
50 | *
51 | * @return ORKOrderedTask
52 | */
53 | + (ORKOrderedTask *)twentyThreeAndMeTaskWithIdentifier:(NSString *)identifier
54 | allowedUserMode:(ORKTwentyThreeAndMeAllowedUserMode)allowedUserMode
55 | studyDependency:(ORKTwentyThreeAndMeStudyDependency)studyDependency
56 | authClientId:(NSString *)clientId
57 | authClientSecret:(NSString *)clientSecret
58 | authScopes:(NSString *)scopes
59 | investigatorDisplayName:(NSString *)investigatorDisplayName
60 | studyDisplayName:(NSString *)studyDisplayName
61 | studyContactEmail:(NSString *)studyContactEmail
62 | baseURLOverride:(nullable NSString *)baseURLOverride;
63 |
64 | @end
65 |
66 | NS_ASSUME_NONNULL_END
67 |
--------------------------------------------------------------------------------
/TwentyThreeAndMe/Common/ORKOrderedTask+TwentyThreeAndMe.m:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2016, 23andMe, Inc. All rights reserved.
3 |
4 | Redistribution and use in source and binary forms, with or without modification,
5 | are permitted provided that the following conditions are met:
6 |
7 | 1. Redistributions of source code must retain the above copyright notice, this
8 | list of conditions and the following disclaimer.
9 |
10 | 2. Redistributions in binary form must reproduce the above copyright notice,
11 | this list of conditions and the following disclaimer in the documentation and/or
12 | other materials provided with the distribution.
13 |
14 | 3. Neither the name of the copyright holder(s) nor the names of any contributors
15 | may be used to endorse or promote products derived from this software without
16 | specific prior written permission. No license is granted to the trademarks of
17 | the copyright holders even if such marks are included in this software.
18 |
19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
23 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 | */
30 |
31 | #import "ORKOrderedTask+TwentyThreeAndMe.h"
32 |
33 | #import "ORKTwentyThreeAndMeIntroStep.h"
34 | #import "ORKTwentyThreeAndMeConnectStep.h"
35 | #import "ORKTwentyThreeAndMeCompleteStep.h"
36 |
37 | @implementation ORKOrderedTask (TwentyThreeAndMe)
38 |
39 | NSString * const ORKTwentyThreeAndMeIntroStepIdentifier = @"twentyThreeAndMe.intro";
40 | NSString * const ORKTwentyThreeAndMeConnectStepIdentifier = @"twentyThreeAndMe.connect";
41 | NSString * const ORKTwentyThreeAndMeCompleteStepIdentifier = @"twentyThreeAndMe.complete";
42 |
43 | + (ORKOrderedTask *)twentyThreeAndMeTaskWithIdentifier:(NSString *)identifier
44 | allowedUserMode:(ORKTwentyThreeAndMeAllowedUserMode)allowedUserMode
45 | studyDependency:(ORKTwentyThreeAndMeStudyDependency)studyDependency
46 | authClientId:(NSString *)clientId
47 | authClientSecret:(NSString *)clientSecret
48 | authScopes:(NSString *)scopes
49 | investigatorDisplayName:(NSString *)investigatorDisplayName
50 | studyDisplayName:(NSString *)studyDisplayName
51 | studyContactEmail:(NSString *)studyContactEmail
52 | baseURLOverride:(nullable NSString *)baseURLOverride
53 | {
54 | NSMutableArray *steps = [NSMutableArray array];
55 |
56 | {
57 | ORKTwentyThreeAndMeIntroStep *step = [[ORKTwentyThreeAndMeIntroStep alloc] initWithIdentifier:ORKTwentyThreeAndMeIntroStepIdentifier];
58 | step.investigatorDisplayName = investigatorDisplayName;
59 | step.studyDisplayName = studyDisplayName;
60 | step.studyContactEmail = studyContactEmail;
61 | step.allowedUserMode = allowedUserMode;
62 | step.studyDependency = studyDependency;
63 | ORKStepArrayAddStep(steps, step);
64 | }
65 |
66 | {
67 | ORKTwentyThreeAndMeConnectStep *step = [[ORKTwentyThreeAndMeConnectStep alloc] initWithIdentifier:ORKTwentyThreeAndMeConnectStepIdentifier];
68 | step.baseURL = baseURLOverride ? baseURLOverride : @"https://api.23andme.com";
69 | step.redirectURI = @"http://localhost:5000/receive_code/&response_type=code";
70 | step.clientId = clientId;
71 | step.clientSecret = clientSecret;
72 | step.scopes = [scopes stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
73 | step.studyDisplayNameParam = [studyDisplayName stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];;
74 | step.allowedUserMode = allowedUserMode;
75 | ORKStepArrayAddStep(steps, step);
76 | }
77 |
78 | {
79 | ORKTwentyThreeAndMeCompleteStep *step = [[ORKTwentyThreeAndMeCompleteStep alloc] initWithIdentifier:ORKTwentyThreeAndMeCompleteStepIdentifier];
80 | step.studyDisplayName = studyDisplayName;
81 | step.studyContactEmail = studyContactEmail;
82 | step.allowedUserMode = allowedUserMode;
83 | ORKStepArrayAddStep(steps, step);
84 | }
85 |
86 | ORKOrderedTask *task = [[ORKOrderedTask alloc] initWithIdentifier:identifier steps:steps];
87 |
88 | return task;
89 | }
90 |
91 | @end
92 |
--------------------------------------------------------------------------------
/TwentyThreeAndMe/Common/ORKResult+TwentyThreeAndMe.h:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2016, 23andMe, Inc. All rights reserved.
3 |
4 | Redistribution and use in source and binary forms, with or without modification,
5 | are permitted provided that the following conditions are met:
6 |
7 | 1. Redistributions of source code must retain the above copyright notice, this
8 | list of conditions and the following disclaimer.
9 |
10 | 2. Redistributions in binary form must reproduce the above copyright notice,
11 | this list of conditions and the following disclaimer in the documentation and/or
12 | other materials provided with the distribution.
13 |
14 | 3. Neither the name of the copyright holder(s) nor the names of any contributors
15 | may be used to endorse or promote products derived from this software without
16 | specific prior written permission. No license is granted to the trademarks of
17 | the copyright holders even if such marks are included in this software.
18 |
19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
23 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 | */
30 |
31 | #import
32 |
33 | NS_ASSUME_NONNULL_BEGIN
34 |
35 | @class ORKTwentyThreeAndMeConnectResult;
36 |
37 | /**
38 | The 'ORKTwentyThreeAndMeConnectResult' class represents the results of the 23andMe signup connection step.
39 |
40 | AuthToken and RefreshToken are generated at the end of generation. Failed flow results will
41 | not contain these.
42 |
43 | newUserFlow is YES when this step finished using the new user flow. NO otherwise.
44 | */
45 | ORK_CLASS_AVAILABLE
46 | @interface ORKTwentyThreeAndMeConnectResult : ORKResult
47 |
48 | /**
49 | * Auth Token from oauth with 23andMe
50 | */
51 | @property (nonatomic, copy, nullable) NSString *authToken;
52 |
53 | /**
54 | * Refresh Token from oauth with 23andMe
55 | */
56 | @property (nonatomic, copy, nullable) NSString *refreshToken;
57 |
58 | /**
59 | * Whether the new customer flow was used to generate the tokens above.
60 | */
61 | @property (nonatomic) BOOL newUserFlow;
62 |
63 | @end
64 |
65 | NS_ASSUME_NONNULL_END
66 |
--------------------------------------------------------------------------------
/TwentyThreeAndMe/Common/ORKResult+TwentyThreeAndMe.m:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2016, 23andMe, Inc. All rights reserved.
3 |
4 | Redistribution and use in source and binary forms, with or without modification,
5 | are permitted provided that the following conditions are met:
6 |
7 | 1. Redistributions of source code must retain the above copyright notice, this
8 | list of conditions and the following disclaimer.
9 |
10 | 2. Redistributions in binary form must reproduce the above copyright notice,
11 | this list of conditions and the following disclaimer in the documentation and/or
12 | other materials provided with the distribution.
13 |
14 | 3. Neither the name of the copyright holder(s) nor the names of any contributors
15 | may be used to endorse or promote products derived from this software without
16 | specific prior written permission. No license is granted to the trademarks of
17 | the copyright holders even if such marks are included in this software.
18 |
19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
23 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 | */
30 |
31 | #import "ORKResult+TwentyThreeAndMe.h"
32 |
33 | #import "ORKHelpers.h"
34 |
35 | @implementation ORKTwentyThreeAndMeConnectResult
36 |
37 | + (BOOL)supportsSecureCoding {
38 | return YES;
39 | }
40 |
41 | - (void)encodeWithCoder:(NSCoder *)aCoder {
42 | ORK_ENCODE_OBJ(aCoder, authToken);
43 | }
44 |
45 | - (instancetype)initWithCoder:(NSCoder *)aDecoder {
46 | self = [super init];
47 | if (self) {
48 | ORK_DECODE_OBJ_CLASS(aDecoder, authToken, NSString);
49 | }
50 | return self;
51 | }
52 |
53 | - (BOOL)isEqual:(id)object {
54 | BOOL isParentSame = [super isEqual:object];
55 |
56 | __typeof(self) castObject = object;
57 | return (isParentSame &&
58 | ORKEqualObjects(self.authToken, castObject.authToken));
59 | }
60 |
61 | - (instancetype)copyWithZone:(NSZone *)zone {
62 | ORKTwentyThreeAndMeConnectResult *result = [super copyWithZone:zone];
63 | result.authToken = [self.authToken copy];
64 | return result;
65 | }
66 |
67 | - (NSString *)description {
68 | return [NSString stringWithFormat:@"%@ %@", [super description], self.authToken];
69 | }
70 |
71 | @end
72 |
--------------------------------------------------------------------------------
/TwentyThreeAndMe/Common/ORKTwentyThreeAndMeDefines.h:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2016, 23andMe, Inc. All rights reserved.
3 |
4 | Redistribution and use in source and binary forms, with or without modification,
5 | are permitted provided that the following conditions are met:
6 |
7 | 1. Redistributions of source code must retain the above copyright notice, this
8 | list of conditions and the following disclaimer.
9 |
10 | 2. Redistributions in binary form must reproduce the above copyright notice,
11 | this list of conditions and the following disclaimer in the documentation and/or
12 | other materials provided with the distribution.
13 |
14 | 3. Neither the name of the copyright holder(s) nor the names of any contributors
15 | may be used to endorse or promote products derived from this software without
16 | specific prior written permission. No license is granted to the trademarks of
17 | the copyright holders even if such marks are included in this software.
18 |
19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
23 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 | */
30 |
31 | #import
32 |
33 | #ifndef ORKTwentyThreeAndMeDefines_h
34 | #define ORKTwentyThreeAndMeDefines_h
35 |
36 | /**
37 | Identify what type of users should be serviced by this module
38 | */
39 | typedef NS_ENUM(NSInteger, ORKTwentyThreeAndMeAllowedUserMode) {
40 | /// Existing 23andMe customers only
41 | ORKTwentyThreeAndMeAllowedUserModeExistingOnly,
42 |
43 | /// Existing 23andMe customers, and new customers who will receive kits furnished by the study.
44 | ORKTwentyThreeAndMeAllowedUserModeExistingAndNew,
45 | } ORK_ENUM_AVAILABLE;
46 |
47 | /**
48 | Identify whether completion of the module successfully is required for participation in the study
49 | */
50 | typedef NS_ENUM(NSInteger, ORKTwentyThreeAndMeStudyDependency) {
51 | /// Successful completion is required
52 | ORKTwentyThreeAndMeStudyDependencyRequired,
53 |
54 | /// Successful completion is optional
55 | ORKTwentyThreeAndMeStudyDependencyOptional,
56 | } ORK_ENUM_AVAILABLE;
57 |
58 |
59 | #endif /* ORKTwentyThreeAndMeDefines_h */
60 |
--------------------------------------------------------------------------------
/TwentyThreeAndMe/OtherEdits.txt:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2016, 23andMe, Inc. All rights reserved.
3 |
4 | Redistribution and use in source and binary forms, with or without modification,
5 | are permitted provided that the following conditions are met:
6 |
7 | 1. Redistributions of source code must retain the above copyright notice, this
8 | list of conditions and the following disclaimer.
9 |
10 | 2. Redistributions in binary form must reproduce the above copyright notice,
11 | this list of conditions and the following disclaimer in the documentation and/or
12 | other materials provided with the distribution.
13 |
14 | 3. Neither the name of the copyright holder(s) nor the names of any contributors
15 | may be used to endorse or promote products derived from this software without
16 | specific prior written permission. No license is granted to the trademarks of
17 | the copyright holders even if such marks are included in this software.
18 |
19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
23 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 | */
30 |
31 |
32 | /**
33 | * Add to ResearchKit.strings - English
34 | */
35 |
36 | /* 23andMe connect task. */
37 | "TWENTYTHREEANDME_DECLINE_PROMPT_DETAILS" = "Are you sure you want to decline adding your genetic data to %@? Declining may impact your eligibility for this study";
38 | "TWENTYTHREEANDME_DECLINE_PROMPT_ACTION_DECLINE" = "Decline";
39 | "TWENTYTHREEANDME_DECLINE_PROMPT_ACTION_CANCEL" = "Cancel";
40 |
41 | "TWENTYTHREEANDME_INTRO_MAIN_SHARE" = "Add Genetic Data";
42 | "TWENTYTHREEANDME_INTRO_MAIN_DECLINE" = "Decline";
43 |
44 | "TWENTYTHREEANDME_INTRO_1_DESCRIPTION" = "%@ has selected 23andMe to collect genetic data for the %@ study";
45 |
46 | "TWENTYTHREEANDME_INTRO_2_TITLE" = "About this study";
47 | "TWENTYTHREEANDME_INTRO_2_ABOUT_REQUIRED" = "Contributing your genetic data is required for participation in the %@ study. You will need to authorize 23andMe to share that data with %@";
48 | "TWENTYTHREEANDME_INTRO_2_ABOUT_OPTIONAL" = "In order to contribute your genetic data to the %@ study, you will need to authorize 23andMe to share that data with %@";
49 | "TWENTYTHREEANDME_INTRO_2_ELIGIBILITY_HEADER" = "Eligibility";
50 | "TWENTYTHREEANDME_INTRO_2_ELIGIBILITY_EXISTING" = "• Existing 23andMe users";
51 | "TWENTYTHREEANDME_INTRO_2_ELIGIBILITY_NEW" = "• Individuals who agree to receive the 23andMe Personal Genome Service at no cost";
52 |
53 | "TWENTYTHREEANDME_INTRO_3_TITLE" = "About 23andMe";
54 | "TWENTYTHREEANDME_INTRO_3_MISSION" = "23andMe is a genetic service available directly to U.S. customers that includes reports that meet FDA standards for being scientifically and clinically valid. 23andMe helps people understand what’s in their DNA. The 23andMe Personal Genome Service includes more than 60 personalized genetic health, trait and ancestry reports.";
55 | "TWENTYTHREEANDME_INTRO_3_LEARN_MORE" = "Learn more about 23andMe";
56 | "TWENTYTHREEANDME_INTRO_3_QUESTIONS" = "Questions?";
57 | "TWENTYTHREEANDME_INTRO_3_CONTACT" = "Contact %@";
58 |
59 | "TWENTYTHREEANDME_COMPLETE_TITLE" = "Congratulations";
60 | "TWENTYTHREEANDME_COMPLETE_DONE_BUTTON" = "Done";
61 | "TWENTYTHREEANDME_COMPLETE_EXISTING_DETAIL" = "Congratulations, you’ve successfully enrolled in %@. %@ is now authorized to access your genetic data.";
62 | "TWENTYTHREEANDME_COMPLETE_NEW_DETAIL" = "Congratulations, you’ve successfully enrolled in %@. %@ is now authorized to access your genetic data.";
63 | "TWENTYTHREEANDME_COMPLETE_NEW_NEXT_STEP" = "Next steps";
64 | "TWENTYTHREEANDME_COMPLETE_NEW_NEXT_STEP_DETAIL" = "23andMe will mail you a saliva collection kit. Simply follow the instructions included with the kit, mail the sample back, and we will notify you when your reports are ready.";
65 |
66 | "TWENTYTHREEANDME_FAILURE_TITLE" = "Try again";
67 | "TWENTYTHREEANDME_FAILURE_DESCRIPTION" = "Sorry, we weren’t able to enroll you in the genetic component of %@. Please try again, or contact %@ if you have any questions.";
68 | "TWENTYTHREEANDME_FAILURE_CONTACT" = "Contact %@";
69 | "TWENTYTHREEANDME_FAILURE_TRY_AGAIN_BUTTON" = "Try again";
70 | "TWENTYTHREEANDME_FAILURE_DECLINE_BUTTON" = "Decline";
71 |
72 | /**
73 | * Add to ResearchKit.h
74 | *
75 | * Don't forget that when you add the following files to your project, they must have target
76 | * membership set to "public"
77 | */
78 |
79 | #import
80 | #import
81 |
82 | /**
83 | * Add to ResearchKit_Private.h
84 | *
85 | * Don't forget that when you add the following files to your project, they must have target
86 | * membership set to "private"
87 | */
88 |
89 | #import
90 | #import
--------------------------------------------------------------------------------
/TwentyThreeAndMe/Steps/Complete/ORKTwentyThreeAndMeCompleteStep.h:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2016, 23andMe, Inc. All rights reserved.
3 |
4 | Redistribution and use in source and binary forms, with or without modification,
5 | are permitted provided that the following conditions are met:
6 |
7 | 1. Redistributions of source code must retain the above copyright notice, this
8 | list of conditions and the following disclaimer.
9 |
10 | 2. Redistributions in binary form must reproduce the above copyright notice,
11 | this list of conditions and the following disclaimer in the documentation and/or
12 | other materials provided with the distribution.
13 |
14 | 3. Neither the name of the copyright holder(s) nor the names of any contributors
15 | may be used to endorse or promote products derived from this software without
16 | specific prior written permission. No license is granted to the trademarks of
17 | the copyright holders even if such marks are included in this software.
18 |
19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
23 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 | */
30 |
31 | #import
32 |
33 | ORK_CLASS_AVAILABLE
34 | @interface ORKTwentyThreeAndMeCompleteStep : ORKStep
35 |
36 | /**
37 | * The display name of the study
38 | */
39 | @property (nonatomic, copy, nullable) NSString *studyDisplayName;
40 |
41 | /**
42 | * The contact email for the study
43 | */
44 | @property (nonatomic, copy, nullable) NSString *studyContactEmail;
45 |
46 | /**
47 | * Allowed User Mode for the module
48 | */
49 | @property (nonatomic) ORKTwentyThreeAndMeAllowedUserMode allowedUserMode;
50 |
51 | @end
52 |
--------------------------------------------------------------------------------
/TwentyThreeAndMe/Steps/Complete/ORKTwentyThreeAndMeCompleteStep.m:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2016, 23andMe, Inc. All rights reserved.
3 |
4 | Redistribution and use in source and binary forms, with or without modification,
5 | are permitted provided that the following conditions are met:
6 |
7 | 1. Redistributions of source code must retain the above copyright notice, this
8 | list of conditions and the following disclaimer.
9 |
10 | 2. Redistributions in binary form must reproduce the above copyright notice,
11 | this list of conditions and the following disclaimer in the documentation and/or
12 | other materials provided with the distribution.
13 |
14 | 3. Neither the name of the copyright holder(s) nor the names of any contributors
15 | may be used to endorse or promote products derived from this software without
16 | specific prior written permission. No license is granted to the trademarks of
17 | the copyright holders even if such marks are included in this software.
18 |
19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
23 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 | */
30 |
31 | #import "ORKTwentyThreeAndMeCompleteStep.h"
32 |
33 | #import "ORKTwentyThreeAndMeCompleteViewController.h"
34 |
35 | @implementation ORKTwentyThreeAndMeCompleteStep
36 |
37 | + (Class)stepViewControllerClass {
38 | return [ORKTwentyThreeAndMeCompleteViewController class];
39 | }
40 |
41 | @end
42 |
--------------------------------------------------------------------------------
/TwentyThreeAndMe/Steps/Complete/ORKTwentyThreeAndMeCompleteViewController.h:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2016, 23andMe, Inc. All rights reserved.
3 |
4 | Redistribution and use in source and binary forms, with or without modification,
5 | are permitted provided that the following conditions are met:
6 |
7 | 1. Redistributions of source code must retain the above copyright notice, this
8 | list of conditions and the following disclaimer.
9 |
10 | 2. Redistributions in binary form must reproduce the above copyright notice,
11 | this list of conditions and the following disclaimer in the documentation and/or
12 | other materials provided with the distribution.
13 |
14 | 3. Neither the name of the copyright holder(s) nor the names of any contributors
15 | may be used to endorse or promote products derived from this software without
16 | specific prior written permission. No license is granted to the trademarks of
17 | the copyright holders even if such marks are included in this software.
18 |
19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
23 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 | */
30 |
31 | #import
32 |
33 | ORK_CLASS_AVAILABLE
34 | @interface ORKTwentyThreeAndMeCompleteViewController : ORKStepViewController
35 |
36 | @end
37 |
--------------------------------------------------------------------------------
/TwentyThreeAndMe/Steps/Complete/ORKTwentyThreeAndMeCompleteViewController.m:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2016, 23andMe, Inc. All rights reserved.
3 |
4 | Redistribution and use in source and binary forms, with or without modification,
5 | are permitted provided that the following conditions are met:
6 |
7 | 1. Redistributions of source code must retain the above copyright notice, this
8 | list of conditions and the following disclaimer.
9 |
10 | 2. Redistributions in binary form must reproduce the above copyright notice,
11 | this list of conditions and the following disclaimer in the documentation and/or
12 | other materials provided with the distribution.
13 |
14 | 3. Neither the name of the copyright holder(s) nor the names of any contributors
15 | may be used to endorse or promote products derived from this software without
16 | specific prior written permission. No license is granted to the trademarks of
17 | the copyright holders even if such marks are included in this software.
18 |
19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
23 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 | */
30 |
31 | #import "ORKTwentyThreeAndMeCompleteViewController.h"
32 |
33 | #import "ORKTwentyThreeAndMeCompleteStep.h"
34 | #import "ORKTwentyThreeAndMeSuccessExistingViewController.h"
35 | #import "ORKTwentyThreeAndMeSuccessNewViewController.h"
36 | #import "ORKTwentyThreeAndMeFailureViewController.h"
37 |
38 |
39 | @interface ORKTwentyThreeAndMeCompleteViewController()
40 |
41 | @property (nonatomic) ORKTwentyThreeAndMeSuccessExistingViewController *successExistingViewController;
42 |
43 | @property (nonatomic) ORKTwentyThreeAndMeSuccessNewViewController *successNewViewController;
44 |
45 | @property (nonatomic) ORKTwentyThreeAndMeFailureViewController *failureViewController;
46 |
47 | @end
48 |
49 | @implementation ORKTwentyThreeAndMeCompleteViewController
50 |
51 | - (ORKTwentyThreeAndMeCompleteStep *)completeStep {
52 | return (ORKTwentyThreeAndMeCompleteStep *)self.step;
53 | }
54 |
55 | - (void)successExistingDoneButtonPressed {
56 | [self goForward];
57 | }
58 |
59 | - (void)successNewDoneButtonPressed {
60 | [self goForward];
61 | }
62 |
63 | - (void)failureTryAgainButtonPressed {
64 | [self goBackward];
65 | }
66 |
67 | - (void)failureDeclineButtonPressed {
68 | [self.taskViewController.delegate taskViewController:self.taskViewController
69 | didFinishWithReason:ORKTaskViewControllerFinishReasonDiscarded
70 | error:nil];
71 | }
72 |
73 | - (void)viewDidLoad {
74 | [super viewDidLoad];
75 |
76 | ORKTwentyThreeAndMeCompleteStep *completeStep = [self completeStep];
77 | NSString *studyDisplayName = completeStep.studyDisplayName;
78 | NSString *studyContactEmail = completeStep.studyContactEmail;
79 |
80 | self.successExistingViewController = [[ORKTwentyThreeAndMeSuccessExistingViewController alloc] init];
81 | self.successExistingViewController.delegate = self;
82 | self.successExistingViewController.studyDisplayName = studyDisplayName;
83 |
84 | self.successNewViewController = [[ORKTwentyThreeAndMeSuccessNewViewController alloc] init];
85 | self.successNewViewController.delegate = self;
86 | self.successNewViewController.studyDisplayName = studyDisplayName;
87 |
88 | self.failureViewController = [[ORKTwentyThreeAndMeFailureViewController alloc] init];
89 | self.failureViewController.delegate = self;
90 | self.failureViewController.studyDisplayName = studyDisplayName;
91 | self.failureViewController.studyContactEmail = studyContactEmail;
92 |
93 | self.cancelButtonItem = nil;
94 | self.backButtonItem = nil;
95 | }
96 |
97 | - (void)viewWillAppear:(BOOL)animated {
98 | [super viewWillAppear:animated];
99 |
100 | // Use Results to Determine What To Show
101 | ORKTaskResult *taskResult = [self.taskViewController result];
102 | ORKCollectionResult *connectResultCollection = (ORKCollectionResult *)[taskResult resultForIdentifier:@"twentyThreeAndMe.connect"];
103 | ORKTwentyThreeAndMeConnectResult *connectResult = (ORKTwentyThreeAndMeConnectResult *)[connectResultCollection.results firstObject];
104 | if( connectResult.authToken &&
105 | connectResult.refreshToken ) {
106 | [self hideFailureViewController];
107 | if( connectResult.newUserFlow )
108 | {
109 | [self showSuccessNewViewController];
110 | }
111 | else
112 | {
113 | [self showSuccessExistingViewController];
114 | }
115 | }
116 | else {
117 | [self hideSuccessExistingViewController];
118 | [self showFailureViewController];
119 | }
120 | }
121 |
122 | - (void)showSuccessExistingViewController {
123 | [self addChildViewController:self.successExistingViewController];
124 | [self.view addSubview:self.successExistingViewController.view];
125 | [self.successExistingViewController didMoveToParentViewController:self];
126 | }
127 |
128 | - (void)hideSuccessExistingViewController {
129 | [self.successExistingViewController willMoveToParentViewController:nil];
130 | [self.successExistingViewController.view removeFromSuperview];
131 | [self.successExistingViewController removeFromParentViewController];
132 | }
133 |
134 | - (void)showSuccessNewViewController {
135 | [self addChildViewController:self.successNewViewController];
136 | [self.view addSubview:self.successNewViewController.view];
137 | [self.successNewViewController didMoveToParentViewController:self];
138 | }
139 |
140 | - (void)hideSuccessNewViewController {
141 | [self.successNewViewController willMoveToParentViewController:nil];
142 | [self.successNewViewController.view removeFromSuperview];
143 | [self.successNewViewController removeFromParentViewController];
144 | }
145 |
146 | - (void)showFailureViewController {
147 | [self addChildViewController:self.failureViewController];
148 | [self.view addSubview:self.failureViewController.view];
149 | [self.failureViewController didMoveToParentViewController:self];
150 | }
151 |
152 | - (void)hideFailureViewController {
153 | [self.failureViewController willMoveToParentViewController:nil];
154 | [self.failureViewController.view removeFromSuperview];
155 | [self.failureViewController removeFromParentViewController];
156 | }
157 |
158 | @end
159 |
--------------------------------------------------------------------------------
/TwentyThreeAndMe/Steps/Complete/ORKTwentyThreeAndMeFailureViewController.h:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2016, 23andMe, Inc. All rights reserved.
3 |
4 | Redistribution and use in source and binary forms, with or without modification,
5 | are permitted provided that the following conditions are met:
6 |
7 | 1. Redistributions of source code must retain the above copyright notice, this
8 | list of conditions and the following disclaimer.
9 |
10 | 2. Redistributions in binary form must reproduce the above copyright notice,
11 | this list of conditions and the following disclaimer in the documentation and/or
12 | other materials provided with the distribution.
13 |
14 | 3. Neither the name of the copyright holder(s) nor the names of any contributors
15 | may be used to endorse or promote products derived from this software without
16 | specific prior written permission. No license is granted to the trademarks of
17 | the copyright holders even if such marks are included in this software.
18 |
19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
23 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 | */
30 |
31 | #import
32 |
33 | @protocol ORKTwentyThreeAndMeFailureViewControllerDelegate
34 |
35 | /**
36 | * Callback when try again button pressed
37 | */
38 | - (void)failureTryAgainButtonPressed;
39 |
40 | /**
41 | * Callback when decline button pressed
42 | */
43 | - (void)failureDeclineButtonPressed;
44 |
45 | @end
46 |
47 | ORK_CLASS_AVAILABLE
48 | @interface ORKTwentyThreeAndMeFailureViewController : UIViewController
49 |
50 | /**
51 | The delegate for this view controller.
52 | */
53 | @property (nonatomic, weak, nullable) id delegate;
54 |
55 | /**
56 | * The display name of the study
57 | */
58 | @property (nonatomic, nullable) NSString *studyDisplayName;
59 |
60 | /**
61 | * The contact email for the study
62 | */
63 | @property (nonatomic, nullable) NSString *studyContactEmail;
64 |
65 | @end
66 |
--------------------------------------------------------------------------------
/TwentyThreeAndMe/Steps/Complete/ORKTwentyThreeAndMeFailureViewController.m:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2016, 23andMe, Inc. All rights reserved.
3 |
4 | Redistribution and use in source and binary forms, with or without modification,
5 | are permitted provided that the following conditions are met:
6 |
7 | 1. Redistributions of source code must retain the above copyright notice, this
8 | list of conditions and the following disclaimer.
9 |
10 | 2. Redistributions in binary form must reproduce the above copyright notice,
11 | this list of conditions and the following disclaimer in the documentation and/or
12 | other materials provided with the distribution.
13 |
14 | 3. Neither the name of the copyright holder(s) nor the names of any contributors
15 | may be used to endorse or promote products derived from this software without
16 | specific prior written permission. No license is granted to the trademarks of
17 | the copyright holders even if such marks are included in this software.
18 |
19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
23 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 | */
30 |
31 | #import "ORKTwentyThreeAndMeFailureViewController.h"
32 |
33 | #import "UIButton+T23.h"
34 | #import "UILabel+T23.h"
35 |
36 | @interface ORKTwentyThreeAndMeFailureViewController ()
37 |
38 | @end
39 |
40 | @implementation ORKTwentyThreeAndMeFailureViewController
41 |
42 | - (void)viewDidLoad {
43 | [super viewDidLoad];
44 |
45 | [self setupAppearance];
46 | }
47 |
48 | - (void)tryAgainButtonPressed:(UIButton *)sender {
49 | [self.delegate failureTryAgainButtonPressed];
50 | }
51 |
52 | - (void)declineButtonPressed:(UIButton *)sender {
53 | [self.delegate failureDeclineButtonPressed];
54 | }
55 |
56 | - (void)contactStudyButtonPressed:(UIButton *)sender {
57 | NSString *contactStudyByMail = [NSString stringWithFormat:@"mailto:?to=%@&subject=%@&body=%@",
58 | [self.studyContactEmail stringByAddingPercentEscapesUsingEncoding:NSASCIIStringEncoding],
59 | [self.studyDisplayName stringByAddingPercentEscapesUsingEncoding:NSASCIIStringEncoding],
60 | @""];
61 | [[UIApplication sharedApplication] openURL:[NSURL URLWithString:contactStudyByMail]];
62 | }
63 |
64 | - (void)setupAppearance {
65 | //--------------------
66 | // Style
67 | self.view.backgroundColor = [UIColor whiteColor];
68 |
69 | //--------------------
70 | // Gene Pill Image View
71 | UIImage *genePillImage = [UIImage imageNamed:@"failure_chromosome_purple" inBundle:[NSBundle bundleForClass:[self class]] compatibleWithTraitCollection:nil];
72 | UIImageView *genePillImageView = [[UIImageView alloc] initWithImage:genePillImage];
73 | [self.view addSubview:genePillImageView];
74 | genePillImageView.translatesAutoresizingMaskIntoConstraints = NO;
75 | [self.view addConstraint:[NSLayoutConstraint constraintWithItem:genePillImageView
76 | attribute:NSLayoutAttributeTop
77 | relatedBy:NSLayoutRelationEqual
78 | toItem:self.view
79 | attribute:NSLayoutAttributeTop
80 | multiplier:1.0
81 | constant:0.0]];
82 | [self.view addConstraint:[NSLayoutConstraint constraintWithItem:genePillImageView
83 | attribute:NSLayoutAttributeTrailing
84 | relatedBy:NSLayoutRelationEqual
85 | toItem:self.view
86 | attribute:NSLayoutAttributeTrailing
87 | multiplier:1.0
88 | constant:0.0]];
89 |
90 | //--------------------
91 | // Text Content View
92 | UIView *textContentView = [[UIView alloc] init];
93 | [self.view addSubview:textContentView];
94 | textContentView.translatesAutoresizingMaskIntoConstraints = NO;
95 | [self.view addConstraint:[NSLayoutConstraint constraintWithItem:textContentView
96 | attribute:NSLayoutAttributeLeading
97 | relatedBy:NSLayoutRelationEqual
98 | toItem:self.view
99 | attribute:NSLayoutAttributeLeading
100 | multiplier:1.0
101 | constant:0.0]];
102 | [self.view addConstraint:[NSLayoutConstraint constraintWithItem:textContentView
103 | attribute:NSLayoutAttributeTrailing
104 | relatedBy:NSLayoutRelationEqual
105 | toItem:self.view
106 | attribute:NSLayoutAttributeTrailing
107 | multiplier:1.0
108 | constant:0.0]];
109 | [self.view addConstraint:[NSLayoutConstraint constraintWithItem:textContentView
110 | attribute:NSLayoutAttributeCenterY
111 | relatedBy:NSLayoutRelationEqual
112 | toItem:self.view
113 | attribute:NSLayoutAttributeCenterY
114 | multiplier:1.0
115 | constant:-20.0]];
116 |
117 | //--------------------
118 | // Title Label
119 | UILabel *titleLabel = [UILabel t23HeaderLabelWithText:ORKLocalizedString(@"TWENTYTHREEANDME_FAILURE_TITLE", nil)];
120 | [textContentView addSubview:titleLabel];
121 | titleLabel.translatesAutoresizingMaskIntoConstraints = NO;
122 | [textContentView addConstraint:[NSLayoutConstraint constraintWithItem:titleLabel
123 | attribute:NSLayoutAttributeTop
124 | relatedBy:NSLayoutRelationEqual
125 | toItem:textContentView
126 | attribute:NSLayoutAttributeTop
127 | multiplier:1.0
128 | constant:0.0]];
129 | [textContentView addConstraint:[NSLayoutConstraint constraintWithItem:titleLabel
130 | attribute:NSLayoutAttributeLeading
131 | relatedBy:NSLayoutRelationEqual
132 | toItem:textContentView
133 | attribute:NSLayoutAttributeLeading
134 | multiplier:1.0
135 | constant:15.0]];
136 | [textContentView addConstraint:[NSLayoutConstraint constraintWithItem:titleLabel
137 | attribute:NSLayoutAttributeTrailing
138 | relatedBy:NSLayoutRelationEqual
139 | toItem:textContentView
140 | attribute:NSLayoutAttributeTrailing
141 | multiplier:1.0
142 | constant:-15.0]];
143 |
144 | //--------------------
145 | // Description Label
146 | NSString *descriptionLabelText = [NSString stringWithFormat:ORKLocalizedString(@"TWENTYTHREEANDME_FAILURE_DESCRIPTION", nil), self.studyDisplayName, self.studyDisplayName];
147 | UILabel *descriptionLabel = [UILabel t23BodyLabelWithText:descriptionLabelText];
148 | [textContentView addSubview:descriptionLabel];
149 | descriptionLabel.translatesAutoresizingMaskIntoConstraints = NO;
150 | [textContentView addConstraint:[NSLayoutConstraint constraintWithItem:descriptionLabel
151 | attribute:NSLayoutAttributeTop
152 | relatedBy:NSLayoutRelationEqual
153 | toItem:titleLabel
154 | attribute:NSLayoutAttributeBottom
155 | multiplier:1.0
156 | constant:20.0]];
157 | [textContentView addConstraint:[NSLayoutConstraint constraintWithItem:descriptionLabel
158 | attribute:NSLayoutAttributeLeading
159 | relatedBy:NSLayoutRelationEqual
160 | toItem:textContentView
161 | attribute:NSLayoutAttributeLeading
162 | multiplier:1.0
163 | constant:15.0]];
164 | [textContentView addConstraint:[NSLayoutConstraint constraintWithItem:descriptionLabel
165 | attribute:NSLayoutAttributeTrailing
166 | relatedBy:NSLayoutRelationEqual
167 | toItem:textContentView
168 | attribute:NSLayoutAttributeTrailing
169 | multiplier:1.0
170 | constant:-15.0]];
171 |
172 | UIButton *contactStudyButton = [[UIButton alloc] init];
173 | NSString *contactStudyText = [NSString stringWithFormat:ORKLocalizedString(@"TWENTYTHREEANDME_FAILURE_CONTACT", nil), self.studyDisplayName];
174 | [contactStudyButton addTarget:self action:@selector(contactStudyButtonPressed:) forControlEvents:UIControlEventTouchUpInside];
175 | [contactStudyButton setTitle:contactStudyText forState:UIControlStateNormal];
176 | UIColor *t23BlueColor = [UIColor colorWithRed:53.0/255.0 green:149.0/255.0 blue:214.0/255.0 alpha:1.0];
177 | [contactStudyButton setTitleColor:t23BlueColor forState:UIControlStateNormal];
178 | contactStudyButton.titleLabel.font = [UIFont systemFontOfSize:16.0];
179 | [textContentView addSubview:contactStudyButton];
180 | contactStudyButton.translatesAutoresizingMaskIntoConstraints = NO;
181 | [contactStudyButton addConstraint:[NSLayoutConstraint constraintWithItem:contactStudyButton
182 | attribute:NSLayoutAttributeHeight
183 | relatedBy:NSLayoutRelationEqual
184 | toItem:nil
185 | attribute:NSLayoutAttributeNotAnAttribute
186 | multiplier:1.0
187 | constant:45.0]];
188 | [textContentView addConstraint:[NSLayoutConstraint constraintWithItem:contactStudyButton
189 | attribute:NSLayoutAttributeTop
190 | relatedBy:NSLayoutRelationEqual
191 | toItem:descriptionLabel
192 | attribute:NSLayoutAttributeBottom
193 | multiplier:1.0
194 | constant:-10.0]];
195 | [textContentView addConstraint:[NSLayoutConstraint constraintWithItem:contactStudyButton
196 | attribute:NSLayoutAttributeLeading
197 | relatedBy:NSLayoutRelationEqual
198 | toItem:textContentView
199 | attribute:NSLayoutAttributeLeading
200 | multiplier:1.0
201 | constant:15.0]];
202 | [textContentView addConstraint:[NSLayoutConstraint constraintWithItem:contactStudyButton
203 | attribute:NSLayoutAttributeBottom
204 | relatedBy:NSLayoutRelationEqual
205 | toItem:textContentView
206 | attribute:NSLayoutAttributeBottom
207 | multiplier:1.0
208 | constant:0.0]];
209 |
210 | //--------------------
211 | // Try Again Button
212 | UIButton *tryAgainButton = [UIButton t23ButtonWithText:ORKLocalizedString(@"TWENTYTHREEANDME_FAILURE_TRY_AGAIN_BUTTON", nil) andHasBorder:YES];
213 | [self.view addSubview:tryAgainButton];
214 | [tryAgainButton addTarget:self action:@selector(tryAgainButtonPressed:) forControlEvents:UIControlEventTouchUpInside];
215 | tryAgainButton.translatesAutoresizingMaskIntoConstraints = NO;
216 | [self.view addConstraint:[NSLayoutConstraint constraintWithItem:tryAgainButton
217 | attribute:NSLayoutAttributeCenterX
218 | relatedBy:NSLayoutRelationEqual
219 | toItem:self.view
220 | attribute:NSLayoutAttributeCenterX
221 | multiplier:1.0
222 | constant:0.0]];
223 |
224 | //--------------------
225 | // Decline Button
226 | UIButton *declineButton = [UIButton t23ButtonWithText:ORKLocalizedString(@"TWENTYTHREEANDME_FAILURE_DECLINE_BUTTON", nil) andHasBorder:NO];
227 | [self.view addSubview:declineButton];
228 | [declineButton addTarget:self action:@selector(declineButtonPressed:) forControlEvents:UIControlEventTouchUpInside];
229 | declineButton.translatesAutoresizingMaskIntoConstraints = NO;
230 | [self.view addConstraint:[NSLayoutConstraint constraintWithItem:declineButton
231 | attribute:NSLayoutAttributeTop
232 | relatedBy:NSLayoutRelationEqual
233 | toItem:tryAgainButton
234 | attribute:NSLayoutAttributeBottom
235 | multiplier:1.0
236 | constant:5.0]];
237 | [self.view addConstraint:[NSLayoutConstraint constraintWithItem:declineButton
238 | attribute:NSLayoutAttributeCenterX
239 | relatedBy:NSLayoutRelationEqual
240 | toItem:self.view
241 | attribute:NSLayoutAttributeCenterX
242 | multiplier:1.0
243 | constant:0.0]];
244 | [self.view addConstraint:[NSLayoutConstraint constraintWithItem:declineButton
245 | attribute:NSLayoutAttributeBottom
246 | relatedBy:NSLayoutRelationEqual
247 | toItem:self.view
248 | attribute:NSLayoutAttributeBottom
249 | multiplier:1.0
250 | constant:-10.0]];
251 | }
252 |
253 | @end
254 |
--------------------------------------------------------------------------------
/TwentyThreeAndMe/Steps/Complete/ORKTwentyThreeAndMeSuccessExistingViewController.h:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2016, 23andMe, Inc. All rights reserved.
3 |
4 | Redistribution and use in source and binary forms, with or without modification,
5 | are permitted provided that the following conditions are met:
6 |
7 | 1. Redistributions of source code must retain the above copyright notice, this
8 | list of conditions and the following disclaimer.
9 |
10 | 2. Redistributions in binary form must reproduce the above copyright notice,
11 | this list of conditions and the following disclaimer in the documentation and/or
12 | other materials provided with the distribution.
13 |
14 | 3. Neither the name of the copyright holder(s) nor the names of any contributors
15 | may be used to endorse or promote products derived from this software without
16 | specific prior written permission. No license is granted to the trademarks of
17 | the copyright holders even if such marks are included in this software.
18 |
19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
23 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 | */
30 |
31 | #import
32 |
33 | @protocol ORKTwentyThreeAndMeSuccessExistingViewControllerDelegate
34 |
35 | /**
36 | * Delegate callback when done button is pressed
37 | */
38 | - (void)successExistingDoneButtonPressed;
39 |
40 | @end
41 |
42 | ORK_CLASS_AVAILABLE
43 | @interface ORKTwentyThreeAndMeSuccessExistingViewController : UIViewController
44 |
45 | /**
46 | The delegate for this view controller.
47 | */
48 | @property (nonatomic, weak, nullable) id delegate;
49 |
50 | /**
51 | * The display name of the study
52 | */
53 | @property (nonatomic, nullable) NSString *studyDisplayName;
54 |
55 | @end
56 |
--------------------------------------------------------------------------------
/TwentyThreeAndMe/Steps/Complete/ORKTwentyThreeAndMeSuccessExistingViewController.m:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2016, 23andMe, Inc. All rights reserved.
3 |
4 | Redistribution and use in source and binary forms, with or without modification,
5 | are permitted provided that the following conditions are met:
6 |
7 | 1. Redistributions of source code must retain the above copyright notice, this
8 | list of conditions and the following disclaimer.
9 |
10 | 2. Redistributions in binary form must reproduce the above copyright notice,
11 | this list of conditions and the following disclaimer in the documentation and/or
12 | other materials provided with the distribution.
13 |
14 | 3. Neither the name of the copyright holder(s) nor the names of any contributors
15 | may be used to endorse or promote products derived from this software without
16 | specific prior written permission. No license is granted to the trademarks of
17 | the copyright holders even if such marks are included in this software.
18 |
19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
23 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 | */
30 |
31 | #import "ORKTwentyThreeAndMeSuccessExistingViewController.h"
32 |
33 | #import "UIButton+T23.h"
34 | #import "UILabel+T23.h"
35 |
36 | @implementation ORKTwentyThreeAndMeSuccessExistingViewController
37 |
38 | - (void)viewDidLoad {
39 | [super viewDidLoad];
40 |
41 | [self setupAppearance];
42 | }
43 |
44 | - (void)doneButtonPressed:(UIButton *)sender {
45 | [self.delegate successExistingDoneButtonPressed];
46 | }
47 |
48 | - (void)setupAppearance {
49 | //--------------------
50 | // Style
51 | self.view.backgroundColor = [UIColor whiteColor];
52 |
53 | //--------------------
54 | // Gene Pill Image View
55 | UIImage *genePillImage = [UIImage imageNamed:@"congratulations_chromosome_blue" inBundle:[NSBundle bundleForClass:[self class]] compatibleWithTraitCollection:nil];
56 | UIImageView *genePillImageView = [[UIImageView alloc] initWithImage:genePillImage];
57 | [self.view addSubview:genePillImageView];
58 | genePillImageView.translatesAutoresizingMaskIntoConstraints = NO;
59 | [self.view addConstraint:[NSLayoutConstraint constraintWithItem:genePillImageView
60 | attribute:NSLayoutAttributeTop
61 | relatedBy:NSLayoutRelationEqual
62 | toItem:self.view
63 | attribute:NSLayoutAttributeTop
64 | multiplier:1.0
65 | constant:0.0]];
66 | [self.view addConstraint:[NSLayoutConstraint constraintWithItem:genePillImageView
67 | attribute:NSLayoutAttributeLeading
68 | relatedBy:NSLayoutRelationEqual
69 | toItem:self.view
70 | attribute:NSLayoutAttributeLeading
71 | multiplier:1.0
72 | constant:0.0]];
73 |
74 | //--------------------
75 | // Text Content View
76 | UIView *textContentView = [[UIView alloc] init];
77 | [self.view addSubview:textContentView];
78 | textContentView.translatesAutoresizingMaskIntoConstraints = NO;
79 | [self.view addConstraint:[NSLayoutConstraint constraintWithItem:textContentView
80 | attribute:NSLayoutAttributeLeading
81 | relatedBy:NSLayoutRelationEqual
82 | toItem:self.view
83 | attribute:NSLayoutAttributeLeading
84 | multiplier:1.0
85 | constant:0.0]];
86 | [self.view addConstraint:[NSLayoutConstraint constraintWithItem:textContentView
87 | attribute:NSLayoutAttributeTrailing
88 | relatedBy:NSLayoutRelationEqual
89 | toItem:self.view
90 | attribute:NSLayoutAttributeTrailing
91 | multiplier:1.0
92 | constant:0.0]];
93 | [self.view addConstraint:[NSLayoutConstraint constraintWithItem:textContentView
94 | attribute:NSLayoutAttributeCenterY
95 | relatedBy:NSLayoutRelationEqual
96 | toItem:self.view
97 | attribute:NSLayoutAttributeCenterY
98 | multiplier:1.0
99 | constant:0.0]];
100 |
101 | //--------------------
102 | // Title Label
103 | UILabel *titleLabel = [UILabel t23HeaderLabelWithText:ORKLocalizedString(@"TWENTYTHREEANDME_COMPLETE_TITLE", nil)];
104 | [textContentView addSubview:titleLabel];
105 | titleLabel.translatesAutoresizingMaskIntoConstraints = NO;
106 | [textContentView addConstraint:[NSLayoutConstraint constraintWithItem:titleLabel
107 | attribute:NSLayoutAttributeTop
108 | relatedBy:NSLayoutRelationEqual
109 | toItem:textContentView
110 | attribute:NSLayoutAttributeTop
111 | multiplier:1.0
112 | constant:0.0]];
113 | [textContentView addConstraint:[NSLayoutConstraint constraintWithItem:titleLabel
114 | attribute:NSLayoutAttributeLeading
115 | relatedBy:NSLayoutRelationEqual
116 | toItem:textContentView
117 | attribute:NSLayoutAttributeLeading
118 | multiplier:1.0
119 | constant:15.0]];
120 | [textContentView addConstraint:[NSLayoutConstraint constraintWithItem:titleLabel
121 | attribute:NSLayoutAttributeTrailing
122 | relatedBy:NSLayoutRelationEqual
123 | toItem:textContentView
124 | attribute:NSLayoutAttributeTrailing
125 | multiplier:1.0
126 | constant:-15.0]];
127 |
128 | //--------------------
129 | // Description Label
130 | NSString *descriptionLabelText = [NSString stringWithFormat:ORKLocalizedString(@"TWENTYTHREEANDME_COMPLETE_EXISTING_DETAIL", nil), self.studyDisplayName, self.studyDisplayName];
131 | UILabel *descriptionLabel = [UILabel t23BodyLabelWithText:descriptionLabelText];
132 | [textContentView addSubview:descriptionLabel];
133 | descriptionLabel.translatesAutoresizingMaskIntoConstraints = NO;
134 | [textContentView addConstraint:[NSLayoutConstraint constraintWithItem:descriptionLabel
135 | attribute:NSLayoutAttributeTop
136 | relatedBy:NSLayoutRelationEqual
137 | toItem:titleLabel
138 | attribute:NSLayoutAttributeBottom
139 | multiplier:1.0
140 | constant:20.0]];
141 | [textContentView addConstraint:[NSLayoutConstraint constraintWithItem:descriptionLabel
142 | attribute:NSLayoutAttributeLeading
143 | relatedBy:NSLayoutRelationEqual
144 | toItem:textContentView
145 | attribute:NSLayoutAttributeLeading
146 | multiplier:1.0
147 | constant:15.0]];
148 | [textContentView addConstraint:[NSLayoutConstraint constraintWithItem:descriptionLabel
149 | attribute:NSLayoutAttributeTrailing
150 | relatedBy:NSLayoutRelationEqual
151 | toItem:textContentView
152 | attribute:NSLayoutAttributeTrailing
153 | multiplier:1.0
154 | constant:-15.0]];
155 | [textContentView addConstraint:[NSLayoutConstraint constraintWithItem:descriptionLabel
156 | attribute:NSLayoutAttributeBottom
157 | relatedBy:NSLayoutRelationEqual
158 | toItem:textContentView
159 | attribute:NSLayoutAttributeBottom
160 | multiplier:1.0
161 | constant:0.0]];
162 |
163 | //--------------------
164 | // Done Button
165 | UIButton *doneButton = [UIButton t23ButtonWithText:ORKLocalizedString(@"TWENTYTHREEANDME_COMPLETE_DONE_BUTTON", nil) andHasBorder:YES];
166 | [self.view addSubview:doneButton];
167 | [doneButton addTarget:self action:@selector(doneButtonPressed:) forControlEvents:UIControlEventTouchUpInside];
168 | doneButton.translatesAutoresizingMaskIntoConstraints = NO;
169 | [self.view addConstraint:[NSLayoutConstraint constraintWithItem:doneButton
170 | attribute:NSLayoutAttributeBottom
171 | relatedBy:NSLayoutRelationEqual
172 | toItem:self.view
173 | attribute:NSLayoutAttributeBottom
174 | multiplier:1.0
175 | constant:-30.0]];
176 | [self.view addConstraint:[NSLayoutConstraint constraintWithItem:doneButton
177 | attribute:NSLayoutAttributeCenterX
178 | relatedBy:NSLayoutRelationEqual
179 | toItem:self.view
180 | attribute:NSLayoutAttributeCenterX
181 | multiplier:1.0
182 | constant:0.0]];
183 | }
184 |
185 |
186 | @end
187 |
--------------------------------------------------------------------------------
/TwentyThreeAndMe/Steps/Complete/ORKTwentyThreeAndMeSuccessNewViewController.h:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2016, 23andMe, Inc. All rights reserved.
3 |
4 | Redistribution and use in source and binary forms, with or without modification,
5 | are permitted provided that the following conditions are met:
6 |
7 | 1. Redistributions of source code must retain the above copyright notice, this
8 | list of conditions and the following disclaimer.
9 |
10 | 2. Redistributions in binary form must reproduce the above copyright notice,
11 | this list of conditions and the following disclaimer in the documentation and/or
12 | other materials provided with the distribution.
13 |
14 | 3. Neither the name of the copyright holder(s) nor the names of any contributors
15 | may be used to endorse or promote products derived from this software without
16 | specific prior written permission. No license is granted to the trademarks of
17 | the copyright holders even if such marks are included in this software.
18 |
19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
23 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 | */
30 |
31 | #import
32 |
33 | @protocol ORKTwentyThreeAndMeSuccessNewViewControllerDelegate
34 |
35 | /**
36 | * Delegate callback when done button is pressed
37 | */
38 | - (void)successNewDoneButtonPressed;
39 |
40 | @end
41 |
42 | ORK_CLASS_AVAILABLE
43 | @interface ORKTwentyThreeAndMeSuccessNewViewController : UIViewController
44 |
45 | /**
46 | The delegate for this view controller.
47 | */
48 | @property (nonatomic, weak, nullable) id delegate;
49 |
50 | /**
51 | * The display name of the study
52 | */
53 | @property (nonatomic, nullable) NSString *studyDisplayName;
54 |
55 | @end
56 |
--------------------------------------------------------------------------------
/TwentyThreeAndMe/Steps/Complete/ORKTwentyThreeAndMeSuccessNewViewController.m:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2016, 23andMe, Inc. All rights reserved.
3 |
4 | Redistribution and use in source and binary forms, with or without modification,
5 | are permitted provided that the following conditions are met:
6 |
7 | 1. Redistributions of source code must retain the above copyright notice, this
8 | list of conditions and the following disclaimer.
9 |
10 | 2. Redistributions in binary form must reproduce the above copyright notice,
11 | this list of conditions and the following disclaimer in the documentation and/or
12 | other materials provided with the distribution.
13 |
14 | 3. Neither the name of the copyright holder(s) nor the names of any contributors
15 | may be used to endorse or promote products derived from this software without
16 | specific prior written permission. No license is granted to the trademarks of
17 | the copyright holders even if such marks are included in this software.
18 |
19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
23 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 | */
30 |
31 | #import "ORKTwentyThreeAndMeSuccessNewViewController.h"
32 |
33 | #import "UIButton+T23.h"
34 | #import "UILabel+T23.h"
35 |
36 | @implementation ORKTwentyThreeAndMeSuccessNewViewController
37 |
38 | - (void)viewDidLoad {
39 | [super viewDidLoad];
40 |
41 | [self setupAppearance];
42 | }
43 |
44 | - (void)doneButtonPressed:(UIButton *)sender {
45 | [self.delegate successNewDoneButtonPressed];
46 | }
47 |
48 | - (void)setupAppearance {
49 | //--------------------
50 | // Style
51 | self.view.backgroundColor = [UIColor whiteColor];
52 |
53 | //--------------------
54 | // Scroll View
55 | UIScrollView *scrollView = [[UIScrollView alloc] init];
56 | [self.view addSubview:scrollView];
57 | scrollView.translatesAutoresizingMaskIntoConstraints = NO;
58 | [self.view addConstraint:[NSLayoutConstraint constraintWithItem:scrollView
59 | attribute:NSLayoutAttributeTop
60 | relatedBy:NSLayoutRelationEqual
61 | toItem:self.view
62 | attribute:NSLayoutAttributeTop
63 | multiplier:1.0
64 | constant:0.0]];
65 | [self.view addConstraint:[NSLayoutConstraint constraintWithItem:scrollView
66 | attribute:NSLayoutAttributeLeading
67 | relatedBy:NSLayoutRelationEqual
68 | toItem:self.view
69 | attribute:NSLayoutAttributeLeading
70 | multiplier:1.0
71 | constant:0.0]];
72 | [self.view addConstraint:[NSLayoutConstraint constraintWithItem:scrollView
73 | attribute:NSLayoutAttributeTrailing
74 | relatedBy:NSLayoutRelationEqual
75 | toItem:self.view
76 | attribute:NSLayoutAttributeTrailing
77 | multiplier:1.0
78 | constant:0.0]];
79 |
80 | //--------------------
81 | // - Gene Pill Image View
82 | UIImage *genePillImage = [UIImage imageNamed:@"congratulations_chromosome_blue" inBundle:[NSBundle bundleForClass:[self class]] compatibleWithTraitCollection:nil];
83 | UIImageView *genePillImageView = [[UIImageView alloc] initWithImage:genePillImage];
84 | [scrollView addSubview:genePillImageView];
85 | genePillImageView.translatesAutoresizingMaskIntoConstraints = NO;
86 | [scrollView addConstraint:[NSLayoutConstraint constraintWithItem:genePillImageView
87 | attribute:NSLayoutAttributeTop
88 | relatedBy:NSLayoutRelationEqual
89 | toItem:scrollView
90 | attribute:NSLayoutAttributeTop
91 | multiplier:1.0
92 | constant:0.0]];
93 | [scrollView addConstraint:[NSLayoutConstraint constraintWithItem:genePillImageView
94 | attribute:NSLayoutAttributeLeading
95 | relatedBy:NSLayoutRelationEqual
96 | toItem:scrollView
97 | attribute:NSLayoutAttributeLeading
98 | multiplier:1.0
99 | constant:0.0]];
100 |
101 | //--------------------
102 | // - Title Label
103 | UILabel *titleLabel = [UILabel t23HeaderLabelWithText:ORKLocalizedString(@"TWENTYTHREEANDME_COMPLETE_TITLE", nil)];
104 | [scrollView addSubview:titleLabel];
105 | titleLabel.translatesAutoresizingMaskIntoConstraints = NO;
106 | [scrollView addConstraint:[NSLayoutConstraint constraintWithItem:titleLabel
107 | attribute:NSLayoutAttributeTop
108 | relatedBy:NSLayoutRelationEqual
109 | toItem:genePillImageView
110 | attribute:NSLayoutAttributeBottom
111 | multiplier:1.0
112 | constant:10.0]];
113 | [scrollView addConstraint:[NSLayoutConstraint constraintWithItem:titleLabel
114 | attribute:NSLayoutAttributeLeading
115 | relatedBy:NSLayoutRelationEqual
116 | toItem:scrollView
117 | attribute:NSLayoutAttributeLeading
118 | multiplier:1.0
119 | constant:15.0]];
120 | [scrollView addConstraint:[NSLayoutConstraint constraintWithItem:titleLabel
121 | attribute:NSLayoutAttributeTrailing
122 | relatedBy:NSLayoutRelationEqual
123 | toItem:scrollView
124 | attribute:NSLayoutAttributeTrailing
125 | multiplier:1.0
126 | constant:-15.0]];
127 |
128 | //--------------------
129 | // - Scroll View Width Behavior
130 | [scrollView addConstraint:[NSLayoutConstraint constraintWithItem:titleLabel
131 | attribute:NSLayoutAttributeWidth
132 | relatedBy:NSLayoutRelationEqual
133 | toItem:scrollView
134 | attribute:NSLayoutAttributeWidth
135 | multiplier:1.0
136 | constant:-30.0]];
137 |
138 | //--------------------
139 | // - Description Label
140 | NSString *descriptionLabelText = [NSString stringWithFormat:ORKLocalizedString(@"TWENTYTHREEANDME_COMPLETE_NEW_DETAIL", nil), self.studyDisplayName, self.studyDisplayName];
141 | UILabel *descriptionLabel = [UILabel t23BodyLabelWithText:descriptionLabelText];
142 | [scrollView addSubview:descriptionLabel];
143 | descriptionLabel.translatesAutoresizingMaskIntoConstraints = NO;
144 | [scrollView addConstraint:[NSLayoutConstraint constraintWithItem:descriptionLabel
145 | attribute:NSLayoutAttributeTop
146 | relatedBy:NSLayoutRelationEqual
147 | toItem:titleLabel
148 | attribute:NSLayoutAttributeBottom
149 | multiplier:1.0
150 | constant:20.0]];
151 | [scrollView addConstraint:[NSLayoutConstraint constraintWithItem:descriptionLabel
152 | attribute:NSLayoutAttributeLeading
153 | relatedBy:NSLayoutRelationEqual
154 | toItem:scrollView
155 | attribute:NSLayoutAttributeLeading
156 | multiplier:1.0
157 | constant:15.0]];
158 | [scrollView addConstraint:[NSLayoutConstraint constraintWithItem:descriptionLabel
159 | attribute:NSLayoutAttributeTrailing
160 | relatedBy:NSLayoutRelationEqual
161 | toItem:scrollView
162 | attribute:NSLayoutAttributeTrailing
163 | multiplier:1.0
164 | constant:-15.0]];
165 |
166 | //--------------------
167 | // - Next Steps Title
168 | UILabel *nextStepsHeaderLabel = [UILabel t23SubheaderLabelWithText:ORKLocalizedString(@"TWENTYTHREEANDME_COMPLETE_NEW_NEXT_STEP", nil)];
169 | [scrollView addSubview:nextStepsHeaderLabel];
170 | nextStepsHeaderLabel.translatesAutoresizingMaskIntoConstraints = NO;
171 | [scrollView addConstraint:[NSLayoutConstraint constraintWithItem:nextStepsHeaderLabel
172 | attribute:NSLayoutAttributeTop
173 | relatedBy:NSLayoutRelationEqual
174 | toItem:descriptionLabel
175 | attribute:NSLayoutAttributeBottom
176 | multiplier:1.0
177 | constant:15.0]];
178 | [scrollView addConstraint:[NSLayoutConstraint constraintWithItem:nextStepsHeaderLabel
179 | attribute:NSLayoutAttributeLeading
180 | relatedBy:NSLayoutRelationEqual
181 | toItem:scrollView
182 | attribute:NSLayoutAttributeLeading
183 | multiplier:1.0
184 | constant:15.0]];
185 | [scrollView addConstraint:[NSLayoutConstraint constraintWithItem:nextStepsHeaderLabel
186 | attribute:NSLayoutAttributeTrailing
187 | relatedBy:NSLayoutRelationEqual
188 | toItem:scrollView
189 | attribute:NSLayoutAttributeTrailing
190 | multiplier:1.0
191 | constant:-15.0]];
192 |
193 | //--------------------
194 | // - Next Steps Details
195 | NSString *nextStepsDetailsText = ORKLocalizedString(@"TWENTYTHREEANDME_COMPLETE_NEW_NEXT_STEP_DETAIL", nil);
196 | UILabel *nextStepsDetailsLabel = [UILabel t23BodyLabelWithText:nextStepsDetailsText];
197 | [scrollView addSubview:nextStepsDetailsLabel];
198 | nextStepsDetailsLabel.translatesAutoresizingMaskIntoConstraints = NO;
199 | [scrollView addConstraint:[NSLayoutConstraint constraintWithItem:nextStepsDetailsLabel
200 | attribute:NSLayoutAttributeTop
201 | relatedBy:NSLayoutRelationEqual
202 | toItem:nextStepsHeaderLabel
203 | attribute:NSLayoutAttributeBottom
204 | multiplier:1.0
205 | constant:10.0]];
206 | [scrollView addConstraint:[NSLayoutConstraint constraintWithItem:nextStepsDetailsLabel
207 | attribute:NSLayoutAttributeLeading
208 | relatedBy:NSLayoutRelationEqual
209 | toItem:scrollView
210 | attribute:NSLayoutAttributeLeading
211 | multiplier:1.0
212 | constant:15.0]];
213 | [scrollView addConstraint:[NSLayoutConstraint constraintWithItem:nextStepsDetailsLabel
214 | attribute:NSLayoutAttributeTrailing
215 | relatedBy:NSLayoutRelationEqual
216 | toItem:scrollView
217 | attribute:NSLayoutAttributeTrailing
218 | multiplier:1.0
219 | constant:-15.0]];
220 |
221 | //--------------------
222 | // - Bottom Constraint
223 | [scrollView addConstraint:[NSLayoutConstraint constraintWithItem:nextStepsDetailsLabel
224 | attribute:NSLayoutAttributeBottom
225 | relatedBy:NSLayoutRelationEqual
226 | toItem:scrollView
227 | attribute:NSLayoutAttributeBottom
228 | multiplier:1.0
229 | constant:0.0]];
230 |
231 | //--------------------
232 | // Divider View
233 | UIView *dividerView = [[UIView alloc] init];
234 | dividerView.backgroundColor = [UIColor colorWithRed:227.0/255.0 green:229.0/255.0 blue:230.0/255.0 alpha:1.0];
235 | [self.view addSubview:dividerView];
236 | dividerView.translatesAutoresizingMaskIntoConstraints = NO;
237 | [dividerView addConstraint:[NSLayoutConstraint constraintWithItem:dividerView
238 | attribute:NSLayoutAttributeHeight
239 | relatedBy:NSLayoutRelationEqual
240 | toItem:nil
241 | attribute:NSLayoutAttributeNotAnAttribute
242 | multiplier:1.0
243 | constant:1.0]];
244 | [self.view addConstraint:[NSLayoutConstraint constraintWithItem:dividerView
245 | attribute:NSLayoutAttributeTop
246 | relatedBy:NSLayoutRelationEqual
247 | toItem:scrollView
248 | attribute:NSLayoutAttributeBottom
249 | multiplier:1.0
250 | constant:0.0]];
251 | [self.view addConstraint:[NSLayoutConstraint constraintWithItem:dividerView
252 | attribute:NSLayoutAttributeLeading
253 | relatedBy:NSLayoutRelationEqual
254 | toItem:self.view
255 | attribute:NSLayoutAttributeLeading
256 | multiplier:1.0
257 | constant:0.0]];
258 | [self.view addConstraint:[NSLayoutConstraint constraintWithItem:dividerView
259 | attribute:NSLayoutAttributeTrailing
260 | relatedBy:NSLayoutRelationEqual
261 | toItem:self.view
262 | attribute:NSLayoutAttributeTrailing
263 | multiplier:1.0
264 | constant:0.0]];
265 |
266 | //--------------------
267 | // Done Button
268 | UIButton *doneButton = [UIButton t23ButtonWithText:ORKLocalizedString(@"TWENTYTHREEANDME_COMPLETE_DONE_BUTTON", nil) andHasBorder:YES];
269 | [self.view addSubview:doneButton];
270 | [doneButton addTarget:self action:@selector(doneButtonPressed:) forControlEvents:UIControlEventTouchUpInside];
271 | doneButton.translatesAutoresizingMaskIntoConstraints = NO;
272 | [self.view addConstraint:[NSLayoutConstraint constraintWithItem:doneButton
273 | attribute:NSLayoutAttributeTop
274 | relatedBy:NSLayoutRelationEqual
275 | toItem:dividerView
276 | attribute:NSLayoutAttributeBottom
277 | multiplier:1.0
278 | constant:20.0]];
279 | [self.view addConstraint:[NSLayoutConstraint constraintWithItem:doneButton
280 | attribute:NSLayoutAttributeBottom
281 | relatedBy:NSLayoutRelationEqual
282 | toItem:self.view
283 | attribute:NSLayoutAttributeBottom
284 | multiplier:1.0
285 | constant:-20.0]];
286 | [self.view addConstraint:[NSLayoutConstraint constraintWithItem:doneButton
287 | attribute:NSLayoutAttributeCenterX
288 | relatedBy:NSLayoutRelationEqual
289 | toItem:self.view
290 | attribute:NSLayoutAttributeCenterX
291 | multiplier:1.0
292 | constant:0.0]];
293 | }
294 |
295 |
296 | @end
297 |
--------------------------------------------------------------------------------
/TwentyThreeAndMe/Steps/Connect/ORKTwentyThreeAndMeConnectStep.h:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2016, 23andMe, Inc. All rights reserved.
3 |
4 | Redistribution and use in source and binary forms, with or without modification,
5 | are permitted provided that the following conditions are met:
6 |
7 | 1. Redistributions of source code must retain the above copyright notice, this
8 | list of conditions and the following disclaimer.
9 |
10 | 2. Redistributions in binary form must reproduce the above copyright notice,
11 | this list of conditions and the following disclaimer in the documentation and/or
12 | other materials provided with the distribution.
13 |
14 | 3. Neither the name of the copyright holder(s) nor the names of any contributors
15 | may be used to endorse or promote products derived from this software without
16 | specific prior written permission. No license is granted to the trademarks of
17 | the copyright holders even if such marks are included in this software.
18 |
19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
23 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 | */
30 |
31 | #import
32 |
33 | NS_ASSUME_NONNULL_BEGIN
34 |
35 |
36 | /**
37 | * An `ORKTwentyThreeAndMeConnectStep` object allows the participant to connect
38 | * with 23andMe and share their data with the investigators.
39 | */
40 | ORK_CLASS_AVAILABLE
41 | @interface ORKTwentyThreeAndMeConnectStep : ORKStep
42 |
43 | /**
44 | * RedirectURI used by auth. Should match what is in developer portal.
45 | */
46 | @property (nonatomic, copy, nullable) NSString *redirectURI;
47 |
48 | /**
49 | * ClientId used by auth. Should match what is in developer portal.
50 | */
51 | @property (nonatomic, copy, nullable) NSString *clientId;
52 |
53 | /**
54 | * ClientSecret used by auth. Should match what is in developer portal.
55 | */
56 | @property (nonatomic, copy, nullable) NSString *clientSecret;
57 |
58 | /**
59 | * Scopes used by auth.
60 | */
61 | @property (nonatomic, copy, nullable) NSString *scopes;
62 |
63 | /**
64 | * Base URL to use for connections
65 | */
66 | @property (nonatomic, copy, nullable) NSString *baseURL;
67 |
68 | /**
69 | * The display name of the study
70 | */
71 | @property (nonatomic, copy, nullable) NSString *studyDisplayNameParam;
72 |
73 | /**
74 | * Allowed User Mode for the module
75 | */
76 | @property (nonatomic) ORKTwentyThreeAndMeAllowedUserMode allowedUserMode;
77 |
78 | @end
79 |
80 | NS_ASSUME_NONNULL_END
--------------------------------------------------------------------------------
/TwentyThreeAndMe/Steps/Connect/ORKTwentyThreeAndMeConnectStep.m:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2016, 23andMe, Inc. All rights reserved.
3 |
4 | Redistribution and use in source and binary forms, with or without modification,
5 | are permitted provided that the following conditions are met:
6 |
7 | 1. Redistributions of source code must retain the above copyright notice, this
8 | list of conditions and the following disclaimer.
9 |
10 | 2. Redistributions in binary form must reproduce the above copyright notice,
11 | this list of conditions and the following disclaimer in the documentation and/or
12 | other materials provided with the distribution.
13 |
14 | 3. Neither the name of the copyright holder(s) nor the names of any contributors
15 | may be used to endorse or promote products derived from this software without
16 | specific prior written permission. No license is granted to the trademarks of
17 | the copyright holders even if such marks are included in this software.
18 |
19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
23 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 | */
30 |
31 | #import "ORKTwentyThreeAndMeConnectStep.h"
32 |
33 | #import "ORKTwentyThreeAndMeConnectStepViewController.h"
34 |
35 | @implementation ORKTwentyThreeAndMeConnectStep
36 |
37 | + (Class)stepViewControllerClass {
38 | return [ORKTwentyThreeAndMeConnectStepViewController class];
39 | }
40 |
41 | @end
42 |
--------------------------------------------------------------------------------
/TwentyThreeAndMe/Steps/Connect/ORKTwentyThreeAndMeConnectStepViewController.h:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2016, 23andMe, Inc. All rights reserved.
3 |
4 | Redistribution and use in source and binary forms, with or without modification,
5 | are permitted provided that the following conditions are met:
6 |
7 | 1. Redistributions of source code must retain the above copyright notice, this
8 | list of conditions and the following disclaimer.
9 |
10 | 2. Redistributions in binary form must reproduce the above copyright notice,
11 | this list of conditions and the following disclaimer in the documentation and/or
12 | other materials provided with the distribution.
13 |
14 | 3. Neither the name of the copyright holder(s) nor the names of any contributors
15 | may be used to endorse or promote products derived from this software without
16 | specific prior written permission. No license is granted to the trademarks of
17 | the copyright holders even if such marks are included in this software.
18 |
19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
23 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 | */
30 |
31 | #import
32 |
33 | @import WebKit;
34 |
35 | /**
36 | * StepViewController for Connecting to 23andMe auth with a wrapped webview
37 | */
38 | ORK_CLASS_AVAILABLE
39 | @interface ORKTwentyThreeAndMeConnectStepViewController : ORKStepViewController
40 |
41 | @end
42 |
--------------------------------------------------------------------------------
/TwentyThreeAndMe/Steps/Connect/ORKTwentyThreeAndMeConnectStepViewController.m:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2016, 23andMe, Inc. All rights reserved.
3 |
4 | Redistribution and use in source and binary forms, with or without modification,
5 | are permitted provided that the following conditions are met:
6 |
7 | 1. Redistributions of source code must retain the above copyright notice, this
8 | list of conditions and the following disclaimer.
9 |
10 | 2. Redistributions in binary form must reproduce the above copyright notice,
11 | this list of conditions and the following disclaimer in the documentation and/or
12 | other materials provided with the distribution.
13 |
14 | 3. Neither the name of the copyright holder(s) nor the names of any contributors
15 | may be used to endorse or promote products derived from this software without
16 | specific prior written permission. No license is granted to the trademarks of
17 | the copyright holders even if such marks are included in this software.
18 |
19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
23 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 | */
30 |
31 | #import "ORKTwentyThreeAndMeConnectStepViewController.h"
32 |
33 | #import "ORKTwentyThreeAndMeConnectStep.h"
34 |
35 | @interface ORKTwentyThreeAndMeConnectStepViewController ()
36 |
37 | @property (nonatomic, strong) WKWebView *webView;
38 |
39 | @property (strong, nonatomic) NSMutableData *receivedData;
40 |
41 | @property (nonatomic, strong) NSString *authToken;
42 |
43 | @property (nonatomic, strong) NSString *refreshToken;
44 |
45 | @property (nonatomic) BOOL newUserFlow;
46 |
47 | @end
48 |
49 | @implementation ORKTwentyThreeAndMeConnectStepViewController
50 |
51 | - (ORKTwentyThreeAndMeConnectStep *)connectStep {
52 | return (ORKTwentyThreeAndMeConnectStep *)self.step;
53 | }
54 |
55 | - (void)viewDidLoad {
56 | [super viewDidLoad];
57 |
58 | WKWebViewConfiguration *wkConfiguration = [[WKWebViewConfiguration alloc] init];
59 | self.webView = [[WKWebView alloc] initWithFrame:self.view.frame configuration:wkConfiguration];
60 | self.webView.navigationDelegate = self;
61 | [self.view addSubview:self.webView];
62 | self.webView.translatesAutoresizingMaskIntoConstraints = NO;
63 | [self.view addConstraint:[NSLayoutConstraint constraintWithItem:self.webView
64 | attribute:NSLayoutAttributeTop
65 | relatedBy:NSLayoutRelationEqual
66 | toItem:self.view
67 | attribute:NSLayoutAttributeTop
68 | multiplier:1.0
69 | constant:0.0]];
70 | [self.view addConstraint:[NSLayoutConstraint constraintWithItem:self.webView
71 | attribute:NSLayoutAttributeBottom
72 | relatedBy:NSLayoutRelationEqual
73 | toItem:self.view
74 | attribute:NSLayoutAttributeBottom
75 | multiplier:1.0
76 | constant:0.0]];
77 | [self.view addConstraint:[NSLayoutConstraint constraintWithItem:self.webView
78 | attribute:NSLayoutAttributeLeading
79 | relatedBy:NSLayoutRelationEqual
80 | toItem:self.view
81 | attribute:NSLayoutAttributeLeading
82 | multiplier:1.0
83 | constant:0.0]];
84 | [self.view addConstraint:[NSLayoutConstraint constraintWithItem:self.webView
85 | attribute:NSLayoutAttributeTrailing
86 | relatedBy:NSLayoutRelationEqual
87 | toItem:self.view
88 | attribute:NSLayoutAttributeTrailing
89 | multiplier:1.0
90 | constant:0.0]];
91 |
92 | [self loadAuthorizationRequest];
93 | }
94 |
95 | - (void)loadAuthorizationRequest
96 | {
97 | NSString *signupParams = ([self connectStep].allowedUserMode == ORKTwentyThreeAndMeAllowedUserModeExistingOnly) ?
98 | @"hide_signup=true" :
99 | @"enroll_signup=true";
100 | NSString *contentURLString = [NSString stringWithFormat:@"%@/authorize/?redirect_uri=%@&client_id=%@&%@&select_profile=true&scope=%@&client_name=%@", [self connectStep].baseURL, [self connectStep].redirectURI, [self connectStep].clientId, signupParams, [self connectStep].scopes, [self connectStep].studyDisplayNameParam];
101 | NSURL *contentURL = [NSURL URLWithString:contentURLString];
102 | NSURLRequest *nsRequest=[NSURLRequest requestWithURL:contentURL];
103 | [self.webView loadRequest:nsRequest];
104 | }
105 |
106 | #pragma mark - ORKStepResult
107 |
108 | - (ORKStepResult *)result {
109 | ORKStepResult *sResult = [super result];
110 |
111 | // "Now" is the end time of the result, which is either actually now,
112 | // or the last time we were in the responder chain.
113 | NSDate *now = sResult.endDate;
114 |
115 | NSMutableArray *results = [NSMutableArray arrayWithArray:sResult.results];
116 |
117 | ORKTwentyThreeAndMeConnectResult *connectResult = [[ORKTwentyThreeAndMeConnectResult alloc] initWithIdentifier:self.step.identifier];
118 | connectResult.startDate = sResult.startDate;
119 | connectResult.endDate = now;
120 | connectResult.authToken = self.authToken;
121 | connectResult.refreshToken = self.refreshToken;
122 | connectResult.newUserFlow = self.newUserFlow;
123 |
124 | [results addObject:connectResult];
125 | sResult.results = [results copy];
126 |
127 | return sResult;
128 | }
129 |
130 | #pragma mark - WebViewDelegate
131 |
132 | - (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler {
133 | NSURLRequest *request = navigationAction.request;
134 | if ([[[request URL] host] isEqualToString:@"localhost"]) {
135 | // Extract oauth_verifier from URL query
136 | NSString *authCode = nil;
137 | NSString *errorCode = nil;
138 | NSArray* urlParams = [[[request URL] query] componentsSeparatedByString:@"&"];
139 | for (NSString* param in urlParams) {
140 | NSArray* keyValue = [param componentsSeparatedByString:@"="];
141 | NSString* key = [keyValue objectAtIndex:0];
142 | if ([key isEqualToString:@"code"]) {
143 | authCode = [keyValue objectAtIndex:1];
144 | break;
145 | }
146 | else if([key isEqualToString:@"error"]) {
147 | errorCode = [keyValue objectAtIndex:1];
148 | break;
149 | }
150 |
151 | if([key isEqualToString:@"new_user"] ) {
152 | id keyValueElement = [keyValue objectAtIndex:1];
153 | if( [keyValueElement isKindOfClass:[NSString class]] ) {
154 | NSString *newUserParamValue = ((NSString *)keyValueElement).lowercaseString;
155 | if( [newUserParamValue isEqualToString:@"true"] )
156 | {
157 | self.newUserFlow = YES;
158 | }
159 | }
160 | }
161 | }
162 |
163 | if (authCode) {
164 | NSString *data = [NSString stringWithFormat:@"client_id=%@&client_secret=%@&grant_type=authorization_code&code=%@&redirect_uri=%@&scope=%@", [self connectStep].clientId, [self connectStep].clientSecret, authCode, [self connectStep].redirectURI, [self connectStep].scopes];
165 | NSString *tokenURL = [NSString stringWithFormat:@"%@/token/", [self connectStep].baseURL];
166 | NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:tokenURL]];
167 | [request setHTTPMethod:@"POST"];
168 | [request setHTTPBody:[data dataUsingEncoding:NSUTF8StringEncoding]];
169 |
170 | self.receivedData = [[NSMutableData alloc] init];
171 | NSURLConnection *theConnection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
172 | [theConnection start];
173 | }
174 | else if (errorCode && [errorCode isEqualToString:@"access_denied"]) {
175 | [self goForward];
176 | }
177 | else
178 | {
179 | // Error.
180 | [self goForward];
181 | }
182 |
183 | decisionHandler(WKNavigationActionPolicyCancel);
184 | }
185 | else {
186 | decisionHandler(WKNavigationActionPolicyAllow);
187 | }
188 | }
189 |
190 | - (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(WKNavigation *)navigation withError:(NSError *)error
191 | {
192 | // Error
193 | }
194 |
195 | - (void)webView:(WKWebView *)webView didFailNavigation:(WKNavigation *)navigation withError:(NSError *)error
196 | {
197 | // Error
198 | }
199 |
200 | #pragma mark - NSURLConnectionDelegate - Handles Code to Token Connection
201 |
202 | -(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
203 | {
204 | if( self.receivedData ) {
205 | [self.receivedData appendData:data];
206 | }
207 | }
208 |
209 | -(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
210 | {
211 | // Error
212 | [self goForward];
213 | }
214 |
215 | -(void)connectionDidFinishLoading:(NSURLConnection *)connection
216 | {
217 | if( self.receivedData ) {
218 |
219 | // DEBUGGING for Parse Issues
220 | const unsigned char *ptr = [self.receivedData bytes];
221 | NSString *jsonParsed = @"";
222 | for(int i=0; i<[self.receivedData length]; ++i) {
223 | unsigned char c = *ptr++;
224 | jsonParsed = [jsonParsed stringByAppendingFormat:@"%c", c];
225 | }
226 |
227 | NSError *localError = nil;
228 | NSDictionary *parsedData = [NSJSONSerialization JSONObjectWithData:self.receivedData options:NSJSONReadingAllowFragments error:&localError];
229 | if( parsedData ) {
230 | self.authToken = parsedData[@"access_token"];
231 | self.refreshToken = parsedData[@"refresh_token"];
232 | }
233 |
234 | // Success!
235 | [self goForward];
236 | }
237 | }
238 |
239 | @end
240 |
--------------------------------------------------------------------------------
/TwentyThreeAndMe/Steps/Intro/ORKTwentyThreeAndMeIntroPage1ViewController.h:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2016, 23andMe, Inc. All rights reserved.
3 |
4 | Redistribution and use in source and binary forms, with or without modification,
5 | are permitted provided that the following conditions are met:
6 |
7 | 1. Redistributions of source code must retain the above copyright notice, this
8 | list of conditions and the following disclaimer.
9 |
10 | 2. Redistributions in binary form must reproduce the above copyright notice,
11 | this list of conditions and the following disclaimer in the documentation and/or
12 | other materials provided with the distribution.
13 |
14 | 3. Neither the name of the copyright holder(s) nor the names of any contributors
15 | may be used to endorse or promote products derived from this software without
16 | specific prior written permission. No license is granted to the trademarks of
17 | the copyright holders even if such marks are included in this software.
18 |
19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
23 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 | */
30 |
31 | #import
32 |
33 | ORK_CLASS_AVAILABLE
34 | @interface ORKTwentyThreeAndMeIntroPage1ViewController : UIViewController
35 |
36 | /**
37 | * The display name of the investigator
38 | */
39 | @property (nonatomic) NSString *investigatorDisplayName;
40 |
41 | /**
42 | * The display name of the study
43 | */
44 | @property (nonatomic) NSString *studyDisplayName;
45 |
46 | /**
47 | * The contact email for the study
48 | */
49 | @property (nonatomic) NSString *studyContactEmail;
50 |
51 | @end
52 |
--------------------------------------------------------------------------------
/TwentyThreeAndMe/Steps/Intro/ORKTwentyThreeAndMeIntroPage1ViewController.m:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2016, 23andMe, Inc. All rights reserved.
3 |
4 | Redistribution and use in source and binary forms, with or without modification,
5 | are permitted provided that the following conditions are met:
6 |
7 | 1. Redistributions of source code must retain the above copyright notice, this
8 | list of conditions and the following disclaimer.
9 |
10 | 2. Redistributions in binary form must reproduce the above copyright notice,
11 | this list of conditions and the following disclaimer in the documentation and/or
12 | other materials provided with the distribution.
13 |
14 | 3. Neither the name of the copyright holder(s) nor the names of any contributors
15 | may be used to endorse or promote products derived from this software without
16 | specific prior written permission. No license is granted to the trademarks of
17 | the copyright holders even if such marks are included in this software.
18 |
19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
23 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 | */
30 |
31 | #import "ORKTwentyThreeAndMeIntroPage1ViewController.h"
32 |
33 | #import "UIButton+T23.h"
34 | #import "UILabel+T23.h"
35 |
36 | @interface ORKTwentyThreeAndMeIntroPage1ViewController ()
37 |
38 | @end
39 |
40 | @implementation ORKTwentyThreeAndMeIntroPage1ViewController
41 |
42 | - (void)viewDidLoad {
43 | [super viewDidLoad];
44 |
45 | [self setupAppearance];
46 | }
47 |
48 | - (void)setupAppearance {
49 | //--------------------
50 | // Style
51 | self.view.backgroundColor = [UIColor whiteColor];
52 |
53 | //--------------------
54 | // 23andMe Logo Image View
55 | UIImage *logoImage = [UIImage imageNamed:@"intro_23andMe_logo" inBundle:[NSBundle bundleForClass:[self class]] compatibleWithTraitCollection:nil];
56 | UIImageView *logoImageView = [[UIImageView alloc] initWithImage:logoImage];
57 | [self.view addSubview:logoImageView];
58 | logoImageView.translatesAutoresizingMaskIntoConstraints = NO;
59 | [self.view addConstraint:[NSLayoutConstraint constraintWithItem:logoImageView
60 | attribute:NSLayoutAttributeTop
61 | relatedBy:NSLayoutRelationEqual
62 | toItem:self.view
63 | attribute:NSLayoutAttributeTop
64 | multiplier:1.0
65 | constant:0.0]];
66 | [self.view addConstraint:[NSLayoutConstraint constraintWithItem:logoImageView
67 | attribute:NSLayoutAttributeCenterX
68 | relatedBy:NSLayoutRelationEqual
69 | toItem:self.view
70 | attribute:NSLayoutAttributeCenterX
71 | multiplier:1.0
72 | constant:15.0]];
73 |
74 | //--------------------
75 | // Spacer Above
76 | UIView *spacerAboveDescription = [[UIView alloc] init];
77 | [self.view addSubview:spacerAboveDescription];
78 | spacerAboveDescription.translatesAutoresizingMaskIntoConstraints = NO;
79 | [self.view addConstraint:[NSLayoutConstraint constraintWithItem:spacerAboveDescription
80 | attribute:NSLayoutAttributeTop
81 | relatedBy:NSLayoutRelationEqual
82 | toItem:logoImageView
83 | attribute:NSLayoutAttributeBottom
84 | multiplier:1.0
85 | constant:0.0]];
86 | [self.view addConstraint:[NSLayoutConstraint constraintWithItem:spacerAboveDescription
87 | attribute:NSLayoutAttributeLeading
88 | relatedBy:NSLayoutRelationEqual
89 | toItem:self.view
90 | attribute:NSLayoutAttributeLeading
91 | multiplier:1.0
92 | constant:0.0]];
93 | [self.view addConstraint:[NSLayoutConstraint constraintWithItem:spacerAboveDescription
94 | attribute:NSLayoutAttributeTrailing
95 | relatedBy:NSLayoutRelationEqual
96 | toItem:self.view
97 | attribute:NSLayoutAttributeTrailing
98 | multiplier:1.0
99 | constant:0.0]];
100 |
101 | //--------------------
102 | // Description Label
103 | NSString *descriptionText = [NSString stringWithFormat:ORKLocalizedString(@"TWENTYTHREEANDME_INTRO_1_DESCRIPTION", nil), self.investigatorDisplayName, self.studyDisplayName];
104 | UILabel *descriptionLabel = [UILabel t23BodyLabelWithText:descriptionText];
105 | [self.view addSubview:descriptionLabel];
106 | descriptionLabel.translatesAutoresizingMaskIntoConstraints = NO;
107 | [self.view addConstraint:[NSLayoutConstraint constraintWithItem:descriptionLabel
108 | attribute:NSLayoutAttributeTop
109 | relatedBy:NSLayoutRelationEqual
110 | toItem:spacerAboveDescription
111 | attribute:NSLayoutAttributeBottom
112 | multiplier:1.0
113 | constant:0.0]];
114 | [self.view addConstraint:[NSLayoutConstraint constraintWithItem:descriptionLabel
115 | attribute:NSLayoutAttributeLeading
116 | relatedBy:NSLayoutRelationEqual
117 | toItem:self.view
118 | attribute:NSLayoutAttributeLeading
119 | multiplier:1.0
120 | constant:15.0]];
121 | [self.view addConstraint:[NSLayoutConstraint constraintWithItem:descriptionLabel
122 | attribute:NSLayoutAttributeTrailing
123 | relatedBy:NSLayoutRelationEqual
124 | toItem:self.view
125 | attribute:NSLayoutAttributeTrailing
126 | multiplier:1.0
127 | constant:-15.0]];
128 |
129 | //--------------------
130 | // Spacer Below
131 | UIView *spacerBelowDescription = [[UIView alloc] init];
132 | [self.view addSubview:spacerBelowDescription];
133 | spacerBelowDescription.translatesAutoresizingMaskIntoConstraints = NO;
134 | [self.view addConstraint:[NSLayoutConstraint constraintWithItem:spacerBelowDescription
135 | attribute:NSLayoutAttributeTop
136 | relatedBy:NSLayoutRelationEqual
137 | toItem:descriptionLabel
138 | attribute:NSLayoutAttributeBottom
139 | multiplier:1.0
140 | constant:0.0]];
141 | [self.view addConstraint:[NSLayoutConstraint constraintWithItem:spacerBelowDescription
142 | attribute:NSLayoutAttributeHeight
143 | relatedBy:NSLayoutRelationEqual
144 | toItem:spacerAboveDescription
145 | attribute:NSLayoutAttributeHeight
146 | multiplier:1.0
147 | constant:0.0]];
148 | [self.view addConstraint:[NSLayoutConstraint constraintWithItem:spacerBelowDescription
149 | attribute:NSLayoutAttributeLeading
150 | relatedBy:NSLayoutRelationEqual
151 | toItem:self.view
152 | attribute:NSLayoutAttributeLeading
153 | multiplier:1.0
154 | constant:0.0]];
155 | [self.view addConstraint:[NSLayoutConstraint constraintWithItem:spacerBelowDescription
156 | attribute:NSLayoutAttributeTrailing
157 | relatedBy:NSLayoutRelationEqual
158 | toItem:self.view
159 | attribute:NSLayoutAttributeTrailing
160 | multiplier:1.0
161 | constant:0.0]];
162 |
163 | //--------------------
164 | // Gene Pill Image View
165 | UIImage *genePillImage = [UIImage imageNamed:@"intro_chromosome_green_striped" inBundle:[NSBundle bundleForClass:[self class]] compatibleWithTraitCollection:nil];
166 | UIImageView *genePillImageView = [[UIImageView alloc] initWithImage:genePillImage];
167 | [self.view addSubview:genePillImageView];
168 | genePillImageView.translatesAutoresizingMaskIntoConstraints = NO;
169 | [self.view addConstraint:[NSLayoutConstraint constraintWithItem:genePillImageView
170 | attribute:NSLayoutAttributeTrailing
171 | relatedBy:NSLayoutRelationEqual
172 | toItem:self.view
173 | attribute:NSLayoutAttributeTrailing
174 | multiplier:1.0
175 | constant:0.0]];
176 | [self.view addConstraint:[NSLayoutConstraint constraintWithItem:genePillImageView
177 | attribute:NSLayoutAttributeTop
178 | relatedBy:NSLayoutRelationEqual
179 | toItem:spacerBelowDescription
180 | attribute:NSLayoutAttributeBottom
181 | multiplier:1.0
182 | constant:0.0]];
183 |
184 | //--------------------
185 | // Divider View
186 | UIView *dividerView = [[UIView alloc] init];
187 | dividerView.backgroundColor = [UIColor colorWithRed:227.0/255.0 green:229.0/255.0 blue:230.0/255.0 alpha:1.0];
188 | [self.view addSubview:dividerView];
189 | dividerView.translatesAutoresizingMaskIntoConstraints = NO;
190 | [dividerView addConstraint:[NSLayoutConstraint constraintWithItem:dividerView
191 | attribute:NSLayoutAttributeHeight
192 | relatedBy:NSLayoutRelationEqual
193 | toItem:nil
194 | attribute:NSLayoutAttributeNotAnAttribute
195 | multiplier:1.0
196 | constant:1.0]];
197 | [self.view addConstraint:[NSLayoutConstraint constraintWithItem:dividerView
198 | attribute:NSLayoutAttributeTop
199 | relatedBy:NSLayoutRelationEqual
200 | toItem:genePillImageView
201 | attribute:NSLayoutAttributeBottom
202 | multiplier:1.0
203 | constant:24.0]];
204 | [self.view addConstraint:[NSLayoutConstraint constraintWithItem:dividerView
205 | attribute:NSLayoutAttributeLeading
206 | relatedBy:NSLayoutRelationEqual
207 | toItem:self.view
208 | attribute:NSLayoutAttributeLeading
209 | multiplier:1.0
210 | constant:0.0]];
211 | [self.view addConstraint:[NSLayoutConstraint constraintWithItem:dividerView
212 | attribute:NSLayoutAttributeTrailing
213 | relatedBy:NSLayoutRelationEqual
214 | toItem:self.view
215 | attribute:NSLayoutAttributeTrailing
216 | multiplier:1.0
217 | constant:0.0]];
218 | [self.view addConstraint:[NSLayoutConstraint constraintWithItem:dividerView
219 | attribute:NSLayoutAttributeBottom
220 | relatedBy:NSLayoutRelationEqual
221 | toItem:self.view
222 | attribute:NSLayoutAttributeBottom
223 | multiplier:1.0
224 | constant:0.0]];
225 | }
226 |
227 | @end
228 |
--------------------------------------------------------------------------------
/TwentyThreeAndMe/Steps/Intro/ORKTwentyThreeAndMeIntroPage2ViewController.h:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2016, 23andMe, Inc. All rights reserved.
3 |
4 | Redistribution and use in source and binary forms, with or without modification,
5 | are permitted provided that the following conditions are met:
6 |
7 | 1. Redistributions of source code must retain the above copyright notice, this
8 | list of conditions and the following disclaimer.
9 |
10 | 2. Redistributions in binary form must reproduce the above copyright notice,
11 | this list of conditions and the following disclaimer in the documentation and/or
12 | other materials provided with the distribution.
13 |
14 | 3. Neither the name of the copyright holder(s) nor the names of any contributors
15 | may be used to endorse or promote products derived from this software without
16 | specific prior written permission. No license is granted to the trademarks of
17 | the copyright holders even if such marks are included in this software.
18 |
19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
23 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 | */
30 |
31 | #import
32 |
33 | ORK_CLASS_AVAILABLE
34 | @interface ORKTwentyThreeAndMeIntroPage2ViewController : UIViewController
35 |
36 | /**
37 | * The display name of the investigator
38 | */
39 | @property (nonatomic) NSString *investigatorDisplayName;
40 |
41 | /**
42 | * The display name of the study
43 | */
44 | @property (nonatomic) NSString *studyDisplayName;
45 |
46 | /**
47 | * The contact email for the study
48 | */
49 | @property (nonatomic) NSString *studyContactEmail;
50 |
51 | /**
52 | * Allowed User Mode for the module
53 | */
54 | @property (nonatomic) ORKTwentyThreeAndMeAllowedUserMode allowedUserMode;
55 |
56 | /**
57 | * Study Dependency on Module
58 | */
59 | @property (nonatomic) ORKTwentyThreeAndMeStudyDependency studyDependency;
60 |
61 | @end
62 |
--------------------------------------------------------------------------------
/TwentyThreeAndMe/Steps/Intro/ORKTwentyThreeAndMeIntroPage3ViewController.h:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2016, 23andMe, Inc. All rights reserved.
3 |
4 | Redistribution and use in source and binary forms, with or without modification,
5 | are permitted provided that the following conditions are met:
6 |
7 | 1. Redistributions of source code must retain the above copyright notice, this
8 | list of conditions and the following disclaimer.
9 |
10 | 2. Redistributions in binary form must reproduce the above copyright notice,
11 | this list of conditions and the following disclaimer in the documentation and/or
12 | other materials provided with the distribution.
13 |
14 | 3. Neither the name of the copyright holder(s) nor the names of any contributors
15 | may be used to endorse or promote products derived from this software without
16 | specific prior written permission. No license is granted to the trademarks of
17 | the copyright holders even if such marks are included in this software.
18 |
19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
23 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 | */
30 |
31 | #import
32 |
33 | ORK_CLASS_AVAILABLE
34 | @interface ORKTwentyThreeAndMeIntroPage3ViewController : UIViewController
35 |
36 | /**
37 | * The display name of the investigator
38 | */
39 | @property (nonatomic) NSString *investigatorDisplayName;
40 |
41 | /**
42 | * The display name of the study
43 | */
44 | @property (nonatomic) NSString *studyDisplayName;
45 |
46 | /**
47 | * The contact email for the study
48 | */
49 | @property (nonatomic) NSString *studyContactEmail;
50 |
51 | @end
52 |
--------------------------------------------------------------------------------
/TwentyThreeAndMe/Steps/Intro/ORKTwentyThreeAndMeIntroStep.h:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2016, 23andMe, Inc. All rights reserved.
3 |
4 | Redistribution and use in source and binary forms, with or without modification,
5 | are permitted provided that the following conditions are met:
6 |
7 | 1. Redistributions of source code must retain the above copyright notice, this
8 | list of conditions and the following disclaimer.
9 |
10 | 2. Redistributions in binary form must reproduce the above copyright notice,
11 | this list of conditions and the following disclaimer in the documentation and/or
12 | other materials provided with the distribution.
13 |
14 | 3. Neither the name of the copyright holder(s) nor the names of any contributors
15 | may be used to endorse or promote products derived from this software without
16 | specific prior written permission. No license is granted to the trademarks of
17 | the copyright holders even if such marks are included in this software.
18 |
19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
23 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 | */
30 |
31 | #import
32 |
33 | ORK_CLASS_AVAILABLE
34 | @interface ORKTwentyThreeAndMeIntroStep : ORKStep
35 |
36 | /**
37 | * The display name of the investigator
38 | */
39 | @property (nonatomic, copy, nullable) NSString *investigatorDisplayName;
40 |
41 | /**
42 | * The display name of the study
43 | */
44 | @property (nonatomic, copy, nullable) NSString *studyDisplayName;
45 |
46 | /**
47 | * The contact email for the study
48 | */
49 | @property (nonatomic, copy, nullable) NSString *studyContactEmail;
50 |
51 | /**
52 | * Allowed User Mode for the module
53 | */
54 | @property (nonatomic) ORKTwentyThreeAndMeAllowedUserMode allowedUserMode;
55 |
56 | /**
57 | * Study Dependency on Module
58 | */
59 | @property (nonatomic) ORKTwentyThreeAndMeStudyDependency studyDependency;
60 |
61 | @end
62 |
--------------------------------------------------------------------------------
/TwentyThreeAndMe/Steps/Intro/ORKTwentyThreeAndMeIntroStep.m:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2016, 23andMe, Inc. All rights reserved.
3 |
4 | Redistribution and use in source and binary forms, with or without modification,
5 | are permitted provided that the following conditions are met:
6 |
7 | 1. Redistributions of source code must retain the above copyright notice, this
8 | list of conditions and the following disclaimer.
9 |
10 | 2. Redistributions in binary form must reproduce the above copyright notice,
11 | this list of conditions and the following disclaimer in the documentation and/or
12 | other materials provided with the distribution.
13 |
14 | 3. Neither the name of the copyright holder(s) nor the names of any contributors
15 | may be used to endorse or promote products derived from this software without
16 | specific prior written permission. No license is granted to the trademarks of
17 | the copyright holders even if such marks are included in this software.
18 |
19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
23 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 | */
30 |
31 | #import "ORKTwentyThreeAndMeIntroStep.h"
32 |
33 | #import "ORKTwentyThreeAndMeIntroViewController.h"
34 |
35 | @implementation ORKTwentyThreeAndMeIntroStep
36 |
37 | + (Class)stepViewControllerClass {
38 | return [ORKTwentyThreeAndMeIntroViewController class];
39 | }
40 |
41 | @end
42 |
--------------------------------------------------------------------------------
/TwentyThreeAndMe/Steps/Intro/ORKTwentyThreeAndMeIntroViewController.h:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2016, 23andMe, Inc. All rights reserved.
3 |
4 | Redistribution and use in source and binary forms, with or without modification,
5 | are permitted provided that the following conditions are met:
6 |
7 | 1. Redistributions of source code must retain the above copyright notice, this
8 | list of conditions and the following disclaimer.
9 |
10 | 2. Redistributions in binary form must reproduce the above copyright notice,
11 | this list of conditions and the following disclaimer in the documentation and/or
12 | other materials provided with the distribution.
13 |
14 | 3. Neither the name of the copyright holder(s) nor the names of any contributors
15 | may be used to endorse or promote products derived from this software without
16 | specific prior written permission. No license is granted to the trademarks of
17 | the copyright holders even if such marks are included in this software.
18 |
19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
23 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 | */
30 |
31 | #import
32 |
33 | ORK_CLASS_AVAILABLE
34 | @interface ORKTwentyThreeAndMeIntroViewController : ORKStepViewController
35 |
36 | @end
37 |
--------------------------------------------------------------------------------
/TwentyThreeAndMe/Steps/Intro/ORKTwentyThreeAndMeIntroViewController.m:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2016, 23andMe, Inc. All rights reserved.
3 |
4 | Redistribution and use in source and binary forms, with or without modification,
5 | are permitted provided that the following conditions are met:
6 |
7 | 1. Redistributions of source code must retain the above copyright notice, this
8 | list of conditions and the following disclaimer.
9 |
10 | 2. Redistributions in binary form must reproduce the above copyright notice,
11 | this list of conditions and the following disclaimer in the documentation and/or
12 | other materials provided with the distribution.
13 |
14 | 3. Neither the name of the copyright holder(s) nor the names of any contributors
15 | may be used to endorse or promote products derived from this software without
16 | specific prior written permission. No license is granted to the trademarks of
17 | the copyright holders even if such marks are included in this software.
18 |
19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
23 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 | */
30 |
31 | #import "ORKTwentyThreeAndMeIntroViewController.h"
32 |
33 | #import "UIButton+T23.h"
34 | #import "UILabel+T23.h"
35 | #import "ORKTwentyThreeAndMeIntroStep.h"
36 | #import "ORKTwentyThreeAndMeIntroPage1ViewController.h"
37 | #import "ORKTwentyThreeAndMeIntroPage2ViewController.h"
38 | #import "ORKTwentyThreeAndMeIntroPage3ViewController.h"
39 |
40 |
41 | @interface ORKTwentyThreeAndMeIntroViewController()
42 |
43 | @property (nonatomic) UIPageViewController *pageViewController;
44 |
45 | @property (nonatomic) NSArray *pages;
46 |
47 | @property (nonatomic) NSString *investigatorDisplayName;
48 | @property (nonatomic) NSString *studyDisplayName;
49 | @property (nonatomic) NSString *studyContactEmail;
50 | @property (nonatomic) ORKTwentyThreeAndMeAllowedUserMode allowedUserMode;
51 | @property (nonatomic) ORKTwentyThreeAndMeStudyDependency studyDependency;
52 |
53 | @end
54 |
55 | @implementation ORKTwentyThreeAndMeIntroViewController
56 |
57 | - (ORKTwentyThreeAndMeIntroStep *)introStep {
58 | return (ORKTwentyThreeAndMeIntroStep *)self.step;
59 | }
60 |
61 | - (void)viewDidLoad {
62 | [super viewDidLoad];
63 |
64 | ORKTwentyThreeAndMeIntroStep *introStep = [self introStep];
65 | self.investigatorDisplayName = introStep.investigatorDisplayName;
66 | self.studyDisplayName = introStep.studyDisplayName;
67 | self.studyContactEmail = introStep.studyContactEmail;
68 | self.allowedUserMode = introStep.allowedUserMode;
69 | self.studyDependency = introStep.studyDependency;
70 |
71 | ORKTwentyThreeAndMeIntroPage1ViewController *pageVC1 = [[ORKTwentyThreeAndMeIntroPage1ViewController alloc] init];
72 | pageVC1.investigatorDisplayName = self.investigatorDisplayName;
73 | pageVC1.studyDisplayName = self.studyDisplayName;
74 | pageVC1.studyContactEmail = self.studyContactEmail;
75 | ORKTwentyThreeAndMeIntroPage2ViewController *pageVC2 = [[ORKTwentyThreeAndMeIntroPage2ViewController alloc] init];
76 | pageVC2.investigatorDisplayName = self.investigatorDisplayName;
77 | pageVC2.studyDisplayName = self.studyDisplayName;
78 | pageVC2.studyContactEmail = self.studyContactEmail;
79 | pageVC2.allowedUserMode = self.allowedUserMode;
80 | pageVC2.studyDependency = self.studyDependency;
81 | ORKTwentyThreeAndMeIntroPage3ViewController *pageVC3 = [[ORKTwentyThreeAndMeIntroPage3ViewController alloc] init];
82 | pageVC3.investigatorDisplayName = self.investigatorDisplayName;
83 | pageVC3.studyDisplayName = self.studyDisplayName;
84 | pageVC3.studyContactEmail = self.studyContactEmail;
85 | self.pages = @[pageVC1, pageVC2, pageVC3];
86 |
87 | [self setupAppearance];
88 |
89 | [self.pageViewController setViewControllers:@[pageVC1]
90 | direction:UIPageViewControllerNavigationDirectionForward
91 | animated:NO
92 | completion:nil];
93 |
94 | self.cancelButtonItem = nil;
95 | self.backButtonItem = nil;
96 | }
97 |
98 | - (void)shareButtonPressed:(UIButton *)sender {
99 | [self goForward];
100 | }
101 |
102 | - (void)declineButtonPressed:(UIButton *)sender {
103 | NSString *alertMessage = [NSString stringWithFormat:ORKLocalizedString(@"TWENTYTHREEANDME_DECLINE_PROMPT_DETAILS", nil), self.studyDisplayName];
104 | UIAlertController *alertViewController = [UIAlertController alertControllerWithTitle:nil
105 | message:alertMessage
106 | preferredStyle:UIAlertControllerStyleAlert];
107 | UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:ORKLocalizedString(@"TWENTYTHREEANDME_DECLINE_PROMPT_ACTION_CANCEL", nil)
108 | style:UIAlertActionStyleDefault
109 | handler:nil];
110 | UIAlertAction *declineAction = [UIAlertAction actionWithTitle:ORKLocalizedString(@"TWENTYTHREEANDME_DECLINE_PROMPT_ACTION_DECLINE", nil)
111 | style:UIAlertActionStyleDefault
112 | handler:^(UIAlertAction * _Nonnull action) {
113 | [self.taskViewController.delegate taskViewController:self.taskViewController didFinishWithReason:ORKTaskViewControllerFinishReasonDiscarded error:nil];
114 |
115 | }];
116 | [alertViewController addAction:cancelAction];
117 | [alertViewController addAction:declineAction];
118 | [self presentViewController:alertViewController animated:YES completion:nil];
119 | }
120 |
121 | - (void)setupAppearance {
122 | //--------------------
123 | // Style
124 | self.view.backgroundColor = [UIColor whiteColor];
125 |
126 | //--------------------
127 | // Page View Controller Control Appearance
128 | UIPageControl *pageControl = nil;
129 | if( [UIPageControl instancesRespondToSelector:@selector(appearanceWhenContainedInInstancesOfClasses:)] ) {
130 | pageControl = [UIPageControl appearanceWhenContainedInInstancesOfClasses:@[[ORKTwentyThreeAndMeIntroViewController class]]];
131 | }
132 | else {
133 | pageControl = [UIPageControl appearance];
134 | }
135 | pageControl.pageIndicatorTintColor = [UIColor lightGrayColor];
136 | pageControl.currentPageIndicatorTintColor = [UIColor colorWithRed:51.0/255.0 green:52.0/255.0 blue:53.0/255.0 alpha:1.0];
137 | pageControl.backgroundColor = [UIColor whiteColor];
138 |
139 | //--------------------
140 | // Page View Controller
141 | self.pageViewController = [[UIPageViewController alloc] initWithTransitionStyle:UIPageViewControllerTransitionStyleScroll
142 | navigationOrientation:UIPageViewControllerNavigationOrientationHorizontal
143 | options:nil];
144 | self.pageViewController.delegate = self;
145 | self.pageViewController.dataSource = self;
146 | [self addChildViewController:self.pageViewController];
147 | [self.view addSubview:self.pageViewController.view];
148 | [self.pageViewController didMoveToParentViewController:self];
149 |
150 | self.pageViewController.view.translatesAutoresizingMaskIntoConstraints = NO;
151 | [self.view addConstraint:[NSLayoutConstraint constraintWithItem:self.pageViewController.view
152 | attribute:NSLayoutAttributeTop
153 | relatedBy:NSLayoutRelationEqual
154 | toItem:self.view
155 | attribute:NSLayoutAttributeTop
156 | multiplier:1.0
157 | constant:0.0]];
158 | [self.view addConstraint:[NSLayoutConstraint constraintWithItem:self.pageViewController.view
159 | attribute:NSLayoutAttributeLeading
160 | relatedBy:NSLayoutRelationEqual
161 | toItem:self.view
162 | attribute:NSLayoutAttributeLeading
163 | multiplier:1.0
164 | constant:0.0]];
165 | [self.view addConstraint:[NSLayoutConstraint constraintWithItem:self.pageViewController.view
166 | attribute:NSLayoutAttributeTrailing
167 | relatedBy:NSLayoutRelationEqual
168 | toItem:self.view
169 | attribute:NSLayoutAttributeTrailing
170 | multiplier:1.0
171 | constant:0.0]];
172 |
173 | //--------------------
174 | // Share Button
175 | UIButton *shareButton = [UIButton t23ButtonWithText:ORKLocalizedString(@"TWENTYTHREEANDME_INTRO_MAIN_SHARE", nil) andHasBorder:YES];
176 | [self.view addSubview:shareButton];
177 | [shareButton addTarget:self action:@selector(shareButtonPressed:) forControlEvents:UIControlEventTouchUpInside];
178 | shareButton.translatesAutoresizingMaskIntoConstraints = NO;
179 | [self.view addConstraint:[NSLayoutConstraint constraintWithItem:shareButton
180 | attribute:NSLayoutAttributeTop
181 | relatedBy:NSLayoutRelationEqual
182 | toItem:self.pageViewController.view
183 | attribute:NSLayoutAttributeBottom
184 | multiplier:1.0
185 | constant:0.0]];
186 | [self.view addConstraint:[NSLayoutConstraint constraintWithItem:shareButton
187 | attribute:NSLayoutAttributeCenterX
188 | relatedBy:NSLayoutRelationEqual
189 | toItem:self.view
190 | attribute:NSLayoutAttributeCenterX
191 | multiplier:1.0
192 | constant:0.0]];
193 |
194 | //--------------------
195 | // Decline Button
196 | UIButton *declineButton = [UIButton t23ButtonWithText:ORKLocalizedString(@"TWENTYTHREEANDME_INTRO_MAIN_DECLINE", nil) andHasBorder:NO];
197 | [self.view addSubview:declineButton];
198 | [declineButton addTarget:self action:@selector(declineButtonPressed:) forControlEvents:UIControlEventTouchUpInside];
199 | declineButton.translatesAutoresizingMaskIntoConstraints = NO;
200 | [self.view addConstraint:[NSLayoutConstraint constraintWithItem:declineButton
201 | attribute:NSLayoutAttributeTop
202 | relatedBy:NSLayoutRelationEqual
203 | toItem:shareButton
204 | attribute:NSLayoutAttributeBottom
205 | multiplier:1.0
206 | constant:0.0]];
207 | [self.view addConstraint:[NSLayoutConstraint constraintWithItem:declineButton
208 | attribute:NSLayoutAttributeCenterX
209 | relatedBy:NSLayoutRelationEqual
210 | toItem:self.view
211 | attribute:NSLayoutAttributeCenterX
212 | multiplier:1.0
213 | constant:0.0]];
214 |
215 | //--------------------
216 | // Bottom
217 | [self.view addConstraint:[NSLayoutConstraint constraintWithItem:declineButton
218 | attribute:NSLayoutAttributeBottom
219 | relatedBy:NSLayoutRelationEqual
220 | toItem:self.view
221 | attribute:NSLayoutAttributeBottom
222 | multiplier:1.0
223 | constant:0.0]];
224 | }
225 |
226 | - (UIViewController *)pageViewController:(UIPageViewController *)pageViewController
227 | viewControllerBeforeViewController:(UIViewController *)viewController {
228 | NSInteger indexOfCurrentPage = (NSInteger)[self.pages indexOfObject:viewController];
229 | if( indexOfCurrentPage - 1 >= 0 ) {
230 | return self.pages[indexOfCurrentPage - 1];
231 | }
232 |
233 | return nil;
234 | }
235 |
236 | - (UIViewController *)pageViewController:(UIPageViewController *)pageViewController
237 | viewControllerAfterViewController:(UIViewController *)viewController {
238 | NSInteger indexOfCurrentPage = (NSInteger)[self.pages indexOfObject:viewController];
239 | if( indexOfCurrentPage + 1 < [self.pages count] ) {
240 | return self.pages[indexOfCurrentPage + 1];
241 | }
242 |
243 | return nil;
244 | }
245 |
246 | - (NSInteger)presentationCountForPageViewController:(UIPageViewController *)pageViewController {
247 | return [self.pages count];
248 | }
249 |
250 | - (NSInteger)presentationIndexForPageViewController:(UIPageViewController *)pageViewController {
251 |
252 | UIViewController *currentPageViewController = [pageViewController.viewControllers firstObject];
253 | if( currentPageViewController ) {
254 | return [self.pages indexOfObject:currentPageViewController];
255 |
256 | }
257 | return 0;
258 | }
259 |
260 |
261 | @end
--------------------------------------------------------------------------------
/TwentyThreeAndMe/Tasks/ORKTwentyThreeAndMeConnectTaskViewController.h:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2016, 23andMe, Inc. All rights reserved.
3 |
4 | Redistribution and use in source and binary forms, with or without modification,
5 | are permitted provided that the following conditions are met:
6 |
7 | 1. Redistributions of source code must retain the above copyright notice, this
8 | list of conditions and the following disclaimer.
9 |
10 | 2. Redistributions in binary form must reproduce the above copyright notice,
11 | this list of conditions and the following disclaimer in the documentation and/or
12 | other materials provided with the distribution.
13 |
14 | 3. Neither the name of the copyright holder(s) nor the names of any contributors
15 | may be used to endorse or promote products derived from this software without
16 | specific prior written permission. No license is granted to the trademarks of
17 | the copyright holders even if such marks are included in this software.
18 |
19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
23 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 | */
30 |
31 | #import
32 |
33 | NS_ASSUME_NONNULL_BEGIN
34 |
35 | @class ORKTwentyThreeAndMeConnectTaskViewController;
36 |
37 | /**
38 | The task view controller delegate is responsible for processing the results
39 | of the task, exerting some control over how the controller behaves, and providing
40 | auxiliary content as needed.
41 | */
42 | @protocol ORKTwentyThreeAndMeConnectTaskViewControllerDelegate
43 |
44 | /**
45 | Tells the delegate that the task has finished.
46 | */
47 | - (void)twentyThreeAndMeConnectTaskViewController:(ORKTwentyThreeAndMeConnectTaskViewController *)twentyThreeAndMeConnectTaskViewController
48 | didFinishWithResults:(NSDictionary *)results
49 | error:(nullable NSError *)error;
50 |
51 | @end
52 |
53 | /**
54 | *
55 | */
56 | ORK_CLASS_AVAILABLE
57 | @interface ORKTwentyThreeAndMeConnectTaskViewController : ORKTaskViewController
58 |
59 | /**
60 | The delegate for the connect task view controller.
61 | */
62 | @property (nonatomic, weak, nullable) id twentyThreeAndMeConnectDelegate;
63 |
64 | /**
65 | * Returns a predefined task view controller that connects a participant with 23andMe
66 | * Questions/Help: researchkit@23andme.com
67 | *
68 | * @param identifier Task identifier
69 | * @param allowedUserMode Identify the type of users to allow for the module
70 | * @param studyDependency Whether the study requires the module to be succesfully completed. Changes flow/text.
71 | * @param clientId oauth client id
72 | * @param clientSecret oauth client secret
73 | * @param scopes oauth scopes string (will be url encoded)
74 | * @param investigatorDisplayName User facing investigator name
75 | * @param studyDisplayName User facing study name
76 | * @param studyContactEmail Study contact email used in module
77 | *
78 | * @return ORKTwentyThreeAndMeConnectTaskViewController
79 | */
80 | + (ORKTwentyThreeAndMeConnectTaskViewController *)twentyThreeAndMeTaskViewControllerWithIdentifier:(NSString *)identifier
81 | allowedUserMode:(ORKTwentyThreeAndMeAllowedUserMode)allowedUserMode
82 | studyDependency:(ORKTwentyThreeAndMeStudyDependency)studyDependency
83 | authClientId:(NSString *)clientId
84 | authClientSecret:(NSString *)clientSecret
85 | authScopes:(NSString *)scopes
86 | investigatorDisplayName:(NSString *)investigatorDisplayName
87 | studyDisplayName:(NSString *)studyDisplayName
88 | studyContactEmail:(NSString *)studyContactEmail
89 | baseURLOverride:(nullable NSString *)baseURLOverride;
90 |
91 | @end
92 |
93 | NS_ASSUME_NONNULL_END
--------------------------------------------------------------------------------
/TwentyThreeAndMe/Tasks/ORKTwentyThreeAndMeConnectTaskViewController.m:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2016, 23andMe, Inc. All rights reserved.
3 |
4 | Redistribution and use in source and binary forms, with or without modification,
5 | are permitted provided that the following conditions are met:
6 |
7 | 1. Redistributions of source code must retain the above copyright notice, this
8 | list of conditions and the following disclaimer.
9 |
10 | 2. Redistributions in binary form must reproduce the above copyright notice,
11 | this list of conditions and the following disclaimer in the documentation and/or
12 | other materials provided with the distribution.
13 |
14 | 3. Neither the name of the copyright holder(s) nor the names of any contributors
15 | may be used to endorse or promote products derived from this software without
16 | specific prior written permission. No license is granted to the trademarks of
17 | the copyright holders even if such marks are included in this software.
18 |
19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
23 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 | */
30 |
31 | #import "ORKTwentyThreeAndMeConnectTaskViewController.h"
32 |
33 | #import "ORKOrderedTask+TwentyThreeAndMe.h"
34 | #import "ORKResult+TwentyThreeAndMe.h"
35 |
36 | @interface ORKTwentyThreeAndMeConnectTaskViewController ()
37 |
38 | @end
39 |
40 | @implementation ORKTwentyThreeAndMeConnectTaskViewController
41 |
42 | + (ORKTwentyThreeAndMeConnectTaskViewController *)twentyThreeAndMeTaskViewControllerWithIdentifier:(NSString *)identifier
43 | allowedUserMode:(ORKTwentyThreeAndMeAllowedUserMode)allowedUserMode
44 | studyDependency:(ORKTwentyThreeAndMeStudyDependency)studyDependency
45 | authClientId:(NSString *)clientId
46 | authClientSecret:(NSString *)clientSecret
47 | authScopes:(NSString *)scopes
48 | investigatorDisplayName:(NSString *)investigatorDisplayName
49 | studyDisplayName:(NSString *)studyDisplayName
50 | studyContactEmail:(NSString *)studyContactEmail
51 | baseURLOverride:(nullable NSString *)baseURLOverride {
52 | ORKOrderedTask *ttamTask = [ORKOrderedTask twentyThreeAndMeTaskWithIdentifier:identifier
53 | allowedUserMode:allowedUserMode
54 | studyDependency:studyDependency
55 | authClientId:clientId
56 | authClientSecret:clientSecret
57 | authScopes:scopes
58 | investigatorDisplayName:investigatorDisplayName
59 | studyDisplayName:studyDisplayName
60 | studyContactEmail:studyContactEmail
61 | baseURLOverride:baseURLOverride];
62 |
63 | ORKTwentyThreeAndMeConnectTaskViewController *ttamTaskViewController = [[ORKTwentyThreeAndMeConnectTaskViewController alloc] initWithTask:ttamTask
64 | taskRunUUID:nil];
65 | ttamTaskViewController.delegate = ttamTaskViewController;
66 | ttamTaskViewController.showsProgressInNavigationBar = NO;
67 |
68 | return ttamTaskViewController;
69 | }
70 |
71 | #pragma mark Protocol ORKTaskViewControllerDelegate
72 |
73 | - (void)taskViewController:(ORKTaskViewController *)taskViewController
74 | didFinishWithReason:(ORKTaskViewControllerFinishReason)reason
75 | error:(nullable NSError *)error {
76 | NSMutableDictionary *resultDict = [NSMutableDictionary dictionary];
77 | if( reason == ORKTaskViewControllerFinishReasonDiscarded ) {
78 | if( self.twentyThreeAndMeConnectDelegate ) {
79 | [resultDict setObject:@"cancelled" forKey:@"completionType"];
80 | [self.twentyThreeAndMeConnectDelegate twentyThreeAndMeConnectTaskViewController:self didFinishWithResults:resultDict error:nil];
81 | }
82 | }
83 | else if( reason == ORKTaskViewControllerFinishReasonCompleted ) {
84 | if( self.twentyThreeAndMeConnectDelegate ) {
85 | ORKTaskResult *taskResult = [taskViewController result];
86 | ORKCollectionResult *connectResultCollection = (ORKCollectionResult *)[taskResult resultForIdentifier:@"twentyThreeAndMe.connect"];
87 | ORKTwentyThreeAndMeConnectResult *connectResult = (ORKTwentyThreeAndMeConnectResult *)[connectResultCollection.results firstObject];
88 | if( connectResult ) {
89 | [resultDict setObject:connectResult.authToken forKey:@"authToken"];
90 | [resultDict setObject:connectResult.refreshToken forKey:@"refreshToken"];
91 | }
92 |
93 | [resultDict setObject:@"success" forKey:@"completionType"];
94 | [self.twentyThreeAndMeConnectDelegate twentyThreeAndMeConnectTaskViewController:self didFinishWithResults:resultDict error:nil];
95 | }
96 | }
97 | }
98 |
99 | - (void)taskViewController:(ORKTaskViewController *)taskViewController stepViewControllerWillAppear:(ORKStepViewController *)stepViewController {
100 | [stepViewController.backButtonItem setTintColor:[UIColor colorWithRed:146.0/255.0 green:199.0/255.0 blue:70.0/255.0 alpha:1.0]];
101 | [stepViewController.cancelButtonItem setTintColor:[UIColor colorWithRed:146.0/255.0 green:199.0/255.0 blue:70.0/255.0 alpha:1.0]];
102 | }
103 |
104 | @end
105 |
--------------------------------------------------------------------------------
/TwentyThreeAndMe/UIHelpers/UIButton+T23.h:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2016, 23andMe, Inc. All rights reserved.
3 |
4 | Redistribution and use in source and binary forms, with or without modification,
5 | are permitted provided that the following conditions are met:
6 |
7 | 1. Redistributions of source code must retain the above copyright notice, this
8 | list of conditions and the following disclaimer.
9 |
10 | 2. Redistributions in binary form must reproduce the above copyright notice,
11 | this list of conditions and the following disclaimer in the documentation and/or
12 | other materials provided with the distribution.
13 |
14 | 3. Neither the name of the copyright holder(s) nor the names of any contributors
15 | may be used to endorse or promote products derived from this software without
16 | specific prior written permission. No license is granted to the trademarks of
17 | the copyright holders even if such marks are included in this software.
18 |
19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
23 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 | */
30 |
31 |
32 | #import
33 |
34 | @interface UIButton (T23)
35 |
36 | /**
37 | * Helper to build a styled button for 23andMe module content
38 | *
39 | * @param text Button Text string
40 | * @param hasBorder Whether this button should have a styled border
41 | *
42 | * @return UIButton
43 | */
44 | + (UIButton *)t23ButtonWithText:(NSString *)text andHasBorder:(BOOL)hasBorder;
45 |
46 | @end
47 |
--------------------------------------------------------------------------------
/TwentyThreeAndMe/UIHelpers/UIButton+T23.m:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2016, 23andMe, Inc. All rights reserved.
3 |
4 | Redistribution and use in source and binary forms, with or without modification,
5 | are permitted provided that the following conditions are met:
6 |
7 | 1. Redistributions of source code must retain the above copyright notice, this
8 | list of conditions and the following disclaimer.
9 |
10 | 2. Redistributions in binary form must reproduce the above copyright notice,
11 | this list of conditions and the following disclaimer in the documentation and/or
12 | other materials provided with the distribution.
13 |
14 | 3. Neither the name of the copyright holder(s) nor the names of any contributors
15 | may be used to endorse or promote products derived from this software without
16 | specific prior written permission. No license is granted to the trademarks of
17 | the copyright holders even if such marks are included in this software.
18 |
19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
23 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 | */
30 |
31 | #import "UIButton+T23.h"
32 |
33 | @implementation UIButton (T23)
34 |
35 | + (UIButton *)t23ButtonWithText:(NSString *)text andHasBorder:(BOOL)hasBorder {
36 | UIButton *button = [[UIButton alloc] init];
37 | [button setTitle:text forState:UIControlStateNormal];
38 | button.titleLabel.font = [UIFont systemFontOfSize:16.0];
39 | UIColor *t23ButtonGreen = [UIColor colorWithRed:146.0/255.0 green:199.0/255.0 blue:70.0/255.0 alpha:1.0];
40 | [button setTitleColor:t23ButtonGreen forState:UIControlStateNormal];
41 | button.contentEdgeInsets = UIEdgeInsetsMake(0.0, 24.0, 0.0, 24.0);
42 | if( hasBorder ) {
43 | button.layer.cornerRadius = 3.0;
44 | button.layer.borderColor = t23ButtonGreen.CGColor;
45 | button.layer.borderWidth = 1.0;
46 | }
47 | button.translatesAutoresizingMaskIntoConstraints = NO;
48 | [button addConstraint:[NSLayoutConstraint constraintWithItem:button
49 | attribute:NSLayoutAttributeHeight
50 | relatedBy:NSLayoutRelationEqual
51 | toItem:nil
52 | attribute:NSLayoutAttributeNotAnAttribute
53 | multiplier:1.0
54 | constant:45.0]];
55 | return button;
56 | }
57 |
58 | @end
59 |
--------------------------------------------------------------------------------
/TwentyThreeAndMe/UIHelpers/UILabel+T23.h:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2016, 23andMe, Inc. All rights reserved.
3 |
4 | Redistribution and use in source and binary forms, with or without modification,
5 | are permitted provided that the following conditions are met:
6 |
7 | 1. Redistributions of source code must retain the above copyright notice, this
8 | list of conditions and the following disclaimer.
9 |
10 | 2. Redistributions in binary form must reproduce the above copyright notice,
11 | this list of conditions and the following disclaimer in the documentation and/or
12 | other materials provided with the distribution.
13 |
14 | 3. Neither the name of the copyright holder(s) nor the names of any contributors
15 | may be used to endorse or promote products derived from this software without
16 | specific prior written permission. No license is granted to the trademarks of
17 | the copyright holders even if such marks are included in this software.
18 |
19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
23 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 | */
30 |
31 | #import
32 |
33 | @interface UILabel (T23)
34 |
35 | /**
36 | * Helper to generate styled labels for 23andMe module
37 | *
38 | * @param text Text for label to display
39 | *
40 | * @return Styled UILabel
41 | */
42 | + (UILabel *)t23HeaderLabelWithText:(NSString *)text;
43 |
44 | /**
45 | * Helper to generate styled labels for 23andMe module
46 | *
47 | * @param text Text for label to display
48 | *
49 | * @return Styled UILabel
50 | */
51 | + (UILabel *)t23SubheaderLabelWithText:(NSString *)text;
52 |
53 | /**
54 | * Helper to generate styled labels for 23andMe module
55 | *
56 | * @param text Text for label to display
57 | *
58 | * @return Styled UILabel
59 | */
60 | + (UILabel *)t23BodyLabelWithText:(NSString *)text;
61 |
62 | @end
63 |
--------------------------------------------------------------------------------
/TwentyThreeAndMe/UIHelpers/UILabel+T23.m:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2016, 23andMe, Inc. All rights reserved.
3 |
4 | Redistribution and use in source and binary forms, with or without modification,
5 | are permitted provided that the following conditions are met:
6 |
7 | 1. Redistributions of source code must retain the above copyright notice, this
8 | list of conditions and the following disclaimer.
9 |
10 | 2. Redistributions in binary form must reproduce the above copyright notice,
11 | this list of conditions and the following disclaimer in the documentation and/or
12 | other materials provided with the distribution.
13 |
14 | 3. Neither the name of the copyright holder(s) nor the names of any contributors
15 | may be used to endorse or promote products derived from this software without
16 | specific prior written permission. No license is granted to the trademarks of
17 | the copyright holders even if such marks are included in this software.
18 |
19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
23 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 | */
30 |
31 | #import "UILabel+T23.h"
32 |
33 | @implementation UILabel (T23)
34 |
35 | + (UILabel *)t23HeaderLabelWithText:(NSString *)text
36 | {
37 | UILabel *label = [[UILabel alloc] init];
38 | if( [UIFont instancesRespondToSelector:@selector(systemFontOfSize:weight:)] ) {
39 | label.font = [UIFont systemFontOfSize:22.0 weight:UIFontWeightSemibold];
40 | }
41 | else {
42 | label.font = [UIFont boldSystemFontOfSize:22.0];
43 | }
44 | label.numberOfLines = 1;
45 | label.textColor = [UIColor colorWithRed:51.0/255.0 green:52.0/255.0 blue:53.0/255.0 alpha:1.0];
46 | label.text = text;
47 | label.textAlignment = NSTextAlignmentCenter;
48 | return label;
49 | }
50 |
51 | + (UILabel *)t23SubheaderLabelWithText:(NSString *)text
52 | {
53 | UILabel *label = [[UILabel alloc] init];
54 | if( [UIFont instancesRespondToSelector:@selector(systemFontOfSize:weight:)] ) {
55 | label.font = [UIFont systemFontOfSize:16.0 weight:UIFontWeightSemibold];
56 | }
57 | else {
58 | label.font = [UIFont boldSystemFontOfSize:16.0];
59 | }
60 | label.numberOfLines = 1;
61 | label.textColor = [UIColor colorWithRed:51.0/255.0 green:52.0/255.0 blue:53.0/255.0 alpha:1.0];
62 | label.text = text;
63 | label.textAlignment = NSTextAlignmentLeft;
64 | return label;
65 | }
66 |
67 | + (UILabel *)t23BodyLabelWithText:(NSString *)text
68 | {
69 | UILabel *label = [[UILabel alloc] init];
70 | label.font = [UIFont systemFontOfSize:16.0];
71 | label.numberOfLines = 0;
72 | label.textColor = [UIColor colorWithRed:51.0/255.0 green:52.0/255.0 blue:53.0/255.0 alpha:1.0];
73 | label.text = text;
74 | label.textAlignment = NSTextAlignmentLeft;
75 | return label;
76 | }
77 |
78 | @end
79 |
--------------------------------------------------------------------------------