From ca3ccf33254ff9fd132f43badb129818b0974a0e Mon Sep 17 00:00:00 2001 From: Paul Schmiedmayer Date: Fri, 24 May 2024 16:26:36 -0700 Subject: [PATCH 1/3] Update API Interactions --- NCIClinicalTrialsSearchAPI.json | 7 ++++++- .../.openapi-generator/VERSION | 2 +- .../Classes/OpenAPIs/APIHelper.swift | 4 ++-- .../Classes/OpenAPIs/APIs/TrialsAPI.swift | 4 ++-- .../OpenAPIs/URLSessionImplementations.swift | 20 ++++++++++++++++--- NCIClinicalTrialsSearchAPI/README.md | 1 + NCIClinicalTrialsSearchAPI/docs/TrialsAPI.md | 6 +++--- .../ClinicalTrials/NCITrialsModel.swift | 2 +- 8 files changed, 33 insertions(+), 13 deletions(-) diff --git a/NCIClinicalTrialsSearchAPI.json b/NCIClinicalTrialsSearchAPI.json index 3471032..a72d1fe 100644 --- a/NCIClinicalTrialsSearchAPI.json +++ b/NCIClinicalTrialsSearchAPI.json @@ -1558,8 +1558,13 @@ "description": "Text to be searched in multiple fields. It can be combined with keyword_field.

keyword filter results by examining a variety of text-based fields (By default: *_id, other_ids.value, diseases.name._fulltext, diseases.synonyms._fulltext, brief_title, brief_summary, official_title, detail_description, official_title, brief_title, brief_summary, diseases.name._fulltext, detail_description, sites.org_name._fulltext, collaborators.name._fulltext, principal_investigator._fulltext, sites.contact_name._fulltext, sites.org_city._fulltext, sites.org_state_or_province._fulltext, arms.interventions.name, arms.interventions.synonyms, biomarkers.name, biomarkers.synonyms, prior_therapy.name, prior_therapy.synonyms).

Mutiple keywords (with a maximum of 10 allowed) will give you an OR condition of between values in all configured fields.", "required": false, "schema": { - "type": "string" + "type": "array", + "items": { + "type": "string" + } }, + "style": "form", + "explode": true, "examples": { "": { "value": "" diff --git a/NCIClinicalTrialsSearchAPI/.openapi-generator/VERSION b/NCIClinicalTrialsSearchAPI/.openapi-generator/VERSION index 8b23b8d..18bb418 100644 --- a/NCIClinicalTrialsSearchAPI/.openapi-generator/VERSION +++ b/NCIClinicalTrialsSearchAPI/.openapi-generator/VERSION @@ -1 +1 @@ -7.3.0 \ No newline at end of file +7.5.0 diff --git a/NCIClinicalTrialsSearchAPI/OpenAPIClient/Classes/OpenAPIs/APIHelper.swift b/NCIClinicalTrialsSearchAPI/OpenAPIClient/Classes/OpenAPIs/APIHelper.swift index 93c5c76..6dd1b44 100644 --- a/NCIClinicalTrialsSearchAPI/OpenAPIClient/Classes/OpenAPIs/APIHelper.swift +++ b/NCIClinicalTrialsSearchAPI/OpenAPIClient/Classes/OpenAPIs/APIHelper.swift @@ -91,7 +91,7 @@ public struct APIHelper { if destination.isEmpty { return nil } - return destination + return destination.sorted { $0.name < $1.name } } /// maps all values from source to query parameters @@ -114,6 +114,6 @@ public struct APIHelper { if destination.isEmpty { return nil } - return destination + return destination.sorted { $0.name < $1.name } } } diff --git a/NCIClinicalTrialsSearchAPI/OpenAPIClient/Classes/OpenAPIs/APIs/TrialsAPI.swift b/NCIClinicalTrialsSearchAPI/OpenAPIClient/Classes/OpenAPIs/APIs/TrialsAPI.swift index 616d0f3..5e3eace 100644 --- a/NCIClinicalTrialsSearchAPI/OpenAPIClient/Classes/OpenAPIs/APIs/TrialsAPI.swift +++ b/NCIClinicalTrialsSearchAPI/OpenAPIClient/Classes/OpenAPIs/APIs/TrialsAPI.swift @@ -164,7 +164,7 @@ open class TrialsAPI { - parameter completion: completion handler to receive the data and the error objects */ @discardableResult - open class func searchTrialsByGet(size: Int? = nil, from: Int? = nil, sort: String? = nil, order: String? = nil, missing: String? = nil, exists: String? = nil, include: String? = nil, exclude: String? = nil, export: String? = nil, email: String? = nil, filename: String? = nil, fulltext: String? = nil, fieldParamFulltext: String? = nil, trialids: String? = nil, trialIds: String? = nil, keyword: String? = nil, keywordField: String? = nil, aggField: String? = nil, aggName: String? = nil, aggMinCount: Int? = nil, sitesOrgNameFulltext: String? = nil, trialStatus: String? = nil, nciFunded: String? = nil, nciId: String? = nil, nctId: String? = nil, protocolId: String? = nil, ccrId: String? = nil, ctepId: String? = nil, dcpId: String? = nil, currentTrialStatus: String? = nil, phase: String? = nil, studyProtocolType: String? = nil, nciPrograms: String? = nil, briefTitle: String? = nil, briefSummary: String? = nil, officialTitle: String? = nil, primaryPurpose: String? = nil, acceptsHealthyVolunteersIndicator: String? = nil, eligibilityStructuredAcceptsHealthyVolunteers: Bool? = nil, acronym: String? = nil, amendmentDate: String? = nil, anatomicSites: String? = nil, armsDescription: String? = nil, armsName: String? = nil, armsType: String? = nil, armsInterventionsNciThesaurusConceptId: String? = nil, armsInterventionsDescription: String? = nil, armsInterventionsName: String? = nil, armsInterventionsType: String? = nil, armsInterventionsSynonyms: String? = nil, associatedStudiesStudyId: String? = nil, associatedStudiesStudyIdType: String? = nil, eligibilityStructuredGender: String? = nil, eligibilityStructuredMinAgeInYearsLte: Int? = nil, eligibilityStructuredMinAgeInYearsGte: Int? = nil, eligibilityStructuredMaxAgeInYearsLte: Int? = nil, eligibilityStructuredMaxAgeInYearsGte: Int? = nil, eligibilityStructuredMinAgeUnit: String? = nil, eligibilityStructuredMinAgeNumberLte: Int? = nil, eligibilityStructuredMinAgeNumberGte: Int? = nil, eligibilityStructuredMaxAgeUnit: String? = nil, eligibilityStructuredMaxAgeNumberLte: Int? = nil, eligibilityStructuredMaxAgeNumberGte: Int? = nil, currentTrialStatusDateLte: String? = nil, currentTrialStatusDateGte: String? = nil, recordVerificationDateLte: String? = nil, recordVerificationDateGte: String? = nil, sitesOrgCoordinatesLat: Double? = nil, sitesOrgCoordinatesLon: Double? = nil, sitesOrgCoordinatesDist: String? = nil, sitesContactEmail: String? = nil, sitesContactName: String? = nil, sitesContactNameAuto: String? = nil, sitesContactNameRaw: String? = nil, sitesContactPhone: String? = nil, sitesOrgAddressLine1: String? = nil, sitesOrgAddressLine2: String? = nil, sitesOrgCity: String? = nil, sitesOrgPostalCode: String? = nil, sitesOrgStateOrProvince: String? = nil, sitesOrgCountry: String? = nil, sitesOrgCountryRaw: String? = nil, sitesOrgEmail: String? = nil, sitesOrgFamily: String? = nil, sitesOrgFax: String? = nil, sitesOrgName: String? = nil, sitesOrgNameAuto: String? = nil, sitesOrgNameRaw: String? = nil, sitesOrgPhone: String? = nil, sitesRecruitmentStatus: String? = nil, sitesRecruitmentStatusDate: String? = nil, sitesRecruitmentStatusDateLte: String? = nil, sitesRecruitmentStatusDateGte: String? = nil, leadOrgCancerCenter: String? = nil, apiResponseQueue: DispatchQueue = OpenAPIClientAPI.apiResponseQueue, completion: @escaping ((_ data: TrialResponse?, _ error: Error?) -> Void)) -> RequestTask { + open class func searchTrialsByGet(size: Int? = nil, from: Int? = nil, sort: String? = nil, order: String? = nil, missing: String? = nil, exists: String? = nil, include: String? = nil, exclude: String? = nil, export: String? = nil, email: String? = nil, filename: String? = nil, fulltext: String? = nil, fieldParamFulltext: String? = nil, trialids: String? = nil, trialIds: String? = nil, keyword: [String]? = nil, keywordField: String? = nil, aggField: String? = nil, aggName: String? = nil, aggMinCount: Int? = nil, sitesOrgNameFulltext: String? = nil, trialStatus: String? = nil, nciFunded: String? = nil, nciId: String? = nil, nctId: String? = nil, protocolId: String? = nil, ccrId: String? = nil, ctepId: String? = nil, dcpId: String? = nil, currentTrialStatus: String? = nil, phase: String? = nil, studyProtocolType: String? = nil, nciPrograms: String? = nil, briefTitle: String? = nil, briefSummary: String? = nil, officialTitle: String? = nil, primaryPurpose: String? = nil, acceptsHealthyVolunteersIndicator: String? = nil, eligibilityStructuredAcceptsHealthyVolunteers: Bool? = nil, acronym: String? = nil, amendmentDate: String? = nil, anatomicSites: String? = nil, armsDescription: String? = nil, armsName: String? = nil, armsType: String? = nil, armsInterventionsNciThesaurusConceptId: String? = nil, armsInterventionsDescription: String? = nil, armsInterventionsName: String? = nil, armsInterventionsType: String? = nil, armsInterventionsSynonyms: String? = nil, associatedStudiesStudyId: String? = nil, associatedStudiesStudyIdType: String? = nil, eligibilityStructuredGender: String? = nil, eligibilityStructuredMinAgeInYearsLte: Int? = nil, eligibilityStructuredMinAgeInYearsGte: Int? = nil, eligibilityStructuredMaxAgeInYearsLte: Int? = nil, eligibilityStructuredMaxAgeInYearsGte: Int? = nil, eligibilityStructuredMinAgeUnit: String? = nil, eligibilityStructuredMinAgeNumberLte: Int? = nil, eligibilityStructuredMinAgeNumberGte: Int? = nil, eligibilityStructuredMaxAgeUnit: String? = nil, eligibilityStructuredMaxAgeNumberLte: Int? = nil, eligibilityStructuredMaxAgeNumberGte: Int? = nil, currentTrialStatusDateLte: String? = nil, currentTrialStatusDateGte: String? = nil, recordVerificationDateLte: String? = nil, recordVerificationDateGte: String? = nil, sitesOrgCoordinatesLat: Double? = nil, sitesOrgCoordinatesLon: Double? = nil, sitesOrgCoordinatesDist: String? = nil, sitesContactEmail: String? = nil, sitesContactName: String? = nil, sitesContactNameAuto: String? = nil, sitesContactNameRaw: String? = nil, sitesContactPhone: String? = nil, sitesOrgAddressLine1: String? = nil, sitesOrgAddressLine2: String? = nil, sitesOrgCity: String? = nil, sitesOrgPostalCode: String? = nil, sitesOrgStateOrProvince: String? = nil, sitesOrgCountry: String? = nil, sitesOrgCountryRaw: String? = nil, sitesOrgEmail: String? = nil, sitesOrgFamily: String? = nil, sitesOrgFax: String? = nil, sitesOrgName: String? = nil, sitesOrgNameAuto: String? = nil, sitesOrgNameRaw: String? = nil, sitesOrgPhone: String? = nil, sitesRecruitmentStatus: String? = nil, sitesRecruitmentStatusDate: String? = nil, sitesRecruitmentStatusDateLte: String? = nil, sitesRecruitmentStatusDateGte: String? = nil, leadOrgCancerCenter: String? = nil, apiResponseQueue: DispatchQueue = OpenAPIClientAPI.apiResponseQueue, completion: @escaping ((_ data: TrialResponse?, _ error: Error?) -> Void)) -> RequestTask { return searchTrialsByGetWithRequestBuilder(size: size, from: from, sort: sort, order: order, missing: missing, exists: exists, include: include, exclude: exclude, export: export, email: email, filename: filename, fulltext: fulltext, fieldParamFulltext: fieldParamFulltext, trialids: trialids, trialIds: trialIds, keyword: keyword, keywordField: keywordField, aggField: aggField, aggName: aggName, aggMinCount: aggMinCount, sitesOrgNameFulltext: sitesOrgNameFulltext, trialStatus: trialStatus, nciFunded: nciFunded, nciId: nciId, nctId: nctId, protocolId: protocolId, ccrId: ccrId, ctepId: ctepId, dcpId: dcpId, currentTrialStatus: currentTrialStatus, phase: phase, studyProtocolType: studyProtocolType, nciPrograms: nciPrograms, briefTitle: briefTitle, briefSummary: briefSummary, officialTitle: officialTitle, primaryPurpose: primaryPurpose, acceptsHealthyVolunteersIndicator: acceptsHealthyVolunteersIndicator, eligibilityStructuredAcceptsHealthyVolunteers: eligibilityStructuredAcceptsHealthyVolunteers, acronym: acronym, amendmentDate: amendmentDate, anatomicSites: anatomicSites, armsDescription: armsDescription, armsName: armsName, armsType: armsType, armsInterventionsNciThesaurusConceptId: armsInterventionsNciThesaurusConceptId, armsInterventionsDescription: armsInterventionsDescription, armsInterventionsName: armsInterventionsName, armsInterventionsType: armsInterventionsType, armsInterventionsSynonyms: armsInterventionsSynonyms, associatedStudiesStudyId: associatedStudiesStudyId, associatedStudiesStudyIdType: associatedStudiesStudyIdType, eligibilityStructuredGender: eligibilityStructuredGender, eligibilityStructuredMinAgeInYearsLte: eligibilityStructuredMinAgeInYearsLte, eligibilityStructuredMinAgeInYearsGte: eligibilityStructuredMinAgeInYearsGte, eligibilityStructuredMaxAgeInYearsLte: eligibilityStructuredMaxAgeInYearsLte, eligibilityStructuredMaxAgeInYearsGte: eligibilityStructuredMaxAgeInYearsGte, eligibilityStructuredMinAgeUnit: eligibilityStructuredMinAgeUnit, eligibilityStructuredMinAgeNumberLte: eligibilityStructuredMinAgeNumberLte, eligibilityStructuredMinAgeNumberGte: eligibilityStructuredMinAgeNumberGte, eligibilityStructuredMaxAgeUnit: eligibilityStructuredMaxAgeUnit, eligibilityStructuredMaxAgeNumberLte: eligibilityStructuredMaxAgeNumberLte, eligibilityStructuredMaxAgeNumberGte: eligibilityStructuredMaxAgeNumberGte, currentTrialStatusDateLte: currentTrialStatusDateLte, currentTrialStatusDateGte: currentTrialStatusDateGte, recordVerificationDateLte: recordVerificationDateLte, recordVerificationDateGte: recordVerificationDateGte, sitesOrgCoordinatesLat: sitesOrgCoordinatesLat, sitesOrgCoordinatesLon: sitesOrgCoordinatesLon, sitesOrgCoordinatesDist: sitesOrgCoordinatesDist, sitesContactEmail: sitesContactEmail, sitesContactName: sitesContactName, sitesContactNameAuto: sitesContactNameAuto, sitesContactNameRaw: sitesContactNameRaw, sitesContactPhone: sitesContactPhone, sitesOrgAddressLine1: sitesOrgAddressLine1, sitesOrgAddressLine2: sitesOrgAddressLine2, sitesOrgCity: sitesOrgCity, sitesOrgPostalCode: sitesOrgPostalCode, sitesOrgStateOrProvince: sitesOrgStateOrProvince, sitesOrgCountry: sitesOrgCountry, sitesOrgCountryRaw: sitesOrgCountryRaw, sitesOrgEmail: sitesOrgEmail, sitesOrgFamily: sitesOrgFamily, sitesOrgFax: sitesOrgFax, sitesOrgName: sitesOrgName, sitesOrgNameAuto: sitesOrgNameAuto, sitesOrgNameRaw: sitesOrgNameRaw, sitesOrgPhone: sitesOrgPhone, sitesRecruitmentStatus: sitesRecruitmentStatus, sitesRecruitmentStatusDate: sitesRecruitmentStatusDate, sitesRecruitmentStatusDateLte: sitesRecruitmentStatusDateLte, sitesRecruitmentStatusDateGte: sitesRecruitmentStatusDateGte, leadOrgCancerCenter: leadOrgCancerCenter).execute(apiResponseQueue) { result in switch result { case let .success(response): @@ -278,7 +278,7 @@ open class TrialsAPI { - parameter leadOrgCancerCenter: (query) Search by Lead Org Cancer Center (optional) - returns: RequestBuilder */ - open class func searchTrialsByGetWithRequestBuilder(size: Int? = nil, from: Int? = nil, sort: String? = nil, order: String? = nil, missing: String? = nil, exists: String? = nil, include: String? = nil, exclude: String? = nil, export: String? = nil, email: String? = nil, filename: String? = nil, fulltext: String? = nil, fieldParamFulltext: String? = nil, trialids: String? = nil, trialIds: String? = nil, keyword: String? = nil, keywordField: String? = nil, aggField: String? = nil, aggName: String? = nil, aggMinCount: Int? = nil, sitesOrgNameFulltext: String? = nil, trialStatus: String? = nil, nciFunded: String? = nil, nciId: String? = nil, nctId: String? = nil, protocolId: String? = nil, ccrId: String? = nil, ctepId: String? = nil, dcpId: String? = nil, currentTrialStatus: String? = nil, phase: String? = nil, studyProtocolType: String? = nil, nciPrograms: String? = nil, briefTitle: String? = nil, briefSummary: String? = nil, officialTitle: String? = nil, primaryPurpose: String? = nil, acceptsHealthyVolunteersIndicator: String? = nil, eligibilityStructuredAcceptsHealthyVolunteers: Bool? = nil, acronym: String? = nil, amendmentDate: String? = nil, anatomicSites: String? = nil, armsDescription: String? = nil, armsName: String? = nil, armsType: String? = nil, armsInterventionsNciThesaurusConceptId: String? = nil, armsInterventionsDescription: String? = nil, armsInterventionsName: String? = nil, armsInterventionsType: String? = nil, armsInterventionsSynonyms: String? = nil, associatedStudiesStudyId: String? = nil, associatedStudiesStudyIdType: String? = nil, eligibilityStructuredGender: String? = nil, eligibilityStructuredMinAgeInYearsLte: Int? = nil, eligibilityStructuredMinAgeInYearsGte: Int? = nil, eligibilityStructuredMaxAgeInYearsLte: Int? = nil, eligibilityStructuredMaxAgeInYearsGte: Int? = nil, eligibilityStructuredMinAgeUnit: String? = nil, eligibilityStructuredMinAgeNumberLte: Int? = nil, eligibilityStructuredMinAgeNumberGte: Int? = nil, eligibilityStructuredMaxAgeUnit: String? = nil, eligibilityStructuredMaxAgeNumberLte: Int? = nil, eligibilityStructuredMaxAgeNumberGte: Int? = nil, currentTrialStatusDateLte: String? = nil, currentTrialStatusDateGte: String? = nil, recordVerificationDateLte: String? = nil, recordVerificationDateGte: String? = nil, sitesOrgCoordinatesLat: Double? = nil, sitesOrgCoordinatesLon: Double? = nil, sitesOrgCoordinatesDist: String? = nil, sitesContactEmail: String? = nil, sitesContactName: String? = nil, sitesContactNameAuto: String? = nil, sitesContactNameRaw: String? = nil, sitesContactPhone: String? = nil, sitesOrgAddressLine1: String? = nil, sitesOrgAddressLine2: String? = nil, sitesOrgCity: String? = nil, sitesOrgPostalCode: String? = nil, sitesOrgStateOrProvince: String? = nil, sitesOrgCountry: String? = nil, sitesOrgCountryRaw: String? = nil, sitesOrgEmail: String? = nil, sitesOrgFamily: String? = nil, sitesOrgFax: String? = nil, sitesOrgName: String? = nil, sitesOrgNameAuto: String? = nil, sitesOrgNameRaw: String? = nil, sitesOrgPhone: String? = nil, sitesRecruitmentStatus: String? = nil, sitesRecruitmentStatusDate: String? = nil, sitesRecruitmentStatusDateLte: String? = nil, sitesRecruitmentStatusDateGte: String? = nil, leadOrgCancerCenter: String? = nil) -> RequestBuilder { + open class func searchTrialsByGetWithRequestBuilder(size: Int? = nil, from: Int? = nil, sort: String? = nil, order: String? = nil, missing: String? = nil, exists: String? = nil, include: String? = nil, exclude: String? = nil, export: String? = nil, email: String? = nil, filename: String? = nil, fulltext: String? = nil, fieldParamFulltext: String? = nil, trialids: String? = nil, trialIds: String? = nil, keyword: [String]? = nil, keywordField: String? = nil, aggField: String? = nil, aggName: String? = nil, aggMinCount: Int? = nil, sitesOrgNameFulltext: String? = nil, trialStatus: String? = nil, nciFunded: String? = nil, nciId: String? = nil, nctId: String? = nil, protocolId: String? = nil, ccrId: String? = nil, ctepId: String? = nil, dcpId: String? = nil, currentTrialStatus: String? = nil, phase: String? = nil, studyProtocolType: String? = nil, nciPrograms: String? = nil, briefTitle: String? = nil, briefSummary: String? = nil, officialTitle: String? = nil, primaryPurpose: String? = nil, acceptsHealthyVolunteersIndicator: String? = nil, eligibilityStructuredAcceptsHealthyVolunteers: Bool? = nil, acronym: String? = nil, amendmentDate: String? = nil, anatomicSites: String? = nil, armsDescription: String? = nil, armsName: String? = nil, armsType: String? = nil, armsInterventionsNciThesaurusConceptId: String? = nil, armsInterventionsDescription: String? = nil, armsInterventionsName: String? = nil, armsInterventionsType: String? = nil, armsInterventionsSynonyms: String? = nil, associatedStudiesStudyId: String? = nil, associatedStudiesStudyIdType: String? = nil, eligibilityStructuredGender: String? = nil, eligibilityStructuredMinAgeInYearsLte: Int? = nil, eligibilityStructuredMinAgeInYearsGte: Int? = nil, eligibilityStructuredMaxAgeInYearsLte: Int? = nil, eligibilityStructuredMaxAgeInYearsGte: Int? = nil, eligibilityStructuredMinAgeUnit: String? = nil, eligibilityStructuredMinAgeNumberLte: Int? = nil, eligibilityStructuredMinAgeNumberGte: Int? = nil, eligibilityStructuredMaxAgeUnit: String? = nil, eligibilityStructuredMaxAgeNumberLte: Int? = nil, eligibilityStructuredMaxAgeNumberGte: Int? = nil, currentTrialStatusDateLte: String? = nil, currentTrialStatusDateGte: String? = nil, recordVerificationDateLte: String? = nil, recordVerificationDateGte: String? = nil, sitesOrgCoordinatesLat: Double? = nil, sitesOrgCoordinatesLon: Double? = nil, sitesOrgCoordinatesDist: String? = nil, sitesContactEmail: String? = nil, sitesContactName: String? = nil, sitesContactNameAuto: String? = nil, sitesContactNameRaw: String? = nil, sitesContactPhone: String? = nil, sitesOrgAddressLine1: String? = nil, sitesOrgAddressLine2: String? = nil, sitesOrgCity: String? = nil, sitesOrgPostalCode: String? = nil, sitesOrgStateOrProvince: String? = nil, sitesOrgCountry: String? = nil, sitesOrgCountryRaw: String? = nil, sitesOrgEmail: String? = nil, sitesOrgFamily: String? = nil, sitesOrgFax: String? = nil, sitesOrgName: String? = nil, sitesOrgNameAuto: String? = nil, sitesOrgNameRaw: String? = nil, sitesOrgPhone: String? = nil, sitesRecruitmentStatus: String? = nil, sitesRecruitmentStatusDate: String? = nil, sitesRecruitmentStatusDateLte: String? = nil, sitesRecruitmentStatusDateGte: String? = nil, leadOrgCancerCenter: String? = nil) -> RequestBuilder { let localVariablePath = "/trials" let localVariableURLString = OpenAPIClientAPI.basePath + localVariablePath let localVariableParameters: [String: Any]? = nil diff --git a/NCIClinicalTrialsSearchAPI/OpenAPIClient/Classes/OpenAPIs/URLSessionImplementations.swift b/NCIClinicalTrialsSearchAPI/OpenAPIClient/Classes/OpenAPIs/URLSessionImplementations.swift index def439d..3813d86 100644 --- a/NCIClinicalTrialsSearchAPI/OpenAPIClient/Classes/OpenAPIs/URLSessionImplementations.swift +++ b/NCIClinicalTrialsSearchAPI/OpenAPIClient/Classes/OpenAPIs/URLSessionImplementations.swift @@ -8,6 +8,9 @@ import Foundation #if !os(macOS) import MobileCoreServices #endif +#if canImport(UniformTypeIdentifiers) +import UniformTypeIdentifiers +#endif public protocol URLSessionProtocol { func dataTask(with request: URLRequest, completionHandler: @escaping @Sendable (Data?, URLResponse?, Error?) -> Void) -> URLSessionDataTask @@ -560,9 +563,20 @@ private class FormDataEncoding: ParameterEncoding { func mimeType(for url: URL) -> String { let pathExtension = url.pathExtension - if let uti = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, pathExtension as NSString, nil)?.takeRetainedValue(), - let mimetype = UTTypeCopyPreferredTagWithClass(uti, kUTTagClassMIMEType)?.takeRetainedValue() { - return mimetype as String + if #available(iOS 15, macOS 11, *) { + #if canImport(UniformTypeIdentifiers) + if let utType = UTType(filenameExtension: pathExtension) { + return utType.preferredMIMEType ?? "application/octet-stream" + } + #else + return "application/octet-stream" + #endif + } else { + if let uti = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, pathExtension as NSString, nil)?.takeRetainedValue(), + let mimetype = UTTypeCopyPreferredTagWithClass(uti, kUTTagClassMIMEType)?.takeRetainedValue() { + return mimetype as String + } + return "application/octet-stream" } return "application/octet-stream" } diff --git a/NCIClinicalTrialsSearchAPI/README.md b/NCIClinicalTrialsSearchAPI/README.md index b54f9c1..5fc94bc 100644 --- a/NCIClinicalTrialsSearchAPI/README.md +++ b/NCIClinicalTrialsSearchAPI/README.md @@ -7,6 +7,7 @@ This API client was generated by the [OpenAPI Generator](https://openapi-generat - API version: 2.1.0 - Package version: +- Generator version: 7.5.0 - Build package: org.openapitools.codegen.languages.Swift5ClientCodegen ## Installation diff --git a/NCIClinicalTrialsSearchAPI/docs/TrialsAPI.md b/NCIClinicalTrialsSearchAPI/docs/TrialsAPI.md index b494734..4478610 100644 --- a/NCIClinicalTrialsSearchAPI/docs/TrialsAPI.md +++ b/NCIClinicalTrialsSearchAPI/docs/TrialsAPI.md @@ -61,7 +61,7 @@ Name | Type | Description | Notes # **searchTrialsByGet** ```swift - open class func searchTrialsByGet(size: Int? = nil, from: Int? = nil, sort: String? = nil, order: String? = nil, missing: String? = nil, exists: String? = nil, include: String? = nil, exclude: String? = nil, export: String? = nil, email: String? = nil, filename: String? = nil, fulltext: String? = nil, fieldParamFulltext: String? = nil, trialids: String? = nil, trialIds: String? = nil, keyword: String? = nil, keywordField: String? = nil, aggField: String? = nil, aggName: String? = nil, aggMinCount: Int? = nil, sitesOrgNameFulltext: String? = nil, trialStatus: String? = nil, nciFunded: String? = nil, nciId: String? = nil, nctId: String? = nil, protocolId: String? = nil, ccrId: String? = nil, ctepId: String? = nil, dcpId: String? = nil, currentTrialStatus: String? = nil, phase: String? = nil, studyProtocolType: String? = nil, nciPrograms: String? = nil, briefTitle: String? = nil, briefSummary: String? = nil, officialTitle: String? = nil, primaryPurpose: String? = nil, acceptsHealthyVolunteersIndicator: String? = nil, eligibilityStructuredAcceptsHealthyVolunteers: Bool? = nil, acronym: String? = nil, amendmentDate: String? = nil, anatomicSites: String? = nil, armsDescription: String? = nil, armsName: String? = nil, armsType: String? = nil, armsInterventionsNciThesaurusConceptId: String? = nil, armsInterventionsDescription: String? = nil, armsInterventionsName: String? = nil, armsInterventionsType: String? = nil, armsInterventionsSynonyms: String? = nil, associatedStudiesStudyId: String? = nil, associatedStudiesStudyIdType: String? = nil, eligibilityStructuredGender: String? = nil, eligibilityStructuredMinAgeInYearsLte: Int? = nil, eligibilityStructuredMinAgeInYearsGte: Int? = nil, eligibilityStructuredMaxAgeInYearsLte: Int? = nil, eligibilityStructuredMaxAgeInYearsGte: Int? = nil, eligibilityStructuredMinAgeUnit: String? = nil, eligibilityStructuredMinAgeNumberLte: Int? = nil, eligibilityStructuredMinAgeNumberGte: Int? = nil, eligibilityStructuredMaxAgeUnit: String? = nil, eligibilityStructuredMaxAgeNumberLte: Int? = nil, eligibilityStructuredMaxAgeNumberGte: Int? = nil, currentTrialStatusDateLte: String? = nil, currentTrialStatusDateGte: String? = nil, recordVerificationDateLte: String? = nil, recordVerificationDateGte: String? = nil, sitesOrgCoordinatesLat: Double? = nil, sitesOrgCoordinatesLon: Double? = nil, sitesOrgCoordinatesDist: String? = nil, sitesContactEmail: String? = nil, sitesContactName: String? = nil, sitesContactNameAuto: String? = nil, sitesContactNameRaw: String? = nil, sitesContactPhone: String? = nil, sitesOrgAddressLine1: String? = nil, sitesOrgAddressLine2: String? = nil, sitesOrgCity: String? = nil, sitesOrgPostalCode: String? = nil, sitesOrgStateOrProvince: String? = nil, sitesOrgCountry: String? = nil, sitesOrgCountryRaw: String? = nil, sitesOrgEmail: String? = nil, sitesOrgFamily: String? = nil, sitesOrgFax: String? = nil, sitesOrgName: String? = nil, sitesOrgNameAuto: String? = nil, sitesOrgNameRaw: String? = nil, sitesOrgPhone: String? = nil, sitesRecruitmentStatus: String? = nil, sitesRecruitmentStatusDate: String? = nil, sitesRecruitmentStatusDateLte: String? = nil, sitesRecruitmentStatusDateGte: String? = nil, leadOrgCancerCenter: String? = nil, completion: @escaping (_ data: TrialResponse?, _ error: Error?) -> Void) + open class func searchTrialsByGet(size: Int? = nil, from: Int? = nil, sort: String? = nil, order: String? = nil, missing: String? = nil, exists: String? = nil, include: String? = nil, exclude: String? = nil, export: String? = nil, email: String? = nil, filename: String? = nil, fulltext: String? = nil, fieldParamFulltext: String? = nil, trialids: String? = nil, trialIds: String? = nil, keyword: [String]? = nil, keywordField: String? = nil, aggField: String? = nil, aggName: String? = nil, aggMinCount: Int? = nil, sitesOrgNameFulltext: String? = nil, trialStatus: String? = nil, nciFunded: String? = nil, nciId: String? = nil, nctId: String? = nil, protocolId: String? = nil, ccrId: String? = nil, ctepId: String? = nil, dcpId: String? = nil, currentTrialStatus: String? = nil, phase: String? = nil, studyProtocolType: String? = nil, nciPrograms: String? = nil, briefTitle: String? = nil, briefSummary: String? = nil, officialTitle: String? = nil, primaryPurpose: String? = nil, acceptsHealthyVolunteersIndicator: String? = nil, eligibilityStructuredAcceptsHealthyVolunteers: Bool? = nil, acronym: String? = nil, amendmentDate: String? = nil, anatomicSites: String? = nil, armsDescription: String? = nil, armsName: String? = nil, armsType: String? = nil, armsInterventionsNciThesaurusConceptId: String? = nil, armsInterventionsDescription: String? = nil, armsInterventionsName: String? = nil, armsInterventionsType: String? = nil, armsInterventionsSynonyms: String? = nil, associatedStudiesStudyId: String? = nil, associatedStudiesStudyIdType: String? = nil, eligibilityStructuredGender: String? = nil, eligibilityStructuredMinAgeInYearsLte: Int? = nil, eligibilityStructuredMinAgeInYearsGte: Int? = nil, eligibilityStructuredMaxAgeInYearsLte: Int? = nil, eligibilityStructuredMaxAgeInYearsGte: Int? = nil, eligibilityStructuredMinAgeUnit: String? = nil, eligibilityStructuredMinAgeNumberLte: Int? = nil, eligibilityStructuredMinAgeNumberGte: Int? = nil, eligibilityStructuredMaxAgeUnit: String? = nil, eligibilityStructuredMaxAgeNumberLte: Int? = nil, eligibilityStructuredMaxAgeNumberGte: Int? = nil, currentTrialStatusDateLte: String? = nil, currentTrialStatusDateGte: String? = nil, recordVerificationDateLte: String? = nil, recordVerificationDateGte: String? = nil, sitesOrgCoordinatesLat: Double? = nil, sitesOrgCoordinatesLon: Double? = nil, sitesOrgCoordinatesDist: String? = nil, sitesContactEmail: String? = nil, sitesContactName: String? = nil, sitesContactNameAuto: String? = nil, sitesContactNameRaw: String? = nil, sitesContactPhone: String? = nil, sitesOrgAddressLine1: String? = nil, sitesOrgAddressLine2: String? = nil, sitesOrgCity: String? = nil, sitesOrgPostalCode: String? = nil, sitesOrgStateOrProvince: String? = nil, sitesOrgCountry: String? = nil, sitesOrgCountryRaw: String? = nil, sitesOrgEmail: String? = nil, sitesOrgFamily: String? = nil, sitesOrgFax: String? = nil, sitesOrgName: String? = nil, sitesOrgNameAuto: String? = nil, sitesOrgNameRaw: String? = nil, sitesOrgPhone: String? = nil, sitesRecruitmentStatus: String? = nil, sitesRecruitmentStatusDate: String? = nil, sitesRecruitmentStatusDateLte: String? = nil, sitesRecruitmentStatusDateGte: String? = nil, leadOrgCancerCenter: String? = nil, completion: @escaping (_ data: TrialResponse?, _ error: Error?) -> Void) ``` Search Trials by GET @@ -88,7 +88,7 @@ let fulltext = "fulltext_example" // String | DEPRECATED. Use keyword._fulltext where available, described above. (optional) let trialids = "trialids_example" // String | DEPRECATED. Use trial_ids instead. (optional) let trialIds = "" // String | Filter results by examining trial identifiers (ccr_id, ctep_id, dcp_id, nci_id, nct_id, other_ids.value, protocol_id). Example: trials?trial_ids=nci-2011&trial_ids=NCT00 (optional) -let keyword = "" // String | Text to be searched in multiple fields. It can be combined with keyword_field.

keyword filter results by examining a variety of text-based fields (By default: *_id, other_ids.value, diseases.name._fulltext, diseases.synonyms._fulltext, brief_title, brief_summary, official_title, detail_description, official_title, brief_title, brief_summary, diseases.name._fulltext, detail_description, sites.org_name._fulltext, collaborators.name._fulltext, principal_investigator._fulltext, sites.contact_name._fulltext, sites.org_city._fulltext, sites.org_state_or_province._fulltext, arms.interventions.name, arms.interventions.synonyms, biomarkers.name, biomarkers.synonyms, prior_therapy.name, prior_therapy.synonyms).

Mutiple keywords (with a maximum of 10 allowed) will give you an OR condition of between values in all configured fields. (optional) +let keyword = ["inner_example"] // [String] | Text to be searched in multiple fields. It can be combined with keyword_field.

keyword filter results by examining a variety of text-based fields (By default: *_id, other_ids.value, diseases.name._fulltext, diseases.synonyms._fulltext, brief_title, brief_summary, official_title, detail_description, official_title, brief_title, brief_summary, diseases.name._fulltext, detail_description, sites.org_name._fulltext, collaborators.name._fulltext, principal_investigator._fulltext, sites.contact_name._fulltext, sites.org_city._fulltext, sites.org_state_or_province._fulltext, arms.interventions.name, arms.interventions.synonyms, biomarkers.name, biomarkers.synonyms, prior_therapy.name, prior_therapy.synonyms).

Mutiple keywords (with a maximum of 10 allowed) will give you an OR condition of between values in all configured fields. (optional) let keywordField = "" // String | Field(s) to be searched for the text provided in keyword. Use multiple times; once for each field to be searched. For example:
keyword_field=brief_title._fulltext&keyword_field=lead_org._auto. Use keyword_field to override the default fields used by keyword. A maximum of 10 fields is currently allowed. (optional) let aggField = "" // String | Field to be used for aggregation. (optional) let aggName = "" // String | Filter aggregation (use with agg_field). Autocomplete of this value must match the value of the field in agg_field. (optional) @@ -200,7 +200,7 @@ Name | Type | Description | Notes **fieldParamFulltext** | **String** | DEPRECATED. Use <code><field_param>._fulltext</code> where available, described above. | [optional] **trialids** | **String** | DEPRECATED. Use <code>trial_ids</code> instead. | [optional] **trialIds** | **String** | Filter results by examining trial identifiers (ccr_id, ctep_id, dcp_id, nci_id, nct_id, other_ids.value, protocol_id). Example: trials?trial_ids=nci-2011&trial_ids=NCT00 | [optional] - **keyword** | **String** | Text to be searched in multiple fields. It can be combined with <code>keyword_field</code>.<br><br><code>keyword</code> filter results by examining a variety of text-based fields <i>(By default: &#42;_id, other_ids.value, diseases.name._fulltext, diseases.synonyms._fulltext, brief_title, brief_summary, official_title, detail_description, official_title, brief_title, brief_summary, diseases.name._fulltext, detail_description, sites.org_name._fulltext, collaborators.name._fulltext, principal_investigator._fulltext, sites.contact_name._fulltext, sites.org_city._fulltext, sites.org_state_or_province._fulltext, arms.interventions.name, arms.interventions.synonyms, biomarkers.name, biomarkers.synonyms, prior_therapy.name, prior_therapy.synonyms)</i>.<br><br>Mutiple <code>keyword</code>s (with a maximum of 10 allowed) will give you an OR condition of between values in all configured fields. | [optional] + **keyword** | [**[String]**](String.md) | Text to be searched in multiple fields. It can be combined with <code>keyword_field</code>.<br><br><code>keyword</code> filter results by examining a variety of text-based fields <i>(By default: &#42;_id, other_ids.value, diseases.name._fulltext, diseases.synonyms._fulltext, brief_title, brief_summary, official_title, detail_description, official_title, brief_title, brief_summary, diseases.name._fulltext, detail_description, sites.org_name._fulltext, collaborators.name._fulltext, principal_investigator._fulltext, sites.contact_name._fulltext, sites.org_city._fulltext, sites.org_state_or_province._fulltext, arms.interventions.name, arms.interventions.synonyms, biomarkers.name, biomarkers.synonyms, prior_therapy.name, prior_therapy.synonyms)</i>.<br><br>Mutiple <code>keyword</code>s (with a maximum of 10 allowed) will give you an OR condition of between values in all configured fields. | [optional] **keywordField** | **String** | Field(s) to be searched for the text provided in <code>keyword</code>. Use multiple times; once for each field to be searched. For example:<br><code>keyword_field=brief_title._fulltext&keyword_field=lead_org._auto</code>. Use <code>keyword_field</code> to override the default fields used by <code>keyword</code>. A maximum of 10 fields is currently allowed. | [optional] **aggField** | **String** | Field to be used for aggregation. | [optional] **aggName** | **String** | Filter aggregation (use with <b>agg_field</b>). Autocomplete of this value must match the value of the field in <b>agg_field</b>. | [optional] diff --git a/OwnYourData/ClinicalTrials/NCITrialsModel.swift b/OwnYourData/ClinicalTrials/NCITrialsModel.swift index ba1cce8..c07fac7 100644 --- a/OwnYourData/ClinicalTrials/NCITrialsModel.swift +++ b/OwnYourData/ClinicalTrials/NCITrialsModel.swift @@ -77,7 +77,7 @@ class NCITrialsModel { return try await withCheckedThrowingContinuation { continuation in TrialsAPI.searchTrialsByGet( size: 20, - keyword: keywords.isEmpty ? nil : keywords.joined(separator: " "), + keyword: keywords.isEmpty ? nil : keywords, trialStatus: "OPEN", phase: "III", primaryPurpose: "TREATMENT", From 9a781b9208f24991b43301981b2b27bda23049d4 Mon Sep 17 00:00:00 2001 From: Paul Schmiedmayer Date: Fri, 24 May 2024 17:02:56 -0700 Subject: [PATCH 2/3] Update Setup --- OwnYourData.xcodeproj/project.pbxproj | 8 +++--- ...rialsModel.swift => NCITrialsModule.swift} | 18 ++++++------- .../ViewClinicalTrialsView.swift | 2 +- OwnYourData/Onboarding/OnboardingFlow.swift | 1 - OwnYourData/OwnYourDataDelegate.swift | 26 ++++++++++++++++++- .../Supporting Files/GoogleService-Info.plist | 4 +++ .../LLMFunctions/GetTrialsLLMFunction.swift | 4 +-- .../TrialsMatching/MatchingModule.swift | 17 +++++++----- 8 files changed, 55 insertions(+), 25 deletions(-) rename OwnYourData/ClinicalTrials/{NCITrialsModel.swift => NCITrialsModule.swift} (89%) diff --git a/OwnYourData.xcodeproj/project.pbxproj b/OwnYourData.xcodeproj/project.pbxproj index f069a6d..3d30430 100644 --- a/OwnYourData.xcodeproj/project.pbxproj +++ b/OwnYourData.xcodeproj/project.pbxproj @@ -55,7 +55,7 @@ 2FB4DBC12BF47ABA00E68AD9 /* FHIRResource+Identifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2FB4DBC02BF47ABA00E68AD9 /* FHIRResource+Identifier.swift */; }; 2FB4DBC62BF48E4F00E68AD9 /* GetTrialsLLMFunction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2FB4DBC52BF48E4F00E68AD9 /* GetTrialsLLMFunction.swift */; }; 2FB4DBC92BF48E7400E68AD9 /* FHIRPrompt+OwnYourData.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2FB4DBC82BF48E7400E68AD9 /* FHIRPrompt+OwnYourData.swift */; }; - 2FB4DBCD2BF4915900E68AD9 /* NCITrialsModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2FB4DBCC2BF4915900E68AD9 /* NCITrialsModel.swift */; }; + 2FB4DBCD2BF4915900E68AD9 /* NCITrialsModule.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2FB4DBCC2BF4915900E68AD9 /* NCITrialsModule.swift */; }; 2FB4DBD52BF4946E00E68AD9 /* MatchingState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2FB4DBD42BF4946E00E68AD9 /* MatchingState.swift */; }; 2FB4DBD72BF4948700E68AD9 /* MatchingStateView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2FB4DBD62BF4948700E68AD9 /* MatchingStateView.swift */; }; 2FB4DBDB2BF4A08000E68AD9 /* MatchingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2FB4DBDA2BF4A08000E68AD9 /* MatchingView.swift */; }; @@ -163,7 +163,7 @@ 2FB4DBC02BF47ABA00E68AD9 /* FHIRResource+Identifier.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "FHIRResource+Identifier.swift"; sourceTree = ""; }; 2FB4DBC52BF48E4F00E68AD9 /* GetTrialsLLMFunction.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GetTrialsLLMFunction.swift; sourceTree = ""; }; 2FB4DBC82BF48E7400E68AD9 /* FHIRPrompt+OwnYourData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "FHIRPrompt+OwnYourData.swift"; sourceTree = ""; }; - 2FB4DBCC2BF4915900E68AD9 /* NCITrialsModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCITrialsModel.swift; sourceTree = ""; }; + 2FB4DBCC2BF4915900E68AD9 /* NCITrialsModule.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCITrialsModule.swift; sourceTree = ""; }; 2FB4DBD42BF4946E00E68AD9 /* MatchingState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MatchingState.swift; sourceTree = ""; }; 2FB4DBD62BF4948700E68AD9 /* MatchingStateView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MatchingStateView.swift; sourceTree = ""; }; 2FB4DBDA2BF4A08000E68AD9 /* MatchingView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MatchingView.swift; sourceTree = ""; }; @@ -283,7 +283,7 @@ 2F42E9E32B91BB7000D88DB7 /* ClinicalTrials */ = { isa = PBXGroup; children = ( - 2FB4DBCC2BF4915900E68AD9 /* NCITrialsModel.swift */, + 2FB4DBCC2BF4915900E68AD9 /* NCITrialsModule.swift */, 2F42E9E62B91BB8300D88DB7 /* ViewClinicalTrialsView.swift */, 2FCDFF812BF3417300158BDE /* TrialView.swift */, 2F42E9E52B91BB8300D88DB7 /* WebView.swift */, @@ -753,7 +753,7 @@ 2FB4DBC92BF48E7400E68AD9 /* FHIRPrompt+OwnYourData.swift in Sources */, 2FB4DBC62BF48E4F00E68AD9 /* GetTrialsLLMFunction.swift in Sources */, 2F4E23832989D51F0013F3D9 /* OwnYourDataTestingSetup.swift in Sources */, - 2FB4DBCD2BF4915900E68AD9 /* NCITrialsModel.swift in Sources */, + 2FB4DBCD2BF4915900E68AD9 /* NCITrialsModule.swift in Sources */, 2F42E9DC2B91BB2500D88DB7 /* DocumentManager.swift in Sources */, 2F42E9E02B91BB2500D88DB7 /* PDFListDetailView.swift in Sources */, 2FCDFF822BF3417300158BDE /* TrialView.swift in Sources */, diff --git a/OwnYourData/ClinicalTrials/NCITrialsModel.swift b/OwnYourData/ClinicalTrials/NCITrialsModule.swift similarity index 89% rename from OwnYourData/ClinicalTrials/NCITrialsModel.swift rename to OwnYourData/ClinicalTrials/NCITrialsModule.swift index c07fac7..1448165 100644 --- a/OwnYourData/ClinicalTrials/NCITrialsModel.swift +++ b/OwnYourData/ClinicalTrials/NCITrialsModule.swift @@ -8,24 +8,22 @@ import CoreLocation import OpenAPIClient +import Spezi import SpeziLocation @Observable -class NCITrialsModel { - #warning("Insert NIC Token here to test the app.") - private static let apiKey: String = "" - - - private let locationModule: SpeziLocation +class NCITrialsModule: Module, EnvironmentAccessible { + @ObservationIgnored @Dependency private var locationModule: SpeziLocation + private let apiKey: String private(set) var trials: [TrialDetail] = [] var zipCode: String = "10025" var searchDistance: String = "100" - init(locationModule: SpeziLocation) { - self.locationModule = locationModule + init(apiKey: String) { + self.apiKey = apiKey } @@ -69,14 +67,14 @@ class NCITrialsModel { } private func loadTrials(keywords: [String], coordinate: CLLocationCoordinate2D?) async throws -> TrialResponse { - OpenAPIClientAPI.customHeaders = ["X-API-KEY": Self.apiKey] + OpenAPIClientAPI.customHeaders = ["X-API-KEY": apiKey] CodableHelper.dateFormatter = NICTrialsAPIDateFormatter() let keywords = keywords.filter { !$0.isEmpty } return try await withCheckedThrowingContinuation { continuation in TrialsAPI.searchTrialsByGet( - size: 20, + size: 50, keyword: keywords.isEmpty ? nil : keywords, trialStatus: "OPEN", phase: "III", diff --git a/OwnYourData/ClinicalTrials/ViewClinicalTrialsView.swift b/OwnYourData/ClinicalTrials/ViewClinicalTrialsView.swift index 3644f74..87b4ef8 100644 --- a/OwnYourData/ClinicalTrials/ViewClinicalTrialsView.swift +++ b/OwnYourData/ClinicalTrials/ViewClinicalTrialsView.swift @@ -14,7 +14,7 @@ import SwiftUI struct ViewClinicalTrialsView: View { - @Environment(NCITrialsModel.self) private var nciTrialsModel + @Environment(NCITrialsModule.self) private var nciTrialsModel @State private var viewState: ViewState = .idle diff --git a/OwnYourData/Onboarding/OnboardingFlow.swift b/OwnYourData/Onboarding/OnboardingFlow.swift index ee64e06..eac2621 100644 --- a/OwnYourData/Onboarding/OnboardingFlow.swift +++ b/OwnYourData/Onboarding/OnboardingFlow.swift @@ -47,7 +47,6 @@ struct OnboardingFlow: View { } LocationPermissions() - OpenAIAPIKey() } .interactiveDismissDisabled(!completedOnboardingFlow) } diff --git a/OwnYourData/OwnYourDataDelegate.swift b/OwnYourData/OwnYourDataDelegate.swift index 9467009..5954186 100644 --- a/OwnYourData/OwnYourDataDelegate.swift +++ b/OwnYourData/OwnYourDataDelegate.swift @@ -62,7 +62,7 @@ class OwnYourDataDelegate: SpeziAppDelegate { // See https://swiftpackageindex.com/StanfordSpezi/SpeziLLM/documentation/spezillm LLMRunner { - LLMOpenAIPlatform(configuration: .init(concurrentStreams: 20)) + LLMOpenAIPlatform(configuration: .init(concurrentStreams: 20, apiToken: self.openAIToken)) } FHIRInterpretationModule() @@ -71,6 +71,8 @@ class OwnYourDataDelegate: SpeziAppDelegate { SpeziLocation() MatchingModule() + + NCITrialsModule(apiKey: self.nciAPIToken) } } @@ -112,4 +114,26 @@ class OwnYourDataDelegate: SpeziAppDelegate { ) } } + + nonisolated private var plist: [String: Any] { + guard let url = Bundle.main.url(forResource: "GoogleService-Info", withExtension: "plist"), + let data = try? Data(contentsOf: url), + let plist = try? PropertyListSerialization.propertyList(from: data, format: nil) as? [String: Any] else { + return [:] + } + + return plist + } + + nonisolated private var openAIToken: String? { + plist["OPENAI_KEY"] as? String + } + + nonisolated private var nciAPIToken: String { + guard let nciAPIToken = plist["NCI_API_KEY"] as? String else { + fatalError("Please provide a valid NCI API key in the GoogleService-Info.plist") + } + + return nciAPIToken + } } diff --git a/OwnYourData/Supporting Files/GoogleService-Info.plist b/OwnYourData/Supporting Files/GoogleService-Info.plist index 0dd1639..5c2865e 100644 --- a/OwnYourData/Supporting Files/GoogleService-Info.plist +++ b/OwnYourData/Supporting Files/GoogleService-Info.plist @@ -8,6 +8,10 @@ REVERSED_CLIENT_ID API_KEY API_KEY + NCI_API_KEY + NCI_API_KEY + OPENAI_KEY + OPENAI_KEY GCM_SENDER_ID GCM_SENDER_ID PLIST_VERSION diff --git a/OwnYourData/TrialsMatching/LLMFunctions/GetTrialsLLMFunction.swift b/OwnYourData/TrialsMatching/LLMFunctions/GetTrialsLLMFunction.swift index 0bea568..f06d3c0 100644 --- a/OwnYourData/TrialsMatching/LLMFunctions/GetTrialsLLMFunction.swift +++ b/OwnYourData/TrialsMatching/LLMFunctions/GetTrialsLLMFunction.swift @@ -18,14 +18,14 @@ struct GetTrialsLLMFunction: LLMFunction { static let name = "get_trials" static let description = String(localized: "LLM_GET_TRIALS_FUNCTION_DESCRIPTION") - private let nciTrialsModel: NCITrialsModel + private let nciTrialsModel: NCITrialsModule @Parameter var trailIdentifiers: [String] init( - nciTrialsModel: NCITrialsModel + nciTrialsModel: NCITrialsModule ) { self.nciTrialsModel = nciTrialsModel diff --git a/OwnYourData/TrialsMatching/MatchingModule.swift b/OwnYourData/TrialsMatching/MatchingModule.swift index b6234db..555b96e 100644 --- a/OwnYourData/TrialsMatching/MatchingModule.swift +++ b/OwnYourData/TrialsMatching/MatchingModule.swift @@ -31,9 +31,9 @@ class MatchingModule: Module, EnvironmentAccessible, DefaultInitializable { @ObservationIgnored @Dependency private var llmRunner: LLMRunner @ObservationIgnored @Dependency private var fhirStore: FHIRStore @ObservationIgnored @Dependency private var locationModule: SpeziLocation - + @ObservationIgnored @Dependency private var nciTrialsModel: NCITrialsModule? + @ObservationIgnored @Model private var resourceSummary: FHIRResourceSummary - @ObservationIgnored @Model private var nciTrialsModel: NCITrialsModel var state: MatchingState = .idle private(set) var matchingTrials: [TrialDetail] = [] @@ -49,15 +49,16 @@ class MatchingModule: Module, EnvironmentAccessible, DefaultInitializable { llmRunner: llmRunner, llmSchema: Defaults.llmSchema ) - nciTrialsModel = NCITrialsModel( - locationModule: locationModule - ) } @MainActor func matchTrials() async { do { + guard let nciTrialsModel else { + fatalError("Error that NCI Trials Module was not initialized in the Spezi Configuratin.") + } + withAnimation { self.state = .fhirInspection } @@ -119,6 +120,10 @@ class MatchingModule: Module, EnvironmentAccessible, DefaultInitializable { @MainActor private func trialsIdentificaiton() async throws -> [String] { + guard let nciTrialsModel else { + fatalError("Error that NCI Trials Module was not initialized in the Spezi Configuratin.") + } + let llm = llmRunner( with: LLMOpenAISchema(parameters: .init(modelType: .gpt4_turbo_preview)) { GetFHIRResourceLLMFunction( @@ -126,7 +131,7 @@ class MatchingModule: Module, EnvironmentAccessible, DefaultInitializable { resourceSummary: self.resourceSummary, resourceCountLimit: 100 ) - GetTrialsLLMFunction(nciTrialsModel: self.nciTrialsModel) + GetTrialsLLMFunction(nciTrialsModel: nciTrialsModel) } ) From 8887e9613e69017e91a40cc8ce6b3bfd0fd33d14 Mon Sep 17 00:00:00 2001 From: Paul Schmiedmayer Date: Fri, 24 May 2024 17:07:35 -0700 Subject: [PATCH 3/3] Update README --- NCIClinicalTrialsSearchAPI/docs/TrialsAPI.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NCIClinicalTrialsSearchAPI/docs/TrialsAPI.md b/NCIClinicalTrialsSearchAPI/docs/TrialsAPI.md index 4478610..3498ebb 100644 --- a/NCIClinicalTrialsSearchAPI/docs/TrialsAPI.md +++ b/NCIClinicalTrialsSearchAPI/docs/TrialsAPI.md @@ -200,7 +200,7 @@ Name | Type | Description | Notes **fieldParamFulltext** | **String** | DEPRECATED. Use <code><field_param>._fulltext</code> where available, described above. | [optional] **trialids** | **String** | DEPRECATED. Use <code>trial_ids</code> instead. | [optional] **trialIds** | **String** | Filter results by examining trial identifiers (ccr_id, ctep_id, dcp_id, nci_id, nct_id, other_ids.value, protocol_id). Example: trials?trial_ids=nci-2011&trial_ids=NCT00 | [optional] - **keyword** | [**[String]**](String.md) | Text to be searched in multiple fields. It can be combined with <code>keyword_field</code>.<br><br><code>keyword</code> filter results by examining a variety of text-based fields <i>(By default: &#42;_id, other_ids.value, diseases.name._fulltext, diseases.synonyms._fulltext, brief_title, brief_summary, official_title, detail_description, official_title, brief_title, brief_summary, diseases.name._fulltext, detail_description, sites.org_name._fulltext, collaborators.name._fulltext, principal_investigator._fulltext, sites.contact_name._fulltext, sites.org_city._fulltext, sites.org_state_or_province._fulltext, arms.interventions.name, arms.interventions.synonyms, biomarkers.name, biomarkers.synonyms, prior_therapy.name, prior_therapy.synonyms)</i>.<br><br>Mutiple <code>keyword</code>s (with a maximum of 10 allowed) will give you an OR condition of between values in all configured fields. | [optional] + **keyword** | **[String]** | Text to be searched in multiple fields. It can be combined with <code>keyword_field</code>.<br><br><code>keyword</code> filter results by examining a variety of text-based fields <i>(By default: &#42;_id, other_ids.value, diseases.name._fulltext, diseases.synonyms._fulltext, brief_title, brief_summary, official_title, detail_description, official_title, brief_title, brief_summary, diseases.name._fulltext, detail_description, sites.org_name._fulltext, collaborators.name._fulltext, principal_investigator._fulltext, sites.contact_name._fulltext, sites.org_city._fulltext, sites.org_state_or_province._fulltext, arms.interventions.name, arms.interventions.synonyms, biomarkers.name, biomarkers.synonyms, prior_therapy.name, prior_therapy.synonyms)</i>.<br><br>Mutiple <code>keyword</code>s (with a maximum of 10 allowed) will give you an OR condition of between values in all configured fields. | [optional] **keywordField** | **String** | Field(s) to be searched for the text provided in <code>keyword</code>. Use multiple times; once for each field to be searched. For example:<br><code>keyword_field=brief_title._fulltext&keyword_field=lead_org._auto</code>. Use <code>keyword_field</code> to override the default fields used by <code>keyword</code>. A maximum of 10 fields is currently allowed. | [optional] **aggField** | **String** | Field to be used for aggregation. | [optional] **aggName** | **String** | Filter aggregation (use with <b>agg_field</b>). Autocomplete of this value must match the value of the field in <b>agg_field</b>. | [optional]