diff --git a/.github/assets/SC_Prototype.png b/.github/assets/SC_Prototype.png new file mode 100644 index 0000000..c7fab94 Binary files /dev/null and b/.github/assets/SC_Prototype.png differ diff --git a/.github/assets/SC_Prototype.png.license b/.github/assets/SC_Prototype.png.license new file mode 100644 index 0000000..eb38c65 --- /dev/null +++ b/.github/assets/SC_Prototype.png.license @@ -0,0 +1,5 @@ +This source file is part of the Spatial Continuity project + +SPDX-FileCopyrightText: 2025 Stanford University and the project authors (see CONTRIBUTORS.md) + +SPDX-License-Identifier: MIT diff --git a/.github/assets/tum-logo-dark-mode.png b/.github/assets/tum-logo-dark-mode.png new file mode 100644 index 0000000..296d9fd Binary files /dev/null and b/.github/assets/tum-logo-dark-mode.png differ diff --git a/.github/assets/tum-logo-dark-mode.png.license b/.github/assets/tum-logo-dark-mode.png.license new file mode 100644 index 0000000..c44245a --- /dev/null +++ b/.github/assets/tum-logo-dark-mode.png.license @@ -0,0 +1,5 @@ +This source file is part of the Spatial Continuity project + +SPDX-FileCopyrightText: Technical University of Munich + +SPDX-License-Identifier: MIT diff --git a/.github/assets/tum-logo-light-mode.png b/.github/assets/tum-logo-light-mode.png new file mode 100644 index 0000000..a3c6027 Binary files /dev/null and b/.github/assets/tum-logo-light-mode.png differ diff --git a/.github/assets/tum-logo-light-mode.png.license b/.github/assets/tum-logo-light-mode.png.license new file mode 100644 index 0000000..c44245a --- /dev/null +++ b/.github/assets/tum-logo-light-mode.png.license @@ -0,0 +1,5 @@ +This source file is part of the Spatial Continuity project + +SPDX-FileCopyrightText: Technical University of Munich + +SPDX-License-Identifier: MIT diff --git a/.github/workflows/beta-deployment.yml b/.github/workflows/beta-deployment.yml index 3263792..70c9a0d 100644 --- a/.github/workflows/beta-deployment.yml +++ b/.github/workflows/beta-deployment.yml @@ -1,7 +1,7 @@ # -# This source file is part of the StanfordBDHG Template Application project +# This source file is part of the Spatial Continuity project # -# SPDX-FileCopyrightText: 2023 Stanford University +# SPDX-FileCopyrightText: 2025 Stanford University and the project authors (see CONTRIBUTORS.md) # # SPDX-License-Identifier: MIT # @@ -23,16 +23,3 @@ jobs: actions: read security-events: write secrets: inherit - iosapptestflightdeployment: - name: iOS App TestFlight Deployment - needs: buildandtest - uses: StanfordBDHG/.github/.github/workflows/xcodebuild-or-fastlane.yml@v2 - concurrency: - group: appstoreconnect - permissions: - contents: read - with: - setupsigning: true - fastlanelane: beta - environment: beta - secrets: inherit diff --git a/.github/workflows/build-and-test.yml b/.github/workflows/build-and-test.yml index e2c2a63..12c75fc 100644 --- a/.github/workflows/build-and-test.yml +++ b/.github/workflows/build-and-test.yml @@ -1,7 +1,7 @@ # -# This source file is part of the StanfordBDHG Template Application project +# This source file is part of the Spatial Continuity project # -# SPDX-FileCopyrightText: 2023 Stanford University +# SPDX-FileCopyrightText: 2025 Stanford University and the project authors (see CONTRIBUTORS.md) # # SPDX-License-Identifier: MIT # @@ -29,33 +29,57 @@ jobs: uses: StanfordBDHG/.github/.github/workflows/periphery.yml@v2 permissions: contents: read - codeql: - name: CodeQL + # NOTE: CodeQL disabled until it supports the current Swift toolchain + # codeql_scc: + # name: CodeQL Spatial Continuity Camera + # uses: StanfordBDHG/.github/.github/workflows/xcodebuild-or-fastlane.yml@v2 + # with: + # codeql: true + # fastlanelane: ios codeql_scc + # permissions: + # security-events: write + # actions: read + # codeql_sc: + # name: CodeQL Spatial Continuity + # uses: StanfordBDHG/.github/.github/workflows/xcodebuild-or-fastlane.yml@v2 + # with: + # codeql: true + # fastlanelane: visionos codeql_sc + # permissions: + # security-events: write + # actions: read + buildandtest_scc: + name: Build Spatial Continuity Camera (for Testing) uses: StanfordBDHG/.github/.github/workflows/xcodebuild-or-fastlane.yml@v2 + strategy: + fail-fast: false + matrix: + platform: [iphone] with: - codeql: true - fastlanelane: codeql - permissions: - security-events: write - actions: read - buildandtest: - name: Build and Test + # We use the self-hosted runners as the main GitHub Action runners do not have the necessary performance. + # Remove the `runsonlabels: '["macOS", "self-hosted"]'` lines if you do not administer your own GitHub Runners. + runsonlabels: '["macOS", "self-hosted"]' + fastlanelane: ios test_iphone # ${{ matrix.platform }} + artifactname: ${{ matrix.platform }}.xcresult + buildandtest_sc: + name: Build Spatial Continuity (for Testing) uses: StanfordBDHG/.github/.github/workflows/xcodebuild-or-fastlane.yml@v2 strategy: fail-fast: false matrix: - platform: [iphone, ipad, apple_watch, apple_tv, vision_pro] + platform: [VisionPro] with: # We use the self-hosted runners as the main GitHub Action runners do not have the necessary performance. # Remove the `runsonlabels: '["macOS", "self-hosted"]'` lines if you do not administer your own GitHub Runners. runsonlabels: '["macOS", "self-hosted"]' - fastlanelane: test_${{ matrix.platform }} + fastlanelane: visionos test_vision_pro # ${{ matrix.platform }} artifactname: ${{ matrix.platform }}.xcresult - uploadcoveragereport: - name: Upload Coverage Report - needs: [buildandtest] - uses: StanfordBDHG/.github/.github/workflows/create-and-upload-coverage-report.yml@v2 - with: - coveragereports: iphone.xcresult ipad.xcresult apple_watch.xcresult apple_tv.xcresult vision_pro.xcresult - secrets: - token: ${{ secrets.CODECOV_TOKEN }} + # NOTE: Disabled since no tests are being run ATM + # uploadcoveragereport: + # name: Upload Coverage Report + # needs: [buildandtest] + # uses: StanfordBDHG/.github/.github/workflows/create-and-upload-coverage-report.yml@v2 + # with: + # coveragereports: iphone.xcresult + # secrets: + # token: ${{ secrets.CODECOV_TOKEN }} diff --git a/.gitignore b/.gitignore index f938f2f..3ae9396 100644 --- a/.gitignore +++ b/.gitignore @@ -1,32 +1,17 @@ # -# This source file is part of the StanfordBDHG Template Application project +# This source file is part of the Spatial Continuity project # -# SPDX-FileCopyrightText: 2023 Stanford University +# SPDX-FileCopyrightText: 2025 Stanford University and the project authors (see CONTRIBUTORS.md) # # SPDX-License-Identifier: MIT # -# Swift Package Manager -*.xcodeproj -.swiftpm -.derivedData -.build -!TemplateApplication.xcodeproj - -# IDE related folders -.idea - -# Xcode -xcuserdata/ -*.ipa -*.dSYM -*.dSYM.zip - -# Other files .DS_Store -.env +/.build +/Packages +xcuserdata/ +DerivedData/ +.swiftpm/configuration/registries.json +.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata +.netrc -# Tests -report.junit -report.html -*.xcresult diff --git a/.periphery.yml b/.periphery.yml index 0e19cf1..ba59080 100644 --- a/.periphery.yml +++ b/.periphery.yml @@ -1,16 +1,24 @@ # -# This source file is part of the StanfordBDHG Template Application project +# This source file is part of the Spatial Continuity project # -# SPDX-FileCopyrightText: 2023 Stanford University +# SPDX-FileCopyrightText: 2025 Stanford University and the project authors (see CONTRIBUTORS.md) # # SPDX-License-Identifier: MIT # -project: TemplateApplication.xcodeproj +project: SpatialContinuity.xcodeproj schemes: -- TemplateApplication +- SpatialContinuityCamera +- SpatialContinuity targets: -- TemplateApplication -- TemplateApplicationTests -- TemplateApplicationUITests -- TemplateWatchApplication +- SpatialContinuityCamera +- SpatialContinuity +report_exclude: +- SpatialContinuityShared/**/*.swift +# HACK: Is this the correct way to exclude external libraries from being checked? +- "**/*SpeziLLM*/**/*.swift" +disable_unused_import_analysis: true +relative_results: true +build_arguments: +- -skipPackagePluginValidation +- -skipMacroValidation diff --git a/.reuse/dep5 b/.reuse/dep5 deleted file mode 100644 index 18d2125..0000000 --- a/.reuse/dep5 +++ /dev/null @@ -1,6 +0,0 @@ -Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ - -Files: TemplateApplication.xcodeproj/* -Copyright: 2024 Stanford University and the project authors (see CONTRIBUTORS.md) -License: MIT -Comment: All Xcode Project Configuration Files are part of the StanfordBDHG Template Application project. diff --git a/.swiftformat b/.swiftformat new file mode 100644 index 0000000..f045fe4 --- /dev/null +++ b/.swiftformat @@ -0,0 +1,35 @@ +# +# This source file is part of the Spatial Continuity Project +# +# SPDX-FileCopyrightText: 2025 Stanford University and the project authors (see CONTRIBUTORS.md) +# +# SPDX-License-Identifier: MIT +# + +--acronyms "ID,URL,UUID,SCC" +--allman false +--binarygrouping 4,8 +--commas inline +--decimalgrouping 3,6 +--header \nThis source file is part of the Spatial Continuity project\n\nSPDX-FileCopyrightText: 2025 Stanford University and the project authors (see CONTRIBUTORS.md)\n\nSPDX-License-Identifier: MIT\n +--hexgrouping 4,8 +--hexliteralcase uppercase +--indent 4 +--linebreaks lf +--maxwidth 120 +--octalgrouping 4,8 +--semicolons "never" +--swiftversion 6.0 +--trimwhitespace always +--wrapparameters before-first +--wrapcollections before-first +--wrapconditions after-first + +# Rules +--enable acronyms +--enable blankLinesBetweenImports +--enable isEmpty +--enable wrapConditionalBodies +--enable wrapMultilineConditionalAssignment +--enable redundantProperty +--disable wrapMultilineStatementBraces diff --git a/.swiftformat.license b/.swiftformat.license new file mode 100644 index 0000000..eb38c65 --- /dev/null +++ b/.swiftformat.license @@ -0,0 +1,5 @@ +This source file is part of the Spatial Continuity project + +SPDX-FileCopyrightText: 2025 Stanford University and the project authors (see CONTRIBUTORS.md) + +SPDX-License-Identifier: MIT diff --git a/.swiftlint.yml b/.swiftlint.yml index f056fe8..73373b4 100644 --- a/.swiftlint.yml +++ b/.swiftlint.yml @@ -379,6 +379,7 @@ deployment_target: # Availability checks or attributes shouldn’t be using olde excluded: # paths to ignore during linting. Takes precedence over `included`. - .build - .swiftpm + - "SpatialContinuityShared/Sources/SpatialContinuityShared/LocalVideoStreaming/**/*.swift" closure_body_length: # Closure bodies should not span too many lines. - 35 # warning - default: 20 diff --git a/CITATION.cff b/CITATION.cff index a373635..e4e9787 100644 --- a/CITATION.cff +++ b/CITATION.cff @@ -7,11 +7,51 @@ # cff-version: 1.2.0 -message: "If you use this software, please cite it as below." +message: "If you use this software or reference our publication, please cite it as below." +title: "Spatial Continuity: Investigating Use Cases of Spatial Computing for Users with Low Vision" authors: -- family-names: "Schmiedmayer" - given-names: "Paul" - orcid: "https://orcid.org/0000-0002-8607-9148" -title: "TemplateApplication" -doi: 10.5281/zenodo.7633671 -url: "https://github.com/StanfordBDHG/TemplateApplication" + - family-names: "Heidekrüger" + given-names: "Paul" + orcid: "https://orcid.org/0009-0000-8556-7353" + affiliation: "Technical University of Munich" + - family-names: "Brügge" + given-names: "Bernd" + orcid: "https://orcid.org/0000-0001-8331-0490" + affiliation: "Technical University of Munich" + - family-names: "Aalami" + given-names: "Oliver" + orcid: "https://orcid.org/0000-0002-7799-2429" + affiliation: "Stanford Mussallem Center for Biodesign, Stanford University" + - family-names: "Schmiedmayer" + given-names: "Paul" + orcid: "https://orcid.org/0000-0002-8607-9148" + affiliation: "Stanford Mussallem Center for Biodesign, Stanford University" +doi: "10.1145/3663547.3759711" +url: "https://doi.org/10.1145/3663547.3759711" +preferred-citation: + type: conference-paper + title: "Spatial Continuity: Investigating Use Cases of Spatial Computing for Users with Low Vision" + authors: + - family-names: "Heidekrüger" + given-names: "Paul" + orcid: "https://orcid.org/0009-0000-8556-7353" + - family-names: "Brügge" + given-names: "Bernd" + orcid: "https://orcid.org/0000-0001-8331-0490" + - family-names: "Aalami" + given-names: "Oliver" + orcid: "https://orcid.org/0000-0002-7799-2429" + - family-names: "Schmiedmayer" + given-names: "Paul" + orcid: "https://orcid.org/0000-0002-8607-9148" + doi: "10.1145/3663547.3759711" + collection-title: "Proceedings of the 27th International ACM SIGACCESS Conference on Computers and Accessibility (ASSETS ’25)" + conference: + name: "The 27th International ACM SIGACCESS Conference on Computers and Accessibility (ASSETS ’25)" + location: "Denver, CO, USA" + date-start: 2025-10-26 + date-end: 2025-10-29 + publisher: + name: "ACM" + location: "New York, NY, USA" + year: 2025 \ No newline at end of file diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index c5efe20..772ff92 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -1,14 +1,17 @@ -Template Application Contributors -================================= +Spatial Continuity Contributors +=============================== +* [Paul Heidekrüger](https://github.com/paulhdk) +* [Bernd Brügge](https://ase.in.tum.de/BerndBruegge) +* [Oliver Aalami](https://github.com/aalami5) * [Paul Schmiedmayer](https://github.com/PSchmiedmayer) diff --git a/LICENSE.md b/LICENSE.md index 4e569da..5ba4803 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -1,9 +1,21 @@ MIT License -Copyright (c) 2022 Stanford University +Copyright (c) 2025 Stanford University and the project authors (see CONTRIBUTORS.md) -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/Localizable.xcstrings b/Localizable.xcstrings new file mode 100644 index 0000000..e965083 --- /dev/null +++ b/Localizable.xcstrings @@ -0,0 +1,77 @@ +{ + "sourceLanguage" : "en", + "strings" : { + "%lld" : { + + }, + "API Key Settings" : { + "extractionState" : "manual", + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "API Key Einstellungen" + } + } + } + }, + "Current Pin" : { + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Aktueller Pin" + } + } + } + }, + "Read Image Description" : { + "extractionState" : "manual", + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Bildbeschreibung Vorlesen" + } + } + } + }, + "The live video being streamed from SpatialContinutiyCamera" : { + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Die Liveübertragung von der Sptial Continuity Kamera" + } + } + } + }, + "The static pin received from SpatialContinuityCamera" : { + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Der statische Pin von der Spatial Continuity Kamera" + } + } + } + }, + "The viewfinder's view" : { + + }, + "Your pin will appear here." : { + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Pin erscheint hier" + } + } + } + }, + "Zoom" : { + + } + }, + "version" : "1.0" +} \ No newline at end of file diff --git a/Localizable.xcstrings.license b/Localizable.xcstrings.license new file mode 100644 index 0000000..eb38c65 --- /dev/null +++ b/Localizable.xcstrings.license @@ -0,0 +1,5 @@ +This source file is part of the Spatial Continuity project + +SPDX-FileCopyrightText: 2025 Stanford University and the project authors (see CONTRIBUTORS.md) + +SPDX-License-Identifier: MIT diff --git a/README.md b/README.md index 3f59337..80e9cdb 100644 --- a/README.md +++ b/README.md @@ -1,77 +1,79 @@ -# Template Application +# Spatial Continuity -[![Build and Test](https://github.com/StanfordBDHG/TemplateApplication/actions/workflows/build-and-test.yml/badge.svg)](https://github.com/StanfordBDHG/TemplateApplication/actions/workflows/build-and-test.yml) -[![codecov](https://codecov.io/gh/StanfordBDHG/TemplateApplication/graph/badge.svg?token=ezY7o5Trsk)](https://codecov.io/gh/StanfordBDHG/TemplateApplication) -[![DOI](https://zenodo.org/badge/587923964.svg)](https://zenodo.org/badge/latestdoi/587923964) -This repository contains the StanfordBDHG Template Application. It serves as a template repository for projects requiring a mobile application using continuous integration and continuous delivery setup. +## Overview -## Continous Delivery Workflows +This repository contains a implementation of _Spatial Continuity_. +_Spatial Continuity_ is a novel concept that proposes a combination of spatial computing and large language models (LLM) to provide seamless transitions between virtual and real-world contexts for making the world more accessible to users with low vision. +Ultimately, this should lead to a truly continuous experience where the friction that accessible technologies introduce, e.g., by setup and positioning, is fully removed. -### Beta Deployment +This implementation is part of our work on the "Spatial Continuity: Investigating Use Cases of Spatial Computing for Users with Low Vision" poster, which was accepted at the [27th International ACM SIGACCESS Conference on Computers and Accessibility](https://assets25.sigaccess.org/). -The Beta Deployment workflow is triggered when a new commit is added to the main branch. +![A screenshot from an Apple Vision Pro looking at a poster of the Utah Teapot and a copy of the book Gödel, Escher, Bach, both positioned beside each other on a flat surface. The person wearing the Vision Pro (and taking the screenshot) is holding an iPhone showing a full-screen viewfinder. The iPhone's camera feed is being livestreamed to the Spatial Continuity app on the Vision Pro, which is showing two windows in front of the user, above the poster and the book. One window is showing the livestream from the iPhone, with two additional menu items below, reading "Onboarding" and "Describe". The other window is showing a static pin (screenshot) from the cover of the Gödel, Escher, Bach book, which was taken from the iPhone's livestream to Spatial Continuity.](.github/assets/SC_Prototype.png) -It first runs the Build and Test workflow to ensure all tests are passing. -Once the Build and Test workflow passes, it builds the iOS application so it can be archived and sent to [TestFlight](https://developer.apple.com/testflight/) for internal beta deployment. -### Build and Test +## Functionality -The Build and Test workflow builds and tests the iOS application, shared Swift package, and web service. It runs all unit and user interface (UI) tests defined in the targets. The iOS application is tested on the iOS simulator on macOS. The shared and web service Swift packages are tested on Linux and macOS as well as in release and debug configuration to demonstrate all possible variations. +The current prototype implementation of _Spatial Continuity_ consists of two apps: the Spatial Continuity app on Vision Pro and the Spatial Continuity Camera app on iPhone. -### SwiftLint +The Spatial Continuity Camera app functions as a hand-held magnifying glass. +After connecting, it streams the camera feed from the iPhone to the Spatial Continuity Camera app running on Vision Pro. -The Swiftlint workflow is triggered by every pull request (PR) and checks if the files found in the diff contain any [SwiftLint](https://github.com/realm/SwiftLint) violations. -You can change the SwiftLint configuration in the `.swiftlint.yml` file found at the root of this repository. +The Spatial Continuity Camera app can open screenshots from the camera livestream in a separate window for further inspection. +If an OpenAI API key is provided, spoken image descriptions will be generated as well. -## Continous Delivery Setup -It is a prerequisite to have access to an Apple Developer Account that allows [TestFlight](https://developer.apple.com/testflight/) releases and create an app in [App Store Connect](https://appstoreconnect.apple.com) that matches the bundle identifier you have defined in the App project. +## Setup and Usage -### App Store Connect Access +1. Upon opening the Spatial Continuity app for the first time, you will be presented with the [SpeziLLM](https://github.com/StanfordSpezi/SpeziLLM) onboarding window where you may enter your OpenAI API key. An OpenAI API key is required for generating spoken image descriptions. +2. Ensure that both your iPhone and Vision Pro are on the same network. When opening the Spatial Continuity Camera app on iPhone, the connection should be established automatically. -The [TestFlight](https://developer.apple.com/testflight/) deployment requires access to the App Store Connect API using an API key. Please follow the Apple instructions to [Creating API Keys for the App Store Connect API](https://developer.apple.com/documentation/appstoreconnectapi/creating_api_keys_for_app_store_connect_api). The key needs the `App Manager` access role. -Store the following information in the following GitHub secrets: -- `APPLE_ID`: The Apple ID you use to access the App Store Connect API. -- `APP_STORE_CONNECT_ISSUER_ID`: The issuer ID of the App Store Connect API is displayed in the App Store Connect API keys section. -- `APP_STORE_CONNECT_API_KEY_ID`: The key ID of the API key created in the App Store Connect API keys section. -- `APP_STORE_CONNECT_API_KEY_BASE64`: The content of the key created in App Store Connect condensed into a Base64 representation, e.g., using `base64 -i AuthKey_ABCDEFGHIJ.p8 | pbcopy`. -### Apple Xcode Certificate and Provisioning Profile +## Contributors -The GitHub Action imports the Apple certificate and provisioning profile from the GitHub secrets and installs them in a local KeyChain on the GitHub runner instances. -Please follow the GitHub instructions to [Installing an Apple certificate on macOS runners for Xcode development](https://docs.github.com/en/enterprise-server@3.4/actions/deployment/deploying-xcode-applications/installing-an-apple-certificate-on-macos-runners-for-xcode-development). +You can find a list of contributors in the [CONTRIBUTORS.md](/CONTRIBUTORS.md) file. -Obtaining the Apple provisioning profile requires you to follow the following steps: -1. Register the app identifier in the [Apple Developer Account Identifiers section](https://developer.apple.com/account/resources/identifiers/list) using the bundle identifier for your application, e.g., `com.schmiedmayer.continousdelivery`. -2. Create an **AppStore** distribution provisioning profile in the [Apple Developer Account Profiles section](https://developer.apple.com/account/resources/profiles/list) using the app identifier you have created in the previous step. -3. Download the provisioning profile and convert it to a Base64 representation as detailed in [Installing an Apple certificate on macOS runners for Xcode development](https://docs.github.com/en/enterprise-server@3.4/actions/deployment/deploying-xcode-applications/installing-an-apple-certificate-on-macos-runners-for-xcode-development) and add it as the value for the `BUILD_PROVISION_PROFILE_BASE64` secret. -After following the setup steps detailed in [Installing an Apple certificate on macOS runners for Xcode development](https://docs.github.com/en/enterprise-server@3.4/actions/deployment/deploying-xcode-applications/installing-an-apple-certificate-on-macos-runners-for-xcode-development) and obtaining the Apple provisioning profile as described above, you should have the following secrets configured in the repository settings: -- `BUILD_CERTIFICATE_BASE64`: The Base64 version of the Apple signing certificate to build your iOS application. -- `P12_PASSWORD`: The password for the Apple signing certificate. -- `BUILD_PROVISION_PROFILE_BASE64`: The Base64 version of the Apple provisioning profile to build your iOS application. -- `KEYCHAIN_PASSWORD`: A password for the keychain that will be created on the runner instance. +## Open Source Contributions -Be sure that you update the name of the provisioning profile in the `Gymfile` and update the app name, bundle identifier, Xcode project name, paths, and other settings in the fastlane files when modifying the template to your needs! +As part of this work, we made the following open source contributions: +* https://github.com/apple/swift-openapi-runtime/pull/115 +* https://github.com/apple/swift-openapi-generator/pull/625 +* https://github.com/openai/openai-openapi/pull/311#issuecomment-2600521373 +* https://github.com/StanfordSpezi/SpeziViews/pull/49 +* https://github.com/StanfordSpezi/SpeziAccount/pull/82 +* https://github.com/StanfordSpezi/SpeziLLM/pull/64 +* https://github.com/StanfordSpezi/SpeziViews/pull/43 +* https://github.com/StanfordSpezi/SpeziLLM/pull/61 -### Swift Package and Fastlane Update ACCESS_TOKEN -The [Swift Package and Fastlane Update workflow](https://github.com/PSchmiedmayer/ContinousDelivery/blob/main/.github/workflows/update.yml) requires an `ACCESS_TOKEN` secret: a GitHub Personal Access Token (PAT) allowing write access to the repository. -We suggest using a bot account to create the access token. Using the PAT triggers the GitHub Actions in the create PR. [The GitHub documentation provides instructions on creating a PAT](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/creating-a-personal-access-token). The [scrop of the token](https://docs.github.com/en/developers/apps/building-oauth-apps/scopes-for-oauth-apps) can be limited to the `public_repo` scope for public repositories or the `repo` scrope for private repositories as well as the `workflow` scope. +## Contributing -Removing the `token` input in the GitHub action workflow results in using the default `GITHUB_TOKEN` and the GitHub Action bot account that does not trigger any possible merge checks in the newly created PR. +Contributions to this project are welcome. Please make sure to read the [contribution guidelines](https://github.com/StanfordBDHG/.github/blob/main/CONTRIBUTING.md) and the [contributor covenant code of conduct](https://github.com/StanfordBDHG/.github/blob/main/CODE_OF_CONDUCT.md) first. -### Contributors -This project is based on [ContinousDelivery Example by Paul Schmiedmayer](https://github.com/PSchmiedmayer/ContinousDelivery). You can find a list of contributors in the `CONTRIBUTORS.md` file. +## License + +This project is licensed under the MIT License. See [Licenses](https://github.com/StanfordBDHG/PediatricAppleWatchStudy/tree/main/LICENSES) for more information. + + +## Our Research + +For more information, check out our website at [biodesigndigitalhealth.stanford.edu](https://biodesigndigitalhealth.stanford.edu). + +This project is the result of a collaboration between the Stanford Mussallem Center for Biodesign and the Technical University of Munich. + +![Stanford Byers Center for Biodesign Logo](https://raw.githubusercontent.com/StanfordBDHG/.github/main/assets/biodesign-footer-light.png#gh-light-mode-only) +![Stanford Byers Center for Biodesign Logo](https://raw.githubusercontent.com/StanfordBDHG/.github/main/assets/biodesign-footer-dark.png#gh-dark-mode-only) +Technical University of Munich Logo (Blue) +Technical University of Munich Logo (White) diff --git a/SpatialContinuity.xcodeproj/project.pbxproj b/SpatialContinuity.xcodeproj/project.pbxproj new file mode 100644 index 0000000..380f13a --- /dev/null +++ b/SpatialContinuity.xcodeproj/project.pbxproj @@ -0,0 +1,1016 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 56; + objects = { + +/* Begin PBXBuildFile section */ + 05036FAD96F83782A5BD93AB /* SCCPreviewView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D426CB8B3F4A311C17F1A9CC /* SCCPreviewView.swift */; }; + 5436E9AFB5CC5A5FD301764D /* OnboardingFlow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2BBD782C297202ED97DC9B8A /* OnboardingFlow.swift */; }; + 675E86767CB3D4F09A7565BF /* SCStaticPinView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 99309CCDF0579A7F727495C1 /* SCStaticPinView.swift */; }; + 808EF736835F43FD011E17C2 /* SCCModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DFE1CCE54B888A1DE2C0D97F /* SCCModel.swift */; }; + 85686D9E4C08189777A197A1 /* SCC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C07A66E4664B271A3E8A2A4 /* SCC.swift */; }; + B73848F34E82FF8EA95EDA1E /* OpenAIAPIKey.swift in Sources */ = {isa = PBXBuildFile; fileRef = 89EA8EA6F102C2BB224A7246 /* OpenAIAPIKey.swift */; }; + DA20C2692C57A9A900996D3D /* SpeziLLMOpenAI in Frameworks */ = {isa = PBXBuildFile; productRef = DA20C2682C57A9A900996D3D /* SpeziLLMOpenAI */; }; + DA8C4F642CA37777004C6DAA /* SpatialContinuityShared in Frameworks */ = {isa = PBXBuildFile; productRef = DA8C4F632CA37777004C6DAA /* SpatialContinuityShared */; }; + DA8C4F662CA37D9A004C6DAA /* SCModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA8C4F652CA37D94004C6DAA /* SCModel.swift */; }; + DA8C4F682CA3805E004C6DAA /* LiveVideoView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA8C4F672CA3805A004C6DAA /* LiveVideoView.swift */; }; + DABFEB382BD3999800137B32 /* SpatialContinuityApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = DABFEB372BD3999800137B32 /* SpatialContinuityApp.swift */; }; + DABFEB3C2BD3999800137B32 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = DABFEB3B2BD3999800137B32 /* Assets.xcassets */; }; + DABFEB3F2BD3999800137B32 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = DABFEB3E2BD3999800137B32 /* Preview Assets.xcassets */; }; + DABFEB5A2BD39AA800137B32 /* SpatialContinuityCameraApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = DABFEB592BD39AA800137B32 /* SpatialContinuityCameraApp.swift */; }; + DABFEB5C2BD39AA800137B32 /* SCCView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DABFEB5B2BD39AA800137B32 /* SCCView.swift */; }; + DABFEB5E2BD39AA900137B32 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = DABFEB5D2BD39AA900137B32 /* Assets.xcassets */; }; + DABFEB612BD39AA900137B32 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = DABFEB602BD39AA900137B32 /* Preview Assets.xcassets */; }; + DAD4939C2E881BE000F02F93 /* Localizable.xcstrings.license in Resources */ = {isa = PBXBuildFile; fileRef = DAD493992E881BE000F02F93 /* Localizable.xcstrings.license */; }; + DAD7C43D2D92ACEF0075E175 /* Localizable.xcstrings in Resources */ = {isa = PBXBuildFile; fileRef = DAD7C43C2D92ACEF0075E175 /* Localizable.xcstrings */; }; + DAD7C43E2D92ACEF0075E175 /* Localizable.xcstrings in Resources */ = {isa = PBXBuildFile; fileRef = DAD7C43C2D92ACEF0075E175 /* Localizable.xcstrings */; }; + DAD7C43F2D92ACEF0075E175 /* Localizable.xcstrings in Resources */ = {isa = PBXBuildFile; fileRef = DAD7C43C2D92ACEF0075E175 /* Localizable.xcstrings */; }; + DAD7C4402D92ACEF0075E175 /* Localizable.xcstrings in Resources */ = {isa = PBXBuildFile; fileRef = DAD7C43C2D92ACEF0075E175 /* Localizable.xcstrings */; }; + DAD7C4412D92ACEF0075E175 /* Localizable.xcstrings in Resources */ = {isa = PBXBuildFile; fileRef = DAD7C43C2D92ACEF0075E175 /* Localizable.xcstrings */; }; + DADD7BFA2CA3326B0030DEE2 /* SpatialContinuityShared in Frameworks */ = {isa = PBXBuildFile; productRef = DADD7BF92CA3326B0030DEE2 /* SpatialContinuityShared */; }; + E70DD0132CF472013D510EDD /* StorageKeys.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F83356AA934B5CF91F3E713 /* StorageKeys.swift */; }; + F1976584BC04467AF2515C7E /* LLMOpenAIAppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED50E740B86AFFDB9AE113C7 /* LLMOpenAIAppDelegate.swift */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + DABFEB462BD3999900137B32 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = DABFEB282BD3999800137B32 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DABFEB2F2BD3999800137B32; + remoteInfo = SpatialContinuity; + }; + DABFEB672BD39AA900137B32 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = DABFEB282BD3999800137B32 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DABFEB562BD39AA800137B32; + remoteInfo = SpatialContinuityCamera; + }; + DABFEB712BD39AA900137B32 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = DABFEB282BD3999800137B32 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DABFEB562BD39AA800137B32; + remoteInfo = SpatialContinuityCamera; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXFileReference section */ + 0C07A66E4664B271A3E8A2A4 /* SCC.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = SCC.swift; sourceTree = ""; }; + 2BBD782C297202ED97DC9B8A /* OnboardingFlow.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = OnboardingFlow.swift; sourceTree = ""; }; + 6F83356AA934B5CF91F3E713 /* StorageKeys.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = StorageKeys.swift; sourceTree = ""; }; + 89EA8EA6F102C2BB224A7246 /* OpenAIAPIKey.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = OpenAIAPIKey.swift; sourceTree = ""; }; + 99309CCDF0579A7F727495C1 /* SCStaticPinView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = SCStaticPinView.swift; sourceTree = ""; }; + D426CB8B3F4A311C17F1A9CC /* SCCPreviewView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = SCCPreviewView.swift; sourceTree = ""; }; + DA8C4F652CA37D94004C6DAA /* SCModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SCModel.swift; sourceTree = ""; }; + DA8C4F672CA3805A004C6DAA /* LiveVideoView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LiveVideoView.swift; sourceTree = ""; }; + DABFEB302BD3999800137B32 /* SpatialContinuity.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SpatialContinuity.app; sourceTree = BUILT_PRODUCTS_DIR; }; + DABFEB372BD3999800137B32 /* SpatialContinuityApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SpatialContinuityApp.swift; sourceTree = ""; }; + DABFEB3B2BD3999800137B32 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + DABFEB3E2BD3999800137B32 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; }; + DABFEB402BD3999800137B32 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + DABFEB452BD3999900137B32 /* SpatialContinuityTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SpatialContinuityTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + DABFEB572BD39AA800137B32 /* SpatialContinuityCamera.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SpatialContinuityCamera.app; sourceTree = BUILT_PRODUCTS_DIR; }; + DABFEB592BD39AA800137B32 /* SpatialContinuityCameraApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SpatialContinuityCameraApp.swift; sourceTree = ""; }; + DABFEB5B2BD39AA800137B32 /* SCCView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SCCView.swift; sourceTree = ""; }; + DABFEB5D2BD39AA900137B32 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + DABFEB602BD39AA900137B32 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; }; + DABFEB662BD39AA900137B32 /* SpatialContinuityCameraTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SpatialContinuityCameraTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + DABFEB702BD39AA900137B32 /* SpatialContinuityCameraUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SpatialContinuityCameraUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + DAD493552E881AC700F02F93 /* CONTRIBUTORS.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = CONTRIBUTORS.md; sourceTree = ""; }; + DAD493562E881AC700F02F93 /* .gitignore */ = {isa = PBXFileReference; lastKnownFileType = text; path = .gitignore; sourceTree = ""; }; + DAD493572E881AC700F02F93 /* Appfile */ = {isa = PBXFileReference; lastKnownFileType = text; path = Appfile; sourceTree = ""; }; + DAD493582E881AC700F02F93 /* ExportOptions.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = ExportOptions.plist; sourceTree = ""; }; + DAD493592E881AC700F02F93 /* ExportOptions.plist.license */ = {isa = PBXFileReference; lastKnownFileType = text; path = ExportOptions.plist.license; sourceTree = ""; }; + DAD4935A2E881AC700F02F93 /* Fastfile */ = {isa = PBXFileReference; lastKnownFileType = text; path = Fastfile; sourceTree = ""; }; + DAD4935B2E881AC700F02F93 /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = ""; }; + DAD4935C2E881AC700F02F93 /* README.md.license */ = {isa = PBXFileReference; lastKnownFileType = text; path = README.md.license; sourceTree = ""; }; + DAD4935E2E881AC700F02F93 /* LICENSE.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = LICENSE.md; sourceTree = ""; }; + DAD4935F2E881AC700F02F93 /* MIT.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = MIT.txt; sourceTree = ""; }; + DAD493992E881BE000F02F93 /* Localizable.xcstrings.license */ = {isa = PBXFileReference; lastKnownFileType = text; path = Localizable.xcstrings.license; sourceTree = ""; }; + DAD493BF2E881E0400F02F93 /* SC_Prototype.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = SC_Prototype.png; sourceTree = ""; }; + DAD493C02E881E0400F02F93 /* tum-logo-dark-mode.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "tum-logo-dark-mode.png"; sourceTree = ""; }; + DAD493C12E881E0400F02F93 /* tum-logo-light-mode.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "tum-logo-light-mode.png"; sourceTree = ""; }; + DAD493C32E881E0400F02F93 /* beta-deployment.yml */ = {isa = PBXFileReference; lastKnownFileType = text.yaml; path = "beta-deployment.yml"; sourceTree = ""; }; + DAD493C42E881E0400F02F93 /* build-and-test.yml */ = {isa = PBXFileReference; lastKnownFileType = text.yaml; path = "build-and-test.yml"; sourceTree = ""; }; + DAD493E02E88202600F02F93 /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = ""; }; + DAD7C43C2D92ACEF0075E175 /* Localizable.xcstrings */ = {isa = PBXFileReference; lastKnownFileType = text.json.xcstrings; path = Localizable.xcstrings; sourceTree = ""; }; + DAD821D62C28B89200A6193B /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = Info.plist; sourceTree = ""; }; + DADD7BF82CA332490030DEE2 /* SpatialContinuityShared */ = {isa = PBXFileReference; lastKnownFileType = wrapper; path = SpatialContinuityShared; sourceTree = ""; }; + DFE1CCE54B888A1DE2C0D97F /* SCCModel.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = SCCModel.swift; sourceTree = ""; }; + ED50E740B86AFFDB9AE113C7 /* LLMOpenAIAppDelegate.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = LLMOpenAIAppDelegate.swift; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + DABFEB2D2BD3999800137B32 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + DADD7BFA2CA3326B0030DEE2 /* SpatialContinuityShared in Frameworks */, + DA20C2692C57A9A900996D3D /* SpeziLLMOpenAI in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + DABFEB422BD3999900137B32 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + DABFEB542BD39AA800137B32 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + DA8C4F642CA37777004C6DAA /* SpatialContinuityShared in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + DABFEB632BD39AA900137B32 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + DABFEB6D2BD39AA900137B32 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + A5F427F32A98BA1971770505 /* Onboarding */ = { + isa = PBXGroup; + children = ( + 2BBD782C297202ED97DC9B8A /* OnboardingFlow.swift */, + 89EA8EA6F102C2BB224A7246 /* OpenAIAPIKey.swift */, + ); + path = Onboarding; + sourceTree = ""; + }; + DABFEB272BD3999800137B32 = { + isa = PBXGroup; + children = ( + DAD493E02E88202600F02F93 /* README.md */, + DAD493C62E881E0400F02F93 /* .github */, + DAD493992E881BE000F02F93 /* Localizable.xcstrings.license */, + DAD493552E881AC700F02F93 /* CONTRIBUTORS.md */, + DAD4935D2E881AC700F02F93 /* fastlane */, + DAD4935E2E881AC700F02F93 /* LICENSE.md */, + DAD493602E881AC700F02F93 /* LICENSES */, + DAD7C43C2D92ACEF0075E175 /* Localizable.xcstrings */, + DADD7BF82CA332490030DEE2 /* SpatialContinuityShared */, + DABFEB322BD3999800137B32 /* SpatialContinuity */, + DABFEB582BD39AA800137B32 /* SpatialContinuityCamera */, + DABFEB312BD3999800137B32 /* Products */, + DAFE82FC2C3D73460089B221 /* Frameworks */, + ); + sourceTree = ""; + }; + DABFEB312BD3999800137B32 /* Products */ = { + isa = PBXGroup; + children = ( + DABFEB302BD3999800137B32 /* SpatialContinuity.app */, + DABFEB452BD3999900137B32 /* SpatialContinuityTests.xctest */, + DABFEB572BD39AA800137B32 /* SpatialContinuityCamera.app */, + DABFEB662BD39AA900137B32 /* SpatialContinuityCameraTests.xctest */, + DABFEB702BD39AA900137B32 /* SpatialContinuityCameraUITests.xctest */, + ); + name = Products; + sourceTree = ""; + }; + DABFEB322BD3999800137B32 /* SpatialContinuity */ = { + isa = PBXGroup; + children = ( + DA8C4F672CA3805A004C6DAA /* LiveVideoView.swift */, + DA8C4F652CA37D94004C6DAA /* SCModel.swift */, + DABFEB372BD3999800137B32 /* SpatialContinuityApp.swift */, + DABFEB3B2BD3999800137B32 /* Assets.xcassets */, + DABFEB402BD3999800137B32 /* Info.plist */, + DABFEB3D2BD3999800137B32 /* Preview Content */, + 99309CCDF0579A7F727495C1 /* SCStaticPinView.swift */, + ED50E740B86AFFDB9AE113C7 /* LLMOpenAIAppDelegate.swift */, + 6F83356AA934B5CF91F3E713 /* StorageKeys.swift */, + A5F427F32A98BA1971770505 /* Onboarding */, + ); + path = SpatialContinuity; + sourceTree = ""; + }; + DABFEB3D2BD3999800137B32 /* Preview Content */ = { + isa = PBXGroup; + children = ( + DABFEB3E2BD3999800137B32 /* Preview Assets.xcassets */, + ); + path = "Preview Content"; + sourceTree = ""; + }; + DABFEB582BD39AA800137B32 /* SpatialContinuityCamera */ = { + isa = PBXGroup; + children = ( + DAD821D62C28B89200A6193B /* Info.plist */, + DABFEB592BD39AA800137B32 /* SpatialContinuityCameraApp.swift */, + DABFEB5B2BD39AA800137B32 /* SCCView.swift */, + DABFEB5D2BD39AA900137B32 /* Assets.xcassets */, + DABFEB5F2BD39AA900137B32 /* Preview Content */, + DFE1CCE54B888A1DE2C0D97F /* SCCModel.swift */, + 0C07A66E4664B271A3E8A2A4 /* SCC.swift */, + D426CB8B3F4A311C17F1A9CC /* SCCPreviewView.swift */, + ); + path = SpatialContinuityCamera; + sourceTree = ""; + }; + DABFEB5F2BD39AA900137B32 /* Preview Content */ = { + isa = PBXGroup; + children = ( + DABFEB602BD39AA900137B32 /* Preview Assets.xcassets */, + ); + path = "Preview Content"; + sourceTree = ""; + }; + DAD4935D2E881AC700F02F93 /* fastlane */ = { + isa = PBXGroup; + children = ( + DAD493562E881AC700F02F93 /* .gitignore */, + DAD493572E881AC700F02F93 /* Appfile */, + DAD493582E881AC700F02F93 /* ExportOptions.plist */, + DAD493592E881AC700F02F93 /* ExportOptions.plist.license */, + DAD4935A2E881AC700F02F93 /* Fastfile */, + DAD4935B2E881AC700F02F93 /* README.md */, + DAD4935C2E881AC700F02F93 /* README.md.license */, + ); + path = fastlane; + sourceTree = ""; + }; + DAD493602E881AC700F02F93 /* LICENSES */ = { + isa = PBXGroup; + children = ( + DAD4935F2E881AC700F02F93 /* MIT.txt */, + ); + path = LICENSES; + sourceTree = ""; + }; + DAD493C22E881E0400F02F93 /* assets */ = { + isa = PBXGroup; + children = ( + DAD493BF2E881E0400F02F93 /* SC_Prototype.png */, + DAD493C02E881E0400F02F93 /* tum-logo-dark-mode.png */, + DAD493C12E881E0400F02F93 /* tum-logo-light-mode.png */, + ); + path = assets; + sourceTree = ""; + }; + DAD493C52E881E0400F02F93 /* workflows */ = { + isa = PBXGroup; + children = ( + DAD493C32E881E0400F02F93 /* beta-deployment.yml */, + DAD493C42E881E0400F02F93 /* build-and-test.yml */, + ); + path = workflows; + sourceTree = ""; + }; + DAD493C62E881E0400F02F93 /* .github */ = { + isa = PBXGroup; + children = ( + DAD493C22E881E0400F02F93 /* assets */, + DAD493C52E881E0400F02F93 /* workflows */, + ); + path = .github; + sourceTree = ""; + }; + DAFE82FC2C3D73460089B221 /* Frameworks */ = { + isa = PBXGroup; + children = ( + ); + name = Frameworks; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + DABFEB2F2BD3999800137B32 /* SpatialContinuity */ = { + isa = PBXNativeTarget; + buildConfigurationList = DABFEB4D2BD3999900137B32 /* Build configuration list for PBXNativeTarget "SpatialContinuity" */; + buildPhases = ( + DABFEB2C2BD3999800137B32 /* Sources */, + DABFEB2D2BD3999800137B32 /* Frameworks */, + DABFEB2E2BD3999800137B32 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = SpatialContinuity; + packageProductDependencies = ( + DA20C2682C57A9A900996D3D /* SpeziLLMOpenAI */, + DADD7BF92CA3326B0030DEE2 /* SpatialContinuityShared */, + ); + productName = SpatialContinuity; + productReference = DABFEB302BD3999800137B32 /* SpatialContinuity.app */; + productType = "com.apple.product-type.application"; + }; + DABFEB442BD3999900137B32 /* SpatialContinuityTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = DABFEB502BD3999900137B32 /* Build configuration list for PBXNativeTarget "SpatialContinuityTests" */; + buildPhases = ( + DABFEB412BD3999900137B32 /* Sources */, + DABFEB422BD3999900137B32 /* Frameworks */, + DABFEB432BD3999900137B32 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + DABFEB472BD3999900137B32 /* PBXTargetDependency */, + ); + name = SpatialContinuityTests; + productName = SpatialContinuityTests; + productReference = DABFEB452BD3999900137B32 /* SpatialContinuityTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; + DABFEB562BD39AA800137B32 /* SpatialContinuityCamera */ = { + isa = PBXNativeTarget; + buildConfigurationList = DABFEB782BD39AA900137B32 /* Build configuration list for PBXNativeTarget "SpatialContinuityCamera" */; + buildPhases = ( + DABFEB532BD39AA800137B32 /* Sources */, + DABFEB542BD39AA800137B32 /* Frameworks */, + DABFEB552BD39AA800137B32 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = SpatialContinuityCamera; + productName = SpatialContinuityCamera; + productReference = DABFEB572BD39AA800137B32 /* SpatialContinuityCamera.app */; + productType = "com.apple.product-type.application"; + }; + DABFEB652BD39AA900137B32 /* SpatialContinuityCameraTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = DABFEB7B2BD39AA900137B32 /* Build configuration list for PBXNativeTarget "SpatialContinuityCameraTests" */; + buildPhases = ( + DABFEB622BD39AA900137B32 /* Sources */, + DABFEB632BD39AA900137B32 /* Frameworks */, + DABFEB642BD39AA900137B32 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + DABFEB682BD39AA900137B32 /* PBXTargetDependency */, + ); + name = SpatialContinuityCameraTests; + productName = SpatialContinuityCameraTests; + productReference = DABFEB662BD39AA900137B32 /* SpatialContinuityCameraTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; + DABFEB6F2BD39AA900137B32 /* SpatialContinuityCameraUITests */ = { + isa = PBXNativeTarget; + buildConfigurationList = DABFEB7E2BD39AA900137B32 /* Build configuration list for PBXNativeTarget "SpatialContinuityCameraUITests" */; + buildPhases = ( + DABFEB6C2BD39AA900137B32 /* Sources */, + DABFEB6D2BD39AA900137B32 /* Frameworks */, + DABFEB6E2BD39AA900137B32 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + DABFEB722BD39AA900137B32 /* PBXTargetDependency */, + ); + name = SpatialContinuityCameraUITests; + productName = SpatialContinuityCameraUITests; + productReference = DABFEB702BD39AA900137B32 /* SpatialContinuityCameraUITests.xctest */; + productType = "com.apple.product-type.bundle.ui-testing"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + DABFEB282BD3999800137B32 /* Project object */ = { + isa = PBXProject; + attributes = { + BuildIndependentTargetsInParallel = 1; + LastSwiftUpdateCheck = 1530; + LastUpgradeCheck = 1600; + TargetAttributes = { + DABFEB2F2BD3999800137B32 = { + CreatedOnToolsVersion = 15.3; + }; + DABFEB442BD3999900137B32 = { + CreatedOnToolsVersion = 15.3; + TestTargetID = DABFEB2F2BD3999800137B32; + }; + DABFEB562BD39AA800137B32 = { + CreatedOnToolsVersion = 15.3; + }; + DABFEB652BD39AA900137B32 = { + CreatedOnToolsVersion = 15.3; + TestTargetID = DABFEB562BD39AA800137B32; + }; + DABFEB6F2BD39AA900137B32 = { + CreatedOnToolsVersion = 15.3; + TestTargetID = DABFEB562BD39AA800137B32; + }; + }; + }; + buildConfigurationList = DABFEB2B2BD3999800137B32 /* Build configuration list for PBXProject "SpatialContinuity" */; + compatibilityVersion = "Xcode 14.0"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + de, + ); + mainGroup = DABFEB272BD3999800137B32; + packageReferences = ( + DA20C2672C57A9A900996D3D /* XCRemoteSwiftPackageReference "SpeziLLM" */, + ); + productRefGroup = DABFEB312BD3999800137B32 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + DABFEB2F2BD3999800137B32 /* SpatialContinuity */, + DABFEB442BD3999900137B32 /* SpatialContinuityTests */, + DABFEB562BD39AA800137B32 /* SpatialContinuityCamera */, + DABFEB652BD39AA900137B32 /* SpatialContinuityCameraTests */, + DABFEB6F2BD39AA900137B32 /* SpatialContinuityCameraUITests */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + DABFEB2E2BD3999800137B32 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + DABFEB3F2BD3999800137B32 /* Preview Assets.xcassets in Resources */, + DABFEB3C2BD3999800137B32 /* Assets.xcassets in Resources */, + DAD4939C2E881BE000F02F93 /* Localizable.xcstrings.license in Resources */, + DAD7C43D2D92ACEF0075E175 /* Localizable.xcstrings in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + DABFEB432BD3999900137B32 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + DAD7C43E2D92ACEF0075E175 /* Localizable.xcstrings in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + DABFEB552BD39AA800137B32 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + DABFEB612BD39AA900137B32 /* Preview Assets.xcassets in Resources */, + DABFEB5E2BD39AA900137B32 /* Assets.xcassets in Resources */, + DAD7C43F2D92ACEF0075E175 /* Localizable.xcstrings in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + DABFEB642BD39AA900137B32 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + DAD7C4402D92ACEF0075E175 /* Localizable.xcstrings in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + DABFEB6E2BD39AA900137B32 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + DAD7C4412D92ACEF0075E175 /* Localizable.xcstrings in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + DABFEB2C2BD3999800137B32 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + DABFEB382BD3999800137B32 /* SpatialContinuityApp.swift in Sources */, + DA8C4F682CA3805E004C6DAA /* LiveVideoView.swift in Sources */, + 675E86767CB3D4F09A7565BF /* SCStaticPinView.swift in Sources */, + F1976584BC04467AF2515C7E /* LLMOpenAIAppDelegate.swift in Sources */, + E70DD0132CF472013D510EDD /* StorageKeys.swift in Sources */, + 5436E9AFB5CC5A5FD301764D /* OnboardingFlow.swift in Sources */, + DA8C4F662CA37D9A004C6DAA /* SCModel.swift in Sources */, + B73848F34E82FF8EA95EDA1E /* OpenAIAPIKey.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + DABFEB412BD3999900137B32 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + DABFEB532BD39AA800137B32 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + DABFEB5C2BD39AA800137B32 /* SCCView.swift in Sources */, + DABFEB5A2BD39AA800137B32 /* SpatialContinuityCameraApp.swift in Sources */, + 808EF736835F43FD011E17C2 /* SCCModel.swift in Sources */, + 85686D9E4C08189777A197A1 /* SCC.swift in Sources */, + 05036FAD96F83782A5BD93AB /* SCCPreviewView.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + DABFEB622BD39AA900137B32 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + DABFEB6C2BD39AA900137B32 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + DABFEB472BD3999900137B32 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = DABFEB2F2BD3999800137B32 /* SpatialContinuity */; + targetProxy = DABFEB462BD3999900137B32 /* PBXContainerItemProxy */; + }; + DABFEB682BD39AA900137B32 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = DABFEB562BD39AA800137B32 /* SpatialContinuityCamera */; + targetProxy = DABFEB672BD39AA900137B32 /* PBXContainerItemProxy */; + }; + DABFEB722BD39AA900137B32 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = DABFEB562BD39AA800137B32 /* SpatialContinuityCamera */; + targetProxy = DABFEB712BD39AA900137B32 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin XCBuildConfiguration section */ + DABFEB4B2BD3999900137B32 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + ENABLE_USER_SCRIPT_SANDBOXING = YES; + GCC_C_LANGUAGE_STANDARD = gnu17; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + LOCALIZATION_PREFERS_STRING_CATALOGS = YES; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = xros; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)"; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + XROS_DEPLOYMENT_TARGET = 1.1; + }; + name = Debug; + }; + DABFEB4C2BD3999900137B32 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_USER_SCRIPT_SANDBOXING = YES; + GCC_C_LANGUAGE_STANDARD = gnu17; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + LOCALIZATION_PREFERS_STRING_CATALOGS = YES; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = xros; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_EMIT_LOC_STRINGS = YES; + VALIDATE_PRODUCT = YES; + XROS_DEPLOYMENT_TARGET = 1.1; + }; + name = Release; + }; + DABFEB4E2BD3999900137B32 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_ASSET_PATHS = "\"SpatialContinuity/Preview Content\""; + DEVELOPMENT_TEAM = 29BG4GH882; + ENABLE_PREVIEWS = YES; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = "$(TARGET_NAME)/Info.plist"; + INFOPLIST_KEY_NSLocalNetworkUsageDescription = "Used for connecting Spatial Continuity to Spatial Continuity Camera"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.pbhdk.SpatialContinuity; + PRODUCT_NAME = "$(TARGET_NAME)"; + SUPPORTED_PLATFORMS = "xros xrsimulator"; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_OBJC_INTEROP_MODE = objcxx; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2,7"; + XROS_DEPLOYMENT_TARGET = 2.0; + }; + name = Debug; + }; + DABFEB4F2BD3999900137B32 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_ASSET_PATHS = "\"SpatialContinuity/Preview Content\""; + DEVELOPMENT_TEAM = 29BG4GH882; + ENABLE_PREVIEWS = YES; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = "$(TARGET_NAME)/Info.plist"; + INFOPLIST_KEY_NSLocalNetworkUsageDescription = "Used for connecting Spatial Continuity to Spatial Continuity Camera"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.pbhdk.SpatialContinuity; + PRODUCT_NAME = "$(TARGET_NAME)"; + SUPPORTED_PLATFORMS = "xros xrsimulator"; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_OBJC_INTEROP_MODE = objcxx; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2,7"; + XROS_DEPLOYMENT_TARGET = 2.0; + }; + name = Release; + }; + DABFEB512BD3999900137B32 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = 29BG4GH882; + GENERATE_INFOPLIST_FILE = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.pbhdk.SpatialContinuityTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SUPPORTED_PLATFORMS = "xros xrsimulator"; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2,7"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/SpatialContinuity.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/SpatialContinuity"; + XROS_DEPLOYMENT_TARGET = 1.1; + }; + name = Debug; + }; + DABFEB522BD3999900137B32 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = 29BG4GH882; + GENERATE_INFOPLIST_FILE = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.pbhdk.SpatialContinuityTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SUPPORTED_PLATFORMS = "xros xrsimulator"; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2,7"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/SpatialContinuity.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/SpatialContinuity"; + XROS_DEPLOYMENT_TARGET = 1.1; + }; + name = Release; + }; + DABFEB792BD39AA900137B32 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_ASSET_PATHS = "\"SpatialContinuityCamera/Preview Content\""; + DEVELOPMENT_TEAM = 29BG4GH882; + ENABLE_PREVIEWS = YES; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = SpatialContinuityCamera/Info.plist; + INFOPLIST_KEY_NSCameraUsageDescription = "This app uses the camera to display a preview of Spatial Continuity Camera"; + INFOPLIST_KEY_NSLocalNetworkUsageDescription = "Used for connecting Spatial Continuity Camera to Spatial Continuity on Vision Pro"; + INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES; + INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; + INFOPLIST_KEY_UILaunchScreen_Generation = YES; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + IPHONEOS_DEPLOYMENT_TARGET = 17.4; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.pbhdk.SpatialContinuityCamera; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = iphoneos; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + DABFEB7A2BD39AA900137B32 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_ASSET_PATHS = "\"SpatialContinuityCamera/Preview Content\""; + DEVELOPMENT_TEAM = 29BG4GH882; + ENABLE_PREVIEWS = YES; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = SpatialContinuityCamera/Info.plist; + INFOPLIST_KEY_NSCameraUsageDescription = "This app uses the camera to display a preview of Spatial Continuity Camera"; + INFOPLIST_KEY_NSLocalNetworkUsageDescription = "Used for connecting Spatial Continuity Camera to Spatial Continuity on Vision Pro"; + INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES; + INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; + INFOPLIST_KEY_UILaunchScreen_Generation = YES; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + IPHONEOS_DEPLOYMENT_TARGET = 17.4; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.pbhdk.SpatialContinuityCamera; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = iphoneos; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; + DABFEB7C2BD39AA900137B32 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = 29BG4GH882; + GENERATE_INFOPLIST_FILE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 17.4; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.pbhdk.SpatialContinuityCameraTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = iphoneos; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/SpatialContinuityCamera.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/SpatialContinuityCamera"; + }; + name = Debug; + }; + DABFEB7D2BD39AA900137B32 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = 29BG4GH882; + GENERATE_INFOPLIST_FILE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 17.4; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.pbhdk.SpatialContinuityCameraTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = iphoneos; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/SpatialContinuityCamera.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/SpatialContinuityCamera"; + }; + name = Release; + }; + DABFEB7F2BD39AA900137B32 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = 29BG4GH882; + GENERATE_INFOPLIST_FILE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 17.4; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.pbhdk.SpatialContinuityCameraUITests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = iphoneos; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_TARGET_NAME = SpatialContinuityCamera; + }; + name = Debug; + }; + DABFEB802BD39AA900137B32 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = 29BG4GH882; + GENERATE_INFOPLIST_FILE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 17.4; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.pbhdk.SpatialContinuityCameraUITests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = iphoneos; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_TARGET_NAME = SpatialContinuityCamera; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + DABFEB2B2BD3999800137B32 /* Build configuration list for PBXProject "SpatialContinuity" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + DABFEB4B2BD3999900137B32 /* Debug */, + DABFEB4C2BD3999900137B32 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + DABFEB4D2BD3999900137B32 /* Build configuration list for PBXNativeTarget "SpatialContinuity" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + DABFEB4E2BD3999900137B32 /* Debug */, + DABFEB4F2BD3999900137B32 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + DABFEB502BD3999900137B32 /* Build configuration list for PBXNativeTarget "SpatialContinuityTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + DABFEB512BD3999900137B32 /* Debug */, + DABFEB522BD3999900137B32 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + DABFEB782BD39AA900137B32 /* Build configuration list for PBXNativeTarget "SpatialContinuityCamera" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + DABFEB792BD39AA900137B32 /* Debug */, + DABFEB7A2BD39AA900137B32 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + DABFEB7B2BD39AA900137B32 /* Build configuration list for PBXNativeTarget "SpatialContinuityCameraTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + DABFEB7C2BD39AA900137B32 /* Debug */, + DABFEB7D2BD39AA900137B32 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + DABFEB7E2BD39AA900137B32 /* Build configuration list for PBXNativeTarget "SpatialContinuityCameraUITests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + DABFEB7F2BD39AA900137B32 /* Debug */, + DABFEB802BD39AA900137B32 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + +/* Begin XCRemoteSwiftPackageReference section */ + DA20C2672C57A9A900996D3D /* XCRemoteSwiftPackageReference "SpeziLLM" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/StanfordSpezi/SpeziLLM.git"; + requirement = { + branch = "image-payloads"; + kind = branch; + }; + }; +/* End XCRemoteSwiftPackageReference section */ + +/* Begin XCSwiftPackageProductDependency section */ + DA20C2682C57A9A900996D3D /* SpeziLLMOpenAI */ = { + isa = XCSwiftPackageProductDependency; + package = DA20C2672C57A9A900996D3D /* XCRemoteSwiftPackageReference "SpeziLLM" */; + productName = SpeziLLMOpenAI; + }; + DA8C4F632CA37777004C6DAA /* SpatialContinuityShared */ = { + isa = XCSwiftPackageProductDependency; + productName = SpatialContinuityShared; + }; + DADD7BF92CA3326B0030DEE2 /* SpatialContinuityShared */ = { + isa = XCSwiftPackageProductDependency; + productName = SpatialContinuityShared; + }; +/* End XCSwiftPackageProductDependency section */ + }; + rootObject = DABFEB282BD3999800137B32 /* Project object */; +} diff --git a/SpatialContinuity.xcodeproj/project.pbxproj.license b/SpatialContinuity.xcodeproj/project.pbxproj.license new file mode 100644 index 0000000..eb38c65 --- /dev/null +++ b/SpatialContinuity.xcodeproj/project.pbxproj.license @@ -0,0 +1,5 @@ +This source file is part of the Spatial Continuity project + +SPDX-FileCopyrightText: 2025 Stanford University and the project authors (see CONTRIBUTORS.md) + +SPDX-License-Identifier: MIT diff --git a/TemplateApplication.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/SpatialContinuity.xcodeproj/project.xcworkspace/contents.xcworkspacedata similarity index 100% rename from TemplateApplication.xcodeproj/project.xcworkspace/contents.xcworkspacedata rename to SpatialContinuity.xcodeproj/project.xcworkspace/contents.xcworkspacedata diff --git a/SpatialContinuity.xcodeproj/project.xcworkspace/contents.xcworkspacedata.license b/SpatialContinuity.xcodeproj/project.xcworkspace/contents.xcworkspacedata.license new file mode 100644 index 0000000..eb38c65 --- /dev/null +++ b/SpatialContinuity.xcodeproj/project.xcworkspace/contents.xcworkspacedata.license @@ -0,0 +1,5 @@ +This source file is part of the Spatial Continuity project + +SPDX-FileCopyrightText: 2025 Stanford University and the project authors (see CONTRIBUTORS.md) + +SPDX-License-Identifier: MIT diff --git a/TemplateApplication.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/SpatialContinuity.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist similarity index 100% rename from TemplateApplication.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist rename to SpatialContinuity.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist diff --git a/SpatialContinuity.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist.license b/SpatialContinuity.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist.license new file mode 100644 index 0000000..eb38c65 --- /dev/null +++ b/SpatialContinuity.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist.license @@ -0,0 +1,5 @@ +This source file is part of the Spatial Continuity project + +SPDX-FileCopyrightText: 2025 Stanford University and the project authors (see CONTRIBUTORS.md) + +SPDX-License-Identifier: MIT diff --git a/SpatialContinuity.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/SpatialContinuity.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved new file mode 100644 index 0000000..7104bf1 --- /dev/null +++ b/SpatialContinuity.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -0,0 +1,204 @@ +{ + "originHash" : "983b68c556b4bb27f40ef599a00c90dbfdde0068afe359eb8a0dbea6bf34d551", + "pins" : [ + { + "identity" : "llama.cpp", + "kind" : "remoteSourceControl", + "location" : "https://github.com/StanfordBDHG/llama.cpp", + "state" : { + "revision" : "6839853a321778906e210a33ee2c6aec52f34c97", + "version" : "0.3.3" + } + }, + { + "identity" : "openai", + "kind" : "remoteSourceControl", + "location" : "https://github.com/StanfordBDHG/OpenAI", + "state" : { + "revision" : "1ad95dd531d7c854a3f98f588b0eb68fa83e8a8c", + "version" : "0.2.9" + } + }, + { + "identity" : "openapikit", + "kind" : "remoteSourceControl", + "location" : "https://github.com/mattpolzin/OpenAPIKit", + "state" : { + "revision" : "4991b7e39a19cd1d0d11fe24fc64a601b4820144", + "version" : "3.2.0" + } + }, + { + "identity" : "spezi", + "kind" : "remoteSourceControl", + "location" : "https://github.com/StanfordSpezi/Spezi", + "state" : { + "revision" : "5ada3f3a18c86a658d140c6f4c45ca2e9d5e61ce", + "version" : "1.4.0" + } + }, + { + "identity" : "spezichat", + "kind" : "remoteSourceControl", + "location" : "https://github.com/StanfordSpezi/SpeziChat", + "state" : { + "revision" : "aaa10d71431b78ece8bf29f95c0050632714984d", + "version" : "0.2.0" + } + }, + { + "identity" : "spezifoundation", + "kind" : "remoteSourceControl", + "location" : "https://github.com/StanfordSpezi/SpeziFoundation", + "state" : { + "revision" : "3326feab3dac120c16af63243615592990d33516", + "version" : "1.1.2" + } + }, + { + "identity" : "spezillm", + "kind" : "remoteSourceControl", + "location" : "https://github.com/StanfordSpezi/SpeziLLM.git", + "state" : { + "branch" : "image-payloads", + "revision" : "46e528b2338d0ae8469ff415ee668fcb687a2cd3" + } + }, + { + "identity" : "spezionboarding", + "kind" : "remoteSourceControl", + "location" : "https://github.com/StanfordSpezi/SpeziOnboarding", + "state" : { + "revision" : "8d6dda3501720a1952573439b21a503cbecd9e0f", + "version" : "1.2.0" + } + }, + { + "identity" : "spezispeech", + "kind" : "remoteSourceControl", + "location" : "https://github.com/StanfordSpezi/SpeziSpeech", + "state" : { + "revision" : "0b79f72fc8b0606e09787926446dfafb541669d3", + "version" : "1.1.0" + } + }, + { + "identity" : "spezistorage", + "kind" : "remoteSourceControl", + "location" : "https://github.com/StanfordSpezi/SpeziStorage", + "state" : { + "revision" : "b958df9b31f24800388a7bfc28f457ce7b82556c", + "version" : "1.0.2" + } + }, + { + "identity" : "speziviews", + "kind" : "remoteSourceControl", + "location" : "https://github.com/StanfordSpezi/SpeziViews", + "state" : { + "revision" : "ff61e6594677572df051b96905cc2a7a12cffd10", + "version" : "1.5.0" + } + }, + { + "identity" : "swift-algorithms", + "kind" : "remoteSourceControl", + "location" : "https://github.com/apple/swift-algorithms", + "state" : { + "revision" : "f6919dfc309e7f1b56224378b11e28bab5bccc42", + "version" : "1.2.0" + } + }, + { + "identity" : "swift-argument-parser", + "kind" : "remoteSourceControl", + "location" : "https://github.com/apple/swift-argument-parser", + "state" : { + "revision" : "41982a3656a71c768319979febd796c6fd111d5c", + "version" : "1.5.0" + } + }, + { + "identity" : "swift-collections", + "kind" : "remoteSourceControl", + "location" : "https://github.com/apple/swift-collections.git", + "state" : { + "revision" : "3d2dc41a01f9e49d84f0a3925fb858bed64f702d", + "version" : "1.1.2" + } + }, + { + "identity" : "swift-http-types", + "kind" : "remoteSourceControl", + "location" : "https://github.com/apple/swift-http-types", + "state" : { + "revision" : "ae67c8178eb46944fd85e4dc6dd970e1f3ed6ccd", + "version" : "1.3.0" + } + }, + { + "identity" : "swift-numerics", + "kind" : "remoteSourceControl", + "location" : "https://github.com/apple/swift-numerics.git", + "state" : { + "revision" : "0a5bc04095a675662cf24757cc0640aa2204253b", + "version" : "1.0.2" + } + }, + { + "identity" : "swift-openapi-generator", + "kind" : "remoteSourceControl", + "location" : "https://github.com/apple/swift-openapi-generator.git", + "state" : { + "revision" : "99859083e53912612b56b4b8713a971c20dab3ef", + "version" : "1.3.0" + } + }, + { + "identity" : "swift-openapi-runtime", + "kind" : "remoteSourceControl", + "location" : "https://github.com/apple/swift-openapi-runtime", + "state" : { + "revision" : "26e8ae3515d1ff3607e924ac96fc0094775f55e8", + "version" : "1.5.0" + } + }, + { + "identity" : "swift-openapi-urlsession", + "kind" : "remoteSourceControl", + "location" : "https://github.com/apple/swift-openapi-urlsession.git", + "state" : { + "revision" : "9bf4c712ad7989d6a91dbe68748b8829a50837e4", + "version" : "1.0.2" + } + }, + { + "identity" : "transcoding", + "kind" : "remoteSourceControl", + "location" : "https://github.com/finnvoor/Transcoding", + "state" : { + "revision" : "72fe5ef3054eb0e1639ae9a9b49a92811fb251b2", + "version" : "0.0.1" + } + }, + { + "identity" : "xctruntimeassertions", + "kind" : "remoteSourceControl", + "location" : "https://github.com/StanfordBDHG/XCTRuntimeAssertions", + "state" : { + "revision" : "51da3403f128b120705571ce61e0fe190f8889e6", + "version" : "1.0.1" + } + }, + { + "identity" : "yams", + "kind" : "remoteSourceControl", + "location" : "https://github.com/jpsim/Yams", + "state" : { + "revision" : "3036ba9d69cf1fd04d433527bc339dc0dc75433d", + "version" : "5.1.3" + } + } + ], + "version" : 3 +} diff --git a/SpatialContinuity.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved.license b/SpatialContinuity.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved.license new file mode 100644 index 0000000..eb38c65 --- /dev/null +++ b/SpatialContinuity.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved.license @@ -0,0 +1,5 @@ +This source file is part of the Spatial Continuity project + +SPDX-FileCopyrightText: 2025 Stanford University and the project authors (see CONTRIBUTORS.md) + +SPDX-License-Identifier: MIT diff --git a/SpatialContinuity.xcodeproj/xcshareddata/xcschemes/SpatialContinuity.xcscheme b/SpatialContinuity.xcodeproj/xcshareddata/xcschemes/SpatialContinuity.xcscheme new file mode 100644 index 0000000..aa079f9 --- /dev/null +++ b/SpatialContinuity.xcodeproj/xcshareddata/xcschemes/SpatialContinuity.xcscheme @@ -0,0 +1,93 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/SpatialContinuity.xcodeproj/xcshareddata/xcschemes/SpatialContinuity.xcscheme.license b/SpatialContinuity.xcodeproj/xcshareddata/xcschemes/SpatialContinuity.xcscheme.license new file mode 100644 index 0000000..eb38c65 --- /dev/null +++ b/SpatialContinuity.xcodeproj/xcshareddata/xcschemes/SpatialContinuity.xcscheme.license @@ -0,0 +1,5 @@ +This source file is part of the Spatial Continuity project + +SPDX-FileCopyrightText: 2025 Stanford University and the project authors (see CONTRIBUTORS.md) + +SPDX-License-Identifier: MIT diff --git a/TemplateApplication.xcodeproj/xcshareddata/xcschemes/TemplateApplication.xcscheme b/SpatialContinuity.xcodeproj/xcshareddata/xcschemes/SpatialContinuityCamera.xcscheme similarity index 61% rename from TemplateApplication.xcodeproj/xcshareddata/xcschemes/TemplateApplication.xcscheme rename to SpatialContinuity.xcodeproj/xcshareddata/xcschemes/SpatialContinuityCamera.xcscheme index 484e70d..3107bf4 100644 --- a/TemplateApplication.xcodeproj/xcshareddata/xcschemes/TemplateApplication.xcscheme +++ b/SpatialContinuity.xcodeproj/xcshareddata/xcschemes/SpatialContinuityCamera.xcscheme @@ -1,10 +1,11 @@ + buildImplicitDependencies = "YES" + buildArchitectures = "Automatic"> + BlueprintIdentifier = "DABFEB562BD39AA800137B32" + BuildableName = "SpatialContinuityCamera.app" + BlueprintName = "SpatialContinuityCamera" + ReferencedContainer = "container:SpatialContinuity.xcodeproj"> @@ -26,23 +27,18 @@ buildConfiguration = "Debug" selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" - shouldUseLaunchSchemeArgsEnv = "YES"> - - - - + shouldUseLaunchSchemeArgsEnv = "YES" + shouldAutocreateTestPlan = "YES"> + BlueprintIdentifier = "DABFEB652BD39AA900137B32" + BuildableName = "SpatialContinuityCameraTests.xctest" + BlueprintName = "SpatialContinuityCameraTests" + ReferencedContainer = "container:SpatialContinuity.xcodeproj"> + BlueprintIdentifier = "DABFEB6F2BD39AA900137B32" + BuildableName = "SpatialContinuityCameraUITests.xctest" + BlueprintName = "SpatialContinuityCameraUITests" + ReferencedContainer = "container:SpatialContinuity.xcodeproj"> @@ -72,10 +68,10 @@ runnableDebuggingMode = "0"> + BlueprintIdentifier = "DABFEB562BD39AA800137B32" + BuildableName = "SpatialContinuityCamera.app" + BlueprintName = "SpatialContinuityCamera" + ReferencedContainer = "container:SpatialContinuity.xcodeproj"> @@ -89,10 +85,10 @@ runnableDebuggingMode = "0"> + BlueprintIdentifier = "DABFEB562BD39AA800137B32" + BuildableName = "SpatialContinuityCamera.app" + BlueprintName = "SpatialContinuityCamera" + ReferencedContainer = "container:SpatialContinuity.xcodeproj"> diff --git a/SpatialContinuity.xcodeproj/xcshareddata/xcschemes/SpatialContinuityCamera.xcscheme.license b/SpatialContinuity.xcodeproj/xcshareddata/xcschemes/SpatialContinuityCamera.xcscheme.license new file mode 100644 index 0000000..eb38c65 --- /dev/null +++ b/SpatialContinuity.xcodeproj/xcshareddata/xcschemes/SpatialContinuityCamera.xcscheme.license @@ -0,0 +1,5 @@ +This source file is part of the Spatial Continuity project + +SPDX-FileCopyrightText: 2025 Stanford University and the project authors (see CONTRIBUTORS.md) + +SPDX-License-Identifier: MIT diff --git a/SpatialContinuity/Assets.xcassets/AppIcon.solidimagestack/Back.solidimagestacklayer/Content.imageset/Contents.json b/SpatialContinuity/Assets.xcassets/AppIcon.solidimagestack/Back.solidimagestacklayer/Content.imageset/Contents.json new file mode 100644 index 0000000..04056a5 --- /dev/null +++ b/SpatialContinuity/Assets.xcassets/AppIcon.solidimagestack/Back.solidimagestacklayer/Content.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "idiom" : "vision", + "scale" : "2x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/SpatialContinuity/Assets.xcassets/AppIcon.solidimagestack/Back.solidimagestacklayer/Content.imageset/Contents.json.license b/SpatialContinuity/Assets.xcassets/AppIcon.solidimagestack/Back.solidimagestacklayer/Content.imageset/Contents.json.license new file mode 100644 index 0000000..eb38c65 --- /dev/null +++ b/SpatialContinuity/Assets.xcassets/AppIcon.solidimagestack/Back.solidimagestacklayer/Content.imageset/Contents.json.license @@ -0,0 +1,5 @@ +This source file is part of the Spatial Continuity project + +SPDX-FileCopyrightText: 2025 Stanford University and the project authors (see CONTRIBUTORS.md) + +SPDX-License-Identifier: MIT diff --git a/TemplateApplication/Assets.xcassets/Contents.json b/SpatialContinuity/Assets.xcassets/AppIcon.solidimagestack/Back.solidimagestacklayer/Contents.json similarity index 100% rename from TemplateApplication/Assets.xcassets/Contents.json rename to SpatialContinuity/Assets.xcassets/AppIcon.solidimagestack/Back.solidimagestacklayer/Contents.json diff --git a/SpatialContinuity/Assets.xcassets/AppIcon.solidimagestack/Back.solidimagestacklayer/Contents.json.license b/SpatialContinuity/Assets.xcassets/AppIcon.solidimagestack/Back.solidimagestacklayer/Contents.json.license new file mode 100644 index 0000000..eb38c65 --- /dev/null +++ b/SpatialContinuity/Assets.xcassets/AppIcon.solidimagestack/Back.solidimagestacklayer/Contents.json.license @@ -0,0 +1,5 @@ +This source file is part of the Spatial Continuity project + +SPDX-FileCopyrightText: 2025 Stanford University and the project authors (see CONTRIBUTORS.md) + +SPDX-License-Identifier: MIT diff --git a/SpatialContinuity/Assets.xcassets/AppIcon.solidimagestack/Contents.json b/SpatialContinuity/Assets.xcassets/AppIcon.solidimagestack/Contents.json new file mode 100644 index 0000000..950af4d --- /dev/null +++ b/SpatialContinuity/Assets.xcassets/AppIcon.solidimagestack/Contents.json @@ -0,0 +1,17 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + }, + "layers" : [ + { + "filename" : "Front.solidimagestacklayer" + }, + { + "filename" : "Middle.solidimagestacklayer" + }, + { + "filename" : "Back.solidimagestacklayer" + } + ] +} diff --git a/SpatialContinuity/Assets.xcassets/AppIcon.solidimagestack/Contents.json.license b/SpatialContinuity/Assets.xcassets/AppIcon.solidimagestack/Contents.json.license new file mode 100644 index 0000000..eb38c65 --- /dev/null +++ b/SpatialContinuity/Assets.xcassets/AppIcon.solidimagestack/Contents.json.license @@ -0,0 +1,5 @@ +This source file is part of the Spatial Continuity project + +SPDX-FileCopyrightText: 2025 Stanford University and the project authors (see CONTRIBUTORS.md) + +SPDX-License-Identifier: MIT diff --git a/SpatialContinuity/Assets.xcassets/AppIcon.solidimagestack/Front.solidimagestacklayer/Content.imageset/Contents.json b/SpatialContinuity/Assets.xcassets/AppIcon.solidimagestack/Front.solidimagestacklayer/Content.imageset/Contents.json new file mode 100644 index 0000000..04056a5 --- /dev/null +++ b/SpatialContinuity/Assets.xcassets/AppIcon.solidimagestack/Front.solidimagestacklayer/Content.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "idiom" : "vision", + "scale" : "2x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/SpatialContinuity/Assets.xcassets/AppIcon.solidimagestack/Front.solidimagestacklayer/Content.imageset/Contents.json.license b/SpatialContinuity/Assets.xcassets/AppIcon.solidimagestack/Front.solidimagestacklayer/Content.imageset/Contents.json.license new file mode 100644 index 0000000..eb38c65 --- /dev/null +++ b/SpatialContinuity/Assets.xcassets/AppIcon.solidimagestack/Front.solidimagestacklayer/Content.imageset/Contents.json.license @@ -0,0 +1,5 @@ +This source file is part of the Spatial Continuity project + +SPDX-FileCopyrightText: 2025 Stanford University and the project authors (see CONTRIBUTORS.md) + +SPDX-License-Identifier: MIT diff --git a/SpatialContinuity/Assets.xcassets/AppIcon.solidimagestack/Front.solidimagestacklayer/Contents.json b/SpatialContinuity/Assets.xcassets/AppIcon.solidimagestack/Front.solidimagestacklayer/Contents.json new file mode 100644 index 0000000..73c0059 --- /dev/null +++ b/SpatialContinuity/Assets.xcassets/AppIcon.solidimagestack/Front.solidimagestacklayer/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/SpatialContinuity/Assets.xcassets/AppIcon.solidimagestack/Front.solidimagestacklayer/Contents.json.license b/SpatialContinuity/Assets.xcassets/AppIcon.solidimagestack/Front.solidimagestacklayer/Contents.json.license new file mode 100644 index 0000000..eb38c65 --- /dev/null +++ b/SpatialContinuity/Assets.xcassets/AppIcon.solidimagestack/Front.solidimagestacklayer/Contents.json.license @@ -0,0 +1,5 @@ +This source file is part of the Spatial Continuity project + +SPDX-FileCopyrightText: 2025 Stanford University and the project authors (see CONTRIBUTORS.md) + +SPDX-License-Identifier: MIT diff --git a/SpatialContinuity/Assets.xcassets/AppIcon.solidimagestack/Middle.solidimagestacklayer/Content.imageset/Contents.json b/SpatialContinuity/Assets.xcassets/AppIcon.solidimagestack/Middle.solidimagestacklayer/Content.imageset/Contents.json new file mode 100644 index 0000000..04056a5 --- /dev/null +++ b/SpatialContinuity/Assets.xcassets/AppIcon.solidimagestack/Middle.solidimagestacklayer/Content.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "idiom" : "vision", + "scale" : "2x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/SpatialContinuity/Assets.xcassets/AppIcon.solidimagestack/Middle.solidimagestacklayer/Content.imageset/Contents.json.license b/SpatialContinuity/Assets.xcassets/AppIcon.solidimagestack/Middle.solidimagestacklayer/Content.imageset/Contents.json.license new file mode 100644 index 0000000..eb38c65 --- /dev/null +++ b/SpatialContinuity/Assets.xcassets/AppIcon.solidimagestack/Middle.solidimagestacklayer/Content.imageset/Contents.json.license @@ -0,0 +1,5 @@ +This source file is part of the Spatial Continuity project + +SPDX-FileCopyrightText: 2025 Stanford University and the project authors (see CONTRIBUTORS.md) + +SPDX-License-Identifier: MIT diff --git a/SpatialContinuity/Assets.xcassets/AppIcon.solidimagestack/Middle.solidimagestacklayer/Contents.json b/SpatialContinuity/Assets.xcassets/AppIcon.solidimagestack/Middle.solidimagestacklayer/Contents.json new file mode 100644 index 0000000..73c0059 --- /dev/null +++ b/SpatialContinuity/Assets.xcassets/AppIcon.solidimagestack/Middle.solidimagestacklayer/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/SpatialContinuity/Assets.xcassets/AppIcon.solidimagestack/Middle.solidimagestacklayer/Contents.json.license b/SpatialContinuity/Assets.xcassets/AppIcon.solidimagestack/Middle.solidimagestacklayer/Contents.json.license new file mode 100644 index 0000000..eb38c65 --- /dev/null +++ b/SpatialContinuity/Assets.xcassets/AppIcon.solidimagestack/Middle.solidimagestacklayer/Contents.json.license @@ -0,0 +1,5 @@ +This source file is part of the Spatial Continuity project + +SPDX-FileCopyrightText: 2025 Stanford University and the project authors (see CONTRIBUTORS.md) + +SPDX-License-Identifier: MIT diff --git a/SpatialContinuity/Assets.xcassets/Contents.json b/SpatialContinuity/Assets.xcassets/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/SpatialContinuity/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/SpatialContinuity/Assets.xcassets/Contents.json.license b/SpatialContinuity/Assets.xcassets/Contents.json.license new file mode 100644 index 0000000..eb38c65 --- /dev/null +++ b/SpatialContinuity/Assets.xcassets/Contents.json.license @@ -0,0 +1,5 @@ +This source file is part of the Spatial Continuity project + +SPDX-FileCopyrightText: 2025 Stanford University and the project authors (see CONTRIBUTORS.md) + +SPDX-License-Identifier: MIT diff --git a/SpatialContinuity/Info.plist b/SpatialContinuity/Info.plist new file mode 100644 index 0000000..e04aee5 --- /dev/null +++ b/SpatialContinuity/Info.plist @@ -0,0 +1,20 @@ + + + + + NSBonjourServices + + _SCCBonj_.tcp + _SCCBonj_.udp + + UIApplicationSceneManifest + + UIApplicationPreferredDefaultSceneSessionRole + UIWindowSceneSessionRoleApplication + UIApplicationSupportsMultipleScenes + + UISceneConfigurations + + + + diff --git a/SpatialContinuity/Info.plist.license b/SpatialContinuity/Info.plist.license new file mode 100644 index 0000000..eb38c65 --- /dev/null +++ b/SpatialContinuity/Info.plist.license @@ -0,0 +1,5 @@ +This source file is part of the Spatial Continuity project + +SPDX-FileCopyrightText: 2025 Stanford University and the project authors (see CONTRIBUTORS.md) + +SPDX-License-Identifier: MIT diff --git a/SpatialContinuity/LLMOpenAIAppDelegate.swift b/SpatialContinuity/LLMOpenAIAppDelegate.swift new file mode 100644 index 0000000..c1b8d47 --- /dev/null +++ b/SpatialContinuity/LLMOpenAIAppDelegate.swift @@ -0,0 +1,21 @@ +// +// This source file is part of the Spatial Continuity project +// +// SPDX-FileCopyrightText: 2025 Stanford University and the project authors (see CONTRIBUTORS.md) +// +// SPDX-License-Identifier: MIT +// + +import Spezi +import SpeziLLM +import SpeziLLMOpenAI + +class LLMOpenAIAppDelegate: SpeziAppDelegate { + override var configuration: Configuration { + Configuration { + LLMRunner { + LLMOpenAIPlatform() + } + } + } +} diff --git a/SpatialContinuity/LiveVideoView.swift b/SpatialContinuity/LiveVideoView.swift new file mode 100644 index 0000000..5f694e9 --- /dev/null +++ b/SpatialContinuity/LiveVideoView.swift @@ -0,0 +1,25 @@ +// +// This source file is part of the Spatial Continuity project +// +// SPDX-FileCopyrightText: 2025 Stanford University and the project authors (see CONTRIBUTORS.md) +// +// SPDX-License-Identifier: MIT +// + +import SwiftUI + +struct LiveVideoView: View { + @Binding var currentFrame: UIImage? + + var body: some View { + GeometryReader { geometry in + if let currentFrame { + Image(uiImage: currentFrame) + .resizable() + .scaledToFit() + .frame(width: geometry.size.width, height: geometry.size.height) + .accessibilityLabel("The live video being streamed from SpatialContinutiyCamera") + } + } + } +} diff --git a/SpatialContinuity/Onboarding/OnboardingFlow.swift b/SpatialContinuity/Onboarding/OnboardingFlow.swift new file mode 100644 index 0000000..c939f5c --- /dev/null +++ b/SpatialContinuity/Onboarding/OnboardingFlow.swift @@ -0,0 +1,22 @@ +// +// This source file is part of the Spatial Continuity project +// +// SPDX-FileCopyrightText: 2025 Stanford University and the project authors (see CONTRIBUTORS.md) +// +// SPDX-License-Identifier: MIT +// + +import SpeziOnboarding +import SwiftUI + +// Source: https://swiftpackageindex.com/stanfordspezi/spezillm/0.8.3/documentation/spezillmopenai + +struct OnboardingFlow: View { + @AppStorage(StorageKeys.onboardingFlowComplete) var completedOnboardingFlow = false + + var body: some View { + OnboardingStack(onboardingFlowComplete: $completedOnboardingFlow) { + OpenAIAPIKey() + } + } +} diff --git a/SpatialContinuity/Onboarding/OpenAIAPIKey.swift b/SpatialContinuity/Onboarding/OpenAIAPIKey.swift new file mode 100644 index 0000000..e021441 --- /dev/null +++ b/SpatialContinuity/Onboarding/OpenAIAPIKey.swift @@ -0,0 +1,23 @@ +// +// This source file is part of the Spatial Continuity project +// +// SPDX-FileCopyrightText: 2025 Stanford University and the project authors (see CONTRIBUTORS.md) +// +// SPDX-License-Identifier: MIT +// + +import SpeziLLMOpenAI +import SpeziOnboarding +import SwiftUI + +// Source: https://swiftpackageindex.com/stanfordspezi/spezillm/0.8.3/documentation/spezillmopenai + +struct OpenAIAPIKey: View { + @Environment(OnboardingNavigationPath.self) private var onboardingNavigationPath: OnboardingNavigationPath + + var body: some View { + LLMOpenAIAPITokenOnboardingStep { + onboardingNavigationPath.nextStep() + } + } +} diff --git a/SpatialContinuity/Preview Content/Preview Assets.xcassets/Contents.json b/SpatialContinuity/Preview Content/Preview Assets.xcassets/Contents.json new file mode 100644 index 0000000..73c0059 --- /dev/null +++ b/SpatialContinuity/Preview Content/Preview Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/SpatialContinuity/Preview Content/Preview Assets.xcassets/Contents.json.license b/SpatialContinuity/Preview Content/Preview Assets.xcassets/Contents.json.license new file mode 100644 index 0000000..eb38c65 --- /dev/null +++ b/SpatialContinuity/Preview Content/Preview Assets.xcassets/Contents.json.license @@ -0,0 +1,5 @@ +This source file is part of the Spatial Continuity project + +SPDX-FileCopyrightText: 2025 Stanford University and the project authors (see CONTRIBUTORS.md) + +SPDX-License-Identifier: MIT diff --git a/SpatialContinuity/SCModel.swift b/SpatialContinuity/SCModel.swift new file mode 100644 index 0000000..002644b --- /dev/null +++ b/SpatialContinuity/SCModel.swift @@ -0,0 +1,31 @@ +// +// This source file is part of the Spatial Continuity project +// +// SPDX-FileCopyrightText: 2025 Stanford University and the project authors (see CONTRIBUTORS.md) +// +// SPDX-License-Identifier: MIT +// + +import SwiftUI + +class SCModel: ObservableObject { + let networking: Networking = .init() + @Published var currentFrame: UIImage? + @Published var currentPin: UIImage? + + init() { + networking.startBrowsing() + + Task { + await handleIncomingVideo() + } + } + + func handleIncomingVideo() async { + for await buffer in networking.pixelBuffers { + Task { @MainActor in + currentFrame = CIImage(cvPixelBuffer: buffer).uiImage + } + } + } +} diff --git a/SpatialContinuity/SCStaticPinView.swift b/SpatialContinuity/SCStaticPinView.swift new file mode 100644 index 0000000..36751e6 --- /dev/null +++ b/SpatialContinuity/SCStaticPinView.swift @@ -0,0 +1,78 @@ +// +// This source file is part of the Spatial Continuity project +// +// SPDX-FileCopyrightText: 2025 Stanford University and the project authors (see CONTRIBUTORS.md) +// +// SPDX-License-Identifier: MIT +// + +import AVFoundation +import SpeziLLM +import SpeziLLMOpenAI +import SwiftUI + +struct StaticPinView: View { + @State var llmSession: LLMOpenAISession? + @State var responseText = "" + @Binding var img: UIImage? + @Environment(LLMRunner.self) var runner + @State var synthesizer: AVSpeechSynthesizer = .init() + + var body: some View { + GeometryReader { geometry in + if let img { + Image(uiImage: img) + .resizable() + .scaledToFit() + .frame(width: geometry.size.width, height: geometry.size.height) + .accessibilityLabel("The static pin received from SpatialContinuityCamera") + .onAppear { + if llmSession == nil { + setUpLLMSession() + } + } + .task(id: img) { + do { + if let llmSession { + await MainActor.run { + llmSession.context.append( + userInput: "Please describe this image in German", + userImgInput: img + ) + } + + for try await token in try await llmSession.generate() { + responseText.append(token) + } + + readDescription() + } + } catch { + print("Didn't receive a response from the OpenAI API \(error)") + } + } + } else { + Text("Your pin will appear here.") + } + } + } + + private func readDescription() { + let description = AVSpeechUtterance(string: responseText) + description.prefersAssistiveTechnologySettings = true + description.rate = 0.6 + synthesizer.speak(description) + responseText.removeAll() + } + + private func setUpLLMSession() { + llmSession = runner( + with: LLMOpenAISchema( + parameters: .init( + modelType: .init(value1: .gpt4_turbo, value2: .gpt_hyphen_4_hyphen_turbo), + systemPrompt: "You are an assistant that describes images to users with visual impairments." + ) + ) + ) + } +} diff --git a/SpatialContinuity/SpatialContinuityApp.swift b/SpatialContinuity/SpatialContinuityApp.swift new file mode 100644 index 0000000..e5f4b2a --- /dev/null +++ b/SpatialContinuity/SpatialContinuityApp.swift @@ -0,0 +1,81 @@ +// +// This source file is part of the Spatial Continuity project +// +// SPDX-FileCopyrightText: 2025 Stanford University and the project authors (see CONTRIBUTORS.md) +// +// SPDX-License-Identifier: MIT +// + +@_exported import SpatialContinuityShared +import Spezi +import SpeziViews +import SwiftUI + +@main +struct SpatialContinuityApp: App { + @ApplicationDelegateAdaptor(LLMOpenAIAppDelegate.self) var appDelegate + @StateObject private var model: SCModel = .init() + @AppStorage(StorageKeys.onboardingFlowComplete) var completedOnboardingFlow = false + @Environment(\.openWindow) private var openWindow + @Environment(\.dismissWindow) private var dismissWindow + @State private var pinWindowOpen: Bool = false + + var body: some Scene { + WindowGroup(id: "livestream") { + ZStack { + if completedOnboardingFlow { + LiveVideoView(currentFrame: $model.currentFrame) + .onDisappear { + dismissWindow(id: "currentPin") + } + } else { + EmptyView() + } + } + .sheet(isPresented: !$completedOnboardingFlow) { + OnboardingFlow() + } + .toolbar { + ToolbarItem(placement: .bottomOrnament) { + Button(String(localized: "API Key Settings")) { + completedOnboardingFlow.toggle() + } + } + ToolbarItem(placement: .bottomOrnament) { + Button(String(localized: "Read Image Description")) { + model.currentPin = model.currentFrame + if !pinWindowOpen { + openWindow(id: "currentPin") + } + } + .disabled(!model.networking.isConnected) + } + } + .spezi(appDelegate) + } + .windowResizability(.contentSize) + + WindowGroup("Current Pin", id: "currentPin") { + ZStack { + if completedOnboardingFlow { + StaticPinView(img: $model.currentPin) + .onAppear { + pinWindowOpen = true + } + .onDisappear { + pinWindowOpen = false + } + } + } + .spezi(appDelegate) + } + .windowResizability(.contentSize) + .defaultWindowPlacement { _, context in + guard let contentWindow = context.windows.first(where: { $0.id == "livestream" }) + else { + return WindowPlacement(nil) + } + return WindowPlacement(.trailing(contentWindow)) + } + } +} diff --git a/SpatialContinuity/StorageKeys.swift b/SpatialContinuity/StorageKeys.swift new file mode 100644 index 0000000..ea2dd51 --- /dev/null +++ b/SpatialContinuity/StorageKeys.swift @@ -0,0 +1,11 @@ +// +// This source file is part of the Spatial Continuity project +// +// SPDX-FileCopyrightText: 2025 Stanford University and the project authors (see CONTRIBUTORS.md) +// +// SPDX-License-Identifier: MIT +// + +enum StorageKeys { + static let onboardingFlowComplete = "onboardingFlow.complete" +} diff --git a/TemplateApplication/Assets.xcassets/AccentColor.colorset/Contents.json b/SpatialContinuityCamera/Assets.xcassets/AccentColor.colorset/Contents.json similarity index 100% rename from TemplateApplication/Assets.xcassets/AccentColor.colorset/Contents.json rename to SpatialContinuityCamera/Assets.xcassets/AccentColor.colorset/Contents.json diff --git a/SpatialContinuityCamera/Assets.xcassets/AccentColor.colorset/Contents.json.license b/SpatialContinuityCamera/Assets.xcassets/AccentColor.colorset/Contents.json.license new file mode 100644 index 0000000..eb38c65 --- /dev/null +++ b/SpatialContinuityCamera/Assets.xcassets/AccentColor.colorset/Contents.json.license @@ -0,0 +1,5 @@ +This source file is part of the Spatial Continuity project + +SPDX-FileCopyrightText: 2025 Stanford University and the project authors (see CONTRIBUTORS.md) + +SPDX-License-Identifier: MIT diff --git a/TemplateApplication/Assets.xcassets/AppIcon.appiconset/Contents.json b/SpatialContinuityCamera/Assets.xcassets/AppIcon.appiconset/Contents.json similarity index 52% rename from TemplateApplication/Assets.xcassets/AppIcon.appiconset/Contents.json rename to SpatialContinuityCamera/Assets.xcassets/AppIcon.appiconset/Contents.json index 7cecd2f..13613e3 100644 --- a/TemplateApplication/Assets.xcassets/AppIcon.appiconset/Contents.json +++ b/SpatialContinuityCamera/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -1,16 +1,9 @@ { "images" : [ { - "filename" : "1024.png", "idiom" : "universal", "platform" : "ios", "size" : "1024x1024" - }, - { - "filename" : "1024.png", - "idiom" : "universal", - "platform" : "watchos", - "size" : "1024x1024" } ], "info" : { diff --git a/SpatialContinuityCamera/Assets.xcassets/AppIcon.appiconset/Contents.json.license b/SpatialContinuityCamera/Assets.xcassets/AppIcon.appiconset/Contents.json.license new file mode 100644 index 0000000..eb38c65 --- /dev/null +++ b/SpatialContinuityCamera/Assets.xcassets/AppIcon.appiconset/Contents.json.license @@ -0,0 +1,5 @@ +This source file is part of the Spatial Continuity project + +SPDX-FileCopyrightText: 2025 Stanford University and the project authors (see CONTRIBUTORS.md) + +SPDX-License-Identifier: MIT diff --git a/SpatialContinuityCamera/Assets.xcassets/Contents.json b/SpatialContinuityCamera/Assets.xcassets/Contents.json new file mode 100644 index 0000000..73c0059 --- /dev/null +++ b/SpatialContinuityCamera/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/SpatialContinuityCamera/Assets.xcassets/Contents.json.license b/SpatialContinuityCamera/Assets.xcassets/Contents.json.license new file mode 100644 index 0000000..eb38c65 --- /dev/null +++ b/SpatialContinuityCamera/Assets.xcassets/Contents.json.license @@ -0,0 +1,5 @@ +This source file is part of the Spatial Continuity project + +SPDX-FileCopyrightText: 2025 Stanford University and the project authors (see CONTRIBUTORS.md) + +SPDX-License-Identifier: MIT diff --git a/SpatialContinuityCamera/Info.plist b/SpatialContinuityCamera/Info.plist new file mode 100644 index 0000000..ee275fb --- /dev/null +++ b/SpatialContinuityCamera/Info.plist @@ -0,0 +1,11 @@ + + + + + NSBonjourServices + + _SCCBonj._tcp + _SCCBonj._udp + + + diff --git a/SpatialContinuityCamera/Info.plist.license b/SpatialContinuityCamera/Info.plist.license new file mode 100644 index 0000000..eb38c65 --- /dev/null +++ b/SpatialContinuityCamera/Info.plist.license @@ -0,0 +1,5 @@ +This source file is part of the Spatial Continuity project + +SPDX-FileCopyrightText: 2025 Stanford University and the project authors (see CONTRIBUTORS.md) + +SPDX-License-Identifier: MIT diff --git a/SpatialContinuityCamera/Preview Content/Preview Assets.xcassets/Contents.json b/SpatialContinuityCamera/Preview Content/Preview Assets.xcassets/Contents.json new file mode 100644 index 0000000..73c0059 --- /dev/null +++ b/SpatialContinuityCamera/Preview Content/Preview Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/SpatialContinuityCamera/Preview Content/Preview Assets.xcassets/Contents.json.license b/SpatialContinuityCamera/Preview Content/Preview Assets.xcassets/Contents.json.license new file mode 100644 index 0000000..eb38c65 --- /dev/null +++ b/SpatialContinuityCamera/Preview Content/Preview Assets.xcassets/Contents.json.license @@ -0,0 +1,5 @@ +This source file is part of the Spatial Continuity project + +SPDX-FileCopyrightText: 2025 Stanford University and the project authors (see CONTRIBUTORS.md) + +SPDX-License-Identifier: MIT diff --git a/SpatialContinuityCamera/SCC.swift b/SpatialContinuityCamera/SCC.swift new file mode 100644 index 0000000..10aebfe --- /dev/null +++ b/SpatialContinuityCamera/SCC.swift @@ -0,0 +1,202 @@ +// +// This source file is part of the Spatial Continuity project +// +// SPDX-FileCopyrightText: 2025 Stanford University and the project authors (see CONTRIBUTORS.md) +// +// SPDX-License-Identifier: MIT +// + +import AVFoundation +import CoreImage +import SwiftUI +import UIKit + +// References: +// * https://developer.apple.com/tutorials/sample-apps/capturingphotos-camerapreview +// * https://developer.apple.com/documentation/avfoundation/capture_setup/avcambarcode_detecting_barcodes_and_faces +// * https://www.neuralception.com/detection-app-tutorial-camera-feed/ + +class SCC: NSObject, AVCaptureVideoDataOutputSampleBufferDelegate { + private enum SessionSetupResult { + case success + case notAuthorized + case unconfigured + } + + private let captureSession = AVCaptureSession() + private let sessionQueue = DispatchQueue(label: "sessionQueue") + private var setupResult: SessionSetupResult = .unconfigured + private var addToPreviewStream: ((CIImage) -> Void)? + private var addToPhotoStream: ((AVCapturePhoto) -> Void)? + private var addToVideoStream: ((CVPixelBuffer) -> Void)? + private var photoOutput: AVCapturePhotoOutput? + + private var deviceOrientation: UIDeviceOrientation { + var orientation = UIDevice.current.orientation + if orientation == UIDeviceOrientation.unknown { + orientation = UIDeviceOrientation.portrait + } + return orientation + } + + // Verbatim from https://developer.apple.com/tutorials/sample-apps/capturingphotos-camerapreview + lazy var previewStream: AsyncStream = AsyncStream { continuation in + addToPreviewStream = { ciImage in + continuation.yield(ciImage) + } + } + + lazy var photoStream: AsyncStream = AsyncStream { continuation in + addToPhotoStream = { photo in + continuation.yield(photo) + } + } + + lazy var videoStream: AsyncStream = AsyncStream { continuation in + addToVideoStream = { buffer in + continuation.yield(buffer) + } + } + + var minZoom: CGFloat = 1.0 + var maxZoom: CGFloat = 1.0 + var videoDevice: AVCaptureDevice? + + override init() { + super.init() + setupCamera() + } + + private func videoOrientationFor(_ deviceOrientation: UIDeviceOrientation) -> AVCaptureVideoOrientation? { + switch deviceOrientation { + case .portrait: AVCaptureVideoOrientation.portrait + case .portraitUpsideDown: AVCaptureVideoOrientation.portraitUpsideDown + case .landscapeLeft: AVCaptureVideoOrientation.landscapeRight + case .landscapeRight: AVCaptureVideoOrientation.landscapeLeft + default: nil + } + } + + private func checkCameraAuthorization() -> Bool { + switch AVCaptureDevice.authorizationStatus(for: .video) { + case .authorized: + break + case .notDetermined: + sessionQueue.suspend() + AVCaptureDevice.requestAccess(for: .video, completionHandler: { granted in + if !granted { + self.setupResult = .notAuthorized + } + self.sessionQueue.resume() + }) + default: + setupResult = .unconfigured + print("No camera access") + return false + } + + return true + } + + func setupCamera() { + if !checkCameraAuthorization() { + return + } + + captureSession.beginConfiguration() + + self.videoDevice = AVCaptureDevice.default(.builtInWideAngleCamera, for: .video, position: .back) + + guard let videoDevice else { + print("Couldn't select capture device") + setupResult = .unconfigured + return + } + + minZoom = videoDevice.minAvailableVideoZoomFactor + maxZoom = min(videoDevice.maxAvailableVideoZoomFactor, 16) + + do { + let videoDeviceInput = try AVCaptureDeviceInput(device: videoDevice) + if captureSession.canAddInput(videoDeviceInput) { + captureSession.addInput(videoDeviceInput) + } else { + print("Could not add video device input to the session") + setupResult = .unconfigured + return + } + + // Verbatim from https://developer.apple.com/tutorials/sample-apps/capturingphotos-camerapreview + let videoDeviceOutput = AVCaptureVideoDataOutput() + videoDeviceOutput.setSampleBufferDelegate(self, queue: DispatchQueue(label: "VideoDataOutputQueue")) + if captureSession.canAddOutput(videoDeviceOutput) { + captureSession.addOutput(videoDeviceOutput) + } else { + print("Could not add video device output to the session") + setupResult = .unconfigured + return + } + + let photoDeviceOutput = AVCapturePhotoOutput() + + captureSession.sessionPreset = AVCaptureSession.Preset.photo + + if captureSession.canAddOutput(photoDeviceOutput) { + captureSession.addOutput(photoDeviceOutput) + photoOutput = photoDeviceOutput + // self.photoOutput!.isHighResolutionCaptureEnabled = true + photoOutput?.maxPhotoQualityPrioritization = .quality + } else { + print("Could not add photo device output to the session") + setupResult = .unconfigured + return + } + } catch { + print("Couldn't obtain device input") + setupResult = .unconfigured + return + } + + captureSession.commitConfiguration() + setupResult = .success + } + + func start() async { + if setupResult == .unconfigured { + return + } + + sessionQueue.async { [self] in + captureSession.startRunning() + } + } + + // Verbatim from https://developer.apple.com/tutorials/sample-apps/capturingphotos-camerapreview + func captureOutput( + _: AVCaptureOutput, + didOutput sampleBuffer: CMSampleBuffer, + from connection: AVCaptureConnection + ) { + guard let pixelBuffer = sampleBuffer.imageBuffer else { + return + } + + if connection.isVideoOrientationSupported, + let videoOrientation = videoOrientationFor(deviceOrientation) { + connection.videoOrientation = videoOrientation + } + + addToVideoStream?(pixelBuffer) + addToPreviewStream?(CIImage(cvPixelBuffer: pixelBuffer)) + } +} + +extension SCC: AVCapturePhotoCaptureDelegate { + public func photoOutput(_: AVCapturePhotoOutput, didFinishProcessingPhoto photo: AVCapturePhoto, error: Error?) { + if let error { + print("Couldn't capture frame: \(error.localizedDescription)") + return + } + addToPhotoStream?(photo) + } +} diff --git a/SpatialContinuityCamera/SCCModel.swift b/SpatialContinuityCamera/SCCModel.swift new file mode 100644 index 0000000..df47e3f --- /dev/null +++ b/SpatialContinuityCamera/SCCModel.swift @@ -0,0 +1,68 @@ +// +// This source file is part of the Spatial Continuity project +// +// SPDX-FileCopyrightText: 2025 Stanford University and the project authors (see CONTRIBUTORS.md) +// +// SPDX-License-Identifier: MIT +// + +import AVFoundation +import SwiftUI + +class SCCModel: ObservableObject { + var scc: SCC = .init() + let networking: Networking = .init() + + @Published var viewFinderImage: UIImage? + + init() { + Task { + await handleSCCPreviewStream() + } + + Task { + await handleSCCPhotoStream() + } + + Task { + await handleSCCVideoStream() + } + + networking.startAdvertising() + } + + // Verbatim + func handleSCCPreviewStream() async { + let imageStream = scc.previewStream + .map(\.uiImage) + + for await image in imageStream { + Task { @MainActor in + viewFinderImage = image + } + } + } + + func handleSCCPhotoStream() async { + for await photoFromStream in scc.photoStream { + // peerConn.sendImage(data: photoFromStream.fileDataRepresentation()) + } + } + + func handleSCCVideoStream() async { + for await buffer in scc.videoStream { + networking.send(buffer) + } + } +} + +// Verbatim from https://developer.apple.com/tutorials/sample-apps/capturingphotos-camerapreview +extension CIImage { + var uiImage: UIImage? { + let ciContext = CIContext() + guard let cgImage = ciContext.createCGImage(self, from: extent) else { + return nil + } + return UIImage(cgImage: cgImage) + } +} diff --git a/SpatialContinuityCamera/SCCPreviewView.swift b/SpatialContinuityCamera/SCCPreviewView.swift new file mode 100644 index 0000000..2d243ec --- /dev/null +++ b/SpatialContinuityCamera/SCCPreviewView.swift @@ -0,0 +1,54 @@ +// +// This source file is part of the Spatial Continuity project +// +// SPDX-FileCopyrightText: 2025 Stanford University and the project authors (see CONTRIBUTORS.md) +// +// SPDX-License-Identifier: MIT +// + +import SwiftUI +import UIKit + +struct SCCPreviewView: View { + @Binding var cameraImage: UIImage? + @Binding var scc: SCC + @State var videoZoomFactor: CGFloat = 1.0 + + var body: some View { + GeometryReader { geometry in + if let cimg = cameraImage { + ZStack { + Image(uiImage: cimg) + .resizable() + .scaledToFit() + .frame(width: geometry.size.width, height: geometry.size.height) + .accessibilityLabel("The viewfinder's view") + VStack { + Slider( + value: $videoZoomFactor, + in: scc.minZoom ... scc.maxZoom, + minimumValueLabel: Text("\(Int(scc.minZoom))"), + maximumValueLabel: Text("\(Int(scc.maxZoom))"), + label: { Text("Zoom") } + ) + Text("Zoom") + } + .frame(width: geometry.size.width - 50, alignment: .center) + .position(x: geometry.size.width / 2, y: geometry.size.height - 70) + .onChange(of: videoZoomFactor) { + print(videoZoomFactor) + if let videoDevice = scc.videoDevice { + do { + try videoDevice.lockForConfiguration() + videoDevice.videoZoomFactor = videoZoomFactor + videoDevice.unlockForConfiguration() + } catch { + print(error) + } + } + } + } + } + } + } +} diff --git a/SpatialContinuityCamera/SCCView.swift b/SpatialContinuityCamera/SCCView.swift new file mode 100644 index 0000000..e656770 --- /dev/null +++ b/SpatialContinuityCamera/SCCView.swift @@ -0,0 +1,23 @@ +// +// This source file is part of the Spatial Continuity project +// +// SPDX-FileCopyrightText: 2025 Stanford University and the project authors (see CONTRIBUTORS.md) +// +// SPDX-License-Identifier: MIT +// + +import SwiftUI + +struct SCCView: View { + @StateObject private var model = SCCModel() + + var body: some View { + NavigationStack { + SCCPreviewView(cameraImage: $model.viewFinderImage, scc: $model.scc) + .task { + await model.scc.start() + } + .ignoresSafeArea() + } + } +} diff --git a/SpatialContinuityCamera/SpatialContinuityCameraApp.swift b/SpatialContinuityCamera/SpatialContinuityCameraApp.swift new file mode 100644 index 0000000..8da09c3 --- /dev/null +++ b/SpatialContinuityCamera/SpatialContinuityCameraApp.swift @@ -0,0 +1,19 @@ +// +// This source file is part of the Spatial Continuity project +// +// SPDX-FileCopyrightText: 2025 Stanford University and the project authors (see CONTRIBUTORS.md) +// +// SPDX-License-Identifier: MIT +// + +@_exported import SpatialContinuityShared +import SwiftUI + +@main +struct SpatialContinuityCameraApp: App { + var body: some Scene { + WindowGroup { + SCCView() + } + } +} diff --git a/SpatialContinuityShared/.gitignore b/SpatialContinuityShared/.gitignore new file mode 100644 index 0000000..c306855 --- /dev/null +++ b/SpatialContinuityShared/.gitignore @@ -0,0 +1,16 @@ +# +# This source file is part of the Spatial Continuity project +# +# SPDX-FileCopyrightText: 2025 Stanford University and the project authors (see CONTRIBUTORS.md) +# +# SPDX-License-Identifier: MIT +# + +.DS_Store +/.build +/Packages +xcuserdata/ +DerivedData/ +.swiftpm/configuration/registries.json +.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata +.netrc diff --git a/SpatialContinuityShared/Package.swift b/SpatialContinuityShared/Package.swift new file mode 100644 index 0000000..fb467cb --- /dev/null +++ b/SpatialContinuityShared/Package.swift @@ -0,0 +1,37 @@ +// swift-tools-version: 5.10 +// The swift-tools-version declares the minimum version of Swift required to build this package. + +// This source file is part of the Spatial Continuity project +// +// SPDX-FileCopyrightText: 2025 Stanford University and the project authors (see CONTRIBUTORS.md) +// +// SPDX-License-Identifier: MIT +// + +import PackageDescription + +let package = Package( + name: "SpatialContinuityShared", + platforms: [ + .iOS(.v17), + .visionOS(.v1) + ], + products: [ + // Products define the executables and libraries a package produces, making them visible to other packages. + .library( + name: "SpatialContinuityShared", + targets: ["SpatialContinuityShared"] + ) + ], + dependencies: [ + .package(url: "https://github.com/finnvoor/Transcoding", .upToNextMajor(from: "0.0.1")) + ], + targets: [ + // Targets are the basic building blocks of a package, defining a module or a test suite. + // Targets can depend on other targets in this package and products from dependencies. + .target( + name: "SpatialContinuityShared", + dependencies: ["Transcoding"] + ) + ] +) diff --git a/SpatialContinuityShared/Sources/SpatialContinuityShared/CIImage+Extensions.swift b/SpatialContinuityShared/Sources/SpatialContinuityShared/CIImage+Extensions.swift new file mode 100755 index 0000000..c4a9e6d --- /dev/null +++ b/SpatialContinuityShared/Sources/SpatialContinuityShared/CIImage+Extensions.swift @@ -0,0 +1,31 @@ +// +// This source file is part of the Spatial Continuity project +// +// SPDX-FileCopyrightText: 2025 Stanford University and the project authors (see CONTRIBUTORS.md) +// +// SPDX-License-Identifier: MIT +// + +import SwiftUI +import UIKit + +// Verbatim from https://developer.apple.com/tutorials/sample-apps/capturingphotos-camerapreview +extension CIImage { + /// Returns a corresponding `Image` object if it can be created + public var image: Image? { + let ciContext = CIContext() + guard let cgImage = ciContext.createCGImage(self, from: extent) else { + return nil + } + return Image(decorative: cgImage, scale: 1, orientation: .up) + } + + /// Returns a corresponding `UIImage` object if it can be created + public var uiImage: UIImage? { + let ciContext = CIContext() + guard let cgImage = ciContext.createCGImage(self, from: extent) else { + return nil + } + return UIImage(cgImage: cgImage) + } +} diff --git a/SpatialContinuityShared/Sources/SpatialContinuityShared/Constants.swift b/SpatialContinuityShared/Sources/SpatialContinuityShared/Constants.swift new file mode 100644 index 0000000..a892a66 --- /dev/null +++ b/SpatialContinuityShared/Sources/SpatialContinuityShared/Constants.swift @@ -0,0 +1,12 @@ +// +// This source file is part of the Spatial Continuity project +// +// SPDX-FileCopyrightText: 2025 Stanford University and the project authors (see CONTRIBUTORS.md) +// +// SPDX-License-Identifier: MIT +// + +enum Constants { + static let bonjourServiceTypeTCP = "_SCCBonj._tcp" + static let bonjourServiceTypeUDP = "_SCCBonj._udp" +} diff --git a/SpatialContinuityShared/Sources/SpatialContinuityShared/LocalVideoStreaming/Networking.swift b/SpatialContinuityShared/Sources/SpatialContinuityShared/LocalVideoStreaming/Networking.swift new file mode 100644 index 0000000..b93ce9b --- /dev/null +++ b/SpatialContinuityShared/Sources/SpatialContinuityShared/LocalVideoStreaming/Networking.swift @@ -0,0 +1,117 @@ +// +// This source file is part of the Spatial Continuity project +// +// SPDX-FileCopyrightText: 2025 Stanford University and the project authors (see CONTRIBUTORS.md) +// +// SPDX-License-Identifier: MIT +// + +import Combine +import CoreMedia +import Foundation +import MultipeerConnectivity +import Transcoding + +// MARK: - Networking + +@Observable public final class Networking: NSObject { + // MARK: Lifecycle + + override public init() { + super.init() + + videoEncoderTask = Task { + for await data in videoEncoderAnnexBAdaptor.annexBData { + try? await realtimeStreaming.send(data: data, messageType: .hevcData) + } + } + + videoDecoderTask = Task { + for await decodedSampleBuffer in videoDecoder.decodedSampleBuffers { + if let pixelBuffer = decodedSampleBuffer.imageBuffer { + for continuation in pixelBufferContinuations.values { + continuation.yield(pixelBuffer) + } + } + } + } + + receivedMessageTask = Task { + for await (data, _) in realtimeStreaming.receivedMessages { + videoDecoderAnnexBAdaptor.decode(data) + } + } + } + + public var isConnected: Bool { realtimeStreaming.isConnected } + + @ObservationIgnored public var pixelBuffers: AsyncStream { + .init { continuation in + let id = UUID() + pixelBufferContinuations[id] = continuation + continuation.onTermination = { [weak self] _ in + self?.pixelBufferContinuations[id] = nil + } + } + } + + public func attemptToReconnect() { + realtimeStreaming.attemptToReconnect() + } + + public func disconnect() { + realtimeStreaming.disconnect() + } + + public func setBitrate(_ bitrate: Int) { + videoEncoder.config.averageBitRate = bitrate + } + + public func setExpectedFrameRate(_ frameRate: Int) { + videoEncoder.config.expectedFrameRate = frameRate + } + + public func send(_ pixelBuffer: CVPixelBuffer) { + guard isConnected else { + return + } + videoEncoder.encode(pixelBuffer) + } + + public func startBrowsing() { + realtimeStreaming.startBrowsing(for: Constants.bonjourServiceTypeTCP) + } + + public func startAdvertising() { + realtimeStreaming.startListening(for: Constants.bonjourServiceTypeTCP) + } + + public func stopAdvertising() { + realtimeStreaming.stopListening() + } + + public func resetEncoder() { + videoEncoder.invalidate() + } + + // MARK: Private + + private let realtimeStreaming = RealtimeStreaming() + + private var videoEncoderTask: Task? + private var videoDecoderTask: Task? + private var receivedMessageTask: Task? + + @ObservationIgnored private lazy var videoEncoder = VideoEncoder(config: .ultraLowLatency) + @ObservationIgnored private lazy var videoEncoderAnnexBAdaptor = VideoEncoderAnnexBAdaptor( + videoEncoder: videoEncoder + ) + @ObservationIgnored private lazy var videoDecoder = VideoDecoder(config: .init()) + @ObservationIgnored private lazy var videoDecoderAnnexBAdaptor = VideoDecoderAnnexBAdaptor( + videoDecoder: videoDecoder, + codec: .hevc + ) + + @ObservationIgnored private var pixelBufferContinuations: [UUID: AsyncStream.Continuation] = [:] + @ObservationIgnored private var cancellables = Set() +} diff --git a/SpatialContinuityShared/Sources/SpatialContinuityShared/LocalVideoStreaming/README.md b/SpatialContinuityShared/Sources/SpatialContinuityShared/LocalVideoStreaming/README.md new file mode 100644 index 0000000..2734d2f --- /dev/null +++ b/SpatialContinuityShared/Sources/SpatialContinuityShared/LocalVideoStreaming/README.md @@ -0,0 +1 @@ +The video streaming code in `SpatialContinuityShared` is based on the [LocalVideoStreaming](https://github.com/finnvoor/LocalVideoStreaming) package by @finnvoor, which was released under the CC0 license. diff --git a/SpatialContinuityShared/Sources/SpatialContinuityShared/LocalVideoStreaming/README.md.license b/SpatialContinuityShared/Sources/SpatialContinuityShared/LocalVideoStreaming/README.md.license new file mode 100644 index 0000000..eb38c65 --- /dev/null +++ b/SpatialContinuityShared/Sources/SpatialContinuityShared/LocalVideoStreaming/README.md.license @@ -0,0 +1,5 @@ +This source file is part of the Spatial Continuity project + +SPDX-FileCopyrightText: 2025 Stanford University and the project authors (see CONTRIBUTORS.md) + +SPDX-License-Identifier: MIT diff --git a/SpatialContinuityShared/Sources/SpatialContinuityShared/LocalVideoStreaming/RealtimeStreaming/RealtimeStreaming/Extensions/NWParameters+Extensions.swift b/SpatialContinuityShared/Sources/SpatialContinuityShared/LocalVideoStreaming/RealtimeStreaming/RealtimeStreaming/Extensions/NWParameters+Extensions.swift new file mode 100644 index 0000000..d2d0d9c --- /dev/null +++ b/SpatialContinuityShared/Sources/SpatialContinuityShared/LocalVideoStreaming/RealtimeStreaming/RealtimeStreaming/Extensions/NWParameters+Extensions.swift @@ -0,0 +1,26 @@ +// +// This source file is part of the Spatial Continuity project +// +// SPDX-FileCopyrightText: 2025 Stanford University and the project authors (see CONTRIBUTORS.md) +// +// SPDX-License-Identifier: MIT +// + +import Network + +extension NWParameters { + static var castaway: NWParameters { + let options = NWProtocolTCP.Options() + options.enableKeepalive = true + options.keepaliveIdle = 2 + options.keepaliveCount = 2 + options.keepaliveInterval = 2 + options.connectionTimeout = 5 + options.noDelay = true + let parameters = NWParameters(tls: nil, tcp: options) + parameters.serviceClass = .interactiveVideo + let tlvFramer = NWProtocolFramer.Options(definition: TLVFramingProtocol.definition) + parameters.defaultProtocolStack.applicationProtocols.insert(tlvFramer, at: 0) + return parameters + } +} diff --git a/SpatialContinuityShared/Sources/SpatialContinuityShared/LocalVideoStreaming/RealtimeStreaming/RealtimeStreaming/Extensions/NWProtocolFramer.Message+Extensions.swift b/SpatialContinuityShared/Sources/SpatialContinuityShared/LocalVideoStreaming/RealtimeStreaming/RealtimeStreaming/Extensions/NWProtocolFramer.Message+Extensions.swift new file mode 100644 index 0000000..5bb4372 --- /dev/null +++ b/SpatialContinuityShared/Sources/SpatialContinuityShared/LocalVideoStreaming/RealtimeStreaming/RealtimeStreaming/Extensions/NWProtocolFramer.Message+Extensions.swift @@ -0,0 +1,20 @@ +// +// This source file is part of the Spatial Continuity project +// +// SPDX-FileCopyrightText: 2025 Stanford University and the project authors (see CONTRIBUTORS.md) +// +// SPDX-License-Identifier: MIT +// + +import Network + +extension NWProtocolFramer.Message { + var messageType: MessageType? { + self["messageType"] as? MessageType + } + + convenience init(messageType: MessageType) { + self.init(definition: TLVFramingProtocol.definition) + self["messageType"] = messageType + } +} diff --git a/SpatialContinuityShared/Sources/SpatialContinuityShared/LocalVideoStreaming/RealtimeStreaming/RealtimeStreaming/MessageType.swift b/SpatialContinuityShared/Sources/SpatialContinuityShared/LocalVideoStreaming/RealtimeStreaming/RealtimeStreaming/MessageType.swift new file mode 100644 index 0000000..af4bcf1 --- /dev/null +++ b/SpatialContinuityShared/Sources/SpatialContinuityShared/LocalVideoStreaming/RealtimeStreaming/RealtimeStreaming/MessageType.swift @@ -0,0 +1,14 @@ +// +// This source file is part of the Spatial Continuity project +// +// SPDX-FileCopyrightText: 2025 Stanford University and the project authors (see CONTRIBUTORS.md) +// +// SPDX-License-Identifier: MIT +// + +import Foundation + +public enum MessageType: UInt32 { + case unknown + case hevcData +} diff --git a/SpatialContinuityShared/Sources/SpatialContinuityShared/LocalVideoStreaming/RealtimeStreaming/RealtimeStreaming/RealtimeStreaming.swift b/SpatialContinuityShared/Sources/SpatialContinuityShared/LocalVideoStreaming/RealtimeStreaming/RealtimeStreaming/RealtimeStreaming.swift new file mode 100644 index 0000000..9078dfe --- /dev/null +++ b/SpatialContinuityShared/Sources/SpatialContinuityShared/LocalVideoStreaming/RealtimeStreaming/RealtimeStreaming/RealtimeStreaming.swift @@ -0,0 +1,210 @@ +// +// This source file is part of the Spatial Continuity project +// +// SPDX-FileCopyrightText: 2025 Stanford University and the project authors (see CONTRIBUTORS.md) +// +// SPDX-License-Identifier: MIT +// + +import Foundation +import Network + +@Observable public final class RealtimeStreaming { + // MARK: Lifecycle + + public init() {} + + // MARK: Public + + public var isConnected = false + + public var receivedMessages: AsyncStream<(Data, MessageType)> { + .init { continuation in + let id = UUID() + continuations[id] = continuation + continuation.onTermination = { [weak self] _ in + self?.continuations[id] = nil + } + } + } + + public func attemptToReconnect() { + browserResultsFound(browser?.browseResults ?? []) + } + + public func disconnect() { + connection?.cancel() + } + + public func startBrowsing(for serviceType: String) { + guard browser?.state != .ready else { + return + } + print("Starting browsing") + browser?.cancel() + browser = NWBrowser(for: .bonjour(type: serviceType, domain: nil), using: .castaway) + browser?.stateUpdateHandler = { [weak self] state in + print("Browser chaged to state: \(state)") + guard let self else { + return + } + switch state { + case .ready: + browserResultsFound(browser?.browseResults ?? []) + case let .failed(error): + print("Browsing failed with error: \(error)") + if case let .dns(error) = error, error == kDNSServiceErr_DefunctConnection { + startBrowsing(for: serviceType) + } + default: break + } + } + browser?.browseResultsChangedHandler = { [weak self] _, _ in + self?.browserResultsFound(self?.browser?.browseResults ?? []) + } + browser?.start(queue: browserQueue) + } + + public func startListening(for serviceType: String) { + guard listener?.state != .ready else { + return + } + print("Starting listening") + listener?.cancel() + listener = try? NWListener( + service: .init(type: serviceType), + using: .castaway + ) + listener?.stateUpdateHandler = { [weak self] state in + guard let self else { + return + } + print("Listener chaged to state: \(state)") + switch state { + case let .failed(error): + print("Listening failed with error: \(error)") + if case let .dns(error) = error, error == kDNSServiceErr_DefunctConnection { + startListening(for: serviceType) + } + default: break + } + } + listener?.newConnectionHandler = { [weak self] connection in + guard self?.connection?.state != .ready else { + return + } + self?.startConnection(connection) + } + listener?.start(queue: listenerQueue) + } + + public func stopListening() { + listener?.cancel() + } + + public func send(data: Data, messageType: MessageType) async throws { + guard let connection else { + return + } + + let message = NWProtocolFramer.Message(messageType: messageType) + let contentContext = NWConnection.ContentContext(identifier: "message", metadata: [message]) + + try await withCheckedThrowingContinuation { continuation in + connection.send( + content: data, + contentContext: contentContext, + isComplete: true, + completion: .contentProcessed { error in + if let error { + continuation.resume(throwing: error) + } else { + continuation.resume() + } + } + ) + } as Void + } + + // MARK: Private + + @ObservationIgnored private var browser: NWBrowser? + @ObservationIgnored private lazy var browserQueue = DispatchQueue( + label: "\(String(describing: Self.self)).browser" + ) + + @ObservationIgnored private var listener: NWListener? + @ObservationIgnored private lazy var listenerQueue = DispatchQueue( + label: "\(String(describing: Self.self)).listener" + ) + + @ObservationIgnored private lazy var connectionQueue = DispatchQueue( + label: "\(String(describing: Self.self)).connection" + ) + + @ObservationIgnored private var connection: NWConnection? + + @ObservationIgnored private var continuations: [UUID: AsyncStream<(Data, MessageType)>.Continuation] = [:] + + private func browserResultsFound(_ results: Set) { + for result in results { + print("Found endpoint \(result.endpoint) on interfaces: \(result.interfaces)") + } + guard let result = results.first, connection?.state != .ready else { + return + } + let connection = NWConnection(to: result.endpoint, using: .castaway) + startConnection(connection) + } + + private func startConnection(_ connection: NWConnection) { + print("Starting connection") + self.connection?.cancel() + self.connection = connection + connection.stateUpdateHandler = { [weak self] state in + DispatchQueue.main.async { + self?.isConnected = self?.connection?.state == .ready + } + print("Connection changed to state \(state)") + switch state { + case .ready: + self?.receiveMessage() + case let .failed(error): + print("Connection failed with error: \(error)") + default: break + } + } + connection.start(queue: connectionQueue) + } + + private func receiveMessage() { + guard let connection else { + return + } + + connection.receiveMessage { [weak self] content, contentContext, _, error in + guard let self else { + return + } + guard !(contentContext?.isFinal ?? true) else { + self.connection?.cancel() + return + } + if let message = contentContext?.protocolMetadata( + definition: TLVFramingProtocol.definition + ) as? NWProtocolFramer.Message, + let data = content { + for continuation in continuations.values { + continuation.yield((data, message.messageType ?? .unknown)) + } + } + if let error { + print("receiveMessage failed with error: \(error)") + } else { + receiveMessage() + } + } + } +} + +extension RealtimeStreaming: Sendable {} diff --git a/SpatialContinuityShared/Sources/SpatialContinuityShared/LocalVideoStreaming/RealtimeStreaming/RealtimeStreaming/TLVFramingProtocol.swift b/SpatialContinuityShared/Sources/SpatialContinuityShared/LocalVideoStreaming/RealtimeStreaming/RealtimeStreaming/TLVFramingProtocol.swift new file mode 100644 index 0000000..b64dce8 --- /dev/null +++ b/SpatialContinuityShared/Sources/SpatialContinuityShared/LocalVideoStreaming/RealtimeStreaming/RealtimeStreaming/TLVFramingProtocol.swift @@ -0,0 +1,126 @@ +// +// This source file is part of the Spatial Continuity project +// +// SPDX-FileCopyrightText: 2025 Stanford University and the project authors (see CONTRIBUTORS.md) +// +// SPDX-License-Identifier: MIT +// + +import Foundation +import Network + +// MARK: - TLVFramingProtocol + +class TLVFramingProtocol: NWProtocolFramerImplementation { + // MARK: Lifecycle + + required init(framer _: NWProtocolFramer.Instance) {} + + // MARK: Internal + + static let definition = NWProtocolFramer.Definition(implementation: TLVFramingProtocol.self) + + static var label: String { String(describing: Self.self) } + + func wakeup(framer _: NWProtocolFramer.Instance) {} + func start(framer _: NWProtocolFramer.Instance) -> NWProtocolFramer.StartResult { .ready } + func stop(framer _: NWProtocolFramer.Instance) -> Bool { true } + func cleanup(framer _: NWProtocolFramer.Instance) {} + + func handleInput(framer: NWProtocolFramer.Instance) -> Int { + while true { + var tempHeader: TLVFramingProtocol.Header? + let headerSize = TLVFramingProtocol.Header.encodedSize + let parsed = framer.parseInput( + minimumIncompleteLength: headerSize, + maximumLength: headerSize + ) { buffer, _ -> Int in + guard let buffer else { + return 0 + } + if buffer.count < headerSize { + return 0 + } + tempHeader = TLVFramingProtocol.Header(buffer) + return headerSize + } + + guard parsed, let header = tempHeader else { + return headerSize + } + + let message = NWProtocolFramer.Message(messageType: MessageType(rawValue: header.type) ?? .unknown) + + if !framer.deliverInputNoCopy(length: Int(header.length), message: message, isComplete: true) { + return 0 + } + } + } + + func handleOutput( + framer: NWProtocolFramer.Instance, + message: NWProtocolFramer.Message, + messageLength: Int, + isComplete _: Bool + ) { + let header = TLVFramingProtocol.Header( + type: message.messageType?.rawValue ?? MessageType.unknown.rawValue, + length: UInt32(messageLength) + ) + framer.writeOutput(data: header.encodedData) + do { + try framer.writeOutputNoCopy(length: messageLength) + } catch { + print("Error writing output: \(error)") + } + } +} + +// MARK: TLVFramingProtocol.Header + +extension TLVFramingProtocol { + struct Header: Codable { + // MARK: Lifecycle + + init(type: UInt32, length: UInt32) { + self.type = type + self.length = length + } + + init(_ buffer: UnsafeMutableRawBufferPointer) { + var tempType: UInt32 = 0 + var tempLength: UInt32 = 0 + withUnsafeMutableBytes(of: &tempType) { typePtr in + typePtr.copyMemory(from: UnsafeRawBufferPointer( + start: buffer.baseAddress!.advanced(by: 0), + count: MemoryLayout.size + )) + } + withUnsafeMutableBytes(of: &tempLength) { lengthPtr in + lengthPtr.copyMemory(from: UnsafeRawBufferPointer( + start: buffer.baseAddress!.advanced(by: MemoryLayout.size), + count: MemoryLayout.size + )) + } + type = tempType + length = tempLength + } + + // MARK: Internal + + static var encodedSize: Int { + MemoryLayout.size * 2 + } + + let type: UInt32 + let length: UInt32 + + var encodedData: Data { + var tempType = type + var tempLength = length + var data = Data(bytes: &tempType, count: MemoryLayout.size) + data.append(Data(bytes: &tempLength, count: MemoryLayout.size)) + return data + } + } +} diff --git a/TemplateApplication.xcodeproj/project.pbxproj b/TemplateApplication.xcodeproj/project.pbxproj deleted file mode 100644 index 250c322..0000000 --- a/TemplateApplication.xcodeproj/project.pbxproj +++ /dev/null @@ -1,828 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 56; - objects = { - -/* Begin PBXBuildFile section */ - 2F7025D12A969ACA007C36EF /* TemplateWatchApplication.app in Embed Watch Content */ = {isa = PBXBuildFile; fileRef = 2F7025C42A969AC9007C36EF /* TemplateWatchApplication.app */; platformFilter = ios; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; - 2F7025D62A969F05007C36EF /* MainView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2FC27AA42A967534004B6129 /* MainView.swift */; }; - 2F7025D72A969F05007C36EF /* TemplateApplication.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2FC27AA32A967534004B6129 /* TemplateApplication.swift */; }; - 2F7025D82A969F11007C36EF /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 371BAA6129EFAB1A00011A7C /* Assets.xcassets */; }; - 2F709F802A96836500086E61 /* TemplateApplicationUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2F709F7F2A96836500086E61 /* TemplateApplicationUITests.swift */; }; - 2FC27AA52A967534004B6129 /* TemplateApplication.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2FC27AA32A967534004B6129 /* TemplateApplication.swift */; }; - 2FC27AA62A967534004B6129 /* MainView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2FC27AA42A967534004B6129 /* MainView.swift */; }; - 2FEC3D652A9680EF0084272E /* TemplateApplicationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2FEC3D642A9680EF0084272E /* TemplateApplicationTests.swift */; }; - 371BAA6229EFAB1A00011A7C /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 371BAA6129EFAB1A00011A7C /* Assets.xcassets */; }; -/* End PBXBuildFile section */ - -/* Begin PBXContainerItemProxy section */ - 2F7025CF2A969ACA007C36EF /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 371BAA5229EFAB1900011A7C /* Project object */; - proxyType = 1; - remoteGlobalIDString = 2F7025C32A969AC9007C36EF; - remoteInfo = "TemplateWatchApplication Watch App"; - }; - 2F709F832A96836500086E61 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 371BAA5229EFAB1900011A7C /* Project object */; - proxyType = 1; - remoteGlobalIDString = 371BAA5929EFAB1900011A7C; - remoteInfo = TemplateApplication; - }; - 2FEC3D662A9680EF0084272E /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 371BAA5229EFAB1900011A7C /* Project object */; - proxyType = 1; - remoteGlobalIDString = 371BAA5929EFAB1900011A7C; - remoteInfo = TemplateApplication; - }; -/* End PBXContainerItemProxy section */ - -/* Begin PBXCopyFilesBuildPhase section */ - 2F7025D22A969ACA007C36EF /* Embed Watch Content */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = "$(CONTENTS_FOLDER_PATH)/Watch"; - dstSubfolderSpec = 16; - files = ( - 2F7025D12A969ACA007C36EF /* TemplateWatchApplication.app in Embed Watch Content */, - ); - name = "Embed Watch Content"; - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXCopyFilesBuildPhase section */ - -/* Begin PBXFileReference section */ - 2F7025C42A969AC9007C36EF /* TemplateWatchApplication.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = TemplateWatchApplication.app; sourceTree = BUILT_PRODUCTS_DIR; }; - 2F709F7D2A96836500086E61 /* TemplateApplicationUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = TemplateApplicationUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; - 2F709F7F2A96836500086E61 /* TemplateApplicationUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TemplateApplicationUITests.swift; sourceTree = ""; }; - 2FC27AA02A9673A0004B6129 /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = ""; }; - 2FC27AA22A96740E004B6129 /* MIT.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = MIT.txt; sourceTree = ""; }; - 2FC27AA32A967534004B6129 /* TemplateApplication.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TemplateApplication.swift; sourceTree = ""; }; - 2FC27AA42A967534004B6129 /* MainView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MainView.swift; sourceTree = ""; }; - 2FC27AA72A967A0E004B6129 /* watchOS Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "watchOS Info.plist"; sourceTree = ""; }; - 2FEC3D622A9680EF0084272E /* TemplateApplicationTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = TemplateApplicationTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; - 2FEC3D642A9680EF0084272E /* TemplateApplicationTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TemplateApplicationTests.swift; sourceTree = ""; }; - 2FEC3D6B2A96815E0084272E /* TemplateApplication.xctestplan */ = {isa = PBXFileReference; lastKnownFileType = text; path = TemplateApplication.xctestplan; sourceTree = ""; }; - 371BAA5A29EFAB1900011A7C /* TemplateApplication.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = TemplateApplication.app; sourceTree = BUILT_PRODUCTS_DIR; }; - 371BAA6129EFAB1A00011A7C /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - 2F7025C12A969AC9007C36EF /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 2F709F7A2A96836500086E61 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 2FEC3D5F2A9680EF0084272E /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 371BAA5729EFAB1900011A7C /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - 2F709F7E2A96836500086E61 /* TemplateApplicationUITests */ = { - isa = PBXGroup; - children = ( - 2F709F7F2A96836500086E61 /* TemplateApplicationUITests.swift */, - ); - path = TemplateApplicationUITests; - sourceTree = ""; - }; - 2FC27AA12A96740E004B6129 /* LICENSES */ = { - isa = PBXGroup; - children = ( - 2FC27AA22A96740E004B6129 /* MIT.txt */, - ); - path = LICENSES; - sourceTree = ""; - }; - 2FEC3D632A9680EF0084272E /* TemplateApplicationTests */ = { - isa = PBXGroup; - children = ( - 2FEC3D642A9680EF0084272E /* TemplateApplicationTests.swift */, - ); - path = TemplateApplicationTests; - sourceTree = ""; - }; - 371BAA5129EFAB1900011A7C = { - isa = PBXGroup; - children = ( - 2FC27AA02A9673A0004B6129 /* README.md */, - 2FEC3D6B2A96815E0084272E /* TemplateApplication.xctestplan */, - 371BAA5C29EFAB1900011A7C /* TemplateApplication */, - 2FEC3D632A9680EF0084272E /* TemplateApplicationTests */, - 2F709F7E2A96836500086E61 /* TemplateApplicationUITests */, - 371BAA5B29EFAB1900011A7C /* Products */, - 2FC27AA12A96740E004B6129 /* LICENSES */, - ); - sourceTree = ""; - }; - 371BAA5B29EFAB1900011A7C /* Products */ = { - isa = PBXGroup; - children = ( - 371BAA5A29EFAB1900011A7C /* TemplateApplication.app */, - 2FEC3D622A9680EF0084272E /* TemplateApplicationTests.xctest */, - 2F709F7D2A96836500086E61 /* TemplateApplicationUITests.xctest */, - 2F7025C42A969AC9007C36EF /* TemplateWatchApplication.app */, - ); - name = Products; - sourceTree = ""; - }; - 371BAA5C29EFAB1900011A7C /* TemplateApplication */ = { - isa = PBXGroup; - children = ( - 2FC27AA42A967534004B6129 /* MainView.swift */, - 2FC27AA32A967534004B6129 /* TemplateApplication.swift */, - 2FC27AA72A967A0E004B6129 /* watchOS Info.plist */, - 371BAA6129EFAB1A00011A7C /* Assets.xcassets */, - ); - path = TemplateApplication; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXNativeTarget section */ - 2F7025C32A969AC9007C36EF /* TemplateWatchApplication */ = { - isa = PBXNativeTarget; - buildConfigurationList = 2F7025D52A969ACA007C36EF /* Build configuration list for PBXNativeTarget "TemplateWatchApplication" */; - buildPhases = ( - 2F7025C02A969AC9007C36EF /* Sources */, - 2F7025C12A969AC9007C36EF /* Frameworks */, - 2F7025C22A969AC9007C36EF /* Resources */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = TemplateWatchApplication; - productName = "TemplateWatchApplication Watch App"; - productReference = 2F7025C42A969AC9007C36EF /* TemplateWatchApplication.app */; - productType = "com.apple.product-type.application"; - }; - 2F709F7C2A96836500086E61 /* TemplateApplicationUITests */ = { - isa = PBXNativeTarget; - buildConfigurationList = 2F709F872A96836500086E61 /* Build configuration list for PBXNativeTarget "TemplateApplicationUITests" */; - buildPhases = ( - 2F709F792A96836500086E61 /* Sources */, - 2F709F7A2A96836500086E61 /* Frameworks */, - 2F709F7B2A96836500086E61 /* Resources */, - ); - buildRules = ( - ); - dependencies = ( - 2F709F842A96836500086E61 /* PBXTargetDependency */, - ); - name = TemplateApplicationUITests; - productName = TemplateApplicationUITests; - productReference = 2F709F7D2A96836500086E61 /* TemplateApplicationUITests.xctest */; - productType = "com.apple.product-type.bundle.ui-testing"; - }; - 2FEC3D612A9680EF0084272E /* TemplateApplicationTests */ = { - isa = PBXNativeTarget; - buildConfigurationList = 2FEC3D6A2A9680EF0084272E /* Build configuration list for PBXNativeTarget "TemplateApplicationTests" */; - buildPhases = ( - 2FEC3D5E2A9680EF0084272E /* Sources */, - 2FEC3D5F2A9680EF0084272E /* Frameworks */, - 2FEC3D602A9680EF0084272E /* Resources */, - ); - buildRules = ( - ); - dependencies = ( - 2FEC3D672A9680EF0084272E /* PBXTargetDependency */, - ); - name = TemplateApplicationTests; - productName = TemplateApplicationTests; - productReference = 2FEC3D622A9680EF0084272E /* TemplateApplicationTests.xctest */; - productType = "com.apple.product-type.bundle.unit-test"; - }; - 371BAA5929EFAB1900011A7C /* TemplateApplication */ = { - isa = PBXNativeTarget; - buildConfigurationList = 371BAA6929EFAB1A00011A7C /* Build configuration list for PBXNativeTarget "TemplateApplication" */; - buildPhases = ( - 371BAA5629EFAB1900011A7C /* Sources */, - 371BAA5729EFAB1900011A7C /* Frameworks */, - 371BAA5829EFAB1900011A7C /* Resources */, - 2F7025D22A969ACA007C36EF /* Embed Watch Content */, - ); - buildRules = ( - ); - dependencies = ( - 2F310B062C13C87C003761D5 /* PBXTargetDependency */, - 2F7025D02A969ACA007C36EF /* PBXTargetDependency */, - ); - name = TemplateApplication; - productName = FlashCard; - productReference = 371BAA5A29EFAB1900011A7C /* TemplateApplication.app */; - productType = "com.apple.product-type.application"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - 371BAA5229EFAB1900011A7C /* Project object */ = { - isa = PBXProject; - attributes = { - BuildIndependentTargetsInParallel = 1; - LastSwiftUpdateCheck = 1500; - LastUpgradeCheck = 1540; - TargetAttributes = { - 2F7025C32A969AC9007C36EF = { - CreatedOnToolsVersion = 15.0; - }; - 2F709F7C2A96836500086E61 = { - CreatedOnToolsVersion = 15.0; - TestTargetID = 371BAA5929EFAB1900011A7C; - }; - 2FEC3D612A9680EF0084272E = { - CreatedOnToolsVersion = 15.0; - TestTargetID = 371BAA5929EFAB1900011A7C; - }; - 371BAA5929EFAB1900011A7C = { - CreatedOnToolsVersion = 15.0; - }; - }; - }; - buildConfigurationList = 371BAA5529EFAB1900011A7C /* Build configuration list for PBXProject "TemplateApplication" */; - compatibilityVersion = "Xcode 14.0"; - developmentRegion = en; - hasScannedForEncodings = 0; - knownRegions = ( - en, - Base, - ); - mainGroup = 371BAA5129EFAB1900011A7C; - packageReferences = ( - 2F310B042C13C873003761D5 /* XCRemoteSwiftPackageReference "SwiftLint" */, - ); - productRefGroup = 371BAA5B29EFAB1900011A7C /* Products */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - 371BAA5929EFAB1900011A7C /* TemplateApplication */, - 2F7025C32A969AC9007C36EF /* TemplateWatchApplication */, - 2FEC3D612A9680EF0084272E /* TemplateApplicationTests */, - 2F709F7C2A96836500086E61 /* TemplateApplicationUITests */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXResourcesBuildPhase section */ - 2F7025C22A969AC9007C36EF /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 2F7025D82A969F11007C36EF /* Assets.xcassets in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 2F709F7B2A96836500086E61 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 2FEC3D602A9680EF0084272E /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 371BAA5829EFAB1900011A7C /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 371BAA6229EFAB1A00011A7C /* Assets.xcassets in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXResourcesBuildPhase section */ - -/* Begin PBXSourcesBuildPhase section */ - 2F7025C02A969AC9007C36EF /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 2F7025D62A969F05007C36EF /* MainView.swift in Sources */, - 2F7025D72A969F05007C36EF /* TemplateApplication.swift in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 2F709F792A96836500086E61 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 2F709F802A96836500086E61 /* TemplateApplicationUITests.swift in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 2FEC3D5E2A9680EF0084272E /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 2FEC3D652A9680EF0084272E /* TemplateApplicationTests.swift in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 371BAA5629EFAB1900011A7C /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 2FC27AA52A967534004B6129 /* TemplateApplication.swift in Sources */, - 2FC27AA62A967534004B6129 /* MainView.swift in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin PBXTargetDependency section */ - 2F310B062C13C87C003761D5 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - productRef = 2F310B052C13C87C003761D5 /* SwiftLintBuildToolPlugin */; - }; - 2F7025D02A969ACA007C36EF /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - platformFilter = ios; - target = 2F7025C32A969AC9007C36EF /* TemplateWatchApplication */; - targetProxy = 2F7025CF2A969ACA007C36EF /* PBXContainerItemProxy */; - }; - 2F709F842A96836500086E61 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 371BAA5929EFAB1900011A7C /* TemplateApplication */; - targetProxy = 2F709F832A96836500086E61 /* PBXContainerItemProxy */; - }; - 2FEC3D672A9680EF0084272E /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 371BAA5929EFAB1900011A7C /* TemplateApplication */; - targetProxy = 2FEC3D662A9680EF0084272E /* PBXContainerItemProxy */; - }; -/* End PBXTargetDependency section */ - -/* Begin XCBuildConfiguration section */ - 2F7025D32A969ACA007C36EF /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; - ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; - CODE_SIGN_IDENTITY = "Apple Development"; - CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1; - DEVELOPMENT_TEAM = 637867499T; - ENABLE_PREVIEWS = YES; - GENERATE_INFOPLIST_FILE = NO; - INFOPLIST_FILE = "TemplateApplication/watchOS Info.plist"; - INFOPLIST_KEY_CFBundleDisplayName = TemplateWatchApplication; - INFOPLIST_KEY_UISupportedInterfaceOrientations = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown"; - INFOPLIST_KEY_WKCompanionAppBundleIdentifier = edu.stanford.templateapplication; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - ); - MARKETING_VERSION = 1.0; - PRODUCT_BUNDLE_IDENTIFIER = edu.stanford.templateapplication.watchapp; - PRODUCT_NAME = "$(TARGET_NAME)"; - PROVISIONING_PROFILE_SPECIFIER = ""; - SDKROOT = watchos; - SKIP_INSTALL = YES; - SWIFT_EMIT_LOC_STRINGS = YES; - SWIFT_VERSION = 5.0; - TARGETED_DEVICE_FAMILY = 4; - WATCHOS_DEPLOYMENT_TARGET = 10.0; - }; - name = Debug; - }; - 2F7025D42A969ACA007C36EF /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; - ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; - CODE_SIGN_IDENTITY = "Apple Development"; - "CODE_SIGN_IDENTITY[sdk=watchos*]" = "iPhone Distribution"; - CODE_SIGN_STYLE = Manual; - CURRENT_PROJECT_VERSION = 1; - DEVELOPMENT_TEAM = ""; - "DEVELOPMENT_TEAM[sdk=watchos*]" = 637867499T; - ENABLE_PREVIEWS = YES; - GENERATE_INFOPLIST_FILE = NO; - INFOPLIST_FILE = "TemplateApplication/watchOS Info.plist"; - INFOPLIST_KEY_CFBundleDisplayName = TemplateWatchApplication; - INFOPLIST_KEY_UISupportedInterfaceOrientations = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown"; - INFOPLIST_KEY_WKCompanionAppBundleIdentifier = edu.stanford.templateapplication; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - ); - MARKETING_VERSION = 1.0; - PRODUCT_BUNDLE_IDENTIFIER = edu.stanford.templateapplication.watchapp; - PRODUCT_NAME = "$(TARGET_NAME)"; - PROVISIONING_PROFILE_SPECIFIER = ""; - "PROVISIONING_PROFILE_SPECIFIER[sdk=watchos*]" = TemplateWatchApplication; - SDKROOT = watchos; - SKIP_INSTALL = YES; - SWIFT_EMIT_LOC_STRINGS = YES; - SWIFT_VERSION = 5.0; - TARGETED_DEVICE_FAMILY = 4; - VALIDATE_PRODUCT = YES; - WATCHOS_DEPLOYMENT_TARGET = 10.0; - }; - name = Release; - }; - 2F709F852A96836500086E61 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; - CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1; - DEAD_CODE_STRIPPING = YES; - DEVELOPMENT_TEAM = 637867499T; - GENERATE_INFOPLIST_FILE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 17.0; - MACOSX_DEPLOYMENT_TARGET = 14.0; - MARKETING_VERSION = 1.0; - PRODUCT_BUNDLE_IDENTIFIER = edu.stanford.templateapplication.uitests; - PRODUCT_NAME = "$(TARGET_NAME)"; - SDKROOT = auto; - SUPPORTED_PLATFORMS = "appletvos appletvsimulator iphoneos iphonesimulator macosx watchos watchsimulator xros xrsimulator"; - SUPPORTS_MACCATALYST = NO; - SWIFT_EMIT_LOC_STRINGS = NO; - SWIFT_VERSION = 5.0; - TARGETED_DEVICE_FAMILY = "1,2,3,4,7"; - TEST_TARGET_NAME = TemplateApplication; - }; - name = Debug; - }; - 2F709F862A96836500086E61 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; - CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1; - DEAD_CODE_STRIPPING = YES; - DEVELOPMENT_TEAM = 637867499T; - GENERATE_INFOPLIST_FILE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 17.0; - MACOSX_DEPLOYMENT_TARGET = 14.0; - MARKETING_VERSION = 1.0; - PRODUCT_BUNDLE_IDENTIFIER = edu.stanford.templateapplication.uitests; - PRODUCT_NAME = "$(TARGET_NAME)"; - SDKROOT = auto; - SUPPORTED_PLATFORMS = "appletvos appletvsimulator iphoneos iphonesimulator macosx watchos watchsimulator xros xrsimulator"; - SUPPORTS_MACCATALYST = NO; - SWIFT_EMIT_LOC_STRINGS = NO; - SWIFT_VERSION = 5.0; - TARGETED_DEVICE_FAMILY = "1,2,3,4,7"; - TEST_TARGET_NAME = TemplateApplication; - }; - name = Release; - }; - 2FEC3D682A9680EF0084272E /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; - BUNDLE_LOADER = "$(TEST_HOST)"; - CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1; - DEVELOPMENT_TEAM = 637867499T; - GENERATE_INFOPLIST_FILE = YES; - MARKETING_VERSION = 1.0; - PRODUCT_BUNDLE_IDENTIFIER = edu.stanford.templateapplication.tests; - PRODUCT_NAME = "$(TARGET_NAME)"; - SDKROOT = watchos; - SUPPORTED_PLATFORMS = "appletvos appletvsimulator iphoneos iphonesimulator macosx watchos watchsimulator xros xrsimulator"; - SUPPORTS_MACCATALYST = NO; - SWIFT_EMIT_LOC_STRINGS = NO; - SWIFT_VERSION = 5.0; - TARGETED_DEVICE_FAMILY = "1,2,3,4,7"; - TEST_HOST = "$(BUILT_PRODUCTS_DIR)/TemplateApplication.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/TemplateApplication"; - WATCHOS_DEPLOYMENT_TARGET = 10.0; - }; - name = Debug; - }; - 2FEC3D692A9680EF0084272E /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; - BUNDLE_LOADER = "$(TEST_HOST)"; - CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1; - DEVELOPMENT_TEAM = 637867499T; - GENERATE_INFOPLIST_FILE = YES; - MARKETING_VERSION = 1.0; - PRODUCT_BUNDLE_IDENTIFIER = edu.stanford.templateapplication.tests; - PRODUCT_NAME = "$(TARGET_NAME)"; - SDKROOT = watchos; - SUPPORTED_PLATFORMS = "appletvos appletvsimulator iphoneos iphonesimulator macosx watchos watchsimulator xros xrsimulator"; - SUPPORTS_MACCATALYST = NO; - SWIFT_EMIT_LOC_STRINGS = NO; - SWIFT_VERSION = 5.0; - TARGETED_DEVICE_FAMILY = "1,2,3,4,7"; - TEST_HOST = "$(BUILT_PRODUCTS_DIR)/TemplateApplication.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/TemplateApplication"; - VALIDATE_PRODUCT = YES; - WATCHOS_DEPLOYMENT_TARGET = 10.0; - }; - name = Release; - }; - 371BAA6729EFAB1A00011A7C /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_ENABLE_OBJC_WEAK = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - COPY_PHASE_STRIP = NO; - DEAD_CODE_STRIPPING = YES; - DEBUG_INFORMATION_FORMAT = dwarf; - ENABLE_STRICT_OBJC_MSGSEND = YES; - ENABLE_TESTABILITY = YES; - ENABLE_USER_SCRIPT_SANDBOXING = YES; - GCC_C_LANGUAGE_STANDARD = gnu17; - GCC_DYNAMIC_NO_PIC = NO; - GCC_NO_COMMON_BLOCKS = YES; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - INFOPLIST_KEY_WKApplication = YES; - LOCALIZATION_PREFERS_STRING_CATALOGS = YES; - MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; - MTL_FAST_MATH = YES; - ONLY_ACTIVE_ARCH = YES; - SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)"; - SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - }; - name = Debug; - }; - 371BAA6829EFAB1A00011A7C /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_ENABLE_OBJC_WEAK = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - COPY_PHASE_STRIP = NO; - DEAD_CODE_STRIPPING = YES; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_NS_ASSERTIONS = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - ENABLE_USER_SCRIPT_SANDBOXING = YES; - GCC_C_LANGUAGE_STANDARD = gnu17; - GCC_NO_COMMON_BLOCKS = YES; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - INFOPLIST_KEY_WKApplication = YES; - LOCALIZATION_PREFERS_STRING_CATALOGS = YES; - MTL_ENABLE_DEBUG_INFO = NO; - MTL_FAST_MATH = YES; - SWIFT_COMPILATION_MODE = wholemodule; - SWIFT_OPTIMIZATION_LEVEL = "-O"; - }; - name = Release; - }; - 371BAA6A29EFAB1A00011A7C /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; - "CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development"; - CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1; - DEVELOPMENT_TEAM = 637867499T; - ENABLE_PREVIEWS = YES; - GENERATE_INFOPLIST_FILE = YES; - "GENERATE_INFOPLIST_FILE[sdk=watchos*]" = NO; - "GENERATE_INFOPLIST_FILE[sdk=watchsimulator*]" = NO; - "INFOPLIST_FILE[sdk=watchos*]" = "TemplateApplication/watchOS Info.plist"; - "INFOPLIST_FILE[sdk=watchsimulator*]" = "TemplateApplication/watchOS Info.plist"; - INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES; - INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; - INFOPLIST_KEY_UILaunchScreen_Generation = YES; - INFOPLIST_KEY_UIStatusBarStyle = UIStatusBarStyleDefault; - INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; - INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; - LD_RUNPATH_SEARCH_PATHS = "@executable_path/../Frameworks"; - MARKETING_VERSION = 1.0; - PRODUCT_BUNDLE_IDENTIFIER = edu.stanford.templateapplication; - "PRODUCT_BUNDLE_IDENTIFIER[sdk=watchos*]" = edu.stanford.templateapplication.watchapp; - "PRODUCT_BUNDLE_IDENTIFIER[sdk=watchsimulator*]" = edu.stanford.templateapplication.watchapp; - PRODUCT_NAME = "$(TARGET_NAME)"; - PROVISIONING_PROFILE_SPECIFIER = ""; - SDKROOT = iphoneos; - SUPPORTED_PLATFORMS = "appletvos appletvsimulator iphoneos iphonesimulator macosx watchos watchsimulator xros xrsimulator"; - SUPPORTS_MACCATALYST = NO; - SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO; - SWIFT_EMIT_LOC_STRINGS = YES; - SWIFT_VERSION = 5.0; - TARGETED_DEVICE_FAMILY = "1,2,3,4,7"; - }; - name = Debug; - }; - 371BAA6B29EFAB1A00011A7C /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; - CODE_SIGN_IDENTITY = "Apple Development"; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; - "CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Distribution"; - "CODE_SIGN_IDENTITY[sdk=watchos*]" = "iPhone Distribution"; - "CODE_SIGN_IDENTITY[sdk=xros*]" = "iPhone Distribution"; - CODE_SIGN_STYLE = Manual; - CURRENT_PROJECT_VERSION = 1; - DEVELOPMENT_TEAM = 637867499T; - "DEVELOPMENT_TEAM[sdk=iphoneos*]" = 637867499T; - "DEVELOPMENT_TEAM[sdk=watchos*]" = 637867499T; - ENABLE_PREVIEWS = YES; - GENERATE_INFOPLIST_FILE = YES; - "GENERATE_INFOPLIST_FILE[sdk=watchos*]" = NO; - "GENERATE_INFOPLIST_FILE[sdk=watchsimulator*]" = NO; - "INFOPLIST_FILE[sdk=watchos*]" = "TemplateApplication/watchOS Info.plist"; - "INFOPLIST_FILE[sdk=watchsimulator*]" = TemplateApplication/Info.plist; - INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES; - INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; - INFOPLIST_KEY_UILaunchScreen_Generation = YES; - INFOPLIST_KEY_UIStatusBarStyle = UIStatusBarStyleDefault; - INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; - INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; - LD_RUNPATH_SEARCH_PATHS = "@executable_path/../Frameworks"; - MARKETING_VERSION = 1.0; - PRODUCT_BUNDLE_IDENTIFIER = edu.stanford.templateapplication; - "PRODUCT_BUNDLE_IDENTIFIER[sdk=watchos*]" = edu.stanford.templateapplication.watchapp; - "PRODUCT_BUNDLE_IDENTIFIER[sdk=watchsimulator*]" = edu.stanford.templateapplication.watchapp; - PRODUCT_NAME = "$(TARGET_NAME)"; - PROVISIONING_PROFILE_SPECIFIER = ""; - "PROVISIONING_PROFILE_SPECIFIER[sdk=appletvos*]" = ""; - "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = TemplateApplication; - "PROVISIONING_PROFILE_SPECIFIER[sdk=watchos*]" = TemplateWatchApplication; - "PROVISIONING_PROFILE_SPECIFIER[sdk=xros*]" = TemplateApplication; - SDKROOT = iphoneos; - SUPPORTED_PLATFORMS = "appletvos appletvsimulator iphoneos iphonesimulator macosx watchos watchsimulator xros xrsimulator"; - SUPPORTS_MACCATALYST = NO; - SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO; - SWIFT_EMIT_LOC_STRINGS = YES; - SWIFT_VERSION = 5.0; - TARGETED_DEVICE_FAMILY = "1,2,3,4,7"; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - 2F7025D52A969ACA007C36EF /* Build configuration list for PBXNativeTarget "TemplateWatchApplication" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 2F7025D32A969ACA007C36EF /* Debug */, - 2F7025D42A969ACA007C36EF /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 2F709F872A96836500086E61 /* Build configuration list for PBXNativeTarget "TemplateApplicationUITests" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 2F709F852A96836500086E61 /* Debug */, - 2F709F862A96836500086E61 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 2FEC3D6A2A9680EF0084272E /* Build configuration list for PBXNativeTarget "TemplateApplicationTests" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 2FEC3D682A9680EF0084272E /* Debug */, - 2FEC3D692A9680EF0084272E /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 371BAA5529EFAB1900011A7C /* Build configuration list for PBXProject "TemplateApplication" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 371BAA6729EFAB1A00011A7C /* Debug */, - 371BAA6829EFAB1A00011A7C /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 371BAA6929EFAB1A00011A7C /* Build configuration list for PBXNativeTarget "TemplateApplication" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 371BAA6A29EFAB1A00011A7C /* Debug */, - 371BAA6B29EFAB1A00011A7C /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - -/* Begin XCRemoteSwiftPackageReference section */ - 2F310B042C13C873003761D5 /* XCRemoteSwiftPackageReference "SwiftLint" */ = { - isa = XCRemoteSwiftPackageReference; - repositoryURL = "https://github.com/realm/SwiftLint.git"; - requirement = { - kind = upToNextMajorVersion; - minimumVersion = 0.55.1; - }; - }; -/* End XCRemoteSwiftPackageReference section */ - -/* Begin XCSwiftPackageProductDependency section */ - 2F310B052C13C87C003761D5 /* SwiftLintBuildToolPlugin */ = { - isa = XCSwiftPackageProductDependency; - package = 2F310B042C13C873003761D5 /* XCRemoteSwiftPackageReference "SwiftLint" */; - productName = "plugin:SwiftLintBuildToolPlugin"; - }; -/* End XCSwiftPackageProductDependency section */ - }; - rootObject = 371BAA5229EFAB1900011A7C /* Project object */; -} diff --git a/TemplateApplication.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/TemplateApplication.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved deleted file mode 100644 index 98a5a5c..0000000 --- a/TemplateApplication.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ /dev/null @@ -1,87 +0,0 @@ -{ - "originHash" : "7a2c9b4bb42c2221bb642dfc27b6e8a478d63cd04f52d3e2819330e24f9fb63f", - "pins" : [ - { - "identity" : "collectionconcurrencykit", - "kind" : "remoteSourceControl", - "location" : "https://github.com/JohnSundell/CollectionConcurrencyKit.git", - "state" : { - "revision" : "b4f23e24b5a1bff301efc5e70871083ca029ff95", - "version" : "0.2.0" - } - }, - { - "identity" : "cryptoswift", - "kind" : "remoteSourceControl", - "location" : "https://github.com/krzyzanowskim/CryptoSwift.git", - "state" : { - "revision" : "c9c3df6ab812de32bae61fc0cd1bf6d45170ebf0", - "version" : "1.8.2" - } - }, - { - "identity" : "sourcekitten", - "kind" : "remoteSourceControl", - "location" : "https://github.com/jpsim/SourceKitten.git", - "state" : { - "revision" : "fd4df99170f5e9d7cf9aa8312aa8506e0e7a44e7", - "version" : "0.35.0" - } - }, - { - "identity" : "swift-argument-parser", - "kind" : "remoteSourceControl", - "location" : "https://github.com/apple/swift-argument-parser.git", - "state" : { - "revision" : "0fbc8848e389af3bb55c182bc19ca9d5dc2f255b", - "version" : "1.4.0" - } - }, - { - "identity" : "swift-syntax", - "kind" : "remoteSourceControl", - "location" : "https://github.com/apple/swift-syntax.git", - "state" : { - "revision" : "303e5c5c36d6a558407d364878df131c3546fad8", - "version" : "510.0.2" - } - }, - { - "identity" : "swiftlint", - "kind" : "remoteSourceControl", - "location" : "https://github.com/realm/SwiftLint.git", - "state" : { - "revision" : "b515723b16eba33f15c4677ee65f3fef2ce8c255", - "version" : "0.55.1" - } - }, - { - "identity" : "swiftytexttable", - "kind" : "remoteSourceControl", - "location" : "https://github.com/scottrhoyt/SwiftyTextTable.git", - "state" : { - "revision" : "c6df6cf533d120716bff38f8ff9885e1ce2a4ac3", - "version" : "0.9.0" - } - }, - { - "identity" : "swxmlhash", - "kind" : "remoteSourceControl", - "location" : "https://github.com/drmohundro/SWXMLHash.git", - "state" : { - "revision" : "a853604c9e9a83ad9954c7e3d2a565273982471f", - "version" : "7.0.2" - } - }, - { - "identity" : "yams", - "kind" : "remoteSourceControl", - "location" : "https://github.com/jpsim/Yams.git", - "state" : { - "revision" : "9234124cff5e22e178988c18d8b95a8ae8007f76", - "version" : "5.1.2" - } - } - ], - "version" : 3 -} diff --git a/TemplateApplication.xctestplan b/TemplateApplication.xctestplan deleted file mode 100644 index 36663b7..0000000 --- a/TemplateApplication.xctestplan +++ /dev/null @@ -1,35 +0,0 @@ -{ - "configurations" : [ - { - "id" : "1E991C0E-B189-4B4F-BB18-7B4CC0662A64", - "name" : "Default", - "options" : { - - } - } - ], - "defaultOptions" : { - "targetForVariableExpansion" : { - "containerPath" : "container:TemplateApplication.xcodeproj", - "identifier" : "371BAA5929EFAB1900011A7C", - "name" : "TemplateApplication" - } - }, - "testTargets" : [ - { - "target" : { - "containerPath" : "container:TemplateApplication.xcodeproj", - "identifier" : "2FEC3D612A9680EF0084272E", - "name" : "TemplateApplicationTests" - } - }, - { - "target" : { - "containerPath" : "container:TemplateApplication.xcodeproj", - "identifier" : "2F709F7C2A96836500086E61", - "name" : "TemplateApplicationUITests" - } - } - ], - "version" : 1 -} diff --git a/TemplateApplication.xctestplan.license b/TemplateApplication.xctestplan.license deleted file mode 100644 index 2e5548d..0000000 --- a/TemplateApplication.xctestplan.license +++ /dev/null @@ -1,6 +0,0 @@ - -This source file is part of the StanfordBDHG Template Application project - -SPDX-FileCopyrightText: 2023 Stanford University - -SPDX-License-Identifier: MIT diff --git a/TemplateApplication/Assets.xcassets/AccentColor.colorset/Contents.json.license b/TemplateApplication/Assets.xcassets/AccentColor.colorset/Contents.json.license deleted file mode 100644 index 2e5548d..0000000 --- a/TemplateApplication/Assets.xcassets/AccentColor.colorset/Contents.json.license +++ /dev/null @@ -1,6 +0,0 @@ - -This source file is part of the StanfordBDHG Template Application project - -SPDX-FileCopyrightText: 2023 Stanford University - -SPDX-License-Identifier: MIT diff --git a/TemplateApplication/Assets.xcassets/AppIcon.appiconset/1024.png b/TemplateApplication/Assets.xcassets/AppIcon.appiconset/1024.png deleted file mode 100644 index 7414dd9..0000000 Binary files a/TemplateApplication/Assets.xcassets/AppIcon.appiconset/1024.png and /dev/null differ diff --git a/TemplateApplication/Assets.xcassets/AppIcon.appiconset/1024.png.license b/TemplateApplication/Assets.xcassets/AppIcon.appiconset/1024.png.license deleted file mode 100644 index 2e5548d..0000000 --- a/TemplateApplication/Assets.xcassets/AppIcon.appiconset/1024.png.license +++ /dev/null @@ -1,6 +0,0 @@ - -This source file is part of the StanfordBDHG Template Application project - -SPDX-FileCopyrightText: 2023 Stanford University - -SPDX-License-Identifier: MIT diff --git a/TemplateApplication/Assets.xcassets/AppIcon.appiconset/Contents.json.license b/TemplateApplication/Assets.xcassets/AppIcon.appiconset/Contents.json.license deleted file mode 100644 index 2e5548d..0000000 --- a/TemplateApplication/Assets.xcassets/AppIcon.appiconset/Contents.json.license +++ /dev/null @@ -1,6 +0,0 @@ - -This source file is part of the StanfordBDHG Template Application project - -SPDX-FileCopyrightText: 2023 Stanford University - -SPDX-License-Identifier: MIT diff --git a/TemplateApplication/Assets.xcassets/Contents.json.license b/TemplateApplication/Assets.xcassets/Contents.json.license deleted file mode 100644 index 2e5548d..0000000 --- a/TemplateApplication/Assets.xcassets/Contents.json.license +++ /dev/null @@ -1,6 +0,0 @@ - -This source file is part of the StanfordBDHG Template Application project - -SPDX-FileCopyrightText: 2023 Stanford University - -SPDX-License-Identifier: MIT diff --git a/TemplateApplication/MainView.swift b/TemplateApplication/MainView.swift deleted file mode 100644 index e1fc159..0000000 --- a/TemplateApplication/MainView.swift +++ /dev/null @@ -1,31 +0,0 @@ -// -// This source file is part of the StanfordBDHG Template Application project -// -// SPDX-FileCopyrightText: 2023 Stanford University -// -// SPDX-License-Identifier: MIT -// - -import SwiftUI - - -struct MainView: View { - var body: some View { - VStack { - Image(systemName: "hand.wave.fill") - .accessibilityLabel(Text("Hand waving")) - .font(.system(size: 100)) - .foregroundColor(.accentColor) - .padding() - Text("Welcome to the Template Application!") - .bold() - } - } -} - - -#if swift(>=5.9) -#Preview { - MainView() -} -#endif diff --git a/TemplateApplication/TemplateApplication.swift b/TemplateApplication/TemplateApplication.swift deleted file mode 100644 index 97e2abe..0000000 --- a/TemplateApplication/TemplateApplication.swift +++ /dev/null @@ -1,19 +0,0 @@ -// -// This source file is part of the StanfordBDHG Template Application project -// -// SPDX-FileCopyrightText: 2023 Stanford University -// -// SPDX-License-Identifier: MIT -// - -import SwiftUI - - -@main -struct TemplateApplication: App { - var body: some Scene { - WindowGroup { - MainView() - } - } -} diff --git a/TemplateApplication/watchOS Info.plist b/TemplateApplication/watchOS Info.plist deleted file mode 100644 index eb1ff19..0000000 --- a/TemplateApplication/watchOS Info.plist +++ /dev/null @@ -1,40 +0,0 @@ - - - - - CFBundleDevelopmentRegion - $(DEVELOPMENT_LANGUAGE) - CFBundleExecutable - $(EXECUTABLE_NAME) - CFBundleIdentifier - $(PRODUCT_BUNDLE_IDENTIFIER) - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - $(PRODUCT_NAME) - CFBundlePackageType - $(PRODUCT_BUNDLE_PACKAGE_TYPE) - CFBundleShortVersionString - $(MARKETING_VERSION) - CFBundleVersion - $(CURRENT_PROJECT_VERSION) - UIApplicationSceneManifest - - UIApplicationSupportsMultipleScenes - - UISceneConfigurations - - - UILaunchScreen - - UILaunchScreen - - - WKApplication - - WKCompanionAppBundleIdentifier - edu.stanford.templateapplication - WKRunsIndependentlyOfCompanionApp - - - diff --git a/TemplateApplication/watchOS Info.plist.license b/TemplateApplication/watchOS Info.plist.license deleted file mode 100644 index 2e5548d..0000000 --- a/TemplateApplication/watchOS Info.plist.license +++ /dev/null @@ -1,6 +0,0 @@ - -This source file is part of the StanfordBDHG Template Application project - -SPDX-FileCopyrightText: 2023 Stanford University - -SPDX-License-Identifier: MIT diff --git a/TemplateApplicationTests/TemplateApplicationTests.swift b/TemplateApplicationTests/TemplateApplicationTests.swift deleted file mode 100644 index 5dc17c3..0000000 --- a/TemplateApplicationTests/TemplateApplicationTests.swift +++ /dev/null @@ -1,16 +0,0 @@ -// -// This source file is part of the StanfordBDHG Template Application project -// -// SPDX-FileCopyrightText: 2023 Stanford University -// -// SPDX-License-Identifier: MIT -// - -import XCTest - - -class TemplateApplicationTests: XCTestCase { - func testExample() throws { - XCTAssertTrue(true) - } -} diff --git a/TemplateApplicationUITests/TemplateApplicationUITests.swift b/TemplateApplicationUITests/TemplateApplicationUITests.swift deleted file mode 100644 index 4a77645..0000000 --- a/TemplateApplicationUITests/TemplateApplicationUITests.swift +++ /dev/null @@ -1,22 +0,0 @@ -// -// This source file is part of the StanfordBDHG Template Application project -// -// SPDX-FileCopyrightText: 2023 Stanford University -// -// SPDX-License-Identifier: MIT -// - -import XCTest - - -class TemplateApplicationUITests: XCTestCase { - override func setUpWithError() throws { - try super.setUpWithError() - continueAfterFailure = false - } - - func testGreeting() throws { - let app = XCUIApplication() - app.launch() - } -} diff --git a/codecov.yml b/codecov.yml deleted file mode 100644 index 8cde096..0000000 --- a/codecov.yml +++ /dev/null @@ -1,11 +0,0 @@ -# -# This source file is part of the StanfordBDHG Template Application project -# -# SPDX-FileCopyrightText: 2023 Stanford University -# -# SPDX-License-Identifier: MIT -# - -ignore: -- TemplateApplicationUITests -- TemplateApplicationTests diff --git a/fastlane/Appfile b/fastlane/Appfile index 8537ee0..ecefe40 100644 --- a/fastlane/Appfile +++ b/fastlane/Appfile @@ -9,5 +9,11 @@ # For more information about the Appfile, see: # https://docs.fastlane.tools/advanced/#appfile -app_identifier "edu.stanford.templateapplication" # The bundle identifier of your app -apple_id ENV["APPLE_ID"] # Your Apple email address \ No newline at end of file +apple_id ENV["APPLE_ID"] # Your Apple email address +for_platform :ios do + app_identifier 'edu.stanford.spatialcontinuitycamera' +end + +for_platform :visionos do + app_identifier 'edu.stanford.spatialcontinuity' +end diff --git a/fastlane/ExportOptions.plist b/fastlane/ExportOptions.plist index 95d8310..4d3eb98 100644 --- a/fastlane/ExportOptions.plist +++ b/fastlane/ExportOptions.plist @@ -6,10 +6,8 @@ app-store provisioningProfiles - edu.stanford.templateapplication - TemplateApplication - edu.stanford.templateapplication.watchapp - TemplateWatchApplication + edu.stanford.spatialcontinuitycamera + SpatialContinuityCamera signingCertificate Apple Distribution: Paul Schmiedmayer (637867499T) diff --git a/fastlane/ExportOptions.plist.license b/fastlane/ExportOptions.plist.license index 2e5548d..89a5df1 100644 --- a/fastlane/ExportOptions.plist.license +++ b/fastlane/ExportOptions.plist.license @@ -1,6 +1,6 @@ -This source file is part of the StanfordBDHG Template Application project +This source file is part of the Spatial Continuity project -SPDX-FileCopyrightText: 2023 Stanford University +SPDX-FileCopyrightText: 2025 Stanford University and the project authors (see CONTRIBUTORS.md) SPDX-License-Identifier: MIT diff --git a/fastlane/Fastfile b/fastlane/Fastfile index 3de03cc..9985faa 100644 --- a/fastlane/Fastfile +++ b/fastlane/Fastfile @@ -1,13 +1,10 @@ # -# This source file is part of the StanfordBDHG Template Application project +# This source file is part of the Spatial Continuity project # -# SPDX-FileCopyrightText: 2023 Stanford University +# SPDX-FileCopyrightText: 2025 Stanford University and the project authors (see CONTRIBUTORS.md) # # SPDX-License-Identifier: MIT # - -default_platform(:ios) - platform :ios do before_all do ENV["FASTLANE_XCODEBUILD_SETTINGS_TIMEOUT"] = "5" @@ -17,46 +14,18 @@ platform :ios do desc "Build and test" lane :test do test_iphone - test_ipad - test_apple_watch - test_apple_tv - test_vision_pro - test_macos end desc "Build and test for iPhone" lane :test_iphone do - private_test(devices: ["iPhone 15 Pro"], result: "iphone") - end - - desc "Build and test for iPad" - lane :test_ipad do - private_test(devices: ["iPad mini (6th generation)"], result: "ipad") - end - - desc "Build and test for Apple Watch" - lane :test_apple_watch do - private_test(devices: ["Apple Watch Series 8 (45mm)"], result: "apple_watch") - end - - desc "Build and test for Apple TV" - lane :test_apple_tv do - private_test(devices: ["Apple TV 4K (3rd generation)"], result: "apple_tv") - end - - desc "Build and test for Vision Pro" - lane :test_vision_pro do - private_test(devices: ["Apple Vision Pro"], result: "vision_pro") - end - - desc "Build and test for macOS" - lane :test_macos do - private_test(devices: ["My Mac"], result: "macos", destination: "platform=macOS") + private_test_scc(devices: ["iPhone 15 Pro"], result: "iphone") end - desc "Internal build and test lane" - private_lane :private_test do |options| + desc "Internal build and test lane for Spatial Continuity Camera" + private_lane :private_test_scc do |options| run_tests( + project: "SpatialContinuity.xcodeproj", + scheme: "SpatialContinuityCamera", skip_build: true, derived_data_path: ".derivedData", xcargs: [ @@ -73,13 +42,16 @@ platform :ios do destination: options[:destination], result_bundle: true, output_directory: ".", - result_bundle_path: "./#{options[:result]}.xcresult" + result_bundle_path: "./#{options[:result]}.xcresult", + build_for_testing: true ) end - desc "CodeQL" - lane :codeql do + desc "CodeQL Spatial Continuity Camera" + lane :codeql_scc do build_app( + project: "SpatialContinuity.xcodeproj", + scheme: "SpatialContinuityCamera", skip_archive: true, skip_codesigning: true, derived_data_path: ".derivedData", @@ -91,8 +63,10 @@ platform :ios do end desc "Build app" - lane :build do + lane :build_scc do build_app( + project: "SpatialContinuity.xcodeproj", + scheme: "SpatialContinuityCamera", derived_data_path: ".derivedData", xcargs: [ "-skipPackagePluginValidation", @@ -100,7 +74,7 @@ platform :ios do ], destination: "generic/platform=iOS", output_directory: ".build", - archive_path: ".build/TemplateApplication.xcarchive", + archive_path: ".build/SpatialContinuityCamera.xcarchive", ) # This is an unfortunate workaround for a bug in fastlane: https://github.com/fastlane/fastlane/pull/21319 Dir.chdir("..") do @@ -109,43 +83,96 @@ platform :ios do xcodebuild \ -exportArchive \ -exportOptionsPlist ./fastlane/ExportOptions.plist \ - -archivePath ./.build/TemplateApplication.xcarchive \ + -archivePath ./.build/SpatialContinuityCamera.xcarchive \ -exportPath ./.build " ) end end +end + +platform :visionos do + before_all do + ENV["FASTLANE_XCODEBUILD_SETTINGS_TIMEOUT"] = "5" + ENV["FASTLANE_XCODEBUILD_SETTINGS_RETRIES"] = "6" + end + + desc "Build and test" + lane :test do + test_vision_pro + end + + desc "Build and test for Vision Pro" + lane :test_vision_pro do + private_test_sc(devices: ["Apple Vision Pro"], result: "vision_pro") + end - desc "Sign in to the App Store Connect API" - lane :signin do - app_store_connect_api_key( - key_id: ENV["APP_STORE_CONNECT_API_KEY_ID"], - issuer_id: ENV["APP_STORE_CONNECT_ISSUER_ID"], - key_content: ENV["APP_STORE_CONNECT_API_KEY_BASE64"], - is_key_content_base64: true + desc "Internal build and test lane for Spatial Continuity" + private_lane :private_test_sc do |options| + run_tests( + project: "SpatialContinuity.xcodeproj", + scheme: "SpatialContinuity", + skip_build: true, + derived_data_path: ".derivedData", + xcargs: [ + "-skipPackagePluginValidation", + "-skipMacroValidation" + ], + code_coverage: true, + devices: options[:devices], + force_quit_simulator: true, + reset_simulator: true, + prelaunch_simulator: false, + concurrent_workers: 1, + max_concurrent_simulators: 1, + destination: options[:destination], + result_bundle: true, + output_directory: ".", + result_bundle_path: "./#{options[:result]}.xcresult", + build_for_testing: true ) end - desc "Publish a beta release to internal TestFlight testers" - lane :beta do - signin - increment_build_number( - { - build_number: latest_testflight_build_number + 1 - } + desc "CodeQL Spatial Continuity" + lane :codeql_sc do + build_app( + project: "SpatialContinuity.xcodeproj", + scheme: "SpatialContinuity", + skip_archive: true, + skip_codesigning: true, + derived_data_path: ".derivedData", + xcargs: [ + "-skipPackagePluginValidation", + "-skipMacroValidation" + ] ) - build - commit = last_git_commit - upload_to_testflight( - ipa: "./.build/TemplateApplication.ipa", - distribute_external: true, - groups: [ - "External Testers" + end + + desc "Build Spatial Continuity" + lane :build_sc do + build_app( + project: "SpatialContinuity.xcodeproj", + scheme: "SpatialContinuity", + derived_data_path: ".derivedData", + xcargs: [ + "-skipPackagePluginValidation", + "-skipMacroValidation" ], - submit_beta_review: true, - notify_external_testers: true, - expire_previous_builds: true, - changelog: commit[:message] + destination: "generic/platform=visionOS", + output_directory: ".build", + archive_path: ".build/SpatialContinuity.xcarchive", ) + # This is an unfortunate workaround for a bug in fastlane: https://github.com/fastlane/fastlane/pull/21319 + Dir.chdir("..") do + sh( + " + xcodebuild \ + -exportArchive \ + -exportOptionsPlist ./fastlane/ExportOptions.plist \ + -archivePath ./.build/SpatialContinuity.xcarchive \ + -exportPath ./.build + " + ) + end end end