{"id":28458795,"url":"https://github.com/openmined/swiftsyft","last_synced_at":"2025-08-10T23:40:21.705Z","repository":{"id":47256058,"uuid":"232324233","full_name":"OpenMined/SwiftSyft","owner":"OpenMined","description":"The official Syft worker for iOS, built in Swift","archived":false,"fork":false,"pushed_at":"2021-09-06T13:51:27.000Z","size":52236,"stargazers_count":50,"open_issues_count":55,"forks_count":17,"subscribers_count":16,"default_branch":"dev","last_synced_at":"2025-06-07T00:39:51.757Z","etag":null,"topics":["swift","syft"],"latest_commit_sha":null,"homepage":null,"language":"Swift","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/OpenMined.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":"2020-01-07T12:53:18.000Z","updated_at":"2024-09-27T14:47:22.000Z","dependencies_parsed_at":"2022-09-13T13:52:39.677Z","dependency_job_id":null,"html_url":"https://github.com/OpenMined/SwiftSyft","commit_stats":null,"previous_names":[],"tags_count":7,"template":false,"template_full_name":null,"purl":"pkg:github/OpenMined/SwiftSyft","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OpenMined%2FSwiftSyft","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OpenMined%2FSwiftSyft/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OpenMined%2FSwiftSyft/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OpenMined%2FSwiftSyft/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/OpenMined","download_url":"https://codeload.github.com/OpenMined/SwiftSyft/tar.gz/refs/heads/dev","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OpenMined%2FSwiftSyft/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":263111349,"owners_count":23415432,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["swift","syft"],"created_at":"2025-06-07T00:39:48.527Z","updated_at":"2025-08-10T23:40:21.671Z","avatar_url":"https://github.com/OpenMined.png","language":"Swift","funding_links":[],"categories":[],"sub_categories":[],"readme":"![SwiftSyft-logo](openmined_assets/openmined_logo.png)\n![CI](https://img.shields.io/github/workflow/status/openmined/swiftsyft/SwiftSyft%20CI)\n[![Coverage](https://codecov.io/gh/OpenMined/SwiftSyft/branch/master/graph/badge.svg)](https://codecov.io/gh/OpenMined/SwiftSyft)\n![License](https://img.shields.io/github/license/openmined/swiftsyft)\n![Contributors](https://img.shields.io/opencollective/all/openmined)\n![OpenCollective](https://img.shields.io/opencollective/all/openmined)\n\n\u003c!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section --\u003e\n[![All Contributors](https://img.shields.io/badge/all_contributors-4-orange.svg?style=flat-square)](#contributors-)\n\u003c!-- ALL-CONTRIBUTORS-BADGE:END --\u003e\n\n# SwiftSyft\n\nSwiftSyft makes it easy for you to **train and inference PySyft models on iOS devices**. This allows you to utilize training data located directly on the device itself, bypassing the need to send a user's data to a central server. This is known as [federated learning](https://ai.googleblog.com/2017/04/federated-learning-collaborative.html).\n\n- :gear: **Training and inference** of any PySyft model written in PyTorch or TensorFlow\n- :bust_in_silhouette: Allows all data to stay on the user's device\n- :back: Support for delegation to background task scheduler\n- :key: Support for **JWT authentication** to protect models from Sybil attacks\n- :+1: Host of **inbuilt best practices** to prevent apps from over using device resources.\n  - :electric_plug: **Charge detection** to allow background training only when device is connected to charger\n  - :zzz: **Sleep and wake detection** so that the app does not occupy resource when user starts using the device\n  - :money_with_wings: **Wifi and metered network detection** to ensure the model updates do not use all the available data quota\n  - :no_bell: All of these smart defaults are easily are **overridable**\n- :mortar*board: Support for both reactive and callback patterns so you have your freedom of choice (\\_in progress*)\n- :lock: Support for **secure multi-party computation** and **secure aggregation** protocols using **peer-to-peer WebRTC** connections (_in progress_).\n\nThere are a variety of additional privacy-preserving protections that may be applied, including [differential privacy](https://towardsdatascience.com/understanding-differential-privacy-85ce191e198a), [muliti-party computation](https://www.inpher.io/technology/what-is-secure-multiparty-computation), and [secure aggregation](https://research.google/pubs/pub45808/).\n\n[OpenMined](https://openmined.org) set out to build the **world's first open-source ecosystem for federated learning on web and mobile**. SwiftSyft is a part of this ecosystem, responsible for bringing secure federated learning to iOS devices. You may also train models on Android devices using [KotlinSyft](https://github.com/OpenMined/KotlinSyft) or in web browsers using [syft.js](https://github.com/OpenMined/syft.js).\n\nIf you want to know how scalable federated systems are built, [Towards Federated Learning at Scale](https://arxiv.org/pdf/1902.01046.pdf) is a fantastic introduction!\n\n## Installation\n\n### Cocoapods\n\nCocoapods is a dependency manager for Cocoa projects. Just add `OpenMinedSwiftSyft` to your Podfile like below:\n\n```\npod 'OpenMinedSwiftSyft', ~\u003e 0.1.3-beta1\n```\n## Quick Start\n\nAs a developer, there are few steps to building your own secure federated learning system upon the OpenMined infrastructure:\n\n1. :robot: Generate your secure ML model using [PySyft](https://github.com/OpenMined/PySyft). By design, PySyft is built upon PyTorch and TensorFlow so you **don't need to learn a new ML framework**. You will also need to write a training plan (training code the worker runs) and an averaging plan (code that PyGrid runs to average the model diff).\n2. :earth_americas: Host your model and plans on [PyGrid](https://github.com/OpenMined/PyGrid) which will deal with all the federated learning components of your pipeline. You will need to set up a PyGrid server somewhere, please see their installation instructions on how to do this.\n3. :tada: Start training on the device!\n\n**:notebook: The entire workflow and process is described in greater detail in our [project roadmap](https://github.com/OpenMined/Roadmap/blob/master/federated_learning/projects/model_centric_fl.md).**\n\nYou can use SwiftSyft as a front-end or as a background service. The following is a quick start example usage:\n\n```swift\n\n// This is a demonstration of how to use SwiftSyft with PyGrid to train a plan on local data on an iOS device\n\n// Authentication token\nlet authToken = /* Get auth token from somewhere (if auth is required): */\n\n// Create a client with a PyGrid server URL\nif let syftClient = SyftClient(url: URL(string: \"ws://127.0.0.1:5000\")!, authToken: authToken) {\n\n  // Store the client as a property so it doesn't get deallocated during training.\n  self.syftClient = syftClient\n\n  // Create a new federated learning job with the model name and version\n  self.syftJob = syftClient.newJob(modelName: \"mnist\", version: \"1.0.0\")\n\n  // This function is called when SwiftSyft has downloaded the plans and model parameters from PyGrid\n  // You are ready to train your model on your data\n  // modelParams - Contains the tensor parameters of your model. Update these tensors during training\n  // and generate the diff at the end of your training run.\n  // plans - contains all the torchscript plans to be executed on your data.\n  // clientConfig - contains the configuration for the training cycle (batchSize, learning rate) and metadata for the model (name, version)\n  // modelReport - Used as a completion block and reports the diffs to PyGrid.\n  self.syftJob?.onReady(execute: { modelParams, plans, clientConfig, modelReport in\n\n    // This returns an array for each MNIST image and the corresponding label as PyTorch tensor\n    // It divides the training data and the label by batches\n    guard let MNISTDataAndLabelTensors = try? MNISTLoader.loadAsTensors(setType: .train) else {\n        return\n    }\n\n    // This loads the MNIST tensor into a dataloader to use for iterating during training\n    let dataLoader = MultiTensorDataLoader(dataset: MNISTDataAndLabelTensors, shuffle: true, batchSize: 64)\n\n    // Iterate through each batch of MNIST data and label\n    for batchedTensors in dataLoader {\n\n      // We need to create an autorelease pool to release the training data from memory after each loop\n      autoreleasepool {\n\n          // Preprocess MNIST data by flattening all of the MNIST batch data as a single array\n          let MNISTTensors = batchedTensors[0].reshape([-1, 784])\n\n          // Preprocess the label ( 0 to 9 ) by creating one-hot features and then flattening the entire thing\n          let labels = batchedTensors[1]\n\n          // Add batch_size, learning_rate and model_params as tensors\n          let batchSize = [UInt32(clientConfig.batchSize)]\n          let learningRate = [clientConfig.learningRate]\n\n          guard\n              let batchSizeTensor = TorchTensor.new(array: batchSize, size: [1]),\n              let learningRateTensor = TorchTensor.new(array: learningRate, size: [1]) ,\n              let modelParamTensors = modelParams.paramTensorsForTraining else\n          {\n              return\n          }\n\n          // Execute the torchscript plan with the training data, validation data, batch size, learning rate and model params\n          let result = plans[\"training_plan\"]?.forward([TorchIValue.new(with: MNISTTensors),\n                                                        TorchIValue.new(with: labels),\n                                                        TorchIValue.new(with: batchSizeTensor),\n                                                        TorchIValue.new(with: learningRateTensor),\n                                                        TorchIValue.new(withTensorList: modelParamTensors)])\n\n          // Example returns a list of tensors in the folowing order: loss, accuracy, model param 1,\n          // model param 2, model param 3, model param 4\n          guard let tensorResults = result?.tupleToTensorList() else {\n              return\n          }\n\n          let lossTensor = tensorResults[0]\n          lossTensor.print()\n          let loss = lossTensor.item()\n\n          let accuracyTensor = tensorResults[1]\n          accuracyTensor.print()\n\n          // Get updated param tensors and update them in param tensors holder\n          let param1 = tensorResults[2]\n          let param2 = tensorResults[3]\n          let param3 = tensorResults[4]\n          let param4 = tensorResults[5]\n\n          modelParams.paramTensorsForTraining = [param1, param2, param3, param4]\n\n      }\n    }\n\n        // Generate diff data and report the final diffs as\n        let diffStateData = try plan.generateDiffData()\n        modelReport(diffStateData)\n\n  })\n\n  // This is the error handler for any job exeuction errors like connecting to PyGrid\n  self.syftJob?.onError(execute: { error in\n    print(error)\n  })\n\n  // This is the error handler for being rejected in a cycle. You can retry again\n  // after the suggested timeout.\n  self.syftJob?.onRejected(execute: { timeout in\n      if let timeout = timeout {\n          // Retry again after timeout\n          print(timeout)\n      }\n  })\n\n  // Start the job. You can set that the job should only execute if the device is being charge and there is\n  // a WiFi connection. These options are on by default if you don't specify them.\n  self.syftJob?.start(chargeDetection: true, wifiDetection: true)\n}\n```\n\n### API Documenation\n\nSee [API Documenation](Documentation/Reference/README.md) for complete reference.\n\n### Running in the background\n\nA mini tutorial on how to run `SwiftSyft` on iOS using the background task scheduler can be found [here](Background-Example.md)\n\n### Running the Demo App\n\nThe demo app fetches the plans, protocols and model weights from PyGrid server hosted locally. The plans are then deserialized and executed using libtorch.\n\n\u003cp align=\"center\"\u003e\n\u003cimg src=\"openmined_assets/swiftsyft_demo.gif\" height=\"354\"\u003e\n\u003c/p\u003e\n\nFollow these steps to setup an environment to run the demo app:\n\n- Clone the repo [PyGrid](https://github.com/OpenMined/PyGrid) and change directory to `PyGrid/apps/domain`\n\n```bash\n$ git clone https://github.com/OpenMined/PyGrid\n$ cd PyGrid/apps/domain\n```\n- Run the PyGrid Domain application\n\n```bash\n$ ./run.sh --port 5000 --start_local_db\n```\n\n- Install [PySyft](https://github.com/OpenMined/PySyft) from source or via PyPy. Follow the instructions specified in the repo.\n- Clone the `PySyft` repo. In your command line, go to `PySyft/examples/federated-learning/model-centric/` folder and run jupyter notebook.\n\n```bash\n$ cd PySyft/examples/federated-learning/model-centric/\n$ jupyter notebook\n```\n- Open the notebook `mcfl_create_plan_mobile.ipynb` notebook. Run all the cells to host a plan to your running PyGrid domain server.\n\n- Set-up demo project using Cocoapods\n- Install [Cocoapods](https://cocoapods.org/)\n\n```bash\ngem install cocoapods\n```\n\n- Install the dependencies of the project.\n\n```bash\npod install # On the root directory of this project\n```\n\n- Open the file `SwiftSyft.xcworkspace` in Xcode.\n- Run the `SwiftSyft` project. It automatically uses `127.0.0.1:5000` as the PyGrid URL.\n\n## Contributing\n\n### Set-up\n\nYou can work on the project by running `pod install` in the root directory. Then open the file `SwiftSyft.xcworkspace` in Xcode. When the project is open on Xcode, you can work on the `SwiftSyft` pod itself in `Pods/Development Pods/SwiftSyft/Classes/*`\n\n### Workflow\n\n1. Star, for and clone the repo\n2. Open the project in Xcode\n3. Check out current issues and Github. For newcomers, check out issues labeled `Good first issue`\n4. Do your work\n5. Push your fork\n6. Submit a PR to OpenMined/SwiftSyft\n\nRead the [contribution guide](https://github.com/OpenMined/.github/blob/master/CONTRIBUTING.md) as a good starting place.\n\n### Support\n\nFor support in using this library, please join the **#lib_swift_syft** Slack channel. If you'd like to follow along with any code changes to the library, please join **#code_swiftsyft** Slack channel. [Click here to join our Slack Community!](https://slack.openmined.org)\n\n## License\n\n[Apache License 2.0](https://choosealicense.com/licenses/apache-2.0/)\n\n## Contributors ✨\n\nThanks goes to these wonderful people ([emoji key](https://allcontributors.org/docs/en/emoji-key)):\n\n\u003c!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section --\u003e\n\u003c!-- prettier-ignore-start --\u003e\n\u003c!-- markdownlint-disable --\u003e\n\u003ctable\u003e\n  \u003ctr\u003e\n    \u003ctd align=\"center\"\u003e\u003ca href=\"https://github.com/mjjimenez\"\u003e\u003cimg src=\"https://avatars3.githubusercontent.com/u/4151269?v=4\" width=\"100px;\" alt=\"\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eMark Jimenez\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"https://github.com/OpenMined/SwiftSyft/commits?author=mjjimenez\" title=\"Code\"\u003e💻\u003c/a\u003e \u003ca href=\"https://github.com/OpenMined/SwiftSyft/commits?author=mjjimenez\" title=\"Documentation\"\u003e📖\u003c/a\u003e\u003c/td\u003e\n    \u003ctd align=\"center\"\u003e\u003ca href=\"https://github.com/mamuleanu\"\u003e\u003cimg src=\"https://avatars0.githubusercontent.com/u/10297451?v=4\" width=\"100px;\" alt=\"\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eMadalin Mamuleanu\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"https://github.com/OpenMined/SwiftSyft/commits?author=mamuleanu\" title=\"Code\"\u003e💻\u003c/a\u003e\u003c/td\u003e\n    \u003ctd align=\"center\"\u003e\u003ca href=\"https://rohith-hacker.github.io/\"\u003e\u003cimg src=\"https://avatars1.githubusercontent.com/u/27728974?v=4\" width=\"100px;\" alt=\"\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eRohith Pudari\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"https://github.com/OpenMined/SwiftSyft/commits?author=Rohith-hacker\" title=\"Code\"\u003e💻\u003c/a\u003e\u003c/td\u003e\n    \u003ctd align=\"center\"\u003e\u003ca href=\"https://github.com/Baschdl\"\u003e\u003cimg src=\"https://avatars0.githubusercontent.com/u/3034832?v=4\" width=\"100px;\" alt=\"\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eSebastian Bischoff\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"https://github.com/OpenMined/SwiftSyft/commits?author=Baschdl\" title=\"Documentation\"\u003e📖\u003c/a\u003e\u003c/td\u003e\n    \u003ctd align=\"center\"\u003e\u003ca href=\"http://lukereichold.com\"\u003e\u003cimg src=\"https://avatars3.githubusercontent.com/u/693592?v=4\" width=\"100px;\" alt=\"\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eLuke Reichold\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"https://github.com/OpenMined/SwiftSyft/commits?author=lukereichold\" title=\"Code\"\u003e💻\u003c/a\u003e\u003c/td\u003e\n  \u003c/tr\u003e\n\u003c/table\u003e\n\n\u003c!-- markdownlint-enable --\u003e\n\u003c!-- prettier-ignore-end --\u003e\n\u003c!-- ALL-CONTRIBUTORS-LIST:END --\u003e\n\nThis project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome!\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fopenmined%2Fswiftsyft","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fopenmined%2Fswiftsyft","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fopenmined%2Fswiftsyft/lists"}