A Swift package for integrating with Eka's medical records system.
The Swift Package Manager is a tool for automating the distribution of Swift code and is integrated into the Swift compiler.
Add EkaMedicalRecordsCore as a dependency in your Package.swift
file:
dependencies: [
.package(url: "https://github.com/eka-care/EkaMedicalRecordsCore.git", branch: "main")
]
Add EkaMedicalRecordsCore
in the target:
.product(name: "EkaMedicalRecordsCore", package: "EkaMedicalRecordsCore")
Initialize the SDK with the required tokens from Auth SDK:
@main
struct RecordsAppApp: App {
// MARK: - Init
init() {
registerCoreSdk()
}
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
// MARK: - Core SDK Init
extension RecordsAppApp {
private func registerCoreSdk() {
CoreInitConfigurations.shared.authToken = AuthSdk.authToken
CoreInitConfigurations.shared.refreshToken = AuthSdk.refreshToken
CoreInitConfigurations.shared.ownerID = "xxxxxABCDEFGH"
}
}
-
Auth Token: Eka's authentication token that you can get from Eka's Auth SDK APIs.
CoreInitConfigurations.shared.authToken = AuthSdk.authToken
-
Refresh Token: Eka's refresh token that you can get from Eka's Auth SDK APIs.
CoreInitConfigurations.shared.refreshToken = AuthSdk.refreshToken
-
OwnerID: Owner ID is the OID for the person for whom you want the records for.
CoreInitConfigurations.shared.ownerID = "xxxxxABCDEFGH"
-
FilterID (optional): FilterID is the OID of the person for whom you want to filter the records for.
CoreInitConfigurations.shared.filterID = "xxxxxABCDEFGH"
Note: You need to set all these properties from wherever you want to open the records screen. FilterID field is optional and will be used only when you need to filter records attached to an ownerID.
extension Record {
@nonobjc public class func fetchRequest() -> NSFetchRequest<Record> {
return NSFetchRequest<Record>(entityName: "Record")
}
@NSManaged public var bid: String?
@NSManaged public var documentDate: Date?
@NSManaged public var documentHash: String?
@NSManaged public var documentID: String?
@NSManaged public var documentType: Int64
@NSManaged public var hasSyncedEdit: Bool
@NSManaged public var isAnalyzing: Bool
@NSManaged public var isArchived: Bool
@NSManaged public var isSmart: Bool
@NSManaged public var oid: String?
@NSManaged public var thumbnail: String?
@NSManaged public var updatedAt: Date?
@NSManaged public var uploadDate: Date?
@NSManaged public var toRecordMeta: NSSet?
@NSManaged public var toSmartReport: SmartReport?
}
// MARK: Generated accessors for toRecordMeta
extension Record {
@objc(addToRecordMetaObject:)
@NSManaged public func addToToRecordMeta(_ value: RecordMeta)
@objc(removeToRecordMetaObject:)
@NSManaged public func removeFromToRecordMeta(_ value: RecordMeta)
@objc(addToRecordMeta:)
@NSManaged public func addToToRecordMeta(_ values: NSSet)
@objc(removeToRecordMeta:)
@NSManaged public func removeFromToRecordMeta(_ values: NSSet)
}
extension RecordMeta {
@nonobjc public class func fetchRequest() -> NSFetchRequest<RecordMeta> {
return NSFetchRequest<RecordMeta>(entityName: "RecordMeta")
}
@NSManaged public var documentURI: String?
@NSManaged public var mimeType: String?
@NSManaged public var toRecord: Record?
}
extension SmartReport {
@nonobjc public class func fetchRequest() -> NSFetchRequest<SmartReport> {
return NSFetchRequest<SmartReport>(entityName: "SmartReport")
}
@NSManaged public var data: Data?
@NSManaged public var toRecord: Record?
}
- Record Model has a one-to-many relationship with RecordMeta
- Record Model has a one-to-one relationship with SmartReport
For all communications with the record database, we use the RecordsRepo
class, which provides the following model:
/// Model used for record insert
public struct RecordModel {
var documentID: String?
var documentDate: Date?
var documentHash: String?
var documentType: Int?
var hasSyncedEdit: Bool?
var isAnalyzing: Bool?
var isSmart: Bool?
var oid: String?
var thumbnail: String?
var updatedAt: Date?
var uploadDate: Date?
var documentURIs: [String]?
var contentType: String?
}
Function:
/// Used to add a single record to the database
/// - Parameter record: record to be added
public func addSingleRecord(
record: RecordModel,
completion didUploadRecord: @escaping (Record?) -> Void
)
Usage:
recordsRepo.addSingleRecord(record: recordModel) { uploadedRecord in
/// Action to be done after record upload
}
/// Used to fetch record entity items
/// - Parameter fetchRequest: fetch request for filtering
/// - Parameter completion: completion block to be executed after fetching records
public func fetchRecords(
fetchRequest: NSFetchRequest<Record>,
completion: @escaping ([Record]) -> Void
) {
databaseManager.fetchRecords(
fetchRequest: fetchRequest,
completion: completion
)
}
/// Used to fetch records from the server and store them in the database
/// - Parameter completion: completion block to be executed after fetching
public func fetchRecordsFromServer(completion: @escaping () -> Void)
/// Used to get file details and save in database
/// This will have both smart report and original record
private func getFileDetails(
record: Record,
completion: @escaping (DocFetchResponse?) -> Void
)
Function:
/// Used to update record
/// - Parameters:
/// - recordID: object Id of the record
/// - documentID: document id of the record
/// - documentDate: document date of the record
/// - documentType: document type of the record
public func updateRecord(
recordID: NSManagedObjectID,
documentID: String? = nil,
documentDate: Date? = nil,
documentType: Int? = nil
)
Usage:
/// Update record in database
recordsRepo.updateRecord(
recordID: record.objectID,
documentID: record.documentID,
documentDate: documentDate,
documentType: selectedDocumentType?.rawValue
)
/// Used to delete a specific record from the database as well as server
/// - Parameter record: record to be deleted
public func deleteRecord(
record: Record
)
struct DocFetchResponse: Codable, Hashable {
let documentID: String?
let description: String?
let patientName, authorizer: String?
let documentDate: String?
let documentType: String?
let tags: [String]?
let canDelete: Bool?
let files: [File]?
let smartReport: SmartReportInfo?
let userTags: [String]?
let derivedTags: [String]?
let thumbnail: String?
let fileExtension: String?
let sharedWith: [String]?
let uploadedByMe: Bool?
enum CodingKeys: String, CodingKey {
case documentID = "document_id"
case description
case patientName = "patient_name"
case authorizer
case documentDate = "document_date"
case documentType = "document_type"
case tags
case canDelete = "can_delete"
case files
case smartReport = "smart_report"
case userTags = "user_tags"
case derivedTags = "derived_tags"
case thumbnail = "thumbnail"
case fileExtension = "file_type"
case sharedWith = "shared_with"
case uploadedByMe = "uploaded_by_me"
}
static func == (lhs: DocFetchResponse, rhs: DocFetchResponse) -> Bool {
return lhs.documentID == rhs.documentID
}
func hash(into hasher: inout Hasher) {
hasher.combine(documentID)
}
}
struct File: Codable {
let assetURL: String?
let fileType, shareText: String?
let maskedFile: MaskedFile?
enum CodingKeys: String, CodingKey {
case assetURL = "asset_url"
case fileType = "file_type"
case shareText = "share_text"
case maskedFile = "masked_file"
}
}
struct MaskedFile: Codable {
let assetURL: String?
let fileType, shareText, title, body: String?
let tagline: String?
enum CodingKeys: String, CodingKey {
case assetURL = "asset_url"
case fileType = "file_type"
case shareText = "share_text"
case title, body, tagline
}
}
public struct SmartReportInfo: Codable, Equatable {
public let verified, unverified: [Verified]?
}
public struct Verified: Codable, Hashable, Identifiable {
public let id = UUID()
public let name, value, unit: String?
public let vitalID: String?
public let ekaID: String?
public let isResultEditable: Bool?
public let pageNum, fileIndex: Int?
public let coordinates: [Coordinate]?
public let range, result, resultID, displayResult: String?
public let date: Int?
enum CodingKeys: String, CodingKey {
case name, value, unit, date
case vitalID = "vital_id"
case ekaID = "eka_id"
case isResultEditable = "is_result_editable"
case pageNum = "page_num"
case fileIndex = "file_index"
case coordinates, range, result
case resultID = "result_id"
case displayResult = "display_result"
}
public static func == (lhs: Verified, rhs: Verified) -> Bool {
return lhs.vitalID == rhs.vitalID
}
public func hash(into hasher: inout Hasher) {
hasher.combine(vitalID)
}
}
public struct Coordinate: Codable, Hashable {
public let x: Double?
public let y: Double?
}
This project is licensed under the MIT License - see the LICENSE file for details.
For any questions or support, please open an issue in the GitHub repository or contact the Eka Care team.