{"id":32318060,"url":"https://github.com/enabyl/swiftyforesight","last_synced_at":"2026-02-21T20:01:23.131Z","repository":{"id":62456886,"uuid":"150905368","full_name":"Enabyl/SwiftyForesight","owner":"Enabyl","description":"Swift API for integrating mobile applications with Foresight cloud framework.","archived":false,"fork":false,"pushed_at":"2019-03-15T01:29:11.000Z","size":130,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-11-27T14:36:42.918Z","etag":null,"topics":["api","cocoapod","enabyl","foresight","swift"],"latest_commit_sha":null,"homepage":"https://cocoapods.org/pods/SwiftyForesight","language":"Swift","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Enabyl.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-09-29T21:43:50.000Z","updated_at":"2021-09-21T19:39:11.000Z","dependencies_parsed_at":"2022-11-01T22:33:12.287Z","dependency_job_id":null,"html_url":"https://github.com/Enabyl/SwiftyForesight","commit_stats":null,"previous_names":[],"tags_count":12,"template":false,"template_full_name":null,"purl":"pkg:github/Enabyl/SwiftyForesight","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Enabyl%2FSwiftyForesight","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Enabyl%2FSwiftyForesight/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Enabyl%2FSwiftyForesight/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Enabyl%2FSwiftyForesight/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Enabyl","download_url":"https://codeload.github.com/Enabyl/SwiftyForesight/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Enabyl%2FSwiftyForesight/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29691938,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-21T18:18:25.093Z","status":"ssl_error","status_checked_at":"2026-02-21T18:18:22.435Z","response_time":107,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["api","cocoapod","enabyl","foresight","swift"],"created_at":"2025-10-23T11:23:48.120Z","updated_at":"2026-02-21T20:01:23.123Z","avatar_url":"https://github.com/Enabyl.png","language":"Swift","funding_links":[],"categories":[],"sub_categories":[],"readme":"![ForesightSwiftAPILogo](https://github.com/Enabyl/SwiftyForesight/blob/master/foresightswiftapi.png)\n\n# SwiftyForesight\nSwift API for integrating mobile applications with Foresight cloud framework.\n\n## Contents\n- [Installation](#installation)\n- [User Guide](#user-guide)\n  - [AWS Dependencies](#aws-dependencies)\n  - [Importing SwiftyForesight](#importing-swiftyforesight)\n  - [CloudManager](#cloudmanager)\n  - [LibraModel](#libramodel)\n  - [LibraData](#libradata)\n- [Version History](#version-history)\n\n## Installation\n`SwiftyForesight` is available for installation via CocoaPods. In your Podfile, enter `pod 'SwiftyForesight'`, then from the terminal enter `pod install`.\n\n## User Guide\nThis library provides an easy interface between iOS devices and the Foresight cloud platform. iOS devices built on the Foresight framework must (1) connect to AWS cloud services, (2) transmit data in the proper format, and (3) download and run custom computational models as they are remotely generated. For these three tasks, this library provides three important classes: `CloudManager`, `LibraData`, and `LibraModel`.\n\n**Important Note**: All asynchronous functions in `SwiftyForesight` include completion handlers. Please use these handlers in cases where data transfer should be synchronized with other processes by using `DispatchGroup`. \n\n### AWS Dependencies\nAs the Foresight framework utilizes Amazon Web Services, important AWS dependencies are installed with the `SwiftyForesight` CocoaPod, if they aren't installed already. To use this library, ensure that you have obtained information about your AWS resources from an Enabyl representative. Also ensure that you have received your `awsconfiguration.json` file and have included it in your main project directory.\n\n### Importing SwiftyForesight\nIn any file in which `SwiftyForesight` classes are used, include `import SwiftyForesight` in the file header.\n\n### CloudManager\nThe `CloudManager` class manages the data connection between the iOS application and various AWS resources. It defines a variety of functions used by the `LibraData` and `LibraModels` classes to communicate with their respective AWS resources. Instantiate your application's `CloudManager` object by calling the initializer.\n\n```swift\n// Instantiate CloudManager object\nlet cloudManager = CloudManager(identityID: \"\u003cname\u003e\", userID: \"\u003cname\u003e\", writeBucket: \"\u003cname\u003e\", readBucket: \"\u003cname\u003e\")\n```\nAn **important note** is that each user on a device using the Foresight framework should have a unique alphanumeric user ID assigned to them. An easy way to generate this ID is to use `UUID.uuidstring()` and storing this ID in the Keychain or User Defaults. This ID is used by the Foresight framework to identify user-specific models, generate performance reports, and more, so it is in the developer's best interest to ensure this ID is kept consistent.\n\nThis class requires the user to specify their identity ID (found in their `awsconfiguration.json` file), the S3 bucket name to which they are transmitting data, and the S3 bucket name from which computational models are downloaded. There is only one use case in which you may wish to directly call a `CloudManager` method, as detailed [below](#datamanagement).\n\n### LibraModel\n#### Initializing\n`LibraModel` is a superclass for all computational models generated by the Foresight framework. Depending on your appilcation, you may have one or more subclass of `LibraModel` running on your device. The two model subtypes currently supported are `SequentialModel` (e.g. LSTM) and `FeedforwardModel` (e.g. Softmax). The below example shows how to instantiate a `SequentialModel` object, however the same process could be performed for a `FeedforwardModel`.\n\n```swift \n// Instantiate SequentialModel object\nlet myModel = SequentialModel(modelClass: MLModel(), numInputFeatures: 10, localFilepath: \u003cpath\u003e, withManager: cloudManager)\n```\n\nThe argument `modelClass` may be used to input a `MLModel` object if one is already installed in the main application bundle as a placeholder until remote models are downloaded and compiled -- in most cases, this will be left with a placeholder as shown above. The user must specify the number of input features in their model, as well as the local filepath (including .mlmodel filename) where remotely-compiled models will be temporarily stored. Finally, the user should include the `CloudManager` object defined earlier so that the model can manage its AWS connection. Perform this process for each computational model that will run on your device.\n\n#### Model Configuration\nIn order to generate predictions with a `LibraModel`, the names assigned to the input and output nodes of the model at the time of training/saving must be specified. The default values for input and output nodes are automatically handled by the `SwiftyForesight` API, however if you set custom names for the input and output nodes of your model you must specify them with the function `seFeatures()`.\n\n#### Fetching and Using Models\nThe `LibraModel` superclass includes two useful methods for performing tasks with these models. These include: \n- `fetch()`: Fetches and downloads the most recent model from the Foresight server platform.\n- `predict()`: Generates predictions based on provided input vectors.\n\nFormatting data for prediction is a simple task. For squential models, feature vectors should be provided in list format (i.e. `[[Double]]`), with each entry being a single feature vector. The total number of feature vectors should correspond with `numInputFeatures` specified above. For feedforward models, feature vectors should be provided in `[Double]` format, with the number of elements also corresponding to `numInputFeatures`. The `predict()` function will return results in `MLMultiArray` objects, from which the elements can be extracted to obtain model predictions.\n\n### LibraData\n#### Initializing\n`LibraData` objects perform the role of formatting data to be sent to remote server resources for training. For each model that is being remotely trained, a `LibraData` object should be instantiated and used to format and upload training data. The first step is to instantiate the object as follows.\n\n```swift\nlet myData = LibraData(hasTimestamp: true, featureVectors: 10, labelVectorLength: 3, withManager: cloudManager)\n```\nThe argument `hasTimestamp` is used during model training to inform how the first feature vector is treated. The `featureVectors` argument should specify how many feature vectors the data has NOT including the timestamp column. `labelVectorLength` specifies the length of the label vector (e.g. for a softmax classifier with three classes, `labelVectorLength` = 3). \n\n#### Formatting Data\n**NOTE** that for both feedforward and sequential models, each feature vector reprents the values of a single feature over training samples, not a cross-section of all features at a single timestep. Below is a demonstrative example of how data should be formatted.\n\n```swift\n// Collect features and labels\nlet featureVector1 = [1.0, 2.0, 3.0]  // First input feature values at t = 1, 2, 3\nlet featureVector2 = [4.0, 5.0, 6.0]  // Second input feature values at t = 1, 2, 3\nlet labelVector1 = [0.0, 1.0]         // First label vector at t = 1\nlet labelVector2 = [1.0, 0.0]         // Second label vector at t = 2\nlet labelVector3 = [1.0, 0.0]         // Third label vector at t = 3\n\n// Format features and labels into an array for import to LibraData object\nlet features = [featureVector1, featureVector2]         // Feature vector\nlet labels = [labelVector1, labelVector2, labelVector3] // Label vector\n```\n\n#### Transmitting Data\nTo format the data for upload, add the feature and label vectors into the `LibraData` object and upload.\n\n```swift\nmyData.addFeatures(features)  // Add features to object\nmyData.addLabels(labels)      // Add labels to object\nmyData.formatData()           // Formatting data for upload\nmyData.uploadDataToRemote(fromLocalFile: \u003cpath\u003e)  // Uploading data to remote\n```\nThe function `formatData()` formats the training data and saves it as a local .csv file. This file is automatically given the name `\u003cuserID\u003e_\u003ceventDate\u003e.csv` so that it may be properly processed at a later time. This file is then uploaded to the remote AWS resource with the function `uploadDataToRemote()` with the same filename. Notice that the local file path must be specified -- this is because the function `uploadDataToRemote()` is also used by other functions in the `SwiftyForesight` framework. However, the function `formatData()` returns the filename in a completion handler, which may then be passed directly to `uploadDataToRemote()`. Note also that `LibraData` includes a safeguard to retry all failed uploads at a later time (e.g., when network connection is lost).\n\n```swift\n// Retrying all failed uploads\nmyData.retryFailedUploads()\n```\n\nIf the user desires to delete all data files associated with failed uploads on the device, `LibraData` also includes the function `clearErrorLogs()`, which can be used to clear this data if it begins to consume more memory than is desirable.\n\n#### Incorporating Metadata\nWhen data files are transmitted to remote resources for model training, it may be useful to include metadata to add context for training algorithms. Metadata is stored in a DynamoDB database. In order to enable metadata, the user must take the following steps.\n\n1. After initializing your `CloudManager`, specify your DynamoDB table name with `CloudManager.tableName = \u003cYourTableName\u003e`.\n2. To add your metadata to your `LibraData` object, use the function `myData.addMetadata()`.\n3. To upload to DynamoDB, use the function `myData.uploadMetadataToRemote()`.\n\nData passed into your `LibraData` object with `addMetadata()` should be a dictionary with the following format:\n\n```swift\n// Generating a metadata dictionary\nlet myDict = [Keys.hash : \u003cuserID\u003e, Keys.range: \u003ceventDate\u003e, Keys.m0: \u003cmetadata0\u003e, Keys.m1: \u003cmetadata1\u003e, ...]\n```\n\nThe default DynamoDB table provided by the Foresight framework accepts up to 12 fields. `_userID` and `_eventDate` are required hash and range keys, respectively, however the user may choose to store up to 10 additional fields of metadata at their discretion. These fields may be added to the metadata dictionary with the keys `_m0` to `_m9` respectively. To prevent input errors, the `Keys` class is provided, which contains static variable holding the proper names of the hash key, range key, and 10 metadata fields. Note that these field names may not be changed, so the user must document and standardize what each metadata field is storing. The best practice guideline for storing metadata is that the `\u003cuserID\u003e` used in this dictionary should be the same as the field `CloudManager.userID`, since the function `removeAllUserMetadata()` queries the DynamoDB database based on the value of `CloudManager.userID`.\n\nMetadata may also be queried with the `LibraData` function `queryData()`, which returns all metadata entries between two specified dates. Dates should be formatted as follows in order for the query to work properly.\n\n```swift\nlet myDate = Date()   // Specify date here\nlet formatter = DateFormatter()\nformatter.dateFormat = \"yyyyMMhhmmss\"\"\nlet properDate = formatter.string(from: myDate)\n```\n\n#### Data Management\nTo maintain regulatory compliance, it is often necessary to give the user of an application the ability to delete all data and metadata that has been collected remotely. `LibraData` provides the function `clearData()` for removing all data that is currently being processed (i.e. neither uploaded nor locally saved). For deleting remote files, we must use `CloudManager` directly. `CloudManager` provides the functions `removeAllUserFiles()` for clearing all data *files* from remote resources, and the function `removeAllUserMetadata()` for removing all *metadata*.\n\n## Version History\n- *v1.0.0*: Initial Version\n- *v1.0.1*: Automated generation of local and remote filenames in proper format.\n- *v1.0.2*: Automated handling of DynamoDB table attributes.\n- *v1.0.3*: Added metadata querying and improved organization of metadata keys.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fenabyl%2Fswiftyforesight","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fenabyl%2Fswiftyforesight","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fenabyl%2Fswiftyforesight/lists"}