diff --git a/.github/workflows/build-xcframework.yml b/.github/workflows/build-xcframework.yml index fef508f0..9fa8023b 100644 --- a/.github/workflows/build-xcframework.yml +++ b/.github/workflows/build-xcframework.yml @@ -11,8 +11,8 @@ jobs: steps: - name: Checkout code - uses: actions/checkout@v2 + uses: actions/checkout@v4 - name: Xcode select run: sudo xcode-select -s '/Applications/Xcode_15.4.app/Contents/Developer' - - name: Build xcframework - run: sh build.sh + - name: Build xcframeworks + run: bash build.sh diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 7338cf03..318a21d6 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -15,7 +15,7 @@ jobs: - name: Xcode select run: sudo xcode-select -s '/Applications/Xcode_15.4.app/Contents/Developer' - name: Build TestApp - run: cd Examples && xcodebuild build -scheme DemoApp -sdk iphonesimulator -destination 'generic/platform=iOS Simulator' -project DemoApp/DemoApp.xcodeproj + run: cd Examples && xcodebuild build -scheme DemoApp -destination 'generic/platform=iOS Simulator' -project DemoApp/DemoApp.xcodeproj - name: Build Snapshotting run: xcodebuild build -scheme Snapshotting -sdk iphonesimulator -destination 'generic/platform=iOS Simulator' - name: Build SnapshottingTests diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 0549022b..1003128d 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -11,25 +11,24 @@ jobs: steps: - name: Checkout code - uses: actions/checkout@v2 + uses: actions/checkout@v4 - name: Xcode select run: sudo xcode-select -s '/Applications/Xcode_15.4.app/Contents/Developer' - - name: Build xcframework - run: sh build.sh - - name: Zip SnapshottingTests xcframework - run: zip -r SnapshottingTests.xcframework.zip SnapshottingTests.xcframework - - name: Zip PreviewGallery xcframework - run: zip -r PreviewGallery.xcframework.zip PreviewGallery.xcframework - - name: Zip preivews support - run: (cd PreviewsSupport && zip -r PreviewsSupport.xcframework.zip PreviewsSupport.xcframework) + - name: Build xcframeworks + run: bash build.sh + - name: Zip xcframeworks + run: | + rm -f *.xcframework.zip + for framework_path in XCFrameworks/*.xcframework + do + framework="$(basename "$framework_path")" + (cd XCFrameworks && zip -r "../$framework.zip" "$framework") + done - name: Upload Artifact - uses: softprops/action-gh-release@v1 + uses: softprops/action-gh-release@de2c0eb89ae2a093876385947365aca7b0e5f844 if: startsWith(github.ref, 'refs/tags/') with: - files: | - PreviewGallery.xcframework.zip - SnapshottingTests.xcframework.zip - PreviewsSupport/PreviewsSupport.xcframework.zip + files: "*.xcframework.zip" body: Release ${{ github.ref }} Automated release created by GitHub Actions. \ No newline at end of file diff --git a/.gitignore b/.gitignore index 85b601d5..39fedaae 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,7 @@ .DS_Store +/build/ +/Package.resolved +/XCFrameworks/ /.build /Packages xcuserdata/ diff --git a/Examples/DemoApp-XCFrameworks/DemoApp-XCFrameworks.xcodeproj/project.pbxproj b/Examples/DemoApp-XCFrameworks/DemoApp-XCFrameworks.xcodeproj/project.pbxproj new file mode 100644 index 00000000..58ee9729 --- /dev/null +++ b/Examples/DemoApp-XCFrameworks/DemoApp-XCFrameworks.xcodeproj/project.pbxproj @@ -0,0 +1,1433 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 56; + objects = { + +/* Begin PBXBuildFile section */ + 8B2B491A2FD01D8B003221F3 /* SnapshottingTests.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8B2B49172FD01D81003221F3 /* SnapshottingTests.xcframework */; }; + 8B2B491B2FD01D8B003221F3 /* SnapshottingTests.xcframework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 8B2B49172FD01D81003221F3 /* SnapshottingTests.xcframework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 8B2B491C2FD01D94003221F3 /* PreviewGallery.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8B2B49122FD01D81003221F3 /* PreviewGallery.xcframework */; }; + 8B2B491D2FD01D94003221F3 /* PreviewGallery.xcframework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 8B2B49122FD01D81003221F3 /* PreviewGallery.xcframework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 8B2B491F2FD01D9F003221F3 /* SnapshottingTests.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8B2B49172FD01D81003221F3 /* SnapshottingTests.xcframework */; }; + 8B2B49202FD01D9F003221F3 /* SnapshottingTests.xcframework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 8B2B49172FD01D81003221F3 /* SnapshottingTests.xcframework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 8B2B49222FD01DAA003221F3 /* SnapshottingTests.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8B2B49172FD01D81003221F3 /* SnapshottingTests.xcframework */; }; + 8B2B49232FD01DAA003221F3 /* SnapshottingTests.xcframework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 8B2B49172FD01D81003221F3 /* SnapshottingTests.xcframework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 8B2B49252FD01DB3003221F3 /* SnapshotPreferences.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8B2B49132FD01D81003221F3 /* SnapshotPreferences.xcframework */; }; + 8B2B49282FD01DBD003221F3 /* PreviewGallery.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8B2B49122FD01D81003221F3 /* PreviewGallery.xcframework */; }; + 8B2B49292FD01DBD003221F3 /* PreviewGallery.xcframework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 8B2B49122FD01D81003221F3 /* PreviewGallery.xcframework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 8B2B492A2FD01DC1003221F3 /* SnapshotPreferences.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8B2B49132FD01D81003221F3 /* SnapshotPreferences.xcframework */; }; + 8B2B492B2FD01DC1003221F3 /* SnapshotPreferences.xcframework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 8B2B49132FD01D81003221F3 /* SnapshotPreferences.xcframework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 8B2B492C2FD01E1C003221F3 /* SnapshotPreviewsCore.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8B2B49142FD01D81003221F3 /* SnapshotPreviewsCore.xcframework */; }; + 8B2B492D2FD01E1C003221F3 /* SnapshotPreviewsCore.xcframework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 8B2B49142FD01D81003221F3 /* SnapshotPreviewsCore.xcframework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 8B2B492E2FD01E23003221F3 /* SnapshotSharedModels.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8B2B49152FD01D81003221F3 /* SnapshotSharedModels.xcframework */; }; + 8B2B492F2FD01E23003221F3 /* SnapshotSharedModels.xcframework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 8B2B49152FD01D81003221F3 /* SnapshotSharedModels.xcframework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 8B2B49312FD01E8B003221F3 /* PreviewsSupport.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8B2B49302FD01E8B003221F3 /* PreviewsSupport.xcframework */; }; + 8B2B49322FD01EC1003221F3 /* SnapshotSharedModels.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8B2B49152FD01D81003221F3 /* SnapshotSharedModels.xcframework */; }; + 8B2B49342FD01EDD003221F3 /* PreviewsSupport.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8B2B49302FD01E8B003221F3 /* PreviewsSupport.xcframework */; }; + 8B2B49352FD01EDD003221F3 /* PreviewsSupport.xcframework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 8B2B49302FD01E8B003221F3 /* PreviewsSupport.xcframework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 8B2B49362FD01EDD003221F3 /* SnapshotPreferences.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8B2B49132FD01D81003221F3 /* SnapshotPreferences.xcframework */; }; + 8B2B49372FD01EDD003221F3 /* SnapshotPreferences.xcframework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 8B2B49132FD01D81003221F3 /* SnapshotPreferences.xcframework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 8B2B49382FD01EDD003221F3 /* SnapshotPreviewsCore.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8B2B49142FD01D81003221F3 /* SnapshotPreviewsCore.xcframework */; }; + 8B2B49392FD01EDD003221F3 /* SnapshotPreviewsCore.xcframework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 8B2B49142FD01D81003221F3 /* SnapshotPreviewsCore.xcframework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 8B2B493A2FD01EDD003221F3 /* SnapshotSharedModels.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8B2B49152FD01D81003221F3 /* SnapshotSharedModels.xcframework */; }; + 8B2B493B2FD01EDD003221F3 /* SnapshotSharedModels.xcframework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 8B2B49152FD01D81003221F3 /* SnapshotSharedModels.xcframework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 8B2B493C2FD01F1B003221F3 /* PreviewsSupport.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8B2B49302FD01E8B003221F3 /* PreviewsSupport.xcframework */; }; + 8B2B493D2FD01F1B003221F3 /* PreviewsSupport.xcframework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 8B2B49302FD01E8B003221F3 /* PreviewsSupport.xcframework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 8B2B493E2FD01F1B003221F3 /* SnapshotPreviewsCore.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8B2B49142FD01D81003221F3 /* SnapshotPreviewsCore.xcframework */; }; + 8B2B493F2FD01F1B003221F3 /* SnapshotPreviewsCore.xcframework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 8B2B49142FD01D81003221F3 /* SnapshotPreviewsCore.xcframework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 8B2B49402FD01F1B003221F3 /* SnapshotSharedModels.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8B2B49152FD01D81003221F3 /* SnapshotSharedModels.xcframework */; }; + 8B2B49412FD01F1B003221F3 /* SnapshotSharedModels.xcframework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 8B2B49152FD01D81003221F3 /* SnapshotSharedModels.xcframework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 8B2B49422FD01F30003221F3 /* PreviewsSupport.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8B2B49302FD01E8B003221F3 /* PreviewsSupport.xcframework */; }; + 8B2B49432FD01F30003221F3 /* PreviewsSupport.xcframework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 8B2B49302FD01E8B003221F3 /* PreviewsSupport.xcframework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 8B2B49442FD01F30003221F3 /* SnapshotPreviewsCore.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8B2B49142FD01D81003221F3 /* SnapshotPreviewsCore.xcframework */; }; + 8B2B49452FD01F30003221F3 /* SnapshotPreviewsCore.xcframework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 8B2B49142FD01D81003221F3 /* SnapshotPreviewsCore.xcframework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 8B2B49462FD01F30003221F3 /* SnapshotSharedModels.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8B2B49152FD01D81003221F3 /* SnapshotSharedModels.xcframework */; }; + 8B2B49472FD01F30003221F3 /* SnapshotSharedModels.xcframework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 8B2B49152FD01D81003221F3 /* SnapshotSharedModels.xcframework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 8B2B49482FD01F3A003221F3 /* PreviewsSupport.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8B2B49302FD01E8B003221F3 /* PreviewsSupport.xcframework */; }; + 8B2B49492FD01F3A003221F3 /* PreviewsSupport.xcframework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 8B2B49302FD01E8B003221F3 /* PreviewsSupport.xcframework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 8B2B494A2FD01F3A003221F3 /* SnapshotPreviewsCore.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8B2B49142FD01D81003221F3 /* SnapshotPreviewsCore.xcframework */; }; + 8B2B494B2FD01F3A003221F3 /* SnapshotPreviewsCore.xcframework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 8B2B49142FD01D81003221F3 /* SnapshotPreviewsCore.xcframework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 8B2B494C2FD01F3A003221F3 /* SnapshotSharedModels.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8B2B49152FD01D81003221F3 /* SnapshotSharedModels.xcframework */; }; + 8B2B494D2FD01F3A003221F3 /* SnapshotSharedModels.xcframework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 8B2B49152FD01D81003221F3 /* SnapshotSharedModels.xcframework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 8B2B494E2FD09E01003221F3 /* PreviewsSupport.xcframework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 8B2B49302FD01E8B003221F3 /* PreviewsSupport.xcframework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 8B2B494F2FD0A000003221F3 /* Snapshotting.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8B2B49162FD01D81003221F3 /* Snapshotting.xcframework */; }; + 8B2B49502FD0A000003221F3 /* Snapshotting.xcframework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 8B2B49162FD01D81003221F3 /* Snapshotting.xcframework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + FA0B20F12A7DA20200EC91D3 /* AnyViewPreview.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA0B20F02A7DA20200EC91D3 /* AnyViewPreview.swift */; }; + FA0B20FA2A7DCB0100EC91D3 /* ArrayBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA0B20F82A7DCB0100EC91D3 /* ArrayBuilder.swift */; }; + FA0B20FB2A7DCB0100EC91D3 /* PreviewVariants.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA0B20F92A7DCB0100EC91D3 /* PreviewVariants.swift */; }; + FA13B8F02B3E8BAB00F58836 /* DateView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA13B8EE2B3E8B3300F58836 /* DateView.swift */; }; + FA1671C32A5367A800A42DB0 /* DemoAppApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA1671C22A5367A800A42DB0 /* DemoAppApp.swift */; }; + FA1671C52A5367A800A42DB0 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA1671C42A5367A800A42DB0 /* ContentView.swift */; }; + FA1671C72A5367A800A42DB0 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = FA1671C62A5367A800A42DB0 /* Assets.xcassets */; }; + FA1671CB2A5367A800A42DB0 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = FA1671CA2A5367A800A42DB0 /* Preview Assets.xcassets */; }; + FA1671DA2A5399F700A42DB0 /* DemoModule.h in Headers */ = {isa = PBXBuildFile; fileRef = FA1671D92A5399F700A42DB0 /* DemoModule.h */; settings = {ATTRIBUTES = (Public, ); }; }; + FA1671DE2A5399F700A42DB0 /* DemoModule.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = FA1671D72A5399F700A42DB0 /* DemoModule.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + FA1671E42A539A0500A42DB0 /* RowView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA1671E32A539A0500A42DB0 /* RowView.swift */; }; + FA1671E62A539CCF00A42DB0 /* ButtonView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA1671E52A539CCF00A42DB0 /* ButtonView.swift */; }; + FA1671E82A539EA900A42DB0 /* ProductCard.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA1671E72A539EA900A42DB0 /* ProductCard.swift */; }; + FA1671EA2A539F6E00A42DB0 /* RatingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA1671E92A539F6E00A42DB0 /* RatingView.swift */; }; + FA1671F32A53A0AA00A42DB0 /* InfoCardView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA1671F22A53A0AA00A42DB0 /* InfoCardView.swift */; }; + FA1671F52A53A0E100A42DB0 /* FeatureCardView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA1671F42A53A0E100A42DB0 /* FeatureCardView.swift */; }; + FA1671F72A53A15200A42DB0 /* TripCardView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA1671F62A53A15200A42DB0 /* TripCardView.swift */; }; + FA1671F92A53DBF200A42DB0 /* HomeMapView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA1671F82A53DBF200A42DB0 /* HomeMapView.swift */; }; + FA1671FB2A53E03800A42DB0 /* MessageRow.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA1671FA2A53E03800A42DB0 /* MessageRow.swift */; }; + FA1671FD2A53E11E00A42DB0 /* MessageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA1671FC2A53E11E00A42DB0 /* MessageView.swift */; }; + FA1671FF2A53E1AF00A42DB0 /* ConversationMessageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA1671FE2A53E1AF00A42DB0 /* ConversationMessageView.swift */; }; + FA1E452E2ADF3C3D002C85DB /* UIViewPreviews.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA1E452D2ADF3C3D002C85DB /* UIViewPreviews.swift */; }; + FA309EC32C38D71C00C85FF4 /* DemoApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA309EC22C38D71C00C85FF4 /* DemoApp.swift */; }; + FA309EC52C38D71C00C85FF4 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA309EC42C38D71C00C85FF4 /* ContentView.swift */; }; + FA309EC72C38D71D00C85FF4 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = FA309EC62C38D71D00C85FF4 /* Assets.xcassets */; }; + FA309ECA2C38D71D00C85FF4 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = FA309EC92C38D71D00C85FF4 /* Preview Assets.xcassets */; }; + FA309ECD2C38D71D00C85FF4 /* Demo Watch App.app in Embed Watch Content */ = {isa = PBXBuildFile; fileRef = FA309EC02C38D71C00C85FF4 /* Demo Watch App.app */; platformFilter = ios; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; + FA309EE72C38EB9B00C85FF4 /* DemoWatchAccessibilityPreviewTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA309ED82C38D77C00C85FF4 /* DemoWatchAccessibilityPreviewTest.swift */; }; + FA40515D2A95B587007A66D4 /* EmptyView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA40515C2A95B587007A66D4 /* EmptyView.swift */; }; + FA5E82972A96448A008DE3F0 /* StateView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA5E82962A96448A008DE3F0 /* StateView.swift */; }; + FA8F8B7E2C66C4C4007CEA33 /* DemoAppPreviewTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA8F8B7D2C66C4C4007CEA33 /* DemoAppPreviewTest.swift */; }; + FA9C8E442A56959300DC4574 /* RatingPreviews.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA9C8E432A56959300DC4574 /* RatingPreviews.swift */; }; + FAA4F4CF2B271D9C00127B63 /* Color.swift in Sources */ = {isa = PBXBuildFile; fileRef = FAA4F4CE2B271D9C00127B63 /* Color.swift */; }; + FABCCD932AC39081008F4D3A /* EMGTestHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = FABCCD922AC39081008F4D3A /* EMGTestHandler.swift */; }; + FAC912372C894B6E00459191 /* OSVersionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FAC912362C894B6E00459191 /* OSVersionView.swift */; }; + FACA23792A55FBEE0080545A /* DemoModule.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA1671D72A5399F700A42DB0 /* DemoModule.framework */; }; + FACBADA32C67B8D60012D600 /* DemoWatchPreviewTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = FACBADA22C67B8D60012D600 /* DemoWatchPreviewTest.swift */; }; + FACBADAC2C67B9A50012D600 /* DemoWatchSnapshotTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = FACBADAB2C67B9A50012D600 /* DemoWatchSnapshotTest.swift */; }; + FAD0107B2AA29ABA007D1AF6 /* TextView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FAD0107A2AA29ABA007D1AF6 /* TextView.swift */; }; + FAD52BF62A7B5EEA001F1832 /* ExpandingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FAD52BF12A7B5EEA001F1832 /* ExpandingView.swift */; }; + FAD52BF72A7B5EEA001F1832 /* CodeEntryView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FAD52BF22A7B5EEA001F1832 /* CodeEntryView.swift */; }; + FAD52BF82A7B5EEA001F1832 /* RideDetailView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FAD52BF32A7B5EEA001F1832 /* RideDetailView.swift */; }; + FAD52BF92A7B5EEA001F1832 /* RideShareButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = FAD52BF42A7B5EEA001F1832 /* RideShareButton.swift */; }; + FAD52BFA2A7B5EEA001F1832 /* RideOptionsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FAD52BF52A7B5EEA001F1832 /* RideOptionsView.swift */; }; + FADB112C2C67A17500985C48 /* DemoAppSnapshotTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = FADB112B2C67A17500985C48 /* DemoAppSnapshotTest.swift */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + FA1671DB2A5399F700A42DB0 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = FA1671B72A5367A800A42DB0 /* Project object */; + proxyType = 1; + remoteGlobalIDString = FA1671D62A5399F700A42DB0; + remoteInfo = DemoModule; + }; + FA309ECB2C38D71D00C85FF4 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = FA1671B72A5367A800A42DB0 /* Project object */; + proxyType = 1; + remoteGlobalIDString = FA309EBF2C38D71C00C85FF4; + remoteInfo = "Demo Watch App"; + }; + FA309EDC2C38D77C00C85FF4 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = FA1671B72A5367A800A42DB0 /* Project object */; + proxyType = 1; + remoteGlobalIDString = FA309EBF2C38D71C00C85FF4; + remoteInfo = "Demo Watch App"; + }; + FA8F8B7F2C66C4C4007CEA33 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = FA1671B72A5367A800A42DB0 /* Project object */; + proxyType = 1; + remoteGlobalIDString = FA1671BE2A5367A800A42DB0; + remoteInfo = DemoApp; + }; + FACBADA42C67B8D60012D600 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = FA1671B72A5367A800A42DB0 /* Project object */; + proxyType = 1; + remoteGlobalIDString = FA309EBF2C38D71C00C85FF4; + remoteInfo = "Demo Watch App"; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 8B2B491E2FD01D94003221F3 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + 8B2B49372FD01EDD003221F3 /* SnapshotPreferences.xcframework in Embed Frameworks */, + 8B2B49352FD01EDD003221F3 /* PreviewsSupport.xcframework in Embed Frameworks */, + 8B2B49392FD01EDD003221F3 /* SnapshotPreviewsCore.xcframework in Embed Frameworks */, + 8B2B491D2FD01D94003221F3 /* PreviewGallery.xcframework in Embed Frameworks */, + 8B2B493B2FD01EDD003221F3 /* SnapshotSharedModels.xcframework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; + 8B2B49212FD01D9F003221F3 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + 8B2B49472FD01F30003221F3 /* SnapshotSharedModels.xcframework in Embed Frameworks */, + 8B2B49452FD01F30003221F3 /* SnapshotPreviewsCore.xcframework in Embed Frameworks */, + 8B2B49432FD01F30003221F3 /* PreviewsSupport.xcframework in Embed Frameworks */, + 8B2B49202FD01D9F003221F3 /* SnapshottingTests.xcframework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; + 8B2B49242FD01DAA003221F3 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + 8B2B494D2FD01F3A003221F3 /* SnapshotSharedModels.xcframework in Embed Frameworks */, + 8B2B494B2FD01F3A003221F3 /* SnapshotPreviewsCore.xcframework in Embed Frameworks */, + 8B2B49492FD01F3A003221F3 /* PreviewsSupport.xcframework in Embed Frameworks */, + 8B2B49232FD01DAA003221F3 /* SnapshottingTests.xcframework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; + FA1671E22A5399F700A42DB0 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + 8B2B492B2FD01DC1003221F3 /* SnapshotPreferences.xcframework in Embed Frameworks */, + FA1671DE2A5399F700A42DB0 /* DemoModule.framework in Embed Frameworks */, + 8B2B494E2FD09E01003221F3 /* PreviewsSupport.xcframework in Embed Frameworks */, + 8B2B492D2FD01E1C003221F3 /* SnapshotPreviewsCore.xcframework in Embed Frameworks */, + 8B2B49292FD01DBD003221F3 /* PreviewGallery.xcframework in Embed Frameworks */, + 8B2B492F2FD01E23003221F3 /* SnapshotSharedModels.xcframework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; + FA309ECE2C38D71D00C85FF4 /* Embed Watch Content */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = "$(CONTENTS_FOLDER_PATH)/Watch"; + dstSubfolderSpec = 16; + files = ( + FA309ECD2C38D71D00C85FF4 /* Demo Watch App.app in Embed Watch Content */, + ); + name = "Embed Watch Content"; + runOnlyForDeploymentPostprocessing = 0; + }; + FA309EE42C38D7A900C85FF4 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + 8B2B49502FD0A000003221F3 /* Snapshotting.xcframework in Embed Frameworks */, + 8B2B491B2FD01D8B003221F3 /* SnapshottingTests.xcframework in Embed Frameworks */, + 8B2B493D2FD01F1B003221F3 /* PreviewsSupport.xcframework in Embed Frameworks */, + 8B2B493F2FD01F1B003221F3 /* SnapshotPreviewsCore.xcframework in Embed Frameworks */, + 8B2B49412FD01F1B003221F3 /* SnapshotSharedModels.xcframework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 8B2B49122FD01D81003221F3 /* PreviewGallery.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = PreviewGallery.xcframework; path = ../../XCFrameworks/PreviewGallery.xcframework; sourceTree = ""; }; + 8B2B49132FD01D81003221F3 /* SnapshotPreferences.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = SnapshotPreferences.xcframework; path = ../../XCFrameworks/SnapshotPreferences.xcframework; sourceTree = ""; }; + 8B2B49142FD01D81003221F3 /* SnapshotPreviewsCore.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = SnapshotPreviewsCore.xcframework; path = ../../XCFrameworks/SnapshotPreviewsCore.xcframework; sourceTree = ""; }; + 8B2B49152FD01D81003221F3 /* SnapshotSharedModels.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = SnapshotSharedModels.xcframework; path = ../../XCFrameworks/SnapshotSharedModels.xcframework; sourceTree = ""; }; + 8B2B49162FD01D81003221F3 /* Snapshotting.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = Snapshotting.xcframework; path = ../../XCFrameworks/Snapshotting.xcframework; sourceTree = ""; }; + 8B2B49172FD01D81003221F3 /* SnapshottingTests.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = SnapshottingTests.xcframework; path = ../../XCFrameworks/SnapshottingTests.xcframework; sourceTree = ""; }; + 8B2B49302FD01E8B003221F3 /* PreviewsSupport.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = PreviewsSupport.xcframework; path = ../../XCFrameworks/PreviewsSupport.xcframework; sourceTree = ""; }; + C39F81522C6ABB7A004C7D57 /* DemoAppTests.xctestplan */ = {isa = PBXFileReference; lastKnownFileType = text; path = DemoAppTests.xctestplan; sourceTree = ""; }; + FA0B20F02A7DA20200EC91D3 /* AnyViewPreview.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnyViewPreview.swift; sourceTree = ""; }; + FA0B20F82A7DCB0100EC91D3 /* ArrayBuilder.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ArrayBuilder.swift; sourceTree = ""; }; + FA0B20F92A7DCB0100EC91D3 /* PreviewVariants.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PreviewVariants.swift; sourceTree = ""; }; + FA13B8EE2B3E8B3300F58836 /* DateView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DateView.swift; sourceTree = ""; }; + FA1671BF2A5367A800A42DB0 /* DemoApp.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = DemoApp.app; sourceTree = BUILT_PRODUCTS_DIR; }; + FA1671C22A5367A800A42DB0 /* DemoAppApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DemoAppApp.swift; sourceTree = ""; }; + FA1671C42A5367A800A42DB0 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = ""; }; + FA1671C62A5367A800A42DB0 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + FA1671C82A5367A800A42DB0 /* DemoApp.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = DemoApp.entitlements; sourceTree = ""; }; + FA1671CA2A5367A800A42DB0 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; }; + FA1671D72A5399F700A42DB0 /* DemoModule.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = DemoModule.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + FA1671D92A5399F700A42DB0 /* DemoModule.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DemoModule.h; sourceTree = ""; }; + FA1671E32A539A0500A42DB0 /* RowView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RowView.swift; sourceTree = ""; }; + FA1671E52A539CCF00A42DB0 /* ButtonView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ButtonView.swift; sourceTree = ""; }; + FA1671E72A539EA900A42DB0 /* ProductCard.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProductCard.swift; sourceTree = ""; }; + FA1671E92A539F6E00A42DB0 /* RatingView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RatingView.swift; sourceTree = ""; }; + FA1671F22A53A0AA00A42DB0 /* InfoCardView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InfoCardView.swift; sourceTree = ""; }; + FA1671F42A53A0E100A42DB0 /* FeatureCardView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FeatureCardView.swift; sourceTree = ""; }; + FA1671F62A53A15200A42DB0 /* TripCardView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TripCardView.swift; sourceTree = ""; }; + FA1671F82A53DBF200A42DB0 /* HomeMapView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeMapView.swift; sourceTree = ""; }; + FA1671FA2A53E03800A42DB0 /* MessageRow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageRow.swift; sourceTree = ""; }; + FA1671FC2A53E11E00A42DB0 /* MessageView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageView.swift; sourceTree = ""; }; + FA1671FE2A53E1AF00A42DB0 /* ConversationMessageView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConversationMessageView.swift; sourceTree = ""; }; + FA1E452D2ADF3C3D002C85DB /* UIViewPreviews.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIViewPreviews.swift; sourceTree = ""; }; + FA309EC02C38D71C00C85FF4 /* Demo Watch App.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Demo Watch App.app"; sourceTree = BUILT_PRODUCTS_DIR; }; + FA309EC22C38D71C00C85FF4 /* DemoApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DemoApp.swift; sourceTree = ""; }; + FA309EC42C38D71C00C85FF4 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = ""; }; + FA309EC62C38D71D00C85FF4 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + FA309EC92C38D71D00C85FF4 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; }; + FA309ED62C38D77C00C85FF4 /* DemoWatchTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = DemoWatchTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + FA309ED82C38D77C00C85FF4 /* DemoWatchAccessibilityPreviewTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DemoWatchAccessibilityPreviewTest.swift; sourceTree = ""; }; + FA40515C2A95B587007A66D4 /* EmptyView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmptyView.swift; sourceTree = ""; }; + FA44246E2AAA5B27005BFCD9 /* DemoApp.xctestplan */ = {isa = PBXFileReference; lastKnownFileType = text; path = DemoApp.xctestplan; sourceTree = ""; }; + FA5E82962A96448A008DE3F0 /* StateView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StateView.swift; sourceTree = ""; }; + FA8F8B7B2C66C4C4007CEA33 /* DemoAppTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = DemoAppTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + FA8F8B7D2C66C4C4007CEA33 /* DemoAppPreviewTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DemoAppPreviewTest.swift; sourceTree = ""; }; + FA9C8E432A56959300DC4574 /* RatingPreviews.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RatingPreviews.swift; sourceTree = ""; }; + FAA4F4CE2B271D9C00127B63 /* Color.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Color.swift; sourceTree = ""; }; + FABCCD922AC39081008F4D3A /* EMGTestHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EMGTestHandler.swift; sourceTree = ""; }; + FAC912362C894B6E00459191 /* OSVersionView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OSVersionView.swift; sourceTree = ""; }; + FACA23752A55FB970080545A /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Platforms/MacOSX.platform/Developer/Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; }; + FACBADA02C67B8D60012D600 /* Demo Watch AppTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "Demo Watch AppTests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; + FACBADA22C67B8D60012D600 /* DemoWatchPreviewTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DemoWatchPreviewTest.swift; sourceTree = ""; }; + FACBADAB2C67B9A50012D600 /* DemoWatchSnapshotTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DemoWatchSnapshotTest.swift; sourceTree = ""; }; + FAD0107A2AA29ABA007D1AF6 /* TextView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextView.swift; sourceTree = ""; }; + FAD52BF12A7B5EEA001F1832 /* ExpandingView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ExpandingView.swift; sourceTree = ""; }; + FAD52BF22A7B5EEA001F1832 /* CodeEntryView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CodeEntryView.swift; sourceTree = ""; }; + FAD52BF32A7B5EEA001F1832 /* RideDetailView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RideDetailView.swift; sourceTree = ""; }; + FAD52BF42A7B5EEA001F1832 /* RideShareButton.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RideShareButton.swift; sourceTree = ""; }; + FAD52BF52A7B5EEA001F1832 /* RideOptionsView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RideOptionsView.swift; sourceTree = ""; }; + FADB112B2C67A17500985C48 /* DemoAppSnapshotTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DemoAppSnapshotTest.swift; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + FA1671BC2A5367A800A42DB0 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 8B2B492A2FD01DC1003221F3 /* SnapshotPreferences.xcframework in Frameworks */, + 8B2B49282FD01DBD003221F3 /* PreviewGallery.xcframework in Frameworks */, + 8B2B492C2FD01E1C003221F3 /* SnapshotPreviewsCore.xcframework in Frameworks */, + FACA23792A55FBEE0080545A /* DemoModule.framework in Frameworks */, + 8B2B49312FD01E8B003221F3 /* PreviewsSupport.xcframework in Frameworks */, + 8B2B492E2FD01E23003221F3 /* SnapshotSharedModels.xcframework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + FA1671D42A5399F700A42DB0 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 8B2B49322FD01EC1003221F3 /* SnapshotSharedModels.xcframework in Frameworks */, + 8B2B49252FD01DB3003221F3 /* SnapshotPreferences.xcframework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + FA309EBD2C38D71C00C85FF4 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 8B2B49362FD01EDD003221F3 /* SnapshotPreferences.xcframework in Frameworks */, + 8B2B49342FD01EDD003221F3 /* PreviewsSupport.xcframework in Frameworks */, + 8B2B49382FD01EDD003221F3 /* SnapshotPreviewsCore.xcframework in Frameworks */, + 8B2B491C2FD01D94003221F3 /* PreviewGallery.xcframework in Frameworks */, + 8B2B493A2FD01EDD003221F3 /* SnapshotSharedModels.xcframework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + FA309ED32C38D77C00C85FF4 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 8B2B494F2FD0A000003221F3 /* Snapshotting.xcframework in Frameworks */, + 8B2B491A2FD01D8B003221F3 /* SnapshottingTests.xcframework in Frameworks */, + 8B2B493C2FD01F1B003221F3 /* PreviewsSupport.xcframework in Frameworks */, + 8B2B493E2FD01F1B003221F3 /* SnapshotPreviewsCore.xcframework in Frameworks */, + 8B2B49402FD01F1B003221F3 /* SnapshotSharedModels.xcframework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + FA8F8B782C66C4C4007CEA33 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 8B2B49462FD01F30003221F3 /* SnapshotSharedModels.xcframework in Frameworks */, + 8B2B49442FD01F30003221F3 /* SnapshotPreviewsCore.xcframework in Frameworks */, + 8B2B49422FD01F30003221F3 /* PreviewsSupport.xcframework in Frameworks */, + 8B2B491F2FD01D9F003221F3 /* SnapshottingTests.xcframework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + FACBAD9D2C67B8D60012D600 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 8B2B494C2FD01F3A003221F3 /* SnapshotSharedModels.xcframework in Frameworks */, + 8B2B494A2FD01F3A003221F3 /* SnapshotPreviewsCore.xcframework in Frameworks */, + 8B2B49482FD01F3A003221F3 /* PreviewsSupport.xcframework in Frameworks */, + 8B2B49222FD01DAA003221F3 /* SnapshottingTests.xcframework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + FA1671B62A5367A800A42DB0 = { + isa = PBXGroup; + children = ( + C39F81522C6ABB7A004C7D57 /* DemoAppTests.xctestplan */, + FA44246E2AAA5B27005BFCD9 /* DemoApp.xctestplan */, + FA1671C12A5367A800A42DB0 /* ../DemoApp/DemoApp */, + FA1671D82A5399F700A42DB0 /* ../DemoApp/DemoModule */, + FA309EC12C38D71C00C85FF4 /* ../DemoApp/Demo Watch App */, + FA309ED72C38D77C00C85FF4 /* ../DemoApp/DemoWatchTests */, + FA8F8B7C2C66C4C4007CEA33 /* ../DemoApp/DemoAppTests */, + FACBADA12C67B8D60012D600 /* ../DemoApp/Demo Watch AppTests */, + FA1671C02A5367A800A42DB0 /* Products */, + FA6E72BD2A54944800448463 /* Frameworks */, + ); + sourceTree = ""; + }; + FA1671C02A5367A800A42DB0 /* Products */ = { + isa = PBXGroup; + children = ( + FA1671BF2A5367A800A42DB0 /* DemoApp.app */, + FA1671D72A5399F700A42DB0 /* DemoModule.framework */, + FA309EC02C38D71C00C85FF4 /* Demo Watch App.app */, + FA309ED62C38D77C00C85FF4 /* DemoWatchTests.xctest */, + FA8F8B7B2C66C4C4007CEA33 /* DemoAppTests.xctest */, + FACBADA02C67B8D60012D600 /* Demo Watch AppTests.xctest */, + ); + name = Products; + sourceTree = ""; + }; + FA1671C12A5367A800A42DB0 /* ../DemoApp/DemoApp */ = { + isa = PBXGroup; + children = ( + FA1671C22A5367A800A42DB0 /* DemoAppApp.swift */, + FABCCD922AC39081008F4D3A /* EMGTestHandler.swift */, + FA1671C42A5367A800A42DB0 /* ContentView.swift */, + FAD52BF02A7B5EBB001F1832 /* TestViews */, + FA1671C62A5367A800A42DB0 /* Assets.xcassets */, + FA1671C82A5367A800A42DB0 /* DemoApp.entitlements */, + FA1671C92A5367A800A42DB0 /* Preview Content */, + ); + path = ../DemoApp/DemoApp; + sourceTree = ""; + }; + FA1671C92A5367A800A42DB0 /* Preview Content */ = { + isa = PBXGroup; + children = ( + FA1671CA2A5367A800A42DB0 /* Preview Assets.xcassets */, + ); + path = "Preview Content"; + sourceTree = ""; + }; + FA1671D82A5399F700A42DB0 /* ../DemoApp/DemoModule */ = { + isa = PBXGroup; + children = ( + FA1671D92A5399F700A42DB0 /* DemoModule.h */, + FA1671E32A539A0500A42DB0 /* RowView.swift */, + FAA4F4CE2B271D9C00127B63 /* Color.swift */, + FA1671E72A539EA900A42DB0 /* ProductCard.swift */, + FA1671E52A539CCF00A42DB0 /* ButtonView.swift */, + FA1671E92A539F6E00A42DB0 /* RatingView.swift */, + FA9C8E432A56959300DC4574 /* RatingPreviews.swift */, + FA1671F22A53A0AA00A42DB0 /* InfoCardView.swift */, + FA1671F42A53A0E100A42DB0 /* FeatureCardView.swift */, + FA1671F62A53A15200A42DB0 /* TripCardView.swift */, + FA1671F82A53DBF200A42DB0 /* HomeMapView.swift */, + FA1671FA2A53E03800A42DB0 /* MessageRow.swift */, + FA1671FC2A53E11E00A42DB0 /* MessageView.swift */, + FA1671FE2A53E1AF00A42DB0 /* ConversationMessageView.swift */, + FA13B8EE2B3E8B3300F58836 /* DateView.swift */, + ); + path = ../DemoApp/DemoModule; + sourceTree = ""; + }; + FA309EC12C38D71C00C85FF4 /* ../DemoApp/Demo Watch App */ = { + isa = PBXGroup; + children = ( + FA309EC22C38D71C00C85FF4 /* DemoApp.swift */, + FA309EC42C38D71C00C85FF4 /* ContentView.swift */, + FA309EC62C38D71D00C85FF4 /* Assets.xcassets */, + FA309EC82C38D71D00C85FF4 /* Preview Content */, + ); + path = "../DemoApp/Demo Watch App"; + sourceTree = ""; + }; + FA309EC82C38D71D00C85FF4 /* Preview Content */ = { + isa = PBXGroup; + children = ( + FA309EC92C38D71D00C85FF4 /* Preview Assets.xcassets */, + ); + path = "Preview Content"; + sourceTree = ""; + }; + FA309ED72C38D77C00C85FF4 /* ../DemoApp/DemoWatchTests */ = { + isa = PBXGroup; + children = ( + FA309ED82C38D77C00C85FF4 /* DemoWatchAccessibilityPreviewTest.swift */, + ); + path = ../DemoApp/DemoWatchTests; + sourceTree = ""; + }; + FA6E72BD2A54944800448463 /* Frameworks */ = { + isa = PBXGroup; + children = ( + 8B2B49122FD01D81003221F3 /* PreviewGallery.xcframework */, + 8B2B49132FD01D81003221F3 /* SnapshotPreferences.xcframework */, + 8B2B49142FD01D81003221F3 /* SnapshotPreviewsCore.xcframework */, + 8B2B49152FD01D81003221F3 /* SnapshotSharedModels.xcframework */, + 8B2B49162FD01D81003221F3 /* Snapshotting.xcframework */, + 8B2B49172FD01D81003221F3 /* SnapshottingTests.xcframework */, + 8B2B49302FD01E8B003221F3 /* PreviewsSupport.xcframework */, + FACA23752A55FB970080545A /* XCTest.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + FA8F8B7C2C66C4C4007CEA33 /* ../DemoApp/DemoAppTests */ = { + isa = PBXGroup; + children = ( + FA8F8B7D2C66C4C4007CEA33 /* DemoAppPreviewTest.swift */, + FADB112B2C67A17500985C48 /* DemoAppSnapshotTest.swift */, + ); + path = ../DemoApp/DemoAppTests; + sourceTree = ""; + }; + FACBADA12C67B8D60012D600 /* ../DemoApp/Demo Watch AppTests */ = { + isa = PBXGroup; + children = ( + FACBADA22C67B8D60012D600 /* DemoWatchPreviewTest.swift */, + FACBADAB2C67B9A50012D600 /* DemoWatchSnapshotTest.swift */, + ); + path = "../DemoApp/Demo Watch AppTests"; + sourceTree = ""; + }; + FAD52BF02A7B5EBB001F1832 /* TestViews */ = { + isa = PBXGroup; + children = ( + FAD52BF22A7B5EEA001F1832 /* CodeEntryView.swift */, + FAD52BF12A7B5EEA001F1832 /* ExpandingView.swift */, + FA5E82962A96448A008DE3F0 /* StateView.swift */, + FA40515C2A95B587007A66D4 /* EmptyView.swift */, + FAD52BF32A7B5EEA001F1832 /* RideDetailView.swift */, + FA0B20F82A7DCB0100EC91D3 /* ArrayBuilder.swift */, + FA0B20F92A7DCB0100EC91D3 /* PreviewVariants.swift */, + FAD52BF52A7B5EEA001F1832 /* RideOptionsView.swift */, + FAD52BF42A7B5EEA001F1832 /* RideShareButton.swift */, + FA0B20F02A7DA20200EC91D3 /* AnyViewPreview.swift */, + FAD0107A2AA29ABA007D1AF6 /* TextView.swift */, + FA1E452D2ADF3C3D002C85DB /* UIViewPreviews.swift */, + FAC912362C894B6E00459191 /* OSVersionView.swift */, + ); + path = TestViews; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXHeadersBuildPhase section */ + FA1671D22A5399F700A42DB0 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + FA1671DA2A5399F700A42DB0 /* DemoModule.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXHeadersBuildPhase section */ + +/* Begin PBXNativeTarget section */ + FA1671BE2A5367A800A42DB0 /* DemoApp */ = { + isa = PBXNativeTarget; + buildConfigurationList = FA1671CE2A5367A800A42DB0 /* Build configuration list for PBXNativeTarget "DemoApp" */; + buildPhases = ( + FA1671BB2A5367A800A42DB0 /* Sources */, + FA1671BC2A5367A800A42DB0 /* Frameworks */, + FA1671BD2A5367A800A42DB0 /* Resources */, + FA1671E22A5399F700A42DB0 /* Embed Frameworks */, + FA309ECE2C38D71D00C85FF4 /* Embed Watch Content */, + ); + buildRules = ( + ); + dependencies = ( + FA1671DC2A5399F700A42DB0 /* PBXTargetDependency */, + FA309ECC2C38D71D00C85FF4 /* PBXTargetDependency */, + ); + name = DemoApp; + packageProductDependencies = ( + ); + productName = DemoApp; + productReference = FA1671BF2A5367A800A42DB0 /* DemoApp.app */; + productType = "com.apple.product-type.application"; + }; + FA1671D62A5399F700A42DB0 /* DemoModule */ = { + isa = PBXNativeTarget; + buildConfigurationList = FA1671DF2A5399F700A42DB0 /* Build configuration list for PBXNativeTarget "DemoModule" */; + buildPhases = ( + FA1671D22A5399F700A42DB0 /* Headers */, + FA1671D32A5399F700A42DB0 /* Sources */, + FA1671D42A5399F700A42DB0 /* Frameworks */, + FA1671D52A5399F700A42DB0 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = DemoModule; + packageProductDependencies = ( + ); + productName = DemoModule; + productReference = FA1671D72A5399F700A42DB0 /* DemoModule.framework */; + productType = "com.apple.product-type.framework"; + }; + FA309EBF2C38D71C00C85FF4 /* Demo Watch App */ = { + isa = PBXNativeTarget; + buildConfigurationList = FA309ED12C38D71D00C85FF4 /* Build configuration list for PBXNativeTarget "Demo Watch App" */; + buildPhases = ( + FA309EBC2C38D71C00C85FF4 /* Sources */, + FA309EBD2C38D71C00C85FF4 /* Frameworks */, + FA309EBE2C38D71C00C85FF4 /* Resources */, + 8B2B491E2FD01D94003221F3 /* Embed Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "Demo Watch App"; + packageProductDependencies = ( + ); + productName = "Demo Watch App"; + productReference = FA309EC02C38D71C00C85FF4 /* Demo Watch App.app */; + productType = "com.apple.product-type.application"; + }; + FA309ED52C38D77C00C85FF4 /* DemoWatchTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = FA309EDE2C38D77C00C85FF4 /* Build configuration list for PBXNativeTarget "DemoWatchTests" */; + buildPhases = ( + FA309ED22C38D77C00C85FF4 /* Sources */, + FA309ED32C38D77C00C85FF4 /* Frameworks */, + FA309ED42C38D77C00C85FF4 /* Resources */, + FA309EE42C38D7A900C85FF4 /* Embed Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + FA309EDD2C38D77C00C85FF4 /* PBXTargetDependency */, + ); + name = DemoWatchTests; + packageProductDependencies = ( + ); + productName = Demo; + productReference = FA309ED62C38D77C00C85FF4 /* DemoWatchTests.xctest */; + productType = "com.apple.product-type.bundle.ui-testing"; + }; + FA8F8B7A2C66C4C4007CEA33 /* DemoAppTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = FA8F8B832C66C4C4007CEA33 /* Build configuration list for PBXNativeTarget "DemoAppTests" */; + buildPhases = ( + FA8F8B772C66C4C4007CEA33 /* Sources */, + FA8F8B782C66C4C4007CEA33 /* Frameworks */, + FA8F8B792C66C4C4007CEA33 /* Resources */, + 8B2B49212FD01D9F003221F3 /* Embed Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + FA8F8B802C66C4C4007CEA33 /* PBXTargetDependency */, + ); + name = DemoAppTests; + packageProductDependencies = ( + ); + productName = DemoAppTests; + productReference = FA8F8B7B2C66C4C4007CEA33 /* DemoAppTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; + FACBAD9F2C67B8D60012D600 /* Demo Watch AppTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = FACBADA62C67B8D60012D600 /* Build configuration list for PBXNativeTarget "Demo Watch AppTests" */; + buildPhases = ( + FACBAD9C2C67B8D60012D600 /* Sources */, + FACBAD9D2C67B8D60012D600 /* Frameworks */, + FACBAD9E2C67B8D60012D600 /* Resources */, + 8B2B49242FD01DAA003221F3 /* Embed Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + FACBADA52C67B8D60012D600 /* PBXTargetDependency */, + ); + name = "Demo Watch AppTests"; + packageProductDependencies = ( + ); + productName = "Demo Watch AppTests"; + productReference = FACBADA02C67B8D60012D600 /* Demo Watch AppTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + FA1671B72A5367A800A42DB0 /* Project object */ = { + isa = PBXProject; + attributes = { + BuildIndependentTargetsInParallel = 1; + LastSwiftUpdateCheck = 1540; + LastUpgradeCheck = 1500; + TargetAttributes = { + FA1671BE2A5367A800A42DB0 = { + CreatedOnToolsVersion = 15.0; + }; + FA1671D62A5399F700A42DB0 = { + CreatedOnToolsVersion = 15.0; + LastSwiftMigration = 1500; + }; + FA309EBF2C38D71C00C85FF4 = { + CreatedOnToolsVersion = 15.4; + }; + FA309ED52C38D77C00C85FF4 = { + CreatedOnToolsVersion = 15.4; + TestTargetID = FA309EBF2C38D71C00C85FF4; + }; + FA8F8B7A2C66C4C4007CEA33 = { + CreatedOnToolsVersion = 15.4; + TestTargetID = FA1671BE2A5367A800A42DB0; + }; + FACBAD9F2C67B8D60012D600 = { + CreatedOnToolsVersion = 15.4; + TestTargetID = FA309EBF2C38D71C00C85FF4; + }; + }; + }; + buildConfigurationList = FA1671BA2A5367A800A42DB0 /* Build configuration list for PBXProject "DemoApp-XCFrameworks" */; + compatibilityVersion = "Xcode 14.0"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = FA1671B62A5367A800A42DB0; + packageReferences = ( + ); + productRefGroup = FA1671C02A5367A800A42DB0 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + FA1671BE2A5367A800A42DB0 /* DemoApp */, + FA1671D62A5399F700A42DB0 /* DemoModule */, + FA309EBF2C38D71C00C85FF4 /* Demo Watch App */, + FA309ED52C38D77C00C85FF4 /* DemoWatchTests */, + FA8F8B7A2C66C4C4007CEA33 /* DemoAppTests */, + FACBAD9F2C67B8D60012D600 /* Demo Watch AppTests */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + FA1671BD2A5367A800A42DB0 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + FA1671CB2A5367A800A42DB0 /* Preview Assets.xcassets in Resources */, + FA1671C72A5367A800A42DB0 /* Assets.xcassets in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + FA1671D52A5399F700A42DB0 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + FA309EBE2C38D71C00C85FF4 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + FA309ECA2C38D71D00C85FF4 /* Preview Assets.xcassets in Resources */, + FA309EC72C38D71D00C85FF4 /* Assets.xcassets in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + FA309ED42C38D77C00C85FF4 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + FA8F8B792C66C4C4007CEA33 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + FACBAD9E2C67B8D60012D600 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + FA1671BB2A5367A800A42DB0 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + FA1671C52A5367A800A42DB0 /* ContentView.swift in Sources */, + FAC912372C894B6E00459191 /* OSVersionView.swift in Sources */, + FAD52BF82A7B5EEA001F1832 /* RideDetailView.swift in Sources */, + FA1671C32A5367A800A42DB0 /* DemoAppApp.swift in Sources */, + FAD0107B2AA29ABA007D1AF6 /* TextView.swift in Sources */, + FA0B20FA2A7DCB0100EC91D3 /* ArrayBuilder.swift in Sources */, + FA1E452E2ADF3C3D002C85DB /* UIViewPreviews.swift in Sources */, + FA40515D2A95B587007A66D4 /* EmptyView.swift in Sources */, + FAD52BFA2A7B5EEA001F1832 /* RideOptionsView.swift in Sources */, + FA5E82972A96448A008DE3F0 /* StateView.swift in Sources */, + FABCCD932AC39081008F4D3A /* EMGTestHandler.swift in Sources */, + FA0B20F12A7DA20200EC91D3 /* AnyViewPreview.swift in Sources */, + FA0B20FB2A7DCB0100EC91D3 /* PreviewVariants.swift in Sources */, + FAD52BF72A7B5EEA001F1832 /* CodeEntryView.swift in Sources */, + FAD52BF62A7B5EEA001F1832 /* ExpandingView.swift in Sources */, + FAD52BF92A7B5EEA001F1832 /* RideShareButton.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + FA1671D32A5399F700A42DB0 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + FA1671E62A539CCF00A42DB0 /* ButtonView.swift in Sources */, + FA9C8E442A56959300DC4574 /* RatingPreviews.swift in Sources */, + FA13B8F02B3E8BAB00F58836 /* DateView.swift in Sources */, + FA1671E42A539A0500A42DB0 /* RowView.swift in Sources */, + FA1671E82A539EA900A42DB0 /* ProductCard.swift in Sources */, + FAA4F4CF2B271D9C00127B63 /* Color.swift in Sources */, + FA1671FB2A53E03800A42DB0 /* MessageRow.swift in Sources */, + FA1671FF2A53E1AF00A42DB0 /* ConversationMessageView.swift in Sources */, + FA1671FD2A53E11E00A42DB0 /* MessageView.swift in Sources */, + FA1671F52A53A0E100A42DB0 /* FeatureCardView.swift in Sources */, + FA1671F32A53A0AA00A42DB0 /* InfoCardView.swift in Sources */, + FA1671EA2A539F6E00A42DB0 /* RatingView.swift in Sources */, + FA1671F92A53DBF200A42DB0 /* HomeMapView.swift in Sources */, + FA1671F72A53A15200A42DB0 /* TripCardView.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + FA309EBC2C38D71C00C85FF4 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + FA309EC52C38D71C00C85FF4 /* ContentView.swift in Sources */, + FA309EC32C38D71C00C85FF4 /* DemoApp.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + FA309ED22C38D77C00C85FF4 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + FA309EE72C38EB9B00C85FF4 /* DemoWatchAccessibilityPreviewTest.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + FA8F8B772C66C4C4007CEA33 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + FADB112C2C67A17500985C48 /* DemoAppSnapshotTest.swift in Sources */, + FA8F8B7E2C66C4C4007CEA33 /* DemoAppPreviewTest.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + FACBAD9C2C67B8D60012D600 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + FACBADAC2C67B9A50012D600 /* DemoWatchSnapshotTest.swift in Sources */, + FACBADA32C67B8D60012D600 /* DemoWatchPreviewTest.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + FA1671DC2A5399F700A42DB0 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = FA1671D62A5399F700A42DB0 /* DemoModule */; + targetProxy = FA1671DB2A5399F700A42DB0 /* PBXContainerItemProxy */; + }; + FA309ECC2C38D71D00C85FF4 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + platformFilter = ios; + target = FA309EBF2C38D71C00C85FF4 /* Demo Watch App */; + targetProxy = FA309ECB2C38D71D00C85FF4 /* PBXContainerItemProxy */; + }; + FA309EDD2C38D77C00C85FF4 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = FA309EBF2C38D71C00C85FF4 /* Demo Watch App */; + targetProxy = FA309EDC2C38D77C00C85FF4 /* PBXContainerItemProxy */; + }; + FA8F8B802C66C4C4007CEA33 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + platformFilters = ( + ios, + maccatalyst, + macos, + ); + target = FA1671BE2A5367A800A42DB0 /* DemoApp */; + targetProxy = FA8F8B7F2C66C4C4007CEA33 /* PBXContainerItemProxy */; + }; + FACBADA52C67B8D60012D600 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = FA309EBF2C38D71C00C85FF4 /* Demo Watch App */; + targetProxy = FACBADA42C67B8D60012D600 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin XCBuildConfiguration section */ + FA1671CC2A5367A800A42DB0 /* 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; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)"; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + FA1671CD2A5367A800A42DB0 /* 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; + SWIFT_COMPILATION_MODE = wholemodule; + }; + name = Release; + }; + FA1671CF2A5367A800A42DB0 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CODE_SIGN_ENTITLEMENTS = ../DemoApp/DemoApp/DemoApp.entitlements; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_ASSET_PATHS = "\"../DemoApp/DemoApp/Preview Content\""; + DEVELOPMENT_TEAM = BR6WD3M6ZD; + ENABLE_DEBUG_DYLIB = NO; + ENABLE_HARDENED_RUNTIME = NO; + ENABLE_PREVIEWS = YES; + GENERATE_INFOPLIST_FILE = YES; + "INFOPLIST_KEY_UIApplicationSceneManifest_Generation[sdk=iphoneos*]" = YES; + "INFOPLIST_KEY_UIApplicationSceneManifest_Generation[sdk=iphonesimulator*]" = YES; + "INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents[sdk=iphoneos*]" = YES; + "INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents[sdk=iphonesimulator*]" = YES; + "INFOPLIST_KEY_UILaunchScreen_Generation[sdk=iphoneos*]" = YES; + "INFOPLIST_KEY_UILaunchScreen_Generation[sdk=iphonesimulator*]" = YES; + "INFOPLIST_KEY_UIStatusBarStyle[sdk=iphoneos*]" = UIStatusBarStyleDefault; + "INFOPLIST_KEY_UIStatusBarStyle[sdk=iphonesimulator*]" = UIStatusBarStyleDefault; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + IPHONEOS_DEPLOYMENT_TARGET = 16.0; + LD_RUNPATH_SEARCH_PATHS = "@executable_path/Frameworks"; + "LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = "@executable_path/../Frameworks"; + MACOSX_DEPLOYMENT_TARGET = 13.4; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.emerge.PreviewsDemoApp; + PRODUCT_NAME = "$(TARGET_NAME)"; + RUN_DOCUMENTATION_COMPILER = YES; + SDKROOT = auto; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator macosx"; + SUPPORTS_MACCATALYST = NO; + SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + FA1671D02A5367A800A42DB0 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CODE_SIGN_ENTITLEMENTS = ../DemoApp/DemoApp/DemoApp.entitlements; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_ASSET_PATHS = "\"../DemoApp/DemoApp/Preview Content\""; + DEVELOPMENT_TEAM = BR6WD3M6ZD; + ENABLE_DEBUG_DYLIB = NO; + ENABLE_HARDENED_RUNTIME = NO; + ENABLE_PREVIEWS = YES; + GENERATE_INFOPLIST_FILE = YES; + "INFOPLIST_KEY_UIApplicationSceneManifest_Generation[sdk=iphoneos*]" = YES; + "INFOPLIST_KEY_UIApplicationSceneManifest_Generation[sdk=iphonesimulator*]" = YES; + "INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents[sdk=iphoneos*]" = YES; + "INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents[sdk=iphonesimulator*]" = YES; + "INFOPLIST_KEY_UILaunchScreen_Generation[sdk=iphoneos*]" = YES; + "INFOPLIST_KEY_UILaunchScreen_Generation[sdk=iphonesimulator*]" = YES; + "INFOPLIST_KEY_UIStatusBarStyle[sdk=iphoneos*]" = UIStatusBarStyleDefault; + "INFOPLIST_KEY_UIStatusBarStyle[sdk=iphonesimulator*]" = UIStatusBarStyleDefault; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + IPHONEOS_DEPLOYMENT_TARGET = 16.0; + LD_RUNPATH_SEARCH_PATHS = "@executable_path/Frameworks"; + "LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = "@executable_path/../Frameworks"; + MACOSX_DEPLOYMENT_TARGET = 13.4; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.emerge.PreviewsDemoApp; + PRODUCT_NAME = "$(TARGET_NAME)"; + RUN_DOCUMENTATION_COMPILER = YES; + SDKROOT = auto; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator macosx"; + SUPPORTS_MACCATALYST = NO; + SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; + FA1671E02A5399F700A42DB0 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DEVELOPMENT_TEAM = BR6WD3M6ZD; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + ENABLE_MODULE_VERIFIER = YES; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_KEY_NSHumanReadableCopyright = ""; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; + LD_RUNPATH_SEARCH_PATHS = ( + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + "LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = ( + "@executable_path/../Frameworks", + "@loader_path/Frameworks", + ); + MACOSX_DEPLOYMENT_TARGET = 13.4; + MARKETING_VERSION = 1.0; + MODULE_VERIFIER_SUPPORTED_LANGUAGES = "objective-c objective-c++"; + MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS = "gnu17 gnu++20"; + PRODUCT_BUNDLE_IDENTIFIER = com.emerge.DemoModule; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + SDKROOT = auto; + SKIP_INSTALL = YES; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator macosx"; + SUPPORTS_MACCATALYST = NO; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + FA1671E12A5399F700A42DB0 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DEVELOPMENT_TEAM = BR6WD3M6ZD; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + ENABLE_MODULE_VERIFIER = YES; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_KEY_NSHumanReadableCopyright = ""; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; + LD_RUNPATH_SEARCH_PATHS = ( + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + "LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = ( + "@executable_path/../Frameworks", + "@loader_path/Frameworks", + ); + MACOSX_DEPLOYMENT_TARGET = 13.4; + MARKETING_VERSION = 1.0; + MODULE_VERIFIER_SUPPORTED_LANGUAGES = "objective-c objective-c++"; + MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS = "gnu17 gnu++20"; + PRODUCT_BUNDLE_IDENTIFIER = com.emerge.DemoModule; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + SDKROOT = auto; + SKIP_INSTALL = YES; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator macosx"; + SUPPORTS_MACCATALYST = NO; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; + FA309ECF2C38D71D00C85FF4 /* 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 = "\"../DemoApp/Demo Watch App/Preview Content\""; + DEVELOPMENT_TEAM = BR6WD3M6ZD; + ENABLE_PREVIEWS = YES; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_KEY_CFBundleDisplayName = Demo; + INFOPLIST_KEY_UIDeviceFamily = 4; + INFOPLIST_KEY_UISupportedInterfaceOrientations = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown"; + INFOPLIST_KEY_WKApplication = YES; + INFOPLIST_KEY_WKCompanionAppBundleIdentifier = com.emerge.PreviewsDemoApp; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.emerge.PreviewsDemoApp.watchkitapp; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = watchos; + SKIP_INSTALL = YES; + SUPPORTED_PLATFORMS = "watchos watchsimulator"; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = 4; + WATCHOS_DEPLOYMENT_TARGET = 10.0; + }; + name = Debug; + }; + FA309ED02C38D71D00C85FF4 /* 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 = "\"../DemoApp/Demo Watch App/Preview Content\""; + DEVELOPMENT_TEAM = BR6WD3M6ZD; + ENABLE_PREVIEWS = YES; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_KEY_CFBundleDisplayName = Demo; + INFOPLIST_KEY_UIDeviceFamily = 4; + INFOPLIST_KEY_UISupportedInterfaceOrientations = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown"; + INFOPLIST_KEY_WKApplication = YES; + INFOPLIST_KEY_WKCompanionAppBundleIdentifier = com.emerge.PreviewsDemoApp; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.emerge.PreviewsDemoApp.watchkitapp; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = watchos; + SKIP_INSTALL = YES; + SUPPORTED_PLATFORMS = "watchos watchsimulator"; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = 4; + VALIDATE_PRODUCT = YES; + WATCHOS_DEPLOYMENT_TARGET = 10.0; + }; + name = Release; + }; + FA309EDF2C38D77C00C85FF4 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = J9H72XH8P9; + GENERATE_INFOPLIST_FILE = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.emerge.Demo; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = watchos; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = 4; + TEST_TARGET_NAME = "Demo Watch App"; + WATCHOS_DEPLOYMENT_TARGET = 10.5; + }; + name = Debug; + }; + FA309EE02C38D77C00C85FF4 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = J9H72XH8P9; + GENERATE_INFOPLIST_FILE = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.emerge.Demo; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = watchos; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = 4; + TEST_TARGET_NAME = "Demo Watch App"; + VALIDATE_PRODUCT = YES; + WATCHOS_DEPLOYMENT_TARGET = 10.5; + }; + name = Release; + }; + FA8F8B812C66C4C4007CEA33 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = J9H72XH8P9; + GENERATE_INFOPLIST_FILE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 17.5; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.emerge.DemoAppTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = iphoneos; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator macosx"; + SUPPORTS_MACCATALYST = NO; + SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO; + SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/DemoApp.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/DemoApp"; + }; + name = Debug; + }; + FA8F8B822C66C4C4007CEA33 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = J9H72XH8P9; + GENERATE_INFOPLIST_FILE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 17.5; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.emerge.DemoAppTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = iphoneos; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator macosx"; + SUPPORTS_MACCATALYST = NO; + SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO; + SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/DemoApp.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/DemoApp"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + FACBADA72C67B8D60012D600 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = J9H72XH8P9; + GENERATE_INFOPLIST_FILE = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = "com.emerge.Demo-Watch-AppTests"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = watchos; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = 4; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Demo Watch App.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Demo Watch App"; + WATCHOS_DEPLOYMENT_TARGET = 10.5; + }; + name = Debug; + }; + FACBADA82C67B8D60012D600 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = J9H72XH8P9; + GENERATE_INFOPLIST_FILE = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = "com.emerge.Demo-Watch-AppTests"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = watchos; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = 4; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Demo Watch App.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Demo Watch App"; + VALIDATE_PRODUCT = YES; + WATCHOS_DEPLOYMENT_TARGET = 10.5; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + FA1671BA2A5367A800A42DB0 /* Build configuration list for PBXProject "DemoApp-XCFrameworks" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + FA1671CC2A5367A800A42DB0 /* Debug */, + FA1671CD2A5367A800A42DB0 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + FA1671CE2A5367A800A42DB0 /* Build configuration list for PBXNativeTarget "DemoApp" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + FA1671CF2A5367A800A42DB0 /* Debug */, + FA1671D02A5367A800A42DB0 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + FA1671DF2A5399F700A42DB0 /* Build configuration list for PBXNativeTarget "DemoModule" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + FA1671E02A5399F700A42DB0 /* Debug */, + FA1671E12A5399F700A42DB0 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + FA309ED12C38D71D00C85FF4 /* Build configuration list for PBXNativeTarget "Demo Watch App" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + FA309ECF2C38D71D00C85FF4 /* Debug */, + FA309ED02C38D71D00C85FF4 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + FA309EDE2C38D77C00C85FF4 /* Build configuration list for PBXNativeTarget "DemoWatchTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + FA309EDF2C38D77C00C85FF4 /* Debug */, + FA309EE02C38D77C00C85FF4 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + FA8F8B832C66C4C4007CEA33 /* Build configuration list for PBXNativeTarget "DemoAppTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + FA8F8B812C66C4C4007CEA33 /* Debug */, + FA8F8B822C66C4C4007CEA33 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + FACBADA62C67B8D60012D600 /* Build configuration list for PBXNativeTarget "Demo Watch AppTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + FACBADA72C67B8D60012D600 /* Debug */, + FACBADA82C67B8D60012D600 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = FA1671B72A5367A800A42DB0 /* Project object */; +} diff --git a/Examples/DemoApp-XCFrameworks/DemoApp-XCFrameworks.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/Examples/DemoApp-XCFrameworks/DemoApp-XCFrameworks.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 00000000..919434a6 --- /dev/null +++ b/Examples/DemoApp-XCFrameworks/DemoApp-XCFrameworks.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/Examples/DemoApp-XCFrameworks/DemoApp-XCFrameworks.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/Examples/DemoApp-XCFrameworks/DemoApp-XCFrameworks.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 00000000..18d98100 --- /dev/null +++ b/Examples/DemoApp-XCFrameworks/DemoApp-XCFrameworks.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/Examples/DemoApp-XCFrameworks/DemoApp-XCFrameworks.xcodeproj/xcshareddata/xcschemes/Demo Watch App.xcscheme b/Examples/DemoApp-XCFrameworks/DemoApp-XCFrameworks.xcodeproj/xcshareddata/xcschemes/Demo Watch App.xcscheme new file mode 100644 index 00000000..fe03cf6c --- /dev/null +++ b/Examples/DemoApp-XCFrameworks/DemoApp-XCFrameworks.xcodeproj/xcshareddata/xcschemes/Demo Watch App.xcscheme @@ -0,0 +1,89 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Examples/DemoApp-XCFrameworks/DemoApp-XCFrameworks.xcodeproj/xcshareddata/xcschemes/DemoApp.xcscheme b/Examples/DemoApp-XCFrameworks/DemoApp-XCFrameworks.xcodeproj/xcshareddata/xcschemes/DemoApp.xcscheme new file mode 100644 index 00000000..8c223079 --- /dev/null +++ b/Examples/DemoApp-XCFrameworks/DemoApp-XCFrameworks.xcodeproj/xcshareddata/xcschemes/DemoApp.xcscheme @@ -0,0 +1,82 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Examples/DemoApp-XCFrameworks/DemoApp-XCFrameworks.xcodeproj/xcshareddata/xcschemes/DemoAppTests.xcscheme b/Examples/DemoApp-XCFrameworks/DemoApp-XCFrameworks.xcodeproj/xcshareddata/xcschemes/DemoAppTests.xcscheme new file mode 100644 index 00000000..b278f59d --- /dev/null +++ b/Examples/DemoApp-XCFrameworks/DemoApp-XCFrameworks.xcodeproj/xcshareddata/xcschemes/DemoAppTests.xcscheme @@ -0,0 +1,59 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Examples/DemoApp-XCFrameworks/DemoApp.xctestplan b/Examples/DemoApp-XCFrameworks/DemoApp.xctestplan new file mode 100644 index 00000000..959cdc64 --- /dev/null +++ b/Examples/DemoApp-XCFrameworks/DemoApp.xctestplan @@ -0,0 +1,20 @@ +{ + "configurations": [ + { + "id": "FF846110-BFA2-419E-BF99-A9FC438920E2", + "name": "Configuration 1", + "options": {} + } + ], + "defaultOptions": {}, + "testTargets": [ + { + "target": { + "containerPath": "container:DemoApp-XCFrameworks.xcodeproj", + "identifier": "FA8F8B7A2C66C4C4007CEA33", + "name": "DemoAppTests" + } + } + ], + "version": 1 +} diff --git a/Examples/DemoApp-XCFrameworks/DemoAppTests.xctestplan b/Examples/DemoApp-XCFrameworks/DemoAppTests.xctestplan new file mode 100644 index 00000000..a7028461 --- /dev/null +++ b/Examples/DemoApp-XCFrameworks/DemoAppTests.xctestplan @@ -0,0 +1,20 @@ +{ + "configurations": [ + { + "id": "B1D580A7-404D-4E1D-80D8-0E56CDD58281", + "name": "Test Scheme Action", + "options": {} + } + ], + "defaultOptions": {}, + "testTargets": [ + { + "target": { + "containerPath": "container:DemoApp-XCFrameworks.xcodeproj", + "identifier": "FA8F8B7A2C66C4C4007CEA33", + "name": "DemoAppTests" + } + } + ], + "version": 1 +} diff --git a/Examples/DemoApp-XCFrameworks/README.md b/Examples/DemoApp-XCFrameworks/README.md new file mode 100644 index 00000000..8ec56529 --- /dev/null +++ b/Examples/DemoApp-XCFrameworks/README.md @@ -0,0 +1,13 @@ +# DemoApp XCFrameworks Example + +This example uses the same demo sources as `Examples/DemoApp`, but links against locally generated XCFrameworks instead of the Swift package. + +Generate the frameworks before opening or building the project. This requires Xcode and delegates to the repository-level XCFramework build script. + +```bash +cd Examples/DemoApp-XCFrameworks +./generate-xcframeworks.sh +open DemoApp-XCFrameworks.xcodeproj +``` + +The project expects the generated artifacts in the repository root `XCFrameworks/` folder, for example `../../XCFrameworks/SnapshottingTests.xcframework` and `../../XCFrameworks/PreviewsSupport.xcframework`. diff --git a/Examples/DemoApp-XCFrameworks/generate-xcframeworks.sh b/Examples/DemoApp-XCFrameworks/generate-xcframeworks.sh new file mode 100755 index 00000000..810f444a --- /dev/null +++ b/Examples/DemoApp-XCFrameworks/generate-xcframeworks.sh @@ -0,0 +1,5 @@ +#!/bin/bash +set -euo pipefail + +cd "$(dirname "$0")/../.." +./build.sh diff --git a/Examples/DemoApp/DemoApp.xcodeproj/project.pbxproj b/Examples/DemoApp/DemoApp.xcodeproj/project.pbxproj index c4e50077..1fb353aa 100644 --- a/Examples/DemoApp/DemoApp.xcodeproj/project.pbxproj +++ b/Examples/DemoApp/DemoApp.xcodeproj/project.pbxproj @@ -1066,6 +1066,8 @@ GENERATE_INFOPLIST_FILE = YES; INFOPLIST_KEY_CFBundleDisplayName = Demo; INFOPLIST_KEY_UISupportedInterfaceOrientations = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown"; + INFOPLIST_KEY_UIDeviceFamily = 4; + INFOPLIST_KEY_WKApplication = YES; INFOPLIST_KEY_WKCompanionAppBundleIdentifier = com.emerge.PreviewsDemoApp; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", @@ -1076,6 +1078,7 @@ PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = watchos; SKIP_INSTALL = YES; + SUPPORTED_PLATFORMS = "watchos watchsimulator"; SWIFT_EMIT_LOC_STRINGS = YES; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = 4; @@ -1096,6 +1099,8 @@ GENERATE_INFOPLIST_FILE = YES; INFOPLIST_KEY_CFBundleDisplayName = Demo; INFOPLIST_KEY_UISupportedInterfaceOrientations = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown"; + INFOPLIST_KEY_UIDeviceFamily = 4; + INFOPLIST_KEY_WKApplication = YES; INFOPLIST_KEY_WKCompanionAppBundleIdentifier = com.emerge.PreviewsDemoApp; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", @@ -1106,6 +1111,7 @@ PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = watchos; SKIP_INSTALL = YES; + SUPPORTED_PLATFORMS = "watchos watchsimulator"; SWIFT_EMIT_LOC_STRINGS = YES; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = 4; diff --git a/Examples/DemoApp/DemoApp.xcodeproj/xcshareddata/xcschemes/Demo Watch App.xcscheme b/Examples/DemoApp/DemoApp.xcodeproj/xcshareddata/xcschemes/Demo Watch App.xcscheme new file mode 100644 index 00000000..54a09655 --- /dev/null +++ b/Examples/DemoApp/DemoApp.xcodeproj/xcshareddata/xcschemes/Demo Watch App.xcscheme @@ -0,0 +1,89 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Examples/DemoApp/DemoAppTests/DemoAppSnapshotTest.swift b/Examples/DemoApp/DemoAppTests/DemoAppSnapshotTest.swift index 30b0e1f4..54a92a5a 100644 --- a/Examples/DemoApp/DemoAppTests/DemoAppSnapshotTest.swift +++ b/Examples/DemoApp/DemoAppTests/DemoAppSnapshotTest.swift @@ -9,8 +9,10 @@ import Foundation #if canImport(UIKit) import UIKit #endif -import SnapshottingTests +#if canImport(AccessibilitySnapshotCore) import AccessibilitySnapshotCore +#endif +import SnapshottingTests class DemoAppSnapshotTest: SnapshotTest { override class func snapshotPreviews() -> [String]? { @@ -28,8 +30,8 @@ class DemoAppSnapshotTest: SnapshotTest { override class func excludedSnapshotPreviewModules() -> [String]? { return nil } - - #if canImport(UIKit) && !os(watchOS) && !os(visionOS) && !os(tvOS) + + #if canImport(UIKit) && canImport(AccessibilitySnapshotCore) && !os(watchOS) && !os(visionOS) && !os(tvOS) override open class func setupA11y() -> ((UIViewController, UIWindow, PreviewLayout) -> UIView)? { return { (controller: UIViewController, window: UIWindow, layout: PreviewLayout) in let containerVC = controller.parent @@ -45,7 +47,7 @@ class DemoAppSnapshotTest: SnapshotTest { viewRenderingMode: controller.view.bounds.size.requiresCoreAnimationSnapshot ? .renderLayerInContext : .drawHierarchyInRect, activationPointDisplayMode: .never, showUserInputLabels: true) - + a11yView.center = window.center window.addSubview(a11yView) @@ -57,8 +59,10 @@ class DemoAppSnapshotTest: SnapshotTest { #endif } +#if canImport(UIKit) extension CGSize { var requiresCoreAnimationSnapshot: Bool { height >= UIScreen.main.bounds.size.height * 2 } } +#endif diff --git a/Examples/DemoApp/DemoWatchTests/DemoWatchAccessibilityPreviewTest.swift b/Examples/DemoApp/DemoWatchTests/DemoWatchAccessibilityPreviewTest.swift index 4568cd58..3c17a3db 100644 --- a/Examples/DemoApp/DemoWatchTests/DemoWatchAccessibilityPreviewTest.swift +++ b/Examples/DemoApp/DemoWatchTests/DemoWatchAccessibilityPreviewTest.swift @@ -5,7 +5,6 @@ // Created by Noah Martin on 7/5/24. // -import Snapshotting import SnapshottingTests import XCTest diff --git a/Package.swift b/Package.swift index 81e24fd1..4e0b37cb 100644 --- a/Package.swift +++ b/Package.swift @@ -10,13 +10,11 @@ let package = Package( // Products define the executables and libraries a package produces, making them visible to other packages. .library( name: "PreviewGallery", - type: .static, // Replace this to build dynamic targets: ["PreviewGallery"]), // Test library to import in your XCTest target. // This is the only library that depends on XCTest.framework .library( name: "SnapshottingTests", - type: .static, // Replace this to build dynamic targets: ["SnapshottingTests"]), // Link the main app to this target to use custom snapshot settings // This lib does not get inserted when running tests to avoid @@ -28,6 +26,10 @@ let package = Package( .library( name: "SnapshotPreviewsCore", targets: ["SnapshotPreviewsCore"]), + // Shared models required by the binary framework distribution. + .library( + name: "SnapshotSharedModels", + targets: ["SnapshotSharedModels"]), // Dynamic library that your main app will have inserted to generate previews .library( name: "Snapshotting", diff --git a/README.md b/README.md index f3bfed5f..39dc33f2 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ Generate snapshot images from your Xcode previews with zero test code, and export them to disk for upload to [Sentry Snapshots](https://docs.sentry.io/product/snapshots/) or any other visual diffing service. Works with SwiftUI and UIKit previews using `PreviewProvider` or `#Preview`, on all Apple platforms (iOS / macOS / watchOS / tvOS / visionOS). -# Installation +## Installation Add the package as a Swift Package Manager dependency using the repository URL: @@ -19,7 +19,7 @@ https://github.com/EmergeTools/SnapshotPreviews Link your XCTest target to the `SnapshottingTests` product. If you also want to customize per-preview rendering (e.g. precision, layout) you can link `SnapshotPreferences` to your app target. -# Generating Snapshots +## Generating Snapshots Create a test class that inherits from `SnapshotTest`. There are no test functions to write — they're added at runtime, one per discovered preview: @@ -44,7 +44,7 @@ By default each rendered preview is attached to the XCTest results bundle as a P ![Screenshot of Xcode test output](https://raw.githubusercontent.com/EmergeTools/SnapshotPreviews/master/images/testOutput.png) -## Filtering by module +### Filtering by module If your app links several frameworks, you can scope discovery to specific modules: @@ -59,13 +59,13 @@ override class func excludedSnapshotPreviewModules() -> [String]? { ["LegacyModu > [!NOTE] > Preview macros (`#Preview("Display Name")`) produce snapshot names based on file path and display name, for example: `MyModule/MyFile.swift:Display Name`. -# Uploading Snapshots to Sentry +## Exporting snapshots for Sentry `SnapshotPreviews` is the recommended iOS feeder for [Sentry Snapshots](https://docs.sentry.io/product/snapshots/). The flow has two steps: `xcodebuild test` writes PNGs + JSON sidecars to a directory, then `sentry-cli build snapshots` uploads that directory. ![Sentry Snapshots visual diff UI](https://github.com/user-attachments/assets/3a9e5c84-7954-4e73-89a1-3e5a181b7c7c) -## 1. Export the snapshots from your test run +### 1. Export the snapshots from your test run Set `TEST_RUNNER_SNAPSHOTS_EXPORT_DIR` on the test invocation. When set, `SnapshotTest` writes images directly to that directory instead of attaching them to the `.xcresult` bundle. @@ -114,7 +114,7 @@ import SnapshotPreferences No Xcode code-coverage data (`.profraw` / `.profdata`) is written by the exporter — only the PNGs and sidecars. If you need code coverage from the same test run, enable it on the scheme as usual; coverage output goes to the `.xcresult` bundle independently. -## 2. Upload to Sentry +### 2. Upload to Sentry Choose one of the upload options below. @@ -156,9 +156,9 @@ Use Sentry's Fastlane integration if your CI already uploads Apple artifacts thr See Sentry's [CI integration docs](https://docs.sentry.io/product/snapshots/integrating-into-ci/) for sharding across simulators and base/head SHA pinning. -# Tips +## Tips -## Unique display names +### Unique display names Give every preview a unique display name. This is what shows up in XCTest results and in the exported filenames / metadata: @@ -176,11 +176,11 @@ struct MyView_Previews: PreviewProvider { Display names should be unique within each `PreviewProvider`, or within a file when using preview macros. -## Snapshot best practices +### Snapshot best practices Snapshot previews should be deterministic. Avoid live network calls, timers, animations that do not settle, locale-dependent data, and dates generated from the current clock. Prefer fixed fixtures and mocked dependencies so the same preview renders the same pixels in Xcode, local test runs, and CI. -## Detecting the snapshot environment +### Detecting the snapshot environment Set `SNAPSHOTS_RUNNING_FOR_PREVIEWS=1` in your unit test scheme to mirror the variable Xcode sets when rendering live previews. You can then disable preview-unfriendly behavior (logging, analytics, network calls) with a single check: @@ -192,7 +192,7 @@ extension ProcessInfo { } ``` -## Snapshot modifiers +### Snapshot modifiers Link the `SnapshotPreferences` product to your app target to customize individual previews before they are rendered by `SnapshotTest`. @@ -205,7 +205,7 @@ Link the `SnapshotPreferences` product to your app target to customize individua | `.snapshotAdditionalContext(["fixture": "loaded"])` | You want extra sidecar metadata for debugging or filtering. | Adds fields to the JSON sidecar `context` object. Repeated context modifiers merge, and later duplicate keys win. Custom keys override generated context keys. | | `.snapshotDiffThreshold(0.05)` | A snapshot has small expected pixel differences. | Sets `diff_threshold` in the exported sidecar for this preview. `0.05` allows up to a 5% changed-pixel share before Sentry marks the image as changed. | -## Variants +### Variants > [!TIP] > `PreviewVariants` simplifies snapshot testing by ensuring a consistent set of variants and that every view has a name. @@ -231,16 +231,51 @@ struct MyView_Previews: PreviewProvider { } ``` -# Additional Features +## Additional Features -## Preview rendering check (no PNGs) +### Preview rendering check (no PNGs) If you only want to verify that every preview lays out without crashing — for example, to catch a missing `@EnvironmentObject` — inherit from `PreviewLayoutTest` instead of `SnapshotTest`. It runs the same discovery pipeline but skips the image render, so it's significantly faster. This gives you *preview coverage* (every preview was exercised); it does not produce Xcode code-coverage data. -## Preview Gallery +### Preview Gallery `PreviewGallery` is an interactive SwiftUI view that turns your previews into a browsable gallery of components — useful for internal builds where Xcode isn't available. Link your app to the `PreviewGallery` product and present it from wherever makes sense: +> [!NOTE] +> `PreviewGallery` discovers previews from runtime metadata in the built app. If no previews are present in that build, the gallery will open with no previews to display. + +#### Internal distribution builds + +`PreviewGallery` is designed for development and trusted internal distribution. If you want to include it in a TestFlight or other internal build, create a dedicated build configuration or archive scheme instead of changing your production Release configuration. The previews must both compile into that build and survive optimization: + +1. Link the app target to the `PreviewGallery` product. +2. Configure Swift optimization so preview metadata is retained. Release configurations often use whole-module optimization, which can remove unreferenced preview declarations even when they compile successfully. For the internal gallery configuration, disable whole-module optimization or use a Debug-like compilation mode, then verify that the gallery shows the expected previews before distributing it. +3. If your previews are wrapped in `#if DEBUG`, add a custom Swift compilation condition, such as `PREVIEW_GALLERY`, to the internal build configuration. In Xcode, set this under **Build Settings > Swift Compiler - Custom Flags > Active Compilation Conditions** (`SWIFT_ACTIVE_COMPILATION_CONDITIONS`). Then keep preview declarations compiled for Debug and that internal configuration: + +```swift +#if DEBUG || PREVIEW_GALLERY +#Preview { + MyView() +} +#endif +``` + +For `PreviewProvider` previews, wrap the provider type the same way: + +```swift +#if DEBUG || PREVIEW_GALLERY +struct MyView_Previews: PreviewProvider { + static var previews: some View { + MyView() + } +} +#endif +``` + +If your previews rely on assets, JSON fixtures, or other resources from a `Preview Content` folder, make sure those resources are included in the internal gallery build. Xcode Development Assets are intended for previews and Simulator development without increasing final app size, so they may not be present in builds you distribute. + +Only expose the gallery in trusted internal builds, and gate access appropriately, because previews can reveal unfinished UI, mock data, or internal states. +

@@ -263,7 +298,7 @@ struct InternalSettingsView: View { } ``` -## Accessibility audits +### Accessibility audits Xcode [accessibility audits](https://developer.apple.com/documentation/xctest/xcuiapplication/4191487-performaccessibilityaudit) can run on every preview as part of a UI test. Inherit from `AccessibilityPreviewTest` and override the audit type / issue handler as needed: @@ -293,11 +328,32 @@ See the demo app under `Examples/` for a full example. Previews are discovered in the test binary by parsing the `__swift5_proto` Mach-O section to find types that conform to `PreviewProvider` (and the related protocols generated by the `#Preview` macro). Background on how this works in the Swift runtime: [The Surprising Cost of Protocol Conformances in Swift](https://www.emergetools.com/blog/posts/SwiftProtocolConformance). -# Related Reading +## Binary frameworks + +While Swift Package Manager is the recommended way to integrate SnapshotPreviews, every release also ships the frameworks as prebuilt XCFramework `.zip` assets: + +- `SnapshotPreferences.xcframework.zip` — user-facing SwiftUI preference modifiers. +- `PreviewGallery.xcframework.zip` — user-facing preview gallery UI. +- `SnapshottingTests.xcframework.zip` — user-facing XCTest snapshot and layout helpers. +- `SnapshotSharedModels.xcframework.zip` — required support dependency shared by the public APIs. +- `SnapshotPreviewsCore.xcframework.zip` — required support dependency for preview discovery and rendering. +- `PreviewsSupport.xcframework.zip` — required binary support dependency for `SnapshotPreviewsCore`. +- `Snapshotting.xcframework.zip` — compatibility/runtime artifact for inserted-dylib accessibility and UI-test workflows. + +Xcode does not infer transitive dependencies between manually added binary frameworks, so add the full dependency set for each target: + +- App target using per-preview rendering preferences: link and embed `SnapshotPreferences.xcframework` and `SnapshotSharedModels.xcframework`. +- App target using the gallery UI: link and embed `PreviewGallery.xcframework`, `SnapshotPreviewsCore.xcframework`, `SnapshotPreferences.xcframework`, `SnapshotSharedModels.xcframework`, and `PreviewsSupport.xcframework`. +- XCTest snapshot/layout target: link and embed `SnapshottingTests.xcframework`, `SnapshotPreviewsCore.xcframework`, `SnapshotSharedModels.xcframework`, and `PreviewsSupport.xcframework`. +- Accessibility/UI-test target using the inserted-dylib flow: link and embed `SnapshottingTests.xcframework`, `Snapshotting.xcframework`, `SnapshotPreviewsCore.xcframework`, `SnapshotSharedModels.xcframework`, and `PreviewsSupport.xcframework`. + +You don't need to build anything to use the released artifacts above. You can build them locally from source using `bash build.sh` from the repository root. It requires Xcode and writes the frameworks to `XCFrameworks/`. + +## Related Reading - [How to use VariadicView, SwiftUI's Private View API](https://www.emergetools.com/blog/posts/how-to-use-variadic-view) — `VariadicView` is how multiple images are rendered for one `PreviewProvider`. - [The Surprising Cost of Protocol Conformances in Swift](https://www.emergetools.com/blog/posts/SwiftProtocolConformance) — how preview types are discovered in app binaries. -# Star History +## Star History [![Star History Chart](https://api.star-history.com/svg?repos=EmergeTools/SnapshotPreviews&type=Date)](https://star-history.com/#EmergeTools/SnapshotPreviews&Date) diff --git a/XCFrameworkPackage.swift b/XCFrameworkPackage.swift new file mode 100644 index 00000000..dc697598 --- /dev/null +++ b/XCFrameworkPackage.swift @@ -0,0 +1,66 @@ +// swift-tools-version: 5.7 + +import Foundation +import PackageDescription + +let product = ProcessInfo.processInfo.environment["SNAPSHOT_PREVIEWS_XCFRAMEWORK_PRODUCT"] ?? "" + +func selectedTargets() -> [Target] { + switch product { + case "SnapshotSharedModels": + return [ + .target(name: "SnapshotSharedModels"), + ] + case "SnapshotPreviewsCore": + return [ + .target(name: "SnapshotPreviewsCore", dependencies: ["PreviewsSupport", "SnapshotSharedModels"]), + .binaryTarget(name: "PreviewsSupport", path: "XCFrameworks/PreviewsSupport.xcframework"), + .binaryTarget(name: "SnapshotSharedModels", path: "XCFrameworks/SnapshotSharedModels.xcframework"), + ] + case "SnapshotPreferences": + return [ + .target(name: "SnapshotPreferences", dependencies: ["SnapshotSharedModels"]), + .binaryTarget(name: "SnapshotSharedModels", path: "XCFrameworks/SnapshotSharedModels.xcframework"), + ] + case "PreviewGallery": + return [ + .target(name: "PreviewGallery", dependencies: ["PreviewsSupport", "SnapshotSharedModels", "SnapshotPreviewsCore", "SnapshotPreferences"]), + .binaryTarget(name: "PreviewsSupport", path: "XCFrameworks/PreviewsSupport.xcframework"), + .binaryTarget(name: "SnapshotSharedModels", path: "XCFrameworks/SnapshotSharedModels.xcframework"), + .binaryTarget(name: "SnapshotPreviewsCore", path: "XCFrameworks/SnapshotPreviewsCore.xcframework"), + .binaryTarget(name: "SnapshotPreferences", path: "XCFrameworks/SnapshotPreferences.xcframework"), + ] + case "SnapshottingTests": + return [ + .target(name: "SnapshottingTestsObjc", dependencies: [.product(name: "SimpleDebugger", package: "SimpleDebugger", condition: .when(platforms: [.iOS, .macOS, .macCatalyst]))]), + .target(name: "SnapshottingTests", dependencies: ["PreviewsSupport", "SnapshotSharedModels", "SnapshotPreviewsCore", "SnapshottingTestsObjc"]), + .binaryTarget(name: "PreviewsSupport", path: "XCFrameworks/PreviewsSupport.xcframework"), + .binaryTarget(name: "SnapshotSharedModels", path: "XCFrameworks/SnapshotSharedModels.xcframework"), + .binaryTarget(name: "SnapshotPreviewsCore", path: "XCFrameworks/SnapshotPreviewsCore.xcframework"), + ] + case "Snapshotting": + return [ + .target(name: "Snapshotting", dependencies: ["SnapshottingSwift"]), + .target(name: "SnapshottingSwift", dependencies: ["PreviewsSupport", "SnapshotSharedModels", "SnapshotPreviewsCore", .product(name: "FlyingFox", package: "FlyingFox")]), + .binaryTarget(name: "PreviewsSupport", path: "XCFrameworks/PreviewsSupport.xcframework"), + .binaryTarget(name: "SnapshotSharedModels", path: "XCFrameworks/SnapshotSharedModels.xcframework"), + .binaryTarget(name: "SnapshotPreviewsCore", path: "XCFrameworks/SnapshotPreviewsCore.xcframework"), + ] + default: + fatalError("Set SNAPSHOT_PREVIEWS_XCFRAMEWORK_PRODUCT to the framework being built") + } +} + +let package = Package( + name: product, + platforms: [.iOS(.v15), .macOS(.v12), .watchOS(.v9)], + products: [ + .library(name: product, type: .dynamic, targets: [product]), + ], + dependencies: [ + .package(url: "https://github.com/swhitty/FlyingFox.git", exact: "0.16.0"), + .package(url: "https://github.com/EmergeTools/SimpleDebugger.git", exact: "1.0.0"), + ], + targets: selectedTargets(), + cxxLanguageStandard: .cxx11 +) diff --git a/build.sh b/build.sh index a657ac81..376c56de 100755 --- a/build.sh +++ b/build.sh @@ -1,62 +1,193 @@ #!/bin/bash -set -e - -SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd -P)" -PROJECT_ROOT="$(dirname "$SCRIPT_DIR")" - -PROJECT_BUILD_DIR="${PROJECT_BUILD_DIR:-"${PROJECT_ROOT}/build"}" -XCODEBUILD_BUILD_DIR="$PROJECT_BUILD_DIR/xcodebuild" -XCODEBUILD_DERIVED_DATA_PATH="$XCODEBUILD_BUILD_DIR/DerivedData" - -build_framework() { - local sdk="$1" - local destination="$2" - local scheme="$3" - - local XCODEBUILD_ARCHIVE_PATH="./$scheme-$sdk.xcarchive" - - rm -rf "$XCODEBUILD_ARCHIVE_PATH" - - xcodebuild archive \ - -scheme $scheme \ - -archivePath $XCODEBUILD_ARCHIVE_PATH \ - -derivedDataPath "$XCODEBUILD_DERIVED_DATA_PATH" \ - -sdk "$sdk" \ - -destination "$destination" \ - BUILD_LIBRARY_FOR_DISTRIBUTION=YES \ - INSTALL_PATH='Library/Frameworks' \ - OTHER_SWIFT_FLAGS=-no-verify-emitted-module-interface - - FRAMEWORK_MODULES_PATH="$XCODEBUILD_ARCHIVE_PATH/Products/Library/Frameworks/$scheme.framework/Modules" - mkdir -p "$FRAMEWORK_MODULES_PATH" - cp -r \ - "$XCODEBUILD_DERIVED_DATA_PATH/Build/Intermediates.noindex/ArchiveIntermediates/$scheme/BuildProductsPath/Release-$sdk/$scheme.swiftmodule" \ - "$FRAMEWORK_MODULES_PATH/$scheme.swiftmodule" - # Delete private swiftinterface - rm -f "$FRAMEWORK_MODULES_PATH/$scheme.swiftmodule/*.private.swiftinterface" - find "$FRAMEWORK_MODULES_PATH/$scheme.swiftmodule" -type f -name "*.swiftinterface" | while read -r file; do - # Remove lines containing "NSInvocation" - sed -e '/NSInvocation/d' -e 's/XCTest\.//g' "$file" > temp && mv temp "$file" - done +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd -P)" +PROJECT_ROOT="$SCRIPT_DIR" + +OUTPUT_DIR="$PROJECT_ROOT/XCFrameworks" +PROJECT_BUILD_DIR="${PROJECT_BUILD_DIR:-"$PROJECT_ROOT/build"}" +XCFRAMEWORK_BUILD_DIR="$PROJECT_BUILD_DIR/xcframeworks" +TEMP_PACKAGE_DIR="$XCFRAMEWORK_BUILD_DIR/package" +ARCHIVES_DIR="$XCFRAMEWORK_BUILD_DIR/archives" +DERIVED_DATA_DIR="$XCFRAMEWORK_BUILD_DIR/DerivedData" + +FRAMEWORKS=( + SnapshotSharedModels + SnapshotPreviewsCore + SnapshotPreferences + PreviewGallery + SnapshottingTests + Snapshotting +) + +SWIFT_MODULE_FRAMEWORKS=( + SnapshotSharedModels + SnapshotPreviewsCore + SnapshotPreferences + PreviewGallery + SnapshottingTests +) +PLATFORMS=( + "iphoneos|generic/platform=iOS" + "iphonesimulator|generic/platform=iOS Simulator" + "macosx|generic/platform=macOS" + "watchos|generic/platform=watchOS" + "watchsimulator|generic/platform=watchOS Simulator" +) + +prepare_temp_package() { + local framework="$1" + + if [ -d "$TEMP_PACKAGE_DIR" ]; then + rm -r "$TEMP_PACKAGE_DIR" + fi + + mkdir -p "$TEMP_PACKAGE_DIR" + ln -s "$PROJECT_ROOT/Sources" "$TEMP_PACKAGE_DIR/Sources" + ln -s "$PROJECT_ROOT/XCFrameworks" "$TEMP_PACKAGE_DIR/XCFrameworks" + cp "$PROJECT_ROOT/XCFrameworkPackage.swift" "$TEMP_PACKAGE_DIR/Package.swift" } -# Update the Package.swift to build the library as dynamic instead of static -sed -i '' '/Replace this/ s/.*/type: .dynamic,/' Package.swift +requires_swift_module() { + local framework="$1" + + for swift_module_framework in "${SWIFT_MODULE_FRAMEWORKS[@]}"; do + if [ "$swift_module_framework" = "$framework" ]; then + return 0 + fi + done + + return 1 +} + +build_framework_archive() { + local framework="$1" + local sdk="$2" + local destination="$3" + local archive_path="$ARCHIVES_DIR/$framework-$sdk.xcarchive" + + if [ -d "$archive_path" ]; then + rm -r "$archive_path" + fi + + SNAPSHOT_PREVIEWS_XCFRAMEWORK_PRODUCT="$framework" xcodebuild archive \ + -scheme "$framework" \ + -archivePath "$archive_path" \ + -derivedDataPath "$DERIVED_DATA_DIR/$framework" \ + -sdk "$sdk" \ + -destination "$destination" \ + BUILD_LIBRARY_FOR_DISTRIBUTION=YES \ + INSTALL_PATH="Library/Frameworks" \ + SKIP_INSTALL=NO \ + OTHER_SWIFT_FLAGS="-no-verify-emitted-module-interface" + + copy_swift_module "$framework" "$sdk" "$archive_path" +} + +copy_swift_module() { + local framework="$1" + local sdk="$2" + local archive_path="$3" + local configuration="Release-$sdk" + + if [ "$sdk" = "macosx" ]; then + configuration="Release" + fi + + local source_module_path="$DERIVED_DATA_DIR/$framework/Build/Intermediates.noindex/ArchiveIntermediates/$framework/BuildProductsPath/$configuration/$framework.swiftmodule" + if [ ! -d "$source_module_path" ]; then + if requires_swift_module "$framework"; then + echo "Missing Swift module output for $framework at $source_module_path" >&2 + exit 1 + fi -# Build SnapshottingTests -build_framework "iphonesimulator" "generic/platform=iOS Simulator" "SnapshottingTests" -build_framework "iphoneos" "generic/platform=iOS" "SnapshottingTests" + return + fi -# Build PreviewGallery -build_framework "iphonesimulator" "generic/platform=iOS Simulator" "PreviewGallery" -build_framework "iphoneos" "generic/platform=iOS" "PreviewGallery" + local framework_path="$archive_path/Products/Library/Frameworks/$framework.framework" + local modules_path="$framework_path/Modules" -echo "Builds completed successfully." + if [ "$sdk" = "macosx" ] && [ -d "$framework_path/Versions/A" ]; then + modules_path="$framework_path/Versions/A/Modules" + if [ -e "$framework_path/Modules" ]; then + rm -r "$framework_path/Modules" + fi + ln -s "Versions/Current/Modules" "$framework_path/Modules" + fi -rm -rf "SnapshottingTests.xcframework" -xcodebuild -create-xcframework -framework SnapshottingTests-iphonesimulator.xcarchive/Products/Library/Frameworks/SnapshottingTests.framework -framework SnapshottingTests-iphoneos.xcarchive/Products/Library/Frameworks/SnapshottingTests.framework -output SnapshottingTests.xcframework + mkdir -p "$modules_path" + if [ -d "$modules_path/$framework.swiftmodule" ]; then + rm -r "$modules_path/$framework.swiftmodule" + fi + cp -r "$source_module_path" "$modules_path/$framework.swiftmodule" + sanitize_swift_interfaces "$modules_path" "$framework" +} + +sanitize_swift_interfaces() { + local modules_path="$1" + local framework="$2" + + find "$modules_path" -type f -name "*.private.swiftinterface" -delete + find "$modules_path" -type f -name "*.swiftinterface" | while read -r file; do + sed \ + -e '/NSInvocation/d' \ + -e 's/XCTest\.//g' \ + -e "s/${framework}\.//g" \ + "$file" > "$file.tmp" + mv "$file.tmp" "$file" + done +} + +create_xcframework() { + local framework="$1" + local output_path="$OUTPUT_DIR/$framework.xcframework" + local args=() + + for platform in "${PLATFORMS[@]}"; do + local sdk="${platform%%|*}" + args+=( + -framework + "$ARCHIVES_DIR/$framework-$sdk.xcarchive/Products/Library/Frameworks/$framework.framework" + ) + done + + if [ -d "$output_path" ]; then + rm -r "$output_path" + fi + + xcodebuild -create-xcframework "${args[@]}" -output "$output_path" +} + +copy_previews_support() { + local source_path="$PROJECT_ROOT/PreviewsSupport/PreviewsSupport.xcframework" + local output_path="$OUTPUT_DIR/PreviewsSupport.xcframework" + + if [ -d "$output_path" ]; then + rm -r "$output_path" + fi + ditto "$source_path" "$output_path" +} + +main() { + mkdir -p "$OUTPUT_DIR" "$ARCHIVES_DIR" + copy_previews_support + + for framework in "${FRAMEWORKS[@]}"; do + prepare_temp_package "$framework" + pushd "$TEMP_PACKAGE_DIR" >/dev/null + for platform in "${PLATFORMS[@]}"; do + sdk="${platform%%|*}" + destination="${platform#*|}" + build_framework_archive "$framework" "$sdk" "$destination" + done + popd >/dev/null + + create_xcframework "$framework" + done + + echo "XCFrameworks written to $OUTPUT_DIR" +} -rm -rf "PreviewGallery.xcframework" -xcodebuild -create-xcframework -framework PreviewGallery-iphonesimulator.xcarchive/Products/Library/Frameworks/PreviewGallery.framework -framework PreviewGallery-iphoneos.xcarchive/Products/Library/Frameworks/PreviewGallery.framework -output PreviewGallery.xcframework \ No newline at end of file +main "$@"