title: Research Kit - Objective-C error: "Visual consent step has no visible scenes"
body: <p>edit: I finally solved this, it was a combination of a caching problem and a missing line of code. I never actually added the task to the view controller, somehow I missed that step. But also I had strange errors just running the github demo project and had to reboot and sudo delete the cache directory in order to get Xcode to function as it should.</p>
  
  <hr>
  
  <p>I am trying to implement Research Kit in Objective-C. There are no tutorials and very little documentation to turn to. I am getting a crash "Visual consent step has no visible scenes". I have one view controller and on that view controller I have a button that triggers the IBAction "consentTapped". I have attempted to adapt the Ray Wenderlich tutorial <a href="http://www.raywenderlich.com/104575/researchkit-tutorial-with-swift" rel="nofollow">http://www.raywenderlich.com/104575/researchkit-tutorial-with-swift</a> and this GitHub project: <a href="https://github.com/weberbry/ResearchKitConsentDemo" rel="nofollow">https://github.com/weberbry/ResearchKitConsentDemo</a></p>
  
  <p>In an attempt to troubleshoot this myself I have put all the code in viewDidAppear, taking it out of encapsulated methods because I thought I made a mistake that way but there is still a problem:</p>
  
  <p>Here is my code:</p>
  
  <pre><code>#import "ViewController.h"
  #import &lt;ResearchKit/ResearchKit.h&gt;
  
  @interface ViewController ()&lt;ORKTaskViewControllerDelegate&gt;
  
  @property (strong, nonatomic) ORKConsentDocument *consentDocument;
  @property (strong, nonatomic) ORKOrderedTask *orderedTask;
  @end
  
  @implementation ViewController
  
  - (void)viewDidLoad {
      [super viewDidLoad];
  }
  
  - (void)viewDidAppear:(BOOL)animated {
      [super viewDidAppear:animated];
  
  
      NSString *resource = [[NSBundle mainBundle] pathForResource:@"ConsentText" ofType:@"json"];
      NSData *consentData = [NSData dataWithContentsOfFile:resource];
      NSDictionary *parsedConsentData = [NSJSONSerialization JSONObjectWithData:consentData options:NSJSONReadingMutableContainers error:nil];
  
      NSArray *sectionDataParsedFromInputFile = [parsedConsentData objectForKey:@"sections"];
  
  
      NSMutableArray *consentSections = [NSMutableArray new];
      for (NSDictionary *sectionDictionary in sectionDataParsedFromInputFile) {
  
  
          ORKConsentSectionType sectionType = [[sectionDictionary objectForKey:@"sectionType"] integerValue];
          NSString *title = [sectionDictionary objectForKey:@"sectionTitle"];
          NSString *summary = [sectionDictionary objectForKey:@"sectionSummary"];
          NSString *detail = [sectionDictionary objectForKey:@"sectionDetail"];
  
          ORKConsentSection *section = [[ORKConsentSection alloc] initWithType:sectionType];
          section.title = title;
          section.summary = summary;
          section.htmlContent = detail;
  
  
          ORKConsentSection *consentSection = section;
          [consentSections addObject:consentSection];
      }
  
  
      ORKConsentSection *introSection = [[ORKConsentSection alloc] initWithType:ORKConsentSectionTypeOnlyInDocument];
      introSection.title = @"Intro Language";
      introSection.content = @"This will only be shown in the consent document because this sectionType is map to ORKConsentSectionTypeOnlyInDocument. A consent document can include many sections with type ORKConsentSectionTypeOnlyInDocument. In this document there is a ORKConsentSectionTypeOnlyInDocument section as an intro and one as a closing section";
      [consentSections insertObject:introSection atIndex:0];
  
  
      ORKConsentSection *closingSection = [[ORKConsentSection alloc] initWithType:ORKConsentSectionTypeOnlyInDocument];
      closingSection.title = @"Additional Terms";
      closingSection.htmlContent = @"Adding a ORKConsentSectionTypeOnlyInDocument at the end of a consent can be helpful to include any additional legal or related information.";
      [consentSections addObject:closingSection];
  
  
      self.consentDocument = [ORKConsentDocument new];
      self.consentDocument.title = @"Demo Consent";
      self.consentDocument.sections = consentSections;
  
  
      ORKConsentSignature *signature = [ORKConsentSignature new];
      self.consentDocument.signatures = [NSArray arrayWithObject:signature];
  
  
      ORKVisualConsentStep *visualConsentStep = [[ORKVisualConsentStep alloc] initWithIdentifier:@"visualConsentStep" document:self.consentDocument];
  
  
      ORKConsentReviewStep *consentReviewStep = [[ORKConsentReviewStep alloc] initWithIdentifier:@"consentReviewStep" signature:self.consentDocument.signatures.firstObject inDocument:self.consentDocument];
      consentReviewStep.text = @"Review Consent!";
      consentReviewStep.reasonForConsent = @"I confirm that I consent to join this study";
  
      self.orderedTask =  [[ORKOrderedTask alloc] initWithIdentifier:@"consent" steps:@[visualConsentStep, consentReviewStep]];
  
  }
  
  - (IBAction)consentTapped:(id)sender {
  
      ORKTaskViewController *taskViewController = [[ORKTaskViewController alloc]initWithTask:self.orderedTask taskRunUUID:nil];
      taskViewController.delegate = self;
      [self presentViewController:taskViewController animated:YES completion:nil];
  }
  
  - (void)taskViewController:(ORKTaskViewController *)taskViewController
         didFinishWithReason:(ORKTaskViewControllerFinishReason)reason
                       error:(NSError *)error {
      ORKTaskResult *taskResult = [taskViewController result];
      [self dismissViewControllerAnimated:YES completion:nil];
  }
  </code></pre>
  
  <p>Due to the wording of the error I feel like there should be another view controller scene but I didn't see one on the Ray Wenderlich tutorial unless I missed it. I don't know swift at all yet so if you do and you see that I missed something please let me know.</p>
  
  <p>The crash happens as you leave viewDidAppear. </p>
  
  <p>Also this is my very first post here so if I have not followed community guidelines please let me know and I will modify my post at once.</p>
  
  <hr>
  
  <p>edit: here is the working code. And remember, sudo delete your DerivedData folder, and reboot if you have strange errors in addition to the original error I posted. The missing line was "taskViewController.task = self.orderedTask;"</p>
  
  <pre><code>#import "ViewController.h"
  #import &lt;ResearchKit/ResearchKit.h&gt;
  
  @interface ViewController ()&lt;ORKTaskViewControllerDelegate&gt;
  
  @property (strong, nonatomic) ORKConsentDocument *consentDocument;
  @property (strong, nonatomic) ORKOrderedTask *orderedTask;
  @end
  
  @implementation ViewController
  
  - (void)viewDidLoad {
      [super viewDidLoad];
  }
  
  - (void)viewDidAppear:(BOOL)animated {
      [super viewDidAppear:animated];
  
  
      NSString *resource = [[NSBundle mainBundle] pathForResource:@"ConsentText" ofType:@"json"];
      NSData *consentData = [NSData dataWithContentsOfFile:resource];
      NSDictionary *parsedConsentData = [NSJSONSerialization JSONObjectWithData:consentData options:NSJSONReadingMutableContainers error:nil];
  
      NSArray *sectionDataParsedFromInputFile = [parsedConsentData objectForKey:@"sections"];
  
      NSMutableArray *consentSections = [NSMutableArray new];
      for (NSDictionary *sectionDictionary in sectionDataParsedFromInputFile) {
  
          ORKConsentSectionType sectionType = [[sectionDictionary objectForKey:@"sectionType"] integerValue];
          NSString *title = [sectionDictionary objectForKey:@"sectionTitle"];
          NSString *summary = [sectionDictionary objectForKey:@"sectionSummary"];
          NSString *detail = [sectionDictionary objectForKey:@"sectionDetail"];
  
          ORKConsentSection *section = [[ORKConsentSection alloc] initWithType:sectionType];
          section.title = title;
          section.summary = summary;
          section.htmlContent = detail;
  
          ORKConsentSection *consentSection = section;
          [consentSections addObject:consentSection];
      }
  
      ORKConsentSection *introSection = [[ORKConsentSection alloc] initWithType:ORKConsentSectionTypeOnlyInDocument];
      introSection.title = @"Intro Language";
      introSection.htmlContent = @"This will only be shown in the consent document because this sectionType is map to ORKConsentSectionTypeOnlyInDocument. A consent document can include many sections with type ORKConsentSectionTypeOnlyInDocument. In this document there is a ORKConsentSectionTypeOnlyInDocument section as an intro and one as a closing section";
  
      [consentSections insertObject:introSection atIndex:0];
  
  
      ORKConsentSection *closingSection = [[ORKConsentSection alloc] initWithType:ORKConsentSectionTypeOnlyInDocument];
      closingSection.title = @"Additional Terms";
      closingSection.htmlContent = @"Adding a ORKConsentSectionTypeOnlyInDocument at the end of a consent can be helpful to include any additional legal or related information.";
      [consentSections addObject:closingSection];
  
  
      NSArray *sections = consentSections;
  
  
      self.consentDocument = [ORKConsentDocument new];
      self.consentDocument.title = @"Demo Consent";
      self.consentDocument.sections = consentSections;
  
      ORKConsentSignature *signature = [ORKConsentSignature new];
      self.consentDocument.signatures = [NSArray arrayWithObject:signature];
  
  
      ORKVisualConsentStep *visualConsentStep = [[ORKVisualConsentStep alloc] initWithIdentifier:@"visualConsentStep" document:self.consentDocument];
  
  
      ORKConsentReviewStep *consentReviewStep = [[ORKConsentReviewStep alloc] initWithIdentifier:@"consentReviewStep" signature:self.consentDocument.signatures.firstObject inDocument:self.consentDocument];
      consentReviewStep.text = @"Review Consent!";
      consentReviewStep.reasonForConsent = @"I confirm that I consent to join this study";
  
  
      self.orderedTask =  [[ORKOrderedTask alloc] initWithIdentifier:@"consent" steps:@[visualConsentStep, consentReviewStep]];
  
  }
  
  - (IBAction)consentTapped:(id)sender {
  
      ORKTaskViewController *taskViewController = [[ORKTaskViewController alloc] init];
      taskViewController.task = self.orderedTask;
      taskViewController.delegate = self;
      [self presentViewController:taskViewController animated:YES completion:nil];
  }
  
  - (void)taskViewController:(ORKTaskViewController *)taskViewController
         didFinishWithReason:(ORKTaskViewControllerFinishReason)reason
                       error:(NSError *)error {
      ORKTaskResult *taskResult = [taskViewController result];
      [self dismissViewControllerAnimated:YES completion:nil];
  }
  </code></pre>