diff --git a/README.md b/README.md index 9df8fef..8f4ac73 100644 --- a/README.md +++ b/README.md @@ -388,3 +388,183 @@ Al finalizar, se puede correr la aplicación y observar las diferentes secciones Debido a que los desarroladores de Apple, utilizan el idioma para hacer sus aplicaciones y el soporte, algunas de las secciones en la aplicación, podrían estar en idioma inglés. +Al tener terminado el consentimiento, se tendrá que enviar a una nueva pantalla donde se encuentran los formularios, tareas y demás actividades que ResearchKit permite hacer, ya que al momento de terminar solo se regresa a la pantalla principal. + +Para hacer este cambio de cuando el consentimiento este completo, se crea una condicion *if* en el **IntroViewController** que indique que si se completó el consentimiento, proceda a la pantalla de **TasksViewController**, o e su defecto que haga efecto el segue, toTasks. + +``` + override func viewDidLoad() { + super.viewDidLoad() + // Do any additional setup after loading the view, typically from a nib. + if ORKPasscodeViewController.isPasscodeStoredInKeychain(){ + toTasks() + }else{ + toConsent() + } + } +``` + +Sin olvidarse de importar ResearchKitUI + +Además, se tiene que llevar al usuario al controlador de vista(TasksViewController) de tareas cuando se completen las tareas del consentimiento. Por ello, se agrega el sigueinte código al **IntroViewController**: + +``` +@IBAction func unwindToTasks(_ segue: UIStoryboardSegue){ + toTasks() +} + +``` + +y desde el main.storyboard se debe arrastrar con click derecho desde la pantalla de ConsentViewController del boton principal, (ConsentViewController) hasta el de exit y seleccionar la unica opcion que hay que es unwindTotask. + + +![](imagenes/unwind1.png) +![](imagenes/unwind2.png) + +y agregaremos un identificador al segue con el nombre unwindToTask. + +![](imagenes/unwind3.png) + +Se dirigirá al ConsentViewController en la funcion taskViewController que se encuentra en la parte inferior y la modificará para que haga la correcta transición del nuevo segue: + +``` + func taskViewController(_ taskViewController: ORKTaskViewController, didFinishWith reason: ORKTaskFinishReason, error: Error?) { + + switch reason { + case .completed: + performSegue(withIdentifier: "unwindToTasks", sender: nil) + case .discarded: + dismiss(animated: true, completion: nil) + case .failed: + dismiss(animated: true, completion: nil) + case .saved: + dismiss(animated: true, completion: nil) + case .earlyTermination: + dismiss(animated: true, completion: nil) + + @unknown default: + dismiss(animated: true, completion: nil) + } + } +``` + +En el TasksViewController del Main.storyboard se requiere crear un nuevo botón para el abandono del estudio y así poder regresar a la pantalla de inicio. + +![](imagenes/bAbandonar.png) + +y para hacer el regreso a la pantalla de Consent al presionar el botón de abandonar, se crea, un segue de tipo show hasta el ConsentViewController. Y a este segue, se le pondrá un identificador que lleve por nombre returnToConsent: + +![](imagenes/returnC.png) +![](imagenes/returnC1.png) +![](imagenes/returnC2.png) + +Para hacer que funcione este segue al presionar el botón de abandonar el estudio, en el TasksViewController, es necesario crear un ButtonAction de tipo UIButton +con el nombre leaveButtonTapped. + +![](imagenes/Bleave.png) + +en el código generado se pondra el siguiente código, el cual elimina el almacén de contraseñas y presenta el ConsentViewController: + +``` +ORKPasscodeViewController.removePasscodeFromKeychain() +performSegue(withIdentifier: "returnToConsent", sender: nil) + +``` +De esta manera, el usuario abandonará el estudio, y si desea unirse de nuevo, se le presentará el documento de consentimiento y se le pedirá que cree un código de acceso. + +Afortunadamente, ResearchKit no solo tiene la herramienta para visualizar el proceso de consentimiento, sino también la herramienta para guardar el documento de consentimiento firmado como PDF. + +Para hacer la visualización del consentimiento se tiene que modificar desde el **ConsentViewController** la función *func taskViewController(_ taskViewController: ORKTaskViewController, didFinishWith reason: ORKTaskFinishReason, error: Error?) {* + +con el sigueinte código: + +``` + func taskViewController(_ taskViewController: ORKTaskViewController, didFinishWith reason: ORKTaskFinishReason, error: Error?) { + + switch reason { + case .completed: + // Obtener el resultado de la firma + guard let signatureResult = taskViewController.result.stepResult(forStepIdentifier: "ConsentReviewStep")?.firstResult as? ORKConsentSignatureResult else { + print("No se pudo obtener el resultado de la firma.") + return + } + + // Crear una copia del documento de consentimiento + let consentDocument = ConsentDocument.copy() as! ORKConsentDocument + signatureResult.apply(to: consentDocument) + + // Generar el PDF + consentDocument.makePDF { (data, error) in + if let error = error { + print("Error al crear PDF: \(error.localizedDescription)") + return + } + + guard let data = data else { + print("No se generó ningún dato para el PDF.") + return + } + + // Guardar el PDF en el directorio de documentos + do { + var docURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).last + docURL = docURL?.appendingPathComponent("consent.pdf") + try data.write(to: docURL!, options: .atomicWrite) + print("PDF guardado en: \(docURL!.path)") + } catch { + print("Error al guardar el PDF: \(error.localizedDescription)") + } + } + + // Realizar la transición al siguiente controlador + performSegue(withIdentifier: "unwindToTasks", sender: nil) + + case .discarded, .failed, .saved: + dismiss(animated: true, completion: nil) + + case .earlyTermination: + dismiss(animated: true, completion: nil) + + @unknown default: + // Manejar casos no contemplados + dismiss(animated: true, completion: nil) + } + } +``` + +y se creará un nuevo botón en la pantalla del **TasksViewController** donde al presionar se pueda visualizar el consentimiento que se firmó. + +Al botón generado se le generará un Button Action con el Nombre consentButtonTapped de tipo UIButton, directamente ne **TasksViewController**. + +![](imagenes/consentPDF.png) + +y se le agrega el siguiente código para generar el PDF. + +``` + @IBAction func consentButtonTapped(_ sender: UIButton) { + let taskViewController = ORKTaskViewController(task: consentPDFViewerTask(), taskRun: nil) + taskViewController.delegate = self + present(taskViewController, animated: true, completion: nil) + + } + + func consentPDFViewerTask() -> ORKOrderedTask{ + var docURL = (FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)).last + docURL = docURL?.appendingPathComponent("consent.pdf") + let PDFViewerStep = ORKPDFViewerStep.init(identifier: "ConsentPDFViewer", pdfURL: docURL) + PDFViewerStep.title = "Consent" + return ORKOrderedTask(identifier: String("ConsentPDF"), steps: [PDFViewerStep]) + } + + @objc(taskViewController:didFinishWithReason:error:) func taskViewController(_ taskViewController: ORKTaskViewController, didFinishWith reason: ORKTaskFinishReason, error: Error?) { + taskViewController.dismiss(animated: true, completion: nil) + } +``` + +sin olvidar agregar *ORKTaskViewControllerDelegate* en la clase principal + +Para comprobar el funcionameinto, se procede a realizar el consentimiento y al teminar, se da click en el Consentimiento PDF y generará algo como lo siguiente: + +![](imagenes/pdfC.png) + + diff --git a/RK-Journals/RK-Journals.xcodeproj/project.xcworkspace/xcuserdata/JD2207.xcuserdatad/UserInterfaceState.xcuserstate b/RK-Journals/RK-Journals.xcodeproj/project.xcworkspace/xcuserdata/JD2207.xcuserdatad/UserInterfaceState.xcuserstate index e61f0e6..e864310 100644 Binary files a/RK-Journals/RK-Journals.xcodeproj/project.xcworkspace/xcuserdata/JD2207.xcuserdatad/UserInterfaceState.xcuserstate and b/RK-Journals/RK-Journals.xcodeproj/project.xcworkspace/xcuserdata/JD2207.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/RK-Journals/RK-Journals/Base.lproj/Main.storyboard b/RK-Journals/RK-Journals/Base.lproj/Main.storyboard index 56e5a98..1cfc608 100644 --- a/RK-Journals/RK-Journals/Base.lproj/Main.storyboard +++ b/RK-Journals/RK-Journals/Base.lproj/Main.storyboard @@ -27,31 +27,65 @@ - + - + + + + + + + + + + + + + + + - + - +