Просмотр исходного кода

Merge pull request #3673 from dreampiggy/project/visionos_cocoapods

[Part 2]Added the official visionOS support with CocoaPods, include Demo/Tests/CI
DreamPiggy 2 лет назад
Родитель
Сommit
80c8b2023a
43 измененных файлов с 1967 добавлено и 218 удалено
  1. 79 57
      .github/workflows/CI.yml
  2. 6 0
      Configs/Test-Shared.xcconfig
  3. 11 0
      Examples/Packages/RealityKitContent/Package.realitycomposerpro/ProjectData/main.json
  4. 209 0
      Examples/Packages/RealityKitContent/Package.realitycomposerpro/WorkspaceData/SceneMetadataList.json
  5. 17 0
      Examples/Packages/RealityKitContent/Package.realitycomposerpro/WorkspaceData/Settings.rcprojectdata
  6. 25 0
      Examples/Packages/RealityKitContent/Package.swift
  7. 3 0
      Examples/Packages/RealityKitContent/README.md
  8. 216 0
      Examples/Packages/RealityKitContent/Sources/RealityKitContent/RealityKitContent.rkassets/Materials/GridMaterial.usda
  9. 59 0
      Examples/Packages/RealityKitContent/Sources/RealityKitContent/RealityKitContent.rkassets/Scene.usda
  10. 4 0
      Examples/Packages/RealityKitContent/Sources/RealityKitContent/RealityKitContent.swift
  11. 367 46
      Examples/SDWebImage Demo.xcodeproj/project.pbxproj
  12. 77 0
      Examples/SDWebImage Demo.xcodeproj/xcshareddata/xcschemes/SDWebImage Vision Demo.xcscheme
  13. 30 0
      Examples/SDWebImage Vision Demo/App.swift
  14. 12 0
      Examples/SDWebImage Vision Demo/Assets.xcassets/AppIcon.solidimagestack/Back.solidimagestacklayer/Content.imageset/Contents.json
  15. 6 0
      Examples/SDWebImage Vision Demo/Assets.xcassets/AppIcon.solidimagestack/Back.solidimagestacklayer/Contents.json
  16. 17 0
      Examples/SDWebImage Vision Demo/Assets.xcassets/AppIcon.solidimagestack/Contents.json
  17. 12 0
      Examples/SDWebImage Vision Demo/Assets.xcassets/AppIcon.solidimagestack/Front.solidimagestacklayer/Content.imageset/Contents.json
  18. 6 0
      Examples/SDWebImage Vision Demo/Assets.xcassets/AppIcon.solidimagestack/Front.solidimagestacklayer/Contents.json
  19. 12 0
      Examples/SDWebImage Vision Demo/Assets.xcassets/AppIcon.solidimagestack/Middle.solidimagestacklayer/Content.imageset/Contents.json
  20. 6 0
      Examples/SDWebImage Vision Demo/Assets.xcassets/AppIcon.solidimagestack/Middle.solidimagestacklayer/Contents.json
  21. 6 0
      Examples/SDWebImage Vision Demo/Assets.xcassets/Contents.json
  22. 114 0
      Examples/SDWebImage Vision Demo/ContentView.swift
  23. 48 0
      Examples/SDWebImage Vision Demo/DetailView.swift
  24. 20 0
      Examples/SDWebImage Vision Demo/Info.plist
  25. 6 0
      Examples/SDWebImage Vision Demo/Preview Content/Preview Assets.xcassets/Contents.json
  26. 33 13
      Podfile
  27. 2 1
      README.md
  28. 2 0
      SDWebImage.podspec
  29. 31 0
      Tests/Expecta.podspec
  30. 25 0
      Tests/KVOController.podspec
  31. 363 51
      Tests/SDWebImage Tests.xcodeproj/project.pbxproj
  32. 74 0
      Tests/SDWebImage Tests.xcodeproj/xcshareddata/xcschemes/Tests Vision.xcscheme
  33. 22 0
      Tests/Tests Vision/Info.plist
  34. 0 19
      Tests/Tests/SDAnimatedImageTest.m
  35. 6 10
      Tests/Tests/SDImageCacheTests.m
  36. 2 0
      Tests/Tests/SDImageCoderTests.m
  37. 8 1
      Tests/Tests/SDImageTransformerTests.m
  38. 3 1
      Tests/Tests/SDTestCase.h
  39. 19 0
      Tests/Tests/SDTestCase.m
  40. 4 0
      Tests/Tests/SDUtilsTests.m
  41. 1 14
      Tests/Tests/SDWebCacheCategoriesTests.m
  42. 0 5
      Tests/Tests/SDWebImageDownloaderTests.m
  43. 4 0
      Tests/Tests/SDWebImageManagerTests.m

+ 79 - 57
.github/workflows/CI.yml

@@ -12,25 +12,31 @@ permissions:
   contents: read
 
 jobs:
-  Pods:
+  Lint:
     name: Cocoapods Lint
-    runs-on: macos-11
+    runs-on: macos-13
     env:
-      DEVELOPER_DIR: /Applications/Xcode_13.2.1.app
+      DEVELOPER_DIR: /Applications/Xcode_15.2.app
     steps:
       - name: Checkout
         uses: actions/checkout@v3
 
+      - name: Prepare VisionOS
+        run: |
+          defaults write com.apple.dt.Xcode AllowUnsupportedVisionOSHost -bool YES
+          defaults write com.apple.CoreSimulator AllowUnsupportedVisionOSHost -bool YES
+          xcodebuild -downloadPlatform visionOS
+
       - name: Install Cocoapods
         run: gem install cocoapods --no-document --quiet
         
       - name: Install Xcpretty
         run: gem install xcpretty --no-document --quiet
         
-      - name: Pod Update.
+      - name: Pod Update
         run: pod repo update --silent
         
-      - name: Pod Install.
+      - name: Pod Install
         run: pod install
 
       - name: Run SDWebImage podspec lint
@@ -39,26 +45,28 @@ jobs:
           pod lib lint SDWebImage.podspec --allow-warnings --skip-tests
           
   Demo:
-    name: Run Demo
-    runs-on: macos-11
+    name: Cocoapods Demo
+    runs-on: macos-13
     env:
-      DEVELOPER_DIR: /Applications/Xcode_13.2.1.app
+      DEVELOPER_DIR: /Applications/Xcode_15.2.app
       WORKSPACE_NAME: SDWebImage.xcworkspace
-      OSXSCHEME: SDWebImage OSX Demo
-      iOSSCHEME: SDWebImage iOS Demo
-      TVSCHEME: SDWebImage TV Demo
-      WATCHSCHEME: SDWebImage Watch Demo
-    strategy:
-      matrix:
-        iosDestination: ["name=iPhone 13 Pro"]
-        tvOSDestination: ["name=Apple TV 4K"]
-        watchOSDestination: ["platform=watchOS Simulator,name=Apple Watch Series 7 - 45mm"]
-        macOSDestination: ["platform=macOS"]
-        macCatalystDestination: ["platform=macOS,arch=x86_64,variant=Mac Catalyst"]
+      CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
+      iosDestination: platform=iOS Simulator,name=iPhone 15 Pro
+      macOSDestination: platform=macOS,arch=x86_64
+      macCatalystDestination: platform=macOS,arch=x86_64,variant=Mac Catalyst
+      tvOSDestination: platform=tvOS Simulator,name=Apple TV 4K (3rd generation)
+      watchOSDestination: platform=watchOS Simulator,name=Apple Watch Series 9 (45mm)
+      visionOSDestination: platform=visionOS Simulator,name=Apple Vision Pro
     steps:
       - name: Checkout
         uses: actions/checkout@v3
 
+      - name: Prepare VisionOS
+        run: |
+          defaults write com.apple.dt.Xcode AllowUnsupportedVisionOSHost -bool YES
+          defaults write com.apple.CoreSimulator AllowUnsupportedVisionOSHost -bool YES
+          xcodebuild -downloadPlatform visionOS
+
       - name: Install Cocoapods
         run: gem install cocoapods --no-document --quiet
         
@@ -74,39 +82,51 @@ jobs:
       - name: Run demo for OSX
         run: |
           set -o pipefail
-          xcodebuild build -workspace "${{ env.WORKSPACE_NAME }}" -scheme "${{ env.OSXSCHEME }}" -destination "${{ matrix.macOSDestination }}" -configuration Debug CODE_SIGNING_ALLOWED=NO | xcpretty -c
+          xcodebuild build -workspace "${{ env.WORKSPACE_NAME }}" -scheme "SDWebImage OSX Demo" -destination "${{ env.macOSDestination }}" -configuration Debug CODE_SIGNING_ALLOWED=NO | xcpretty -c
           
       - name: Run demo for iOS
         run: |
           set -o pipefail
-          xcodebuild build -workspace "${{ env.WORKSPACE_NAME }}" -scheme "${{ env.iOSSCHEME }}" -destination "${{ matrix.iosDestination }}" -configuration Debug CODE_SIGNING_ALLOWED=NO | xcpretty -c
+          xcodebuild build -workspace "${{ env.WORKSPACE_NAME }}" -scheme "SDWebImage iOS Demo" -destination "${{ env.iosDestination }}" -configuration Debug CODE_SIGNING_ALLOWED=NO | xcpretty -c
           
       - name: Run demo for TV
         run: |
           set -o pipefail
-          xcodebuild build -workspace "${{ env.WORKSPACE_NAME }}" -scheme "${{ env.TVSCHEME }}" -destination "${{ matrix.tvOSDestination }}" -configuration Debug CODE_SIGNING_ALLOWED=NO | xcpretty -c
+          xcodebuild build -workspace "${{ env.WORKSPACE_NAME }}" -scheme "SDWebImage TV Demo" -destination "${{ env.tvOSDestination }}" -configuration Debug CODE_SIGNING_ALLOWED=NO | xcpretty -c
           
       - name: Run demo for Watch
         run: |
           set -o pipefail
-          xcodebuild build -workspace "${{ env.WORKSPACE_NAME }}" -scheme "${{ env.WATCHSCHEME }}" -destination "${{ matrix.watchOSDestination }}" -configuration Debug CODE_SIGNING_ALLOWED=NO | xcpretty -c
-          
+          xcodebuild build -workspace "${{ env.WORKSPACE_NAME }}" -scheme "SDWebImage Watch Demo" -destination "${{ env.watchOSDestination }}" -configuration Debug CODE_SIGNING_ALLOWED=NO | xcpretty -c
+
+      - name: Run demo for Vision
+        run: |
+          set -o pipefail
+          xcodebuild build -workspace "${{ env.WORKSPACE_NAME }}" -scheme "SDWebImage Vision Demo" -destination "${{ env.visionOSDestination }}" -configuration Debug CODE_SIGNING_ALLOWED=NO | xcpretty -c
+
   Test:
     name: Unit Test
-    runs-on: macos-11
+    runs-on: macos-13
     env:
-      DEVELOPER_DIR: /Applications/Xcode_13.2.1.app
+      DEVELOPER_DIR: /Applications/Xcode_15.2.app
       WORKSPACE_NAME: SDWebImage.xcworkspace
       CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
-    strategy:
-      matrix:
-        iosDestination: ["platform=iOS Simulator,name=iPhone 13 Pro"]
-        macOSDestination: ["platform=macOS,arch=x86_64"]
-        tvOSDestination: ["platform=tvOS Simulator,name=Apple TV 4K"]
+      iosDestination: platform=iOS Simulator,name=iPhone 15 Pro
+      macOSDestination: platform=macOS,arch=x86_64
+      macCatalystDestination: platform=macOS,arch=x86_64,variant=Mac Catalyst
+      tvOSDestination: platform=tvOS Simulator,name=Apple TV 4K (3rd generation)
+      watchOSDestination: platform=watchOS Simulator,name=Apple Watch Series 9 (45mm)
+      visionOSDestination: platform=visionOS Simulator,name=Apple Vision Pro
     steps:
       - name: Checkout
         uses: actions/checkout@v3
 
+      - name: Prepare VisionOS
+        run: |
+          defaults write com.apple.dt.Xcode AllowUnsupportedVisionOSHost -bool YES
+          defaults write com.apple.CoreSimulator AllowUnsupportedVisionOSHost -bool YES
+          xcodebuild -downloadPlatform visionOS
+
       - name: Install Cocoapods
         run: gem install cocoapods --no-document --quiet
         
@@ -118,29 +138,35 @@ jobs:
         
       - name: Pod Install
         run: pod install
-        
+
       - name: Clean DerivedData
         run: |
           rm -rf ~/Library/Developer/Xcode/DerivedData/
           mkdir DerivedData
         
-      - name: Test - ${{ matrix.iosDestination }}
+      - name: Test for iOS
         run: |
           set -o pipefail
-          xcodebuild test -workspace "${{ env.WORKSPACE_NAME }}" -scheme "Tests iOS" -destination "${{ matrix.iosDestination }}" -configuration Debug CODE_SIGNING_ALLOWED=NO
+          xcodebuild test -workspace "${{ env.WORKSPACE_NAME }}" -scheme "Tests iOS" -destination "${{ env.iosDestination }}" -configuration Debug CODE_SIGNING_ALLOWED=NO
           mv ~/Library/Developer/Xcode/DerivedData/ ./DerivedData/iOS
           
-      - name: Test - ${{ matrix.macOSDestination }}
+      - name: Test for macOS
         run: |
           set -o pipefail
-          xcodebuild test -workspace "${{ env.WORKSPACE_NAME }}" -scheme "Tests Mac" -destination "${{ matrix.macOSDestination }}" -configuration Debug CODE_SIGNING_ALLOWED=NO
+          xcodebuild test -workspace "${{ env.WORKSPACE_NAME }}" -scheme "Tests Mac" -destination "${{ env.macOSDestination }}" -configuration Debug CODE_SIGNING_ALLOWED=NO
           mv ~/Library/Developer/Xcode/DerivedData/ ./DerivedData/macOS
     
-      - name: Test - ${{ matrix.tvOSDestination }}
+      - name: Test for tvOS
         run: |
           set -o pipefail
-          xcodebuild test -workspace "${{ env.WORKSPACE_NAME }}" -scheme "Tests TV" -destination "${{ matrix.tvOSDestination }}" -configuration Debug CODE_SIGNING_ALLOWED=NO
+          xcodebuild test -workspace "${{ env.WORKSPACE_NAME }}" -scheme "Tests TV" -destination "${{ env.tvOSDestination }}" -configuration Debug CODE_SIGNING_ALLOWED=NO
           mv ~/Library/Developer/Xcode/DerivedData/ ./DerivedData/tvOS
+
+      - name: Test for visionOS
+        run: |
+          set -o pipefail
+          xcodebuild test -workspace "${{ env.WORKSPACE_NAME }}" -scheme "Tests Vision" -destination "${{ env.visionOSDestination }}" -configuration Debug CODE_SIGNING_ALLOWED=NO
+          mv ~/Library/Developer/Xcode/DerivedData/ ./DerivedData/visionOS
           
       - name: Code Coverage
         run: |
@@ -150,29 +176,24 @@ jobs:
           bash <(curl -s https://codecov.io/bash) -v -D './DerivedData/macOS' -J '^SDWebImage$' -c -X gcov -F macos
           bash <(curl -s https://codecov.io/bash) -v -D './DerivedData/iOS' -J '^SDWebImage$' -c -X gcov -F ios
           bash <(curl -s https://codecov.io/bash) -v -D './DerivedData/tvOS' -J '^SDWebImage$' -c -X gcov -F tvos
+          bash <(curl -s https://codecov.io/bash) -v -D './DerivedData/visionOS' -J '^SDWebImage$' -c -X gcov -F visionos
           
   Build:
     name: Build Library
-    runs-on: macos-11
+    runs-on: macos-13
     env:
-      DEVELOPER_DIR: /Applications/Xcode_13.2.1.app
+      DEVELOPER_DIR: /Applications/Xcode_15.2.app
       PROJECT_NAME: SDWebImage.xcodeproj
       SCHEME_NAME: SDWebImage
     steps:
       - name: Checkout
         uses: actions/checkout@v3
 
-      - name: Install Cocoapods
-        run: gem install cocoapods --no-document --quiet
-        
-      - name: Install Xcpretty
-        run: gem install xcpretty --no-document --quiet
-        
-      - name: Pod Update
-        run: pod repo update --silent
-        
-      - name: Pod Install
-        run: pod install
+      - name: Prepare VisionOS
+        run: |
+          defaults write com.apple.dt.Xcode AllowUnsupportedVisionOSHost -bool YES
+          defaults write com.apple.CoreSimulator AllowUnsupportedVisionOSHost -bool YES
+          xcodebuild -downloadPlatform visionOS
 
       - name: Build the SwiftPM
         run: |
@@ -183,14 +204,15 @@ jobs:
       - name: Build as static library
         run: |
           set -o pipefail
-          xcodebuild build -project "${{ env.PROJECT_NAME }}" -scheme "SDWebImage static" -sdk iphonesimulator PLATFORM_NAME=iphonesimulator -configuration Release | xcpretty -c
+          xcodebuild build -project "${{ env.PROJECT_NAME }}" -scheme "SDWebImage static" -sdk iphonesimulator PLATFORM_NAME=iphonesimulator -configuration Debug | xcpretty -c
           rm -rf ~/Library/Developer/Xcode/DerivedData/
       - name: Build as dynamic frameworks
         run: |
           set -o pipefail
-          xcodebuild build -project "${{ env.PROJECT_NAME }}" -scheme "${{ env.SCHEME_NAME }}" -sdk macosx -configuration Release | xcpretty -c
-          xcodebuild build -project "${{ env.PROJECT_NAME }}" -scheme "${{ env.SCHEME_NAME }}" -sdk iphonesimulator PLATFORM_NAME=iphonesimulator -configuration Release | xcpretty -c
-          xcodebuild build -project "${{ env.PROJECT_NAME }}" -scheme "${{ env.SCHEME_NAME }}" -sdk appletvsimulator -configuration Release | xcpretty -c
-          xcodebuild build -project "${{ env.PROJECT_NAME }}" -scheme "${{ env.SCHEME_NAME }}" -sdk watchsimulator -configuration Release | xcpretty -c
-          xcodebuild build -project "${{ env.PROJECT_NAME }}" -scheme "${{ env.SCHEME_NAME }}" -destination "platform=macOS,arch=x86_64,variant=Mac Catalyst" -configuration Release | xcpretty -c
+          xcodebuild build -project "${{ env.PROJECT_NAME }}" -scheme "${{ env.SCHEME_NAME }}" -sdk macosx -configuration Debug | xcpretty -c
+          xcodebuild build -project "${{ env.PROJECT_NAME }}" -scheme "${{ env.SCHEME_NAME }}" -sdk iphonesimulator PLATFORM_NAME=iphonesimulator -configuration Debug | xcpretty -c
+          xcodebuild build -project "${{ env.PROJECT_NAME }}" -scheme "${{ env.SCHEME_NAME }}" -sdk appletvsimulator -configuration Debug | xcpretty -c
+          xcodebuild build -project "${{ env.PROJECT_NAME }}" -scheme "${{ env.SCHEME_NAME }}" -sdk watchsimulator -configuration Debug | xcpretty -c
+          xcodebuild build -project "${{ env.PROJECT_NAME }}" -scheme "${{ env.SCHEME_NAME }}" -destination "platform=macOS,arch=x86_64,variant=Mac Catalyst" -configuration Debug | xcpretty -c
+          xcodebuild build -project "${{ env.PROJECT_NAME }}" -scheme "${{ env.SCHEME_NAME }}" -sdk xrsimulator -configuration Debug | xcpretty -c
           rm -rf ~/Library/Developer/Xcode/DerivedData/

+ 6 - 0
Configs/Test-Shared.xcconfig

@@ -5,3 +5,9 @@
 
 // This is a list of paths to folders to be searched by the compiler for included or imported header files when compiling C, Objective-C, C++, or Objective-C++. Paths are delimited by whitespace, so any paths with spaces in them need to be properly quoted.
 HEADER_SEARCH_PATHS = $(inherited) "$(SRCROOT)/../SDWebImage/Private"
+
+// Warns when a quoted include is used instead of a framework style include in a framework header.
+CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO
+
+// If enabled, the build system will sandbox user scripts to disallow undeclared input/output dependencies.
+ENABLE_USER_SCRIPT_SANDBOXING = NO

+ 11 - 0
Examples/Packages/RealityKitContent/Package.realitycomposerpro/ProjectData/main.json

@@ -0,0 +1,11 @@
+{
+  "pathsToIds" : {
+    "\/RealityKitContent\/Sources\/RealityKitContent\/RealityKitContent.rkassets\/GridMaterial.usda" : "440DE5B4-E4E4-459B-AABF-9ACE96319272",
+    "\/RealityKitContent\/Sources\/RealityKitContent\/RealityKitContent.rkassets\/procedural_sphere_grid.usda" : "34C460AE-CA1B-4348-BD05-621ACBDFFE97",
+    "\/RealityKitContent\/Sources\/RealityKitContent\/RealityKitContent.rkassets\/Scene.usda" : "0A9B4653-B11E-4D6A-850E-C6FCB621626C",
+    "\/RealityKitContent\/Sources\/RealityKitContent\/RealityKitContent.rkassets\/Untitled Scene.usda" : "03E02005-EFA6-48D6-8A76-05B2822A74E9",
+    "RealityKitContent\/Sources\/RealityKitContent\/RealityKitContent.rkassets\/GridMaterial.usda" : "FBD8436F-6B8B-4B82-99B5-995D538B4704",
+    "RealityKitContent\/Sources\/RealityKitContent\/RealityKitContent.rkassets\/procedural_sphere_grid.usda" : "1CBF3893-ABFD-408C-8B91-045BFD257808",
+    "RealityKitContent\/Sources\/RealityKitContent\/RealityKitContent.rkassets\/Scene.usda" : "26DBAE76-5DD8-47B6-A085-1B4ADA111097"
+  }
+}

+ 209 - 0
Examples/Packages/RealityKitContent/Package.realitycomposerpro/WorkspaceData/SceneMetadataList.json

@@ -0,0 +1,209 @@
+{
+  "0A9B4653-B11E-4D6A-850E-C6FCB621626C" : {
+    "cameraTransform" : [
+      0.9807314,
+      -1.9820146e-10,
+      -0.195361,
+      0,
+      -0.10051192,
+      0.85749435,
+      -0.5045798,
+      0,
+      0.16752096,
+      0.51449335,
+      0.84097165,
+      0,
+      0.09084191,
+      0.05849296,
+      0.13903293,
+      1
+    ],
+    "objectMetadataList" : [
+      [
+        "0A9B4653-B11E-4D6A-850E-C6FCB621626C",
+        "Root"
+      ],
+      {
+        "isExpanded" : true,
+        "isLocked" : false
+      },
+      [
+        "0A9B4653-B11E-4D6A-850E-C6FCB621626C",
+        "Root",
+        "GridMaterial"
+      ],
+      {
+        "isExpanded" : true,
+        "isLocked" : false
+      },
+      [
+        "0A9B4653-B11E-4D6A-850E-C6FCB621626C",
+        "Root",
+        "Sphere"
+      ],
+      {
+        "isExpanded" : true,
+        "isLocked" : false
+      }
+    ]
+  },
+  "1CBF3893-ABFD-408C-8B91-045BFD257808" : {
+    "cameraTransform" : [
+      0.99999994,
+      0,
+      -0,
+      0,
+      -0,
+      0.8660255,
+      -0.49999988,
+      0,
+      0,
+      0.49999988,
+      0.8660255,
+      0,
+      0,
+      0.27093542,
+      0.46927398,
+      1
+    ],
+    "objectMetadataList" : [
+
+    ]
+  },
+  "03E02005-EFA6-48D6-8A76-05B2822A74E9" : {
+    "cameraTransform" : [
+      0.99999994,
+      0,
+      -0,
+      0,
+      -0,
+      0.8660254,
+      -0.49999994,
+      0,
+      0,
+      0.49999994,
+      0.8660254,
+      0,
+      0,
+      0.5981957,
+      1.0361054,
+      1
+    ],
+    "objectMetadataList" : [
+
+    ]
+  },
+  "26DBAE76-5DD8-47B6-A085-1B4ADA111097" : {
+    "cameraTransform" : [
+      1,
+      0,
+      -0,
+      0,
+      -0,
+      0.7071069,
+      -0.7071067,
+      0,
+      0,
+      0.7071067,
+      0.7071069,
+      0,
+      0,
+      0.2681068,
+      0.26850593,
+      1
+    ],
+    "objectMetadataList" : [
+      [
+        "26DBAE76-5DD8-47B6-A085-1B4ADA111097",
+        "Root"
+      ],
+      {
+        "isExpanded" : true,
+        "isLocked" : false
+      }
+    ]
+  },
+  "34C460AE-CA1B-4348-BD05-621ACBDFFE97" : {
+    "cameraTransform" : [
+      0.99999994,
+      0,
+      -0,
+      0,
+      -0,
+      0.8660255,
+      -0.49999988,
+      0,
+      0,
+      0.49999988,
+      0.8660255,
+      0,
+      0,
+      0.27093542,
+      0.46927398,
+      1
+    ],
+    "objectMetadataList" : [
+
+    ]
+  },
+  "440DE5B4-E4E4-459B-AABF-9ACE96319272" : {
+    "cameraTransform" : [
+      0.99999994,
+      0,
+      -0,
+      0,
+      -0,
+      0.8660254,
+      -0.49999994,
+      0,
+      0,
+      0.49999994,
+      0.8660254,
+      0,
+      0,
+      0.5981957,
+      1.0361054,
+      1
+    ],
+    "objectMetadataList" : [
+      [
+        "440DE5B4-E4E4-459B-AABF-9ACE96319272",
+        "Root"
+      ],
+      {
+        "isExpanded" : true,
+        "isLocked" : false
+      }
+    ]
+  },
+  "FBD8436F-6B8B-4B82-99B5-995D538B4704" : {
+    "cameraTransform" : [
+      0.99999994,
+      0,
+      -0,
+      0,
+      -0,
+      0.8660254,
+      -0.49999994,
+      0,
+      0,
+      0.49999994,
+      0.8660254,
+      0,
+      0,
+      0.5981957,
+      1.0361054,
+      1
+    ],
+    "objectMetadataList" : [
+      [
+        "FBD8436F-6B8B-4B82-99B5-995D538B4704",
+        "Root"
+      ],
+      {
+        "isExpanded" : true,
+        "isLocked" : false
+      }
+    ]
+  }
+}

+ 17 - 0
Examples/Packages/RealityKitContent/Package.realitycomposerpro/WorkspaceData/Settings.rcprojectdata

@@ -0,0 +1,17 @@
+{
+  "cameraPresets" : {
+
+  },
+  "secondaryToolbarData" : {
+    "isGridVisible" : true,
+    "sceneReverbPreset" : -1
+  },
+  "unitDefaults" : {
+    "°" : "°",
+    "kg" : "g",
+    "m" : "cm",
+    "m\/s" : "m\/s",
+    "m\/s²" : "m\/s²",
+    "s" : "s"
+  }
+}

+ 25 - 0
Examples/Packages/RealityKitContent/Package.swift

@@ -0,0 +1,25 @@
+// swift-tools-version:5.9
+// The swift-tools-version declares the minimum version of Swift required to build this package.
+
+import PackageDescription
+
+let package = Package(
+    name: "RealityKitContent",
+    products: [
+        // Products define the executables and libraries a package produces, and make them visible to other packages.
+        .library(
+            name: "RealityKitContent",
+            targets: ["RealityKitContent"]),
+    ],
+    dependencies: [
+        // Dependencies declare other packages that this package depends on.
+        // .package(url: /* package url */, from: "1.0.0"),
+    ],
+    targets: [
+        // Targets are the basic building blocks of a package. A target can define a module or a test suite.
+        // Targets can depend on other targets in this package, and on products in packages this package depends on.
+        .target(
+            name: "RealityKitContent",
+            dependencies: []),
+    ]
+)

+ 3 - 0
Examples/Packages/RealityKitContent/README.md

@@ -0,0 +1,3 @@
+# RealityKitContent
+
+A description of this package.

+ 216 - 0
Examples/Packages/RealityKitContent/Sources/RealityKitContent/RealityKitContent.rkassets/Materials/GridMaterial.usda

@@ -0,0 +1,216 @@
+#usda 1.0
+(
+    defaultPrim = "Root"
+    metersPerUnit = 1
+    upAxis = "Y"
+)
+
+def Xform "Root"
+{
+    def Material "GridMaterial"
+    {
+        reorder nameChildren = ["", "", "", "", "", "", "", "", "", "", "", "", "", "", "DefaultSurfaceShader", "MaterialXPreviewSurface", "Texcoord", "Add", "Multiply", "Fractional", "LineCounts", "Multiply_1", "Separate2", "Separate2_1", "Ifgreater", "Ifgreater_1", "Max", "Background_Color"]
+        token outputs:mtlx:surface.connect = </Root/GridMaterial/MaterialXPreviewSurface.outputs:out>
+        token outputs:realitykit:vertex
+        token outputs:surface
+        float2 ui:nodegraph:realitykit:subgraphOutputs:pos = (2222, 300.5)
+        float2 ui:nodegraph:realitykit:subgraphOutputs:size = (182, 89)
+        int ui:nodegraph:realitykit:subgraphOutputs:stackingOrder = 749
+
+        def Shader "DefaultSurfaceShader"
+        {
+            uniform token info:id = "UsdPreviewSurface"
+            color3f inputs:diffuseColor = (1, 1, 1)
+            float inputs:roughness = 0.75
+            token outputs:surface
+        }
+
+        def Shader "MaterialXPreviewSurface"
+        {
+            uniform token info:id = "ND_UsdPreviewSurface_surfaceshader"
+            float inputs:clearcoat
+            float inputs:clearcoatRoughness
+            color3f inputs:diffuseColor.connect = </Root/GridMaterial/Remap.outputs:out>
+            color3f inputs:emissiveColor
+            float inputs:ior
+            float inputs:metallic = 0.15
+            float3 inputs:normal
+            float inputs:occlusion
+            float inputs:opacity
+            float inputs:opacityThreshold
+            float inputs:roughness = 0.5
+            token outputs:out
+            float2 ui:nodegraph:node:pos = (1967, 300.5)
+            float2 ui:nodegraph:node:size = (208, 297)
+            int ui:nodegraph:node:stackingOrder = 870
+            string[] ui:nodegraph:realitykit:node:attributesShowingChildren = ["Advanced"]
+        }
+
+        def Shader "Texcoord"
+        {
+            uniform token info:id = "ND_texcoord_vector2"
+            float2 outputs:out
+            float2 ui:nodegraph:node:pos = (94.14453, 35.29297)
+            float2 ui:nodegraph:node:size = (182, 43)
+            int ui:nodegraph:node:stackingOrder = 1358
+        }
+
+        def Shader "Multiply"
+        {
+            uniform token info:id = "ND_multiply_vector2"
+            float2 inputs:in1.connect = </Root/GridMaterial/Texcoord.outputs:out>
+            float2 inputs:in2 = (32, 15)
+            float2 inputs:in2.connect = </Root/GridMaterial/LineCounts.outputs:out>
+            float2 outputs:out
+            float2 ui:nodegraph:node:pos = (275.64453, 47.29297)
+            float2 ui:nodegraph:node:size = (61, 36)
+            int ui:nodegraph:node:stackingOrder = 1348
+            string[] ui:nodegraph:realitykit:node:attributesShowingChildren = ["inputs:in2"]
+        }
+
+        def Shader "Fractional"
+        {
+            uniform token info:id = "ND_realitykit_fractional_vector2"
+            float2 inputs:in.connect = </Root/GridMaterial/Multiply.outputs:out>
+            float2 outputs:out
+            float2 ui:nodegraph:node:pos = (440.5, 49.5)
+            float2 ui:nodegraph:node:size = (155, 99)
+            int ui:nodegraph:node:stackingOrder = 1345
+        }
+
+        def Shader "BaseColor"
+        {
+            uniform token info:id = "ND_constant_color3"
+            color3f inputs:value = (0.89737034, 0.89737034, 0.89737034) (
+                colorSpace = "Input - Texture - sRGB - sRGB"
+            )
+            color3f inputs:value.connect = None
+            color3f outputs:out
+            float2 ui:nodegraph:node:pos = (1537.5977, 363.07812)
+            float2 ui:nodegraph:node:size = (150, 43)
+            int ui:nodegraph:node:stackingOrder = 1353
+        }
+
+        def Shader "LineColor"
+        {
+            uniform token info:id = "ND_constant_color3"
+            color3f inputs:value = (0.55945957, 0.55945957, 0.55945957) (
+                colorSpace = "Input - Texture - sRGB - sRGB"
+            )
+            color3f inputs:value.connect = None
+            color3f outputs:out
+            float2 ui:nodegraph:node:pos = (1536.9844, 287.86328)
+            float2 ui:nodegraph:node:size = (146, 43)
+            int ui:nodegraph:node:stackingOrder = 1355
+        }
+
+        def Shader "LineWidths"
+        {
+            uniform token info:id = "ND_combine2_vector2"
+            float inputs:in1 = 0.1
+            float inputs:in2 = 0.1
+            float2 outputs:out
+            float2 ui:nodegraph:node:pos = (443.64453, 233.79297)
+            float2 ui:nodegraph:node:size = (151, 43)
+            int ui:nodegraph:node:stackingOrder = 1361
+        }
+
+        def Shader "LineCounts"
+        {
+            uniform token info:id = "ND_combine2_vector2"
+            float inputs:in1 = 24
+            float inputs:in2 = 12
+            float2 outputs:out
+            float2 ui:nodegraph:node:pos = (94.14453, 138.29297)
+            float2 ui:nodegraph:node:size = (153, 43)
+            int ui:nodegraph:node:stackingOrder = 1359
+        }
+
+        def Shader "Remap"
+        {
+            uniform token info:id = "ND_remap_color3"
+            color3f inputs:in.connect = </Root/GridMaterial/Combine3.outputs:out>
+            color3f inputs:inhigh.connect = None
+            color3f inputs:inlow.connect = None
+            color3f inputs:outhigh.connect = </Root/GridMaterial/BaseColor.outputs:out>
+            color3f inputs:outlow.connect = </Root/GridMaterial/LineColor.outputs:out>
+            color3f outputs:out
+            float2 ui:nodegraph:node:pos = (1755.5, 300.5)
+            float2 ui:nodegraph:node:size = (95, 171)
+            int ui:nodegraph:node:stackingOrder = 1282
+            string[] ui:nodegraph:realitykit:node:attributesShowingChildren = ["inputs:outlow"]
+        }
+
+        def Shader "Separate2"
+        {
+            uniform token info:id = "ND_separate2_vector2"
+            float2 inputs:in.connect = </Root/GridMaterial/Range.outputs:out>
+            float outputs:outx
+            float outputs:outy
+            float2 ui:nodegraph:node:pos = (1212.6445, 128.91797)
+            float2 ui:nodegraph:node:size = (116, 117)
+            int ui:nodegraph:node:stackingOrder = 1363
+        }
+
+        def Shader "Combine3"
+        {
+            uniform token info:id = "ND_combine3_color3"
+            float inputs:in1.connect = </Root/GridMaterial/Min.outputs:out>
+            float inputs:in2.connect = </Root/GridMaterial/Min.outputs:out>
+            float inputs:in3.connect = </Root/GridMaterial/Min.outputs:out>
+            color3f outputs:out
+            float2 ui:nodegraph:node:pos = (1578.1445, 128.91797)
+            float2 ui:nodegraph:node:size = (146, 54)
+            int ui:nodegraph:node:stackingOrder = 1348
+        }
+
+        def Shader "Range"
+        {
+            uniform token info:id = "ND_range_vector2"
+            bool inputs:doclamp = 1
+            float2 inputs:gamma = (2, 2)
+            float2 inputs:in.connect = </Root/GridMaterial/Absval.outputs:out>
+            float2 inputs:inhigh.connect = </Root/GridMaterial/LineWidths.outputs:out>
+            float2 inputs:inlow = (0.02, 0.02)
+            float2 inputs:outhigh
+            float2 inputs:outlow
+            float2 outputs:out
+            float2 ui:nodegraph:node:pos = (990.64453, 128.91797)
+            float2 ui:nodegraph:node:size = (98, 207)
+            int ui:nodegraph:node:stackingOrder = 1364
+        }
+
+        def Shader "Subtract"
+        {
+            uniform token info:id = "ND_subtract_vector2"
+            float2 inputs:in1.connect = </Root/GridMaterial/Fractional.outputs:out>
+            float2 inputs:in2.connect = </Root/GridMaterial/LineWidths.outputs:out>
+            float2 outputs:out
+            float2 ui:nodegraph:node:pos = (612.64453, 87.04297)
+            float2 ui:nodegraph:node:size = (63, 36)
+            int ui:nodegraph:node:stackingOrder = 1348
+        }
+
+        def Shader "Absval"
+        {
+            uniform token info:id = "ND_absval_vector2"
+            float2 inputs:in.connect = </Root/GridMaterial/Subtract.outputs:out>
+            float2 outputs:out
+            float2 ui:nodegraph:node:pos = (765.64453, 87.04297)
+            float2 ui:nodegraph:node:size = (123, 43)
+            int ui:nodegraph:node:stackingOrder = 1348
+        }
+
+        def Shader "Min"
+        {
+            uniform token info:id = "ND_min_float"
+            float inputs:in1.connect = </Root/GridMaterial/Separate2.outputs:outx>
+            float inputs:in2.connect = </Root/GridMaterial/Separate2.outputs:outy>
+            float outputs:out
+            float2 ui:nodegraph:node:pos = (1388.1445, 128.91797)
+            float2 ui:nodegraph:node:size = (114, 36)
+            int ui:nodegraph:node:stackingOrder = 1363
+        }
+    }
+}
+

+ 59 - 0
Examples/Packages/RealityKitContent/Sources/RealityKitContent/RealityKitContent.rkassets/Scene.usda

@@ -0,0 +1,59 @@
+#usda 1.0
+(
+    defaultPrim = "Root"
+    metersPerUnit = 1
+    upAxis = "Y"
+)
+
+def Xform "Root"
+{
+    reorder nameChildren = ["GridMaterial", "Sphere"]
+    rel material:binding = None (
+        bindMaterialAs = "weakerThanDescendants"
+    )
+
+    def Sphere "Sphere" (
+        active = true
+        prepend apiSchemas = ["MaterialBindingAPI"]
+    )
+    {
+        rel material:binding = </Root/GridMaterial/GridMaterial> (
+            bindMaterialAs = "weakerThanDescendants"
+        )
+        double radius = 0.05
+        quatf xformOp:orient = (1, 0, 0, 0)
+        float3 xformOp:scale = (1, 1, 1)
+        float3 xformOp:translate = (0, 0, 0.0004)
+        uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"]
+
+        def RealityKitComponent "Collider"
+        {
+            uint group = 1
+            uniform token info:id = "RealityKit.Collider"
+            uint mask = 4294967295
+            token type = "Default"
+
+            def RealityKitStruct "Shape"
+            {
+                float3 extent = (0.2, 0.2, 0.2)
+                float radius = 0.05
+                token shapeType = "Sphere"
+            }
+        }
+
+        def RealityKitComponent "InputTarget"
+        {
+            uniform token info:id = "RealityKit.InputTarget"
+        }
+    }
+
+    def "GridMaterial" (
+        active = true
+        prepend references = @Materials/GridMaterial.usda@
+    )
+    {
+        float3 xformOp:scale = (1, 1, 1)
+        uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"]
+    }
+}
+

+ 4 - 0
Examples/Packages/RealityKitContent/Sources/RealityKitContent/RealityKitContent.swift

@@ -0,0 +1,4 @@
+import Foundation
+
+/// Bundle for the RealityKitContent project
+public let realityKitContentBundle = Bundle.module

+ 367 - 46
Examples/SDWebImage Demo.xcodeproj/project.pbxproj

@@ -3,10 +3,17 @@
 	archiveVersion = 1;
 	classes = {
 	};
-	objectVersion = 52;
+	objectVersion = 54;
 	objects = {
 
 /* Begin PBXBuildFile section */
+		022828CA975463BEC08FDA2D /* Pods_SDWebImage_iOS_Demo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7527DE20028C49345CF3C72F /* Pods_SDWebImage_iOS_Demo.framework */; };
+		3220E2732B7B0755005F83A5 /* RealityKitContent in Frameworks */ = {isa = PBXBuildFile; productRef = 3220E2722B7B0755005F83A5 /* RealityKitContent */; };
+		3220E2752B7B0755005F83A5 /* App.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3220E2742B7B0755005F83A5 /* App.swift */; };
+		3220E2772B7B0755005F83A5 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3220E2762B7B0755005F83A5 /* ContentView.swift */; };
+		3220E2792B7B0755005F83A5 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 3220E2782B7B0755005F83A5 /* Assets.xcassets */; };
+		3220E27C2B7B0755005F83A5 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 3220E27B2B7B0755005F83A5 /* Preview Assets.xcassets */; };
+		32464A842B7B0C30006BE70E /* DetailView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 32464A832B7B0C30006BE70E /* DetailView.swift */; };
 		32892E311FAE898C00BE8320 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 32892E301FAE898C00BE8320 /* Assets.xcassets */; };
 		32892E351FAE89FE00BE8320 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 32892E341FAE89FD00BE8320 /* LaunchScreen.storyboard */; };
 		328CA3AB29980A840063950F /* WindowController.m in Sources */ = {isa = PBXBuildFile; fileRef = 328CA3AA29980A840063950F /* WindowController.m */; };
@@ -16,6 +23,7 @@
 		4314D1B01D0E1182004B36C9 /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4314D1AF1D0E1182004B36C9 /* ViewController.m */; };
 		4314D1B31D0E1182004B36C9 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 4314D1B11D0E1182004B36C9 /* Main.storyboard */; };
 		4314D1B51D0E1182004B36C9 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 4314D1B41D0E1182004B36C9 /* Assets.xcassets */; };
+		434BF852C834EED767AACFB0 /* Pods_SDWebImage_Vision_Demo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 29A9D56D23804E7B2212CFA6 /* Pods_SDWebImage_Vision_Demo.framework */; };
 		43A629D31D0DFD000089D7DD /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 43A629D21D0DFD000089D7DD /* AppDelegate.m */; };
 		43A629D61D0DFD000089D7DD /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 43A629D51D0DFD000089D7DD /* main.m */; };
 		43A629D91D0DFD000089D7DD /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 43A629D81D0DFD000089D7DD /* ViewController.m */; };
@@ -39,11 +47,10 @@
 		537612B0155AB74D005750A4 /* DetailViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 537612AF155AB74D005750A4 /* DetailViewController.m */; };
 		537612B3155AB74D005750A4 /* MasterViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 537612B1155AB74D005750A4 /* MasterViewController.xib */; };
 		537612B6155AB74D005750A4 /* DetailViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 537612B4155AB74D005750A4 /* DetailViewController.xib */; };
-		95616EF6906FA4C794E780E4 /* Pods_SDWebImage_OSX_Demo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1299D5267E136DCF87A1A21A /* Pods_SDWebImage_OSX_Demo.framework */; };
-		AE96B96B254FB4A6A222D71E /* Pods_SDWebImage_TV_Demo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BEDA5EB5742642C924545A48 /* Pods_SDWebImage_TV_Demo.framework */; };
-		CF64B1471621CF4AAEC747B7 /* Pods_SDWebImage_iOS_Demo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 225ECB6E7CB8DB707B498522 /* Pods_SDWebImage_iOS_Demo.framework */; };
+		7714B28A46A2E07B6714BC0F /* Pods_SDWebImage_OSX_Demo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 18242F3D24D6BE93D067E4E8 /* Pods_SDWebImage_OSX_Demo.framework */; };
+		A6EC2DCD5EB62AAEBD5C1345 /* Pods_SDWebImage_TV_Demo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 56FF116D6E7696F07957CE40 /* Pods_SDWebImage_TV_Demo.framework */; };
 		DA248D44195470FD00390AB0 /* MapKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 537612E3155ABA3C005750A4 /* MapKit.framework */; };
-		FB25FF804FC7C7868E4F9364 /* Pods_SDWebImage_Watch_Demo_Extension.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0DBF9DAE0F88B4C7B529C575 /* Pods_SDWebImage_Watch_Demo_Extension.framework */; };
+		E221F54F71FEE9884D7C51FE /* Pods_SDWebImage_Watch_Demo_Extension.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8D99CEC262035CE49117E77D /* Pods_SDWebImage_Watch_Demo_Extension.framework */; };
 /* End PBXBuildFile section */
 
 /* Begin PBXContainerItemProxy section */
@@ -130,10 +137,18 @@
 
 /* Begin PBXFileReference section */
 		0829378FA7103DD8649CCCF3 /* Pods-SDWebImage iOS Demo.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SDWebImage iOS Demo.release.xcconfig"; path = "../Pods/Target Support Files/Pods-SDWebImage iOS Demo/Pods-SDWebImage iOS Demo.release.xcconfig"; sourceTree = "<group>"; };
-		0DBF9DAE0F88B4C7B529C575 /* Pods_SDWebImage_Watch_Demo_Extension.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_SDWebImage_Watch_Demo_Extension.framework; sourceTree = BUILT_PRODUCTS_DIR; };
-		1299D5267E136DCF87A1A21A /* Pods_SDWebImage_OSX_Demo.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_SDWebImage_OSX_Demo.framework; sourceTree = BUILT_PRODUCTS_DIR; };
-		225ECB6E7CB8DB707B498522 /* Pods_SDWebImage_iOS_Demo.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_SDWebImage_iOS_Demo.framework; sourceTree = BUILT_PRODUCTS_DIR; };
+		11FB3839400DA48480ABA6BB /* Pods-SDWebImage Vision Demo.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SDWebImage Vision Demo.release.xcconfig"; path = "../Pods/Target Support Files/Pods-SDWebImage Vision Demo/Pods-SDWebImage Vision Demo.release.xcconfig"; sourceTree = "<group>"; };
+		18242F3D24D6BE93D067E4E8 /* Pods_SDWebImage_OSX_Demo.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_SDWebImage_OSX_Demo.framework; sourceTree = BUILT_PRODUCTS_DIR; };
 		28B8C1BB2DCC32E213DA3DAD /* Pods-SDWebImage TV Demo.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SDWebImage TV Demo.release.xcconfig"; path = "../Pods/Target Support Files/Pods-SDWebImage TV Demo/Pods-SDWebImage TV Demo.release.xcconfig"; sourceTree = "<group>"; };
+		29A9D56D23804E7B2212CFA6 /* Pods_SDWebImage_Vision_Demo.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_SDWebImage_Vision_Demo.framework; sourceTree = BUILT_PRODUCTS_DIR; };
+		3220E26E2B7B0755005F83A5 /* SDWebImage Vision Demo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "SDWebImage Vision Demo.app"; sourceTree = BUILT_PRODUCTS_DIR; };
+		3220E2712B7B0755005F83A5 /* RealityKitContent */ = {isa = PBXFileReference; lastKnownFileType = wrapper; path = RealityKitContent; sourceTree = "<group>"; };
+		3220E2742B7B0755005F83A5 /* App.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = App.swift; sourceTree = "<group>"; };
+		3220E2762B7B0755005F83A5 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = "<group>"; };
+		3220E2782B7B0755005F83A5 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
+		3220E27B2B7B0755005F83A5 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = "<group>"; };
+		3220E27D2B7B0755005F83A5 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
+		32464A832B7B0C30006BE70E /* DetailView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DetailView.swift; sourceTree = "<group>"; };
 		327E1C604113A7CEC9AC02DB /* Pods-SDWebImage Watch Demo Extension.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SDWebImage Watch Demo Extension.debug.xcconfig"; path = "../Pods/Target Support Files/Pods-SDWebImage Watch Demo Extension/Pods-SDWebImage Watch Demo Extension.debug.xcconfig"; sourceTree = "<group>"; };
 		32892E301FAE898C00BE8320 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
 		32892E341FAE89FD00BE8320 /* LaunchScreen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = LaunchScreen.storyboard; sourceTree = "<group>"; };
@@ -188,12 +203,15 @@
 		537612B5155AB74D005750A4 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/DetailViewController.xib; sourceTree = "<group>"; };
 		537612E3155ABA3C005750A4 /* MapKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MapKit.framework; path = System/Library/Frameworks/MapKit.framework; sourceTree = SDKROOT; };
 		537612E6155ABA44005750A4 /* ImageIO.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ImageIO.framework; path = System/Library/Frameworks/ImageIO.framework; sourceTree = SDKROOT; };
+		56FF116D6E7696F07957CE40 /* Pods_SDWebImage_TV_Demo.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_SDWebImage_TV_Demo.framework; sourceTree = BUILT_PRODUCTS_DIR; };
 		5992BFDBF29AB5CBCAC896FB /* Pods-SDWebImage OSX Demo.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SDWebImage OSX Demo.release.xcconfig"; path = "../Pods/Target Support Files/Pods-SDWebImage OSX Demo/Pods-SDWebImage OSX Demo.release.xcconfig"; sourceTree = "<group>"; };
 		5A56E15AF819F64FBF1F65A9 /* Pods-SDWebImage TV Demo.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SDWebImage TV Demo.debug.xcconfig"; path = "../Pods/Target Support Files/Pods-SDWebImage TV Demo/Pods-SDWebImage TV Demo.debug.xcconfig"; sourceTree = "<group>"; };
+		7527DE20028C49345CF3C72F /* Pods_SDWebImage_iOS_Demo.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_SDWebImage_iOS_Demo.framework; sourceTree = BUILT_PRODUCTS_DIR; };
 		789EDF4244C66933FDF3E181 /* Pods-SDWebImage iOS Demo.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SDWebImage iOS Demo.debug.xcconfig"; path = "../Pods/Target Support Files/Pods-SDWebImage iOS Demo/Pods-SDWebImage iOS Demo.debug.xcconfig"; sourceTree = "<group>"; };
 		80C26B77F46D9332F328204E /* Pods-SDWebImage OSX Demo.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SDWebImage OSX Demo.debug.xcconfig"; path = "../Pods/Target Support Files/Pods-SDWebImage OSX Demo/Pods-SDWebImage OSX Demo.debug.xcconfig"; sourceTree = "<group>"; };
+		87F946759088F4E41FDC806A /* Pods-SDWebImage Vision Demo.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SDWebImage Vision Demo.debug.xcconfig"; path = "../Pods/Target Support Files/Pods-SDWebImage Vision Demo/Pods-SDWebImage Vision Demo.debug.xcconfig"; sourceTree = "<group>"; };
+		8D99CEC262035CE49117E77D /* Pods_SDWebImage_Watch_Demo_Extension.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_SDWebImage_Watch_Demo_Extension.framework; sourceTree = BUILT_PRODUCTS_DIR; };
 		9A205232F437C77F45A2EBD1 /* Pods-SDWebImage Watch Demo Extension.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SDWebImage Watch Demo Extension.release.xcconfig"; path = "../Pods/Target Support Files/Pods-SDWebImage Watch Demo Extension/Pods-SDWebImage Watch Demo Extension.release.xcconfig"; sourceTree = "<group>"; };
-		BEDA5EB5742642C924545A48 /* Pods_SDWebImage_TV_Demo.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_SDWebImage_TV_Demo.framework; sourceTree = BUILT_PRODUCTS_DIR; };
 		EA9E0C74219598B400AFB434 /* Module-Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Module-Release.xcconfig"; sourceTree = "<group>"; };
 		EA9E0C75219598B400AFB434 /* App-Debug.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "App-Debug.xcconfig"; sourceTree = "<group>"; };
 		EA9E0C76219598B400AFB434 /* App-Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "App-Release.xcconfig"; sourceTree = "<group>"; };
@@ -203,11 +221,20 @@
 /* End PBXFileReference section */
 
 /* Begin PBXFrameworksBuildPhase section */
+		3220E26B2B7B0755005F83A5 /* Frameworks */ = {
+			isa = PBXFrameworksBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				3220E2732B7B0755005F83A5 /* RealityKitContent in Frameworks */,
+				434BF852C834EED767AACFB0 /* Pods_SDWebImage_Vision_Demo.framework in Frameworks */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
 		4314D1A31D0E1181004B36C9 /* Frameworks */ = {
 			isa = PBXFrameworksBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
-				AE96B96B254FB4A6A222D71E /* Pods_SDWebImage_TV_Demo.framework in Frameworks */,
+				A6EC2DCD5EB62AAEBD5C1345 /* Pods_SDWebImage_TV_Demo.framework in Frameworks */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
@@ -215,7 +242,7 @@
 			isa = PBXFrameworksBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
-				95616EF6906FA4C794E780E4 /* Pods_SDWebImage_OSX_Demo.framework in Frameworks */,
+				7714B28A46A2E07B6714BC0F /* Pods_SDWebImage_OSX_Demo.framework in Frameworks */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
@@ -223,7 +250,7 @@
 			isa = PBXFrameworksBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
-				FB25FF804FC7C7868E4F9364 /* Pods_SDWebImage_Watch_Demo_Extension.framework in Frameworks */,
+				E221F54F71FEE9884D7C51FE /* Pods_SDWebImage_Watch_Demo_Extension.framework in Frameworks */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
@@ -236,7 +263,7 @@
 				5376129A155AB74D005750A4 /* UIKit.framework in Frameworks */,
 				5376129C155AB74D005750A4 /* Foundation.framework in Frameworks */,
 				5376129E155AB74D005750A4 /* CoreGraphics.framework in Frameworks */,
-				CF64B1471621CF4AAEC747B7 /* Pods_SDWebImage_iOS_Demo.framework in Frameworks */,
+				022828CA975463BEC08FDA2D /* Pods_SDWebImage_iOS_Demo.framework in Frameworks */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
@@ -250,6 +277,35 @@
 /* End PBXFrameworksBuildPhase section */
 
 /* Begin PBXGroup section */
+		3220E26F2B7B0755005F83A5 /* SDWebImage Vision Demo */ = {
+			isa = PBXGroup;
+			children = (
+				3220E2742B7B0755005F83A5 /* App.swift */,
+				3220E2762B7B0755005F83A5 /* ContentView.swift */,
+				32464A832B7B0C30006BE70E /* DetailView.swift */,
+				3220E2782B7B0755005F83A5 /* Assets.xcassets */,
+				3220E27D2B7B0755005F83A5 /* Info.plist */,
+				3220E27A2B7B0755005F83A5 /* Preview Content */,
+			);
+			path = "SDWebImage Vision Demo";
+			sourceTree = "<group>";
+		};
+		3220E2702B7B0755005F83A5 /* Packages */ = {
+			isa = PBXGroup;
+			children = (
+				3220E2712B7B0755005F83A5 /* RealityKitContent */,
+			);
+			path = Packages;
+			sourceTree = "<group>";
+		};
+		3220E27A2B7B0755005F83A5 /* Preview Content */ = {
+			isa = PBXGroup;
+			children = (
+				3220E27B2B7B0755005F83A5 /* Preview Assets.xcassets */,
+			);
+			path = "Preview Content";
+			sourceTree = "<group>";
+		};
 		4314D1A71D0E1181004B36C9 /* SDWebImage TV Demo */ = {
 			isa = PBXGroup;
 			children = (
@@ -341,7 +397,9 @@
 				43A629EF1D0E07600089D7DD /* SDWebImage Watch Demo */,
 				43A629FE1D0E07600089D7DD /* SDWebImage Watch Demo Extension */,
 				4314D1A71D0E1181004B36C9 /* SDWebImage TV Demo */,
+				3220E26F2B7B0755005F83A5 /* SDWebImage Vision Demo */,
 				53761298155AB74D005750A4 /* Frameworks */,
+				3220E2702B7B0755005F83A5 /* Packages */,
 				53761296155AB74D005750A4 /* Products */,
 				75D6E1708C75E4AC2FA214EC /* Pods */,
 			);
@@ -355,6 +413,7 @@
 				43A629EE1D0E07600089D7DD /* SDWebImage Watch Demo.app */,
 				43A629FA1D0E07600089D7DD /* SDWebImage Watch Demo Extension.appex */,
 				4314D1A61D0E1181004B36C9 /* SDWebImage TV Demo.app */,
+				3220E26E2B7B0755005F83A5 /* SDWebImage Vision Demo.app */,
 			);
 			name = Products;
 			sourceTree = "<group>";
@@ -367,10 +426,11 @@
 				53761299155AB74D005750A4 /* UIKit.framework */,
 				5376129B155AB74D005750A4 /* Foundation.framework */,
 				5376129D155AB74D005750A4 /* CoreGraphics.framework */,
-				1299D5267E136DCF87A1A21A /* Pods_SDWebImage_OSX_Demo.framework */,
-				BEDA5EB5742642C924545A48 /* Pods_SDWebImage_TV_Demo.framework */,
-				0DBF9DAE0F88B4C7B529C575 /* Pods_SDWebImage_Watch_Demo_Extension.framework */,
-				225ECB6E7CB8DB707B498522 /* Pods_SDWebImage_iOS_Demo.framework */,
+				18242F3D24D6BE93D067E4E8 /* Pods_SDWebImage_OSX_Demo.framework */,
+				56FF116D6E7696F07957CE40 /* Pods_SDWebImage_TV_Demo.framework */,
+				8D99CEC262035CE49117E77D /* Pods_SDWebImage_Watch_Demo_Extension.framework */,
+				7527DE20028C49345CF3C72F /* Pods_SDWebImage_iOS_Demo.framework */,
+				29A9D56D23804E7B2212CFA6 /* Pods_SDWebImage_Vision_Demo.framework */,
 			);
 			name = Frameworks;
 			sourceTree = "<group>";
@@ -414,6 +474,8 @@
 				9A205232F437C77F45A2EBD1 /* Pods-SDWebImage Watch Demo Extension.release.xcconfig */,
 				789EDF4244C66933FDF3E181 /* Pods-SDWebImage iOS Demo.debug.xcconfig */,
 				0829378FA7103DD8649CCCF3 /* Pods-SDWebImage iOS Demo.release.xcconfig */,
+				87F946759088F4E41FDC806A /* Pods-SDWebImage Vision Demo.debug.xcconfig */,
+				11FB3839400DA48480ABA6BB /* Pods-SDWebImage Vision Demo.release.xcconfig */,
 			);
 			name = Pods;
 			sourceTree = "<group>";
@@ -435,6 +497,28 @@
 /* End PBXGroup section */
 
 /* Begin PBXNativeTarget section */
+		3220E26D2B7B0755005F83A5 /* SDWebImage Vision Demo */ = {
+			isa = PBXNativeTarget;
+			buildConfigurationList = 3220E2802B7B0755005F83A5 /* Build configuration list for PBXNativeTarget "SDWebImage Vision Demo" */;
+			buildPhases = (
+				FE8AF0F7620DD545CC0FDB06 /* [CP] Check Pods Manifest.lock */,
+				3220E26A2B7B0755005F83A5 /* Sources */,
+				3220E26B2B7B0755005F83A5 /* Frameworks */,
+				3220E26C2B7B0755005F83A5 /* Resources */,
+				9896DB377881E964826851E6 /* [CP] Embed Pods Frameworks */,
+			);
+			buildRules = (
+			);
+			dependencies = (
+			);
+			name = "SDWebImage Vision Demo";
+			packageProductDependencies = (
+				3220E2722B7B0755005F83A5 /* RealityKitContent */,
+			);
+			productName = "SDWebImage Vision Demo";
+			productReference = 3220E26E2B7B0755005F83A5 /* SDWebImage Vision Demo.app */;
+			productType = "com.apple.product-type.application";
+		};
 		4314D1A51D0E1181004B36C9 /* SDWebImage TV Demo */ = {
 			isa = PBXNativeTarget;
 			buildConfigurationList = 4314D1B71D0E1182004B36C9 /* Build configuration list for PBXNativeTarget "SDWebImage TV Demo" */;
@@ -444,7 +528,7 @@
 				4314D1A31D0E1181004B36C9 /* Frameworks */,
 				4314D1A41D0E1181004B36C9 /* Resources */,
 				327E2DE01FAF0D8000EF52C2 /* Embed Frameworks */,
-				FB94446B4DACAF8F385EB57C /* [CP] Embed Pods Frameworks */,
+				79F9A2D3C039A7C473F3E579 /* [CP] Embed Pods Frameworks */,
 			);
 			buildRules = (
 			);
@@ -464,7 +548,7 @@
 				43A629CC1D0DFD000089D7DD /* Frameworks */,
 				43A629CD1D0DFD000089D7DD /* Resources */,
 				327E2DD61FAF0D7000EF52C2 /* Embed Frameworks */,
-				597F887D0D1A778333E020BA /* [CP] Embed Pods Frameworks */,
+				4E998E1DF728CCAF009D92E4 /* [CP] Embed Pods Frameworks */,
 			);
 			buildRules = (
 			);
@@ -502,7 +586,7 @@
 				43A629F71D0E07600089D7DD /* Frameworks */,
 				43A629F81D0E07600089D7DD /* Resources */,
 				327E2DDB1FAF0D7A00EF52C2 /* Embed Frameworks */,
-				85F5B7F46D00990FBEBF0377 /* [CP] Embed Pods Frameworks */,
+				BE1C2969523FD5B0A6AC02A9 /* [CP] Embed Pods Frameworks */,
 			);
 			buildRules = (
 			);
@@ -523,7 +607,7 @@
 				53761293155AB74D005750A4 /* Resources */,
 				43A62A171D0E07600089D7DD /* Embed Watch Content */,
 				327E2DD11FAF0D6A00EF52C2 /* Embed Frameworks */,
-				8425DD76050A8A49F8DAF736 /* [CP] Embed Pods Frameworks */,
+				3EE15CCA9FC9CD888D0A8221 /* [CP] Embed Pods Frameworks */,
 			);
 			buildRules = (
 			);
@@ -541,9 +625,13 @@
 		5376128C155AB74D005750A4 /* Project object */ = {
 			isa = PBXProject;
 			attributes = {
+				LastSwiftUpdateCheck = 1520;
 				LastUpgradeCheck = 0940;
 				ORGANIZATIONNAME = Dailymotion;
 				TargetAttributes = {
+					3220E26D2B7B0755005F83A5 = {
+						CreatedOnToolsVersion = 15.2;
+					};
 					4314D1A51D0E1181004B36C9 = {
 						CreatedOnToolsVersion = 7.3.1;
 					};
@@ -576,11 +664,21 @@
 				43A629ED1D0E07600089D7DD /* SDWebImage Watch Demo */,
 				43A629F91D0E07600089D7DD /* SDWebImage Watch Demo Extension */,
 				4314D1A51D0E1181004B36C9 /* SDWebImage TV Demo */,
+				3220E26D2B7B0755005F83A5 /* SDWebImage Vision Demo */,
 			);
 		};
 /* End PBXProject section */
 
 /* Begin PBXResourcesBuildPhase section */
+		3220E26C2B7B0755005F83A5 /* Resources */ = {
+			isa = PBXResourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				3220E27C2B7B0755005F83A5 /* Preview Assets.xcassets in Resources */,
+				3220E2792B7B0755005F83A5 /* Assets.xcassets in Resources */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
 		4314D1A41D0E1181004B36C9 /* Resources */ = {
 			isa = PBXResourcesBuildPhase;
 			buildActionMask = 2147483647;
@@ -631,7 +729,29 @@
 /* End PBXResourcesBuildPhase section */
 
 /* Begin PBXShellScriptBuildPhase section */
-		597F887D0D1A778333E020BA /* [CP] Embed Pods Frameworks */ = {
+		3EE15CCA9FC9CD888D0A8221 /* [CP] Embed Pods Frameworks */ = {
+			isa = PBXShellScriptBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+			);
+			inputPaths = (
+				"${PODS_ROOT}/Target Support Files/Pods-SDWebImage iOS Demo/Pods-SDWebImage iOS Demo-frameworks.sh",
+				"${BUILT_PRODUCTS_DIR}/SDWebImage-Core-MapKit-iOS/SDWebImage.framework",
+				"${BUILT_PRODUCTS_DIR}/SDWebImageWebPCoder-iOS/SDWebImageWebPCoder.framework",
+				"${BUILT_PRODUCTS_DIR}/libwebp-iOS/libwebp.framework",
+			);
+			name = "[CP] Embed Pods Frameworks";
+			outputPaths = (
+				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SDWebImage.framework",
+				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SDWebImageWebPCoder.framework",
+				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/libwebp.framework",
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+			shellPath = /bin/sh;
+			shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-SDWebImage iOS Demo/Pods-SDWebImage iOS Demo-frameworks.sh\"\n";
+			showEnvVarsInLog = 0;
+		};
+		4E998E1DF728CCAF009D92E4 /* [CP] Embed Pods Frameworks */ = {
 			isa = PBXShellScriptBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
@@ -653,16 +773,16 @@
 			shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-SDWebImage OSX Demo/Pods-SDWebImage OSX Demo-frameworks.sh\"\n";
 			showEnvVarsInLog = 0;
 		};
-		8425DD76050A8A49F8DAF736 /* [CP] Embed Pods Frameworks */ = {
+		79F9A2D3C039A7C473F3E579 /* [CP] Embed Pods Frameworks */ = {
 			isa = PBXShellScriptBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
 			);
 			inputPaths = (
-				"${PODS_ROOT}/Target Support Files/Pods-SDWebImage iOS Demo/Pods-SDWebImage iOS Demo-frameworks.sh",
-				"${BUILT_PRODUCTS_DIR}/SDWebImage-Core-MapKit-iOS/SDWebImage.framework",
-				"${BUILT_PRODUCTS_DIR}/SDWebImageWebPCoder-iOS/SDWebImageWebPCoder.framework",
-				"${BUILT_PRODUCTS_DIR}/libwebp-iOS/libwebp.framework",
+				"${PODS_ROOT}/Target Support Files/Pods-SDWebImage TV Demo/Pods-SDWebImage TV Demo-frameworks.sh",
+				"${BUILT_PRODUCTS_DIR}/SDWebImage-Core-MapKit-tvOS/SDWebImage.framework",
+				"${BUILT_PRODUCTS_DIR}/SDWebImageWebPCoder-tvOS/SDWebImageWebPCoder.framework",
+				"${BUILT_PRODUCTS_DIR}/libwebp-tvOS/libwebp.framework",
 			);
 			name = "[CP] Embed Pods Frameworks";
 			outputPaths = (
@@ -672,29 +792,27 @@
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 			shellPath = /bin/sh;
-			shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-SDWebImage iOS Demo/Pods-SDWebImage iOS Demo-frameworks.sh\"\n";
+			shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-SDWebImage TV Demo/Pods-SDWebImage TV Demo-frameworks.sh\"\n";
 			showEnvVarsInLog = 0;
 		};
-		85F5B7F46D00990FBEBF0377 /* [CP] Embed Pods Frameworks */ = {
+		9896DB377881E964826851E6 /* [CP] Embed Pods Frameworks */ = {
 			isa = PBXShellScriptBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
 			);
 			inputPaths = (
-				"${PODS_ROOT}/Target Support Files/Pods-SDWebImage Watch Demo Extension/Pods-SDWebImage Watch Demo Extension-frameworks.sh",
-				"${BUILT_PRODUCTS_DIR}/SDWebImage-Core/SDWebImage.framework",
-				"${BUILT_PRODUCTS_DIR}/SDWebImageWebPCoder-watchOS/SDWebImageWebPCoder.framework",
-				"${BUILT_PRODUCTS_DIR}/libwebp-watchOS/libwebp.framework",
+				"${PODS_ROOT}/Target Support Files/Pods-SDWebImage Vision Demo/Pods-SDWebImage Vision Demo-frameworks.sh",
+				"${BUILT_PRODUCTS_DIR}/SDWebImage.default-MapKit/SDWebImage.framework",
+				"${BUILT_PRODUCTS_DIR}/SDWebImageSwiftUI/SDWebImageSwiftUI.framework",
 			);
 			name = "[CP] Embed Pods Frameworks";
 			outputPaths = (
 				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SDWebImage.framework",
-				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SDWebImageWebPCoder.framework",
-				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/libwebp.framework",
+				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SDWebImageSwiftUI.framework",
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 			shellPath = /bin/sh;
-			shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-SDWebImage Watch Demo Extension/Pods-SDWebImage Watch Demo Extension-frameworks.sh\"\n";
+			shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-SDWebImage Vision Demo/Pods-SDWebImage Vision Demo-frameworks.sh\"\n";
 			showEnvVarsInLog = 0;
 		};
 		A50199B809E737E017D7DF1C /* [CP] Check Pods Manifest.lock */ = {
@@ -751,6 +869,28 @@
 			shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n    # print error to STDERR\n    echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n    exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
 			showEnvVarsInLog = 0;
 		};
+		BE1C2969523FD5B0A6AC02A9 /* [CP] Embed Pods Frameworks */ = {
+			isa = PBXShellScriptBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+			);
+			inputPaths = (
+				"${PODS_ROOT}/Target Support Files/Pods-SDWebImage Watch Demo Extension/Pods-SDWebImage Watch Demo Extension-frameworks.sh",
+				"${BUILT_PRODUCTS_DIR}/SDWebImage-Core/SDWebImage.framework",
+				"${BUILT_PRODUCTS_DIR}/SDWebImageWebPCoder-watchOS/SDWebImageWebPCoder.framework",
+				"${BUILT_PRODUCTS_DIR}/libwebp-watchOS/libwebp.framework",
+			);
+			name = "[CP] Embed Pods Frameworks";
+			outputPaths = (
+				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SDWebImage.framework",
+				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SDWebImageWebPCoder.framework",
+				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/libwebp.framework",
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+			shellPath = /bin/sh;
+			shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-SDWebImage Watch Demo Extension/Pods-SDWebImage Watch Demo Extension-frameworks.sh\"\n";
+			showEnvVarsInLog = 0;
+		};
 		FA507C7A3DC5CD9451511EB7 /* [CP] Check Pods Manifest.lock */ = {
 			isa = PBXShellScriptBuildPhase;
 			buildActionMask = 2147483647;
@@ -769,31 +909,41 @@
 			shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n    # print error to STDERR\n    echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n    exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
 			showEnvVarsInLog = 0;
 		};
-		FB94446B4DACAF8F385EB57C /* [CP] Embed Pods Frameworks */ = {
+		FE8AF0F7620DD545CC0FDB06 /* [CP] Check Pods Manifest.lock */ = {
 			isa = PBXShellScriptBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
 			);
+			inputFileListPaths = (
+			);
 			inputPaths = (
-				"${PODS_ROOT}/Target Support Files/Pods-SDWebImage TV Demo/Pods-SDWebImage TV Demo-frameworks.sh",
-				"${BUILT_PRODUCTS_DIR}/SDWebImage-Core-MapKit-tvOS/SDWebImage.framework",
-				"${BUILT_PRODUCTS_DIR}/SDWebImageWebPCoder-tvOS/SDWebImageWebPCoder.framework",
-				"${BUILT_PRODUCTS_DIR}/libwebp-tvOS/libwebp.framework",
+				"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
+				"${PODS_ROOT}/Manifest.lock",
+			);
+			name = "[CP] Check Pods Manifest.lock";
+			outputFileListPaths = (
 			);
-			name = "[CP] Embed Pods Frameworks";
 			outputPaths = (
-				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SDWebImage.framework",
-				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SDWebImageWebPCoder.framework",
-				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/libwebp.framework",
+				"$(DERIVED_FILE_DIR)/Pods-SDWebImage Vision Demo-checkManifestLockResult.txt",
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 			shellPath = /bin/sh;
-			shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-SDWebImage TV Demo/Pods-SDWebImage TV Demo-frameworks.sh\"\n";
+			shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n    # print error to STDERR\n    echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n    exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
 			showEnvVarsInLog = 0;
 		};
 /* End PBXShellScriptBuildPhase section */
 
 /* Begin PBXSourcesBuildPhase section */
+		3220E26A2B7B0755005F83A5 /* Sources */ = {
+			isa = PBXSourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				3220E2772B7B0755005F83A5 /* ContentView.swift in Sources */,
+				32464A842B7B0C30006BE70E /* DetailView.swift in Sources */,
+				3220E2752B7B0755005F83A5 /* App.swift in Sources */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
 		4314D1A21D0E1181004B36C9 /* Sources */ = {
 			isa = PBXSourcesBuildPhase;
 			buildActionMask = 2147483647;
@@ -896,6 +1046,161 @@
 /* End PBXVariantGroup section */
 
 /* Begin XCBuildConfiguration section */
+		3220E27E2B7B0755005F83A5 /* Debug */ = {
+			isa = XCBuildConfiguration;
+			baseConfigurationReference = 87F946759088F4E41FDC806A /* Pods-SDWebImage Vision Demo.debug.xcconfig */;
+			buildSettings = {
+				ALWAYS_SEARCH_USER_PATHS = NO;
+				ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+				ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
+				ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
+				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_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;
+				CODE_SIGN_STYLE = Automatic;
+				COPY_PHASE_STRIP = NO;
+				CURRENT_PROJECT_VERSION = 1;
+				DEBUG_INFORMATION_FORMAT = dwarf;
+				DEVELOPMENT_ASSET_PATHS = "\"SDWebImage Vision Demo/Preview Content\"";
+				ENABLE_PREVIEWS = YES;
+				ENABLE_STRICT_OBJC_MSGSEND = YES;
+				ENABLE_TESTABILITY = 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;
+				GENERATE_INFOPLIST_FILE = YES;
+				INFOPLIST_FILE = "$(TARGET_NAME)/Info.plist";
+				LD_RUNPATH_SEARCH_PATHS = (
+					"$(inherited)",
+					"@executable_path/Frameworks",
+				);
+				LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
+				MARKETING_VERSION = 1.0;
+				MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
+				MTL_FAST_MATH = YES;
+				ONLY_ACTIVE_ARCH = YES;
+				PRODUCT_BUNDLE_IDENTIFIER = "com.dailymotion.SDWebImage-Vision-Demo";
+				PRODUCT_NAME = "$(TARGET_NAME)";
+				SDKROOT = xros;
+				SUPPORTED_PLATFORMS = "xros xrsimulator";
+				SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)";
+				SWIFT_EMIT_LOC_STRINGS = YES;
+				SWIFT_OPTIMIZATION_LEVEL = "-Onone";
+				SWIFT_VERSION = 5.0;
+				TARGETED_DEVICE_FAMILY = "1,2,7";
+				XROS_DEPLOYMENT_TARGET = 1.0;
+			};
+			name = Debug;
+		};
+		3220E27F2B7B0755005F83A5 /* Release */ = {
+			isa = XCBuildConfiguration;
+			baseConfigurationReference = 11FB3839400DA48480ABA6BB /* Pods-SDWebImage Vision Demo.release.xcconfig */;
+			buildSettings = {
+				ALWAYS_SEARCH_USER_PATHS = NO;
+				ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+				ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
+				ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
+				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_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;
+				CODE_SIGN_STYLE = Automatic;
+				COPY_PHASE_STRIP = NO;
+				CURRENT_PROJECT_VERSION = 1;
+				DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+				DEVELOPMENT_ASSET_PATHS = "\"SDWebImage Vision Demo/Preview Content\"";
+				ENABLE_NS_ASSERTIONS = NO;
+				ENABLE_PREVIEWS = YES;
+				ENABLE_STRICT_OBJC_MSGSEND = 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;
+				GENERATE_INFOPLIST_FILE = YES;
+				INFOPLIST_FILE = "$(TARGET_NAME)/Info.plist";
+				LD_RUNPATH_SEARCH_PATHS = (
+					"$(inherited)",
+					"@executable_path/Frameworks",
+				);
+				LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
+				MARKETING_VERSION = 1.0;
+				MTL_ENABLE_DEBUG_INFO = NO;
+				MTL_FAST_MATH = YES;
+				PRODUCT_BUNDLE_IDENTIFIER = "com.dailymotion.SDWebImage-Vision-Demo";
+				PRODUCT_NAME = "$(TARGET_NAME)";
+				SDKROOT = xros;
+				SUPPORTED_PLATFORMS = "xros xrsimulator";
+				SWIFT_COMPILATION_MODE = wholemodule;
+				SWIFT_EMIT_LOC_STRINGS = YES;
+				SWIFT_VERSION = 5.0;
+				TARGETED_DEVICE_FAMILY = "1,2,7";
+				VALIDATE_PRODUCT = YES;
+				XROS_DEPLOYMENT_TARGET = 1.0;
+			};
+			name = Release;
+		};
 		4314D1B81D0E1182004B36C9 /* Debug */ = {
 			isa = XCBuildConfiguration;
 			baseConfigurationReference = 5A56E15AF819F64FBF1F65A9 /* Pods-SDWebImage TV Demo.debug.xcconfig */;
@@ -1057,6 +1362,15 @@
 /* End XCBuildConfiguration section */
 
 /* Begin XCConfigurationList section */
+		3220E2802B7B0755005F83A5 /* Build configuration list for PBXNativeTarget "SDWebImage Vision Demo" */ = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				3220E27E2B7B0755005F83A5 /* Debug */,
+				3220E27F2B7B0755005F83A5 /* Release */,
+			);
+			defaultConfigurationIsVisible = 0;
+			defaultConfigurationName = Release;
+		};
 		4314D1B71D0E1182004B36C9 /* Build configuration list for PBXNativeTarget "SDWebImage TV Demo" */ = {
 			isa = XCConfigurationList;
 			buildConfigurations = (
@@ -1112,6 +1426,13 @@
 			defaultConfigurationName = Release;
 		};
 /* End XCConfigurationList section */
+
+/* Begin XCSwiftPackageProductDependency section */
+		3220E2722B7B0755005F83A5 /* RealityKitContent */ = {
+			isa = XCSwiftPackageProductDependency;
+			productName = RealityKitContent;
+		};
+/* End XCSwiftPackageProductDependency section */
 	};
 	rootObject = 5376128C155AB74D005750A4 /* Project object */;
 }

+ 77 - 0
Examples/SDWebImage Demo.xcodeproj/xcshareddata/xcschemes/SDWebImage Vision Demo.xcscheme

@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Scheme
+   LastUpgradeVersion = "1520"
+   version = "1.7">
+   <BuildAction
+      parallelizeBuildables = "YES"
+      buildImplicitDependencies = "YES">
+      <BuildActionEntries>
+         <BuildActionEntry
+            buildForTesting = "YES"
+            buildForRunning = "YES"
+            buildForProfiling = "YES"
+            buildForArchiving = "YES"
+            buildForAnalyzing = "YES">
+            <BuildableReference
+               BuildableIdentifier = "primary"
+               BlueprintIdentifier = "3220E26D2B7B0755005F83A5"
+               BuildableName = "SDWebImage Vision Demo.app"
+               BlueprintName = "SDWebImage Vision Demo"
+               ReferencedContainer = "container:SDWebImage Demo.xcodeproj">
+            </BuildableReference>
+         </BuildActionEntry>
+      </BuildActionEntries>
+   </BuildAction>
+   <TestAction
+      buildConfiguration = "Debug"
+      selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
+      selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
+      shouldUseLaunchSchemeArgsEnv = "YES"
+      shouldAutocreateTestPlan = "YES">
+   </TestAction>
+   <LaunchAction
+      buildConfiguration = "Debug"
+      selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
+      selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
+      launchStyle = "0"
+      useCustomWorkingDirectory = "NO"
+      ignoresPersistentStateOnLaunch = "NO"
+      debugDocumentVersioning = "YES"
+      debugServiceExtension = "internal"
+      allowLocationSimulation = "YES">
+      <BuildableProductRunnable
+         runnableDebuggingMode = "0">
+         <BuildableReference
+            BuildableIdentifier = "primary"
+            BlueprintIdentifier = "3220E26D2B7B0755005F83A5"
+            BuildableName = "SDWebImage Vision Demo.app"
+            BlueprintName = "SDWebImage Vision Demo"
+            ReferencedContainer = "container:SDWebImage Demo.xcodeproj">
+         </BuildableReference>
+      </BuildableProductRunnable>
+   </LaunchAction>
+   <ProfileAction
+      buildConfiguration = "Release"
+      shouldUseLaunchSchemeArgsEnv = "YES"
+      savedToolIdentifier = ""
+      useCustomWorkingDirectory = "NO"
+      debugDocumentVersioning = "YES">
+      <BuildableProductRunnable
+         runnableDebuggingMode = "0">
+         <BuildableReference
+            BuildableIdentifier = "primary"
+            BlueprintIdentifier = "3220E26D2B7B0755005F83A5"
+            BuildableName = "SDWebImage Vision Demo.app"
+            BlueprintName = "SDWebImage Vision Demo"
+            ReferencedContainer = "container:SDWebImage Demo.xcodeproj">
+         </BuildableReference>
+      </BuildableProductRunnable>
+   </ProfileAction>
+   <AnalyzeAction
+      buildConfiguration = "Debug">
+   </AnalyzeAction>
+   <ArchiveAction
+      buildConfiguration = "Release"
+      revealArchiveInOrganizer = "YES">
+   </ArchiveAction>
+</Scheme>

+ 30 - 0
Examples/SDWebImage Vision Demo/App.swift

@@ -0,0 +1,30 @@
+/*
+* This file is part of the SDWebImage package.
+* (c) DreamPiggy <lizhuoli1126@126.com>
+*
+* For the full copyright and license information, please view the LICENSE
+* file that was distributed with this source code.
+*/
+
+import SwiftUI
+import SDWebImage
+
+class AppDelegate: NSObject, UIApplicationDelegate {
+    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
+        // Insert code here to initialize your application
+        SDImageCodersManager.shared.addCoder(SDImageAWebPCoder.shared)
+        SDImageCodersManager.shared.addCoder(SDImageHEICCoder.shared)
+        return true
+    }
+}
+
+@main
+struct SDWebImage_Vision_DemoApp: App {
+    @UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
+    
+    var body: some Scene {
+        WindowGroup {
+            ContentView()
+        }
+    }
+}

+ 12 - 0
Examples/SDWebImage Vision Demo/Assets.xcassets/AppIcon.solidimagestack/Back.solidimagestacklayer/Content.imageset/Contents.json

@@ -0,0 +1,12 @@
+{
+  "images" : [
+    {
+      "idiom" : "vision",
+      "scale" : "2x"
+    }
+  ],
+  "info" : {
+    "author" : "xcode",
+    "version" : 1
+  }
+}

+ 6 - 0
Examples/SDWebImage Vision Demo/Assets.xcassets/AppIcon.solidimagestack/Back.solidimagestacklayer/Contents.json

@@ -0,0 +1,6 @@
+{
+  "info" : {
+    "author" : "xcode",
+    "version" : 1
+  }
+}

+ 17 - 0
Examples/SDWebImage Vision Demo/Assets.xcassets/AppIcon.solidimagestack/Contents.json

@@ -0,0 +1,17 @@
+{
+  "info" : {
+    "author" : "xcode",
+    "version" : 1
+  },
+  "layers" : [
+    {
+      "filename" : "Front.solidimagestacklayer"
+    },
+    {
+      "filename" : "Middle.solidimagestacklayer"
+    },
+    {
+      "filename" : "Back.solidimagestacklayer"
+    }
+  ]
+}

+ 12 - 0
Examples/SDWebImage Vision Demo/Assets.xcassets/AppIcon.solidimagestack/Front.solidimagestacklayer/Content.imageset/Contents.json

@@ -0,0 +1,12 @@
+{
+  "images" : [
+    {
+      "idiom" : "vision",
+      "scale" : "2x"
+    }
+  ],
+  "info" : {
+    "author" : "xcode",
+    "version" : 1
+  }
+}

+ 6 - 0
Examples/SDWebImage Vision Demo/Assets.xcassets/AppIcon.solidimagestack/Front.solidimagestacklayer/Contents.json

@@ -0,0 +1,6 @@
+{
+  "info" : {
+    "author" : "xcode",
+    "version" : 1
+  }
+}

+ 12 - 0
Examples/SDWebImage Vision Demo/Assets.xcassets/AppIcon.solidimagestack/Middle.solidimagestacklayer/Content.imageset/Contents.json

@@ -0,0 +1,12 @@
+{
+  "images" : [
+    {
+      "idiom" : "vision",
+      "scale" : "2x"
+    }
+  ],
+  "info" : {
+    "author" : "xcode",
+    "version" : 1
+  }
+}

+ 6 - 0
Examples/SDWebImage Vision Demo/Assets.xcassets/AppIcon.solidimagestack/Middle.solidimagestacklayer/Contents.json

@@ -0,0 +1,6 @@
+{
+  "info" : {
+    "author" : "xcode",
+    "version" : 1
+  }
+}

+ 6 - 0
Examples/SDWebImage Vision Demo/Assets.xcassets/Contents.json

@@ -0,0 +1,6 @@
+{
+  "info" : {
+    "version" : 1,
+    "author" : "xcode"
+  }
+}

+ 114 - 0
Examples/SDWebImage Vision Demo/ContentView.swift

@@ -0,0 +1,114 @@
+/*
+* This file is part of the SDWebImage package.
+* (c) DreamPiggy <lizhuoli1126@126.com>
+*
+* For the full copyright and license information, please view the LICENSE
+* file that was distributed with this source code.
+*/
+
+import SwiftUI
+import RealityKit
+import RealityKitContent
+import SDWebImage
+import SDWebImageSwiftUI
+
+struct ContentView: View {
+    @State var imageURLs = [
+    "http://assets.sbnation.com/assets/2512203/dogflops.gif",
+    "https://raw.githubusercontent.com/liyong03/YLGIFImage/master/YLGIFImageDemo/YLGIFImageDemo/joy.gif",
+    "http://apng.onevcat.com/assets/elephant.png",
+    "http://www.ioncannon.net/wp-content/uploads/2011/06/test2.webp",
+    "http://www.ioncannon.net/wp-content/uploads/2011/06/test9.webp",
+    "http://littlesvr.ca/apng/images/SteamEngine.webp",
+    "http://littlesvr.ca/apng/images/world-cup-2014-42.webp",
+    "https://isparta.github.io/compare-webp/image/gif_webp/webp/2.webp",
+    "https://nokiatech.github.io/heif/content/images/ski_jump_1440x960.heic",
+    "https://nokiatech.github.io/heif/content/image_sequences/starfield_animation.heic",
+    "https://nr-platform.s3.amazonaws.com/uploads/platform/published_extension/branding_icon/275/AmazonS3.png",
+    "https://raw.githubusercontent.com/ibireme/YYImage/master/Demo/YYImageDemo/mew_baseline.jpg",
+    "https://via.placeholder.com/200x200.jpg",
+    "https://raw.githubusercontent.com/recurser/exif-orientation-examples/master/Landscape_5.jpg",
+    "https://dev.w3.org/SVG/tools/svgweb/samples/svg-files/w3c.svg",
+    "https://dev.w3.org/SVG/tools/svgweb/samples/svg-files/wikimedia.svg",
+    "https://raw.githubusercontent.com/icons8/flat-color-icons/master/pdf/stack_of_photos.pdf",
+    "https://raw.githubusercontent.com/icons8/flat-color-icons/master/pdf/smartphone_tablet.pdf"
+    ]
+    @State var animated: Bool = false // You can change between WebImage/AnimatedImage
+    
+    // Used to avoid https://twitter.com/fatbobman/status/1572507700436807683?s=20&t=5rfj6BUza5Jii-ynQatCFA
+    struct ItemView: View {
+        @Binding var animated: Bool
+        @State var url: String
+        var body: some View {
+            NavigationLink(destination: DetailView(url: url, animated: self.animated)) {
+                HStack {
+                    if self.animated {
+                        AnimatedImage(url: URL(string:url))
+                        .indicator(.activity)
+                        .transition(.fade)
+                        .resizable()
+                        .scaledToFit()
+                        .frame(width: CGFloat(100), height: CGFloat(100), alignment: .center)
+                    } else {
+                        WebImage(url: URL(string:url))
+                        .resizable()
+                        .indicator(.activity)
+                        .transition(.fade(duration: 0.5))
+                        .scaledToFit()
+                        .frame(width: CGFloat(100), height: CGFloat(100), alignment: .center)
+                    }
+                    Text((url as NSString).lastPathComponent)
+                }
+            }
+            .buttonStyle(PlainButtonStyle())
+        }
+    }
+
+    
+    var body: some View {
+        return NavigationView {
+            contentView()
+            .navigationBarTitle(animated ? "AnimatedImage" : "WebImage")
+            .navigationBarItems(leading:
+                Button(action: { self.reloadCache() }) {
+                    Text("Reload")
+                }, trailing:
+                Button(action: { self.switchView() }) {
+                    Text("Switch")
+                }
+            )
+        }
+    }
+    
+    func contentView() -> some View {
+        List {
+            ForEach(imageURLs, id: \.self) { url in
+                // Must use top level view instead of inlined view structure
+                ItemView(animated: $animated, url: url)
+            }
+            .onDelete { indexSet in
+                indexSet.forEach { index in
+                    self.imageURLs.remove(at: index)
+                }
+            }
+        }
+    }
+    
+    func reloadCache() {
+        SDImageCache.shared.clearMemory()
+        SDImageCache.shared.clearDisk(onCompletion: nil)
+    }
+    
+    func switchView() {
+        SDImageCache.shared.clearMemory()
+        animated.toggle()
+    }
+}
+
+#if DEBUG
+struct ContentView_Previews: PreviewProvider {
+    static var previews: some View {
+        ContentView()
+    }
+}
+#endif

+ 48 - 0
Examples/SDWebImage Vision Demo/DetailView.swift

@@ -0,0 +1,48 @@
+/*
+* This file is part of the SDWebImage package.
+* (c) DreamPiggy <lizhuoli1126@126.com>
+*
+* For the full copyright and license information, please view the LICENSE
+* file that was distributed with this source code.
+*/
+
+import SwiftUI
+import SDWebImageSwiftUI
+
+struct DetailView: View {
+    let url: String
+    @State var animated: Bool = true // You can change between WebImage/AnimatedImage
+    @State var isAnimating: Bool = true
+    
+    var body: some View {
+        VStack {
+            contentView()
+            .navigationBarItems(trailing: Button(isAnimating ? "Stop" : "Start") {
+                self.isAnimating.toggle()
+            })
+        }
+    }
+    func contentView() -> some View {
+        HStack {
+            if animated {
+                AnimatedImage(url: URL(string:url), options: [.progressiveLoad, .delayPlaceholder], isAnimating: $isAnimating)
+                .indicator(.progress)
+                .resizable()
+                .scaledToFit()
+            } else {
+                WebImage(url: URL(string:url), options: [.progressiveLoad, .delayPlaceholder], isAnimating: $isAnimating)
+                .resizable()
+                .indicator(.progress)
+                .scaledToFit()
+            }
+        }
+    }
+}
+
+#if DEBUG
+struct DetailView_Previews: PreviewProvider {
+    static var previews: some View {
+        DetailView(url: "https://nokiatech.github.io/heif/content/images/ski_jump_1440x960.heic", animated: false)
+    }
+}
+#endif

+ 20 - 0
Examples/SDWebImage Vision Demo/Info.plist

@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>NSAppTransportSecurity</key>
+	<dict>
+		<key>NSAllowsArbitraryLoads</key>
+		<true/>
+	</dict>
+	<key>UIApplicationSceneManifest</key>
+	<dict>
+		<key>UIApplicationPreferredDefaultSceneSessionRole</key>
+		<string>UIWindowSceneSessionRoleApplication</string>
+		<key>UIApplicationSupportsMultipleScenes</key>
+		<true/>
+		<key>UISceneConfigurations</key>
+		<dict/>
+	</dict>
+</dict>
+</plist>

+ 6 - 0
Examples/SDWebImage Vision Demo/Preview Content/Preview Assets.xcassets/Contents.json

@@ -0,0 +1,6 @@
+{
+  "info" : {
+    "author" : "xcode",
+    "version" : 1
+  }
+}

+ 33 - 13
Podfile

@@ -10,11 +10,16 @@ def watch_example_pods
   pod 'SDWebImageWebPCoder', :git => 'https://github.com/SDWebImage/SDWebImageWebPCoder.git', :branch => 'master'
 end
 
+def vision_example_pods
+  pod 'SDWebImage/MapKit', :path => './'
+  pod 'SDWebImageSwiftUI', :git => 'https://github.com/SDWebImage/SDWebImageSwiftUI.git', :branch => 'master'
+end
+
 def all_test_pods
   pod 'SDWebImage/MapKit', :path => './'
-  pod 'Expecta'
-  pod 'KVOController'
-  pod 'SDWebImageWebPCoder', :git => 'https://github.com/SDWebImage/SDWebImageWebPCoder.git', :branch => 'master'
+  # These two Pods seems no longer maintained...
+  pod 'Expecta', :podspec => 'Tests/Expecta.podspec'
+  pod 'KVOController', :podspec => 'Tests/KVOController.podspec'
 end
 
 example_project_path = 'Examples/SDWebImage Demo'
@@ -46,6 +51,12 @@ target 'SDWebImage Watch Demo Extension' do
   watch_example_pods
 end
 
+target 'SDWebImage Vision Demo' do
+  project example_project_path
+  platform :visionos, '1.0'
+  vision_example_pods
+end
+
 # Test Project
 target 'Tests iOS' do
   project test_project_path
@@ -65,18 +76,27 @@ target 'Tests TV' do
   all_test_pods
 end
 
+target 'Tests Vision' do
+  project test_project_path
+  platform :visionos, '1.0'
+  all_test_pods
+end
+
 # Inject macro during SDWebImage Demo and Tests
 post_install do |installer_representation|
-  installer_representation.generated_pod_targets.each do |target|
-    if target.pod_name == "SDWebImage"
-      build_settings = target.build_settings
-      build_settings.each do |configuration, build_setting|
-        if configuration == :debug
-          config = build_setting.xcconfig
-          old_value = config.attributes['GCC_PREPROCESSOR_DEFINITIONS']
-          config.attributes['GCC_PREPROCESSOR_DEFINITIONS'] = old_value + ' SD_CHECK_CGIMAGE_RETAIN_SOURCE=1'
-          config.save_as(target.xcconfig_path(configuration))
-        end
+  installer_representation.pods_project.targets.each do |target|
+    if target.product_name == 'SDWebImage'
+      target.build_configurations.each do |config|
+        config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] = '$(inherited) SD_CHECK_CGIMAGE_RETAIN_SOURCE=1'
+      end
+    else
+      target.build_configurations.each do |config|
+        # Override the min deployment target for some test specs to workaround `libarclite.a` missing issue
+        config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '9.0'
+        config.build_settings['MACOSX_DEPLOYMENT_TARGET'] = '10.11'
+        config.build_settings['TVOS_DEPLOYMENT_TARGET'] = '9.0'
+        config.build_settings['WATCHOS_DEPLOYMENT_TARGET'] = '2.0'
+        config.build_settings['XROS_DEPLOYMENT_TARGET'] = '1.0'
       end
     end
   end

+ 2 - 1
README.md

@@ -111,7 +111,8 @@ You can use those directly, or create similar components of your own, by using t
 - tvOS 9.0 or later
 - watchOS 2.0 or later
 - macOS 10.11 or later (10.15 for Catalyst)
-- Xcode 11.0 or later
+- visionOS 1.0 or later
+- Xcode 13.0 or later (visionOS requires Xcode 15.0)
 
 #### Backwards compatibility
 

+ 2 - 0
SDWebImage.podspec

@@ -6,6 +6,7 @@ Pod::Spec.new do |s|
   s.ios.deployment_target = '9.0'
   s.tvos.deployment_target = '9.0'
   s.watchos.deployment_target = '2.0'
+  s.visionos.deployment_target = "1.0"
 
   s.license = 'MIT'
   s.summary = 'Asynchronous image downloader with cache support with an UIImageView category.'
@@ -40,6 +41,7 @@ Pod::Spec.new do |s|
     mk.osx.deployment_target = '10.11'
     mk.ios.deployment_target = '9.0'
     mk.tvos.deployment_target = '9.0'
+    mk.visionos.deployment_target = "1.0"
     mk.source_files = 'SDWebImageMapKit/MapKit/*.{h,m}'
     mk.framework = 'MapKit'
     mk.dependency 'SDWebImage/Core'

+ 31 - 0
Tests/Expecta.podspec

@@ -0,0 +1,31 @@
+Pod::Spec.new do |s|
+  s.name     = 'Expecta'
+  s.version  = '1.0.6'
+  s.license  = { :type => 'MIT', :file => 'LICENSE' }
+  s.summary  = 'A matcher framework for Objective-C & Cocoa.'
+  s.homepage = 'http://github.com/petejkim/expecta'
+  s.author   = { 'Peter Jihoon Kim' => 'raingrove@gmail.com' }
+
+  s.source   = { :git => 'https://github.com/specta/expecta.git', :tag => "v#{s.version}" }
+
+  s.description = %{
+    Expecta is a matcher framework for Objective-C and Cocoa. The main
+    advantage of using Expecta over other matcher frameworks is that you do not
+    have to specify the data types. Also, the syntax of Expecta matchers is
+    much more readable and does not suffer from parenthesitis. If you have used
+    Jasmine before, you will feel right at home!
+  }
+
+  s.source_files = 'Expecta/**/*.{h,m}'
+
+  s.requires_arc = false
+  s.ios.deployment_target = '9.0'
+  s.osx.deployment_target = '10.11'
+  s.tvos.deployment_target = '9.0'
+  s.watchos.deployment_target = '2.0'
+  s.visionos.deployment_target = '1.0'
+
+  s.frameworks = 'Foundation', 'XCTest'
+  s.pod_target_xcconfig = { 'ENABLE_BITCODE' => 'NO' }
+  s.user_target_xcconfig = { 'FRAMEWORK_SEARCH_PATHS' => '$(PLATFORM_DIR)/Developer/Library/Frameworks' }
+end

+ 25 - 0
Tests/KVOController.podspec

@@ -0,0 +1,25 @@
+Pod::Spec.new do |spec|
+  spec.name         = 'KVOController'
+  spec.version      = '1.2.0'
+  spec.license      =  { :type => 'BSD' }
+  spec.homepage     = 'https://github.com/facebook/KVOController'
+  spec.authors      = { 'Kimon Tsinteris' => 'kimon@mac.com', 'Nikita Lutsenko' => 'nlutsenko@me.com' }
+  spec.summary      = 'Simple, modern, thread-safe key-value observing.'
+  spec.description  = <<-DESC
+                      KVOController builds on Cocoa's time-tested key-value observing implementation. It offers a simple, modern API, that is also thread safe.
+                      Benefits include:
+                      Notification using blocks, custom actions, or NSKeyValueObserving callback.
+                      No exceptions on observer removal.
+                      Implicit observer removal on controller dealloc.
+                      Thread-safety with special guards against observer resurrection.
+                      DESC
+  spec.source       = { :git => 'https://github.com/facebook/KVOController.git', :tag => "v#{spec.version.to_s}" }
+  spec.source_files = 'FBKVOController/*.{h,m}'
+  spec.requires_arc = true
+
+  spec.ios.deployment_target = '9.0'
+  spec.osx.deployment_target = '10.11'
+  spec.tvos.deployment_target = '9.0'
+  spec.watchos.deployment_target = '2.0'
+  spec.visionos.deployment_target = '1.0'
+end

+ 363 - 51
Tests/SDWebImage Tests.xcodeproj/project.pbxproj

@@ -27,6 +27,44 @@
 		323B8E2020862322008952BE /* SDWebImageTestLoader.m in Sources */ = {isa = PBXBuildFile; fileRef = 323B8E1E20862322008952BE /* SDWebImageTestLoader.m */; };
 		324047442271956F007C53E1 /* TestEXIF.png in Resources */ = {isa = PBXBuildFile; fileRef = 324047432271956F007C53E1 /* TestEXIF.png */; };
 		324047452271956F007C53E1 /* TestEXIF.png in Resources */ = {isa = PBXBuildFile; fileRef = 324047432271956F007C53E1 /* TestEXIF.png */; };
+		32464A902B7B1833006BE70E /* 1@2x.gif in Resources */ = {isa = PBXBuildFile; fileRef = 32648066250232F7004FA0FC /* 1@2x.gif */; };
+		32464A912B7B1833006BE70E /* TestImage.nef in Resources */ = {isa = PBXBuildFile; fileRef = 32F788A2290D252200B57A1C /* TestImage.nef */; };
+		32464A922B7B1833006BE70E /* TestImage.heic in Resources */ = {isa = PBXBuildFile; fileRef = 327A418B211D660600495442 /* TestImage.heic */; };
+		32464A932B7B1833006BE70E /* TestImageAnimated.heic in Resources */ = {isa = PBXBuildFile; fileRef = 3297A09E23374D1600814590 /* TestImageAnimated.heic */; };
+		32464A942B7B1833006BE70E /* TestJFIF.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 3264CD162AAB1E23001E338B /* TestJFIF.jpg */; };
+		32464A952B7B1833006BE70E /* TestImageStatic.webp in Resources */ = {isa = PBXBuildFile; fileRef = 32515F9724AF1919005E8F79 /* TestImageStatic.webp */; };
+		32464A962B7B1833006BE70E /* TestImage.gif in Resources */ = {isa = PBXBuildFile; fileRef = 433BBBB61D7EF8200086B6E9 /* TestImage.gif */; };
+		32464A972B7B1833006BE70E /* TestImage.bmp in Resources */ = {isa = PBXBuildFile; fileRef = 321F310D27D0DC490042B274 /* TestImage.bmp */; };
+		32464A982B7B1833006BE70E /* TestLoopCount.gif in Resources */ = {isa = PBXBuildFile; fileRef = 326E69462334C0C200B7252C /* TestLoopCount.gif */; };
+		32464A992B7B1833006BE70E /* TestEXIF.png in Resources */ = {isa = PBXBuildFile; fileRef = 324047432271956F007C53E1 /* TestEXIF.png */; };
+		32464A9A2B7B1833006BE70E /* TestImage.png in Resources */ = {isa = PBXBuildFile; fileRef = 433BBBB81D7EF8260086B6E9 /* TestImage.png */; };
+		32464A9B2B7B1833006BE70E /* TestAnimatedImageMemory.webp in Resources */ = {isa = PBXBuildFile; fileRef = 6B181A1A265757ED00BD06B3 /* TestAnimatedImageMemory.webp */; };
+		32464A9C2B7B1833006BE70E /* TestImage.pdf in Resources */ = {isa = PBXBuildFile; fileRef = 3234306123E2BAC800C290C8 /* TestImage.pdf */; };
+		32464A9D2B7B1833006BE70E /* TestImageAnimated.apng in Resources */ = {isa = PBXBuildFile; fileRef = 327054E1206CEFF3006EA328 /* TestImageAnimated.apng */; };
+		32464A9E2B7B1833006BE70E /* TestImageAnimated.webp in Resources */ = {isa = PBXBuildFile; fileRef = 32515F9824AF1919005E8F79 /* TestImageAnimated.webp */; };
+		32464A9F2B7B1833006BE70E /* IndexedPNG.png in Resources */ = {isa = PBXBuildFile; fileRef = 3278F5E12B04C1AC0004A6EE /* IndexedPNG.png */; };
+		32464AA02B7B1833006BE70E /* TestImage.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 5F7F38AC1AE2A77A00B0E330 /* TestImage.jpg */; };
+		32464AA12B7B1833006BE70E /* MonochromeTestImage.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 433BBBBA1D7EFA8B0086B6E9 /* MonochromeTestImage.jpg */; };
+		32464AA22B7B1833006BE70E /* TestImageLarge.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 43828A441DA67F9900000E62 /* TestImageLarge.jpg */; };
+		32464AA32B7B1833006BE70E /* TestImage.heif in Resources */ = {isa = PBXBuildFile; fileRef = 32905E63211D786E00460FCF /* TestImage.heif */; };
+		32464AA42B7B1833006BE70E /* TestImageLarge.png in Resources */ = {isa = PBXBuildFile; fileRef = 320224F62440C39B00E5B29D /* TestImageLarge.png */; };
+		32464AA52B7B1845006BE70E /* SDWebImageManagerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = DA248D6A195476AC00390AB0 /* SDWebImageManagerTests.m */; };
+		32464AA62B7B1845006BE70E /* SDMockFileManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 37D122871EC48B5E00D98CEB /* SDMockFileManager.m */; };
+		32464AA72B7B1845006BE70E /* SDImageTransformerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 3254C31F20641077008D1022 /* SDImageTransformerTests.m */; };
+		32464AA82B7B1845006BE70E /* SDUtilsTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 3222417E2272F808002429DB /* SDUtilsTests.m */; };
+		32464AA92B7B1845006BE70E /* SDWebImageTestLoader.m in Sources */ = {isa = PBXBuildFile; fileRef = 323B8E1E20862322008952BE /* SDWebImageTestLoader.m */; };
+		32464AAA2B7B1845006BE70E /* SDWebImageTestDownloadOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = 3226ECBA20754F7700FAFACF /* SDWebImageTestDownloadOperation.m */; };
+		32464AAB2B7B1845006BE70E /* SDWebImageDownloaderTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 1E3C51E819B46E370092B5E6 /* SDWebImageDownloaderTests.m */; };
+		32464AAC2B7B1845006BE70E /* SDTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 2D7AF05F1F329763000083C2 /* SDTestCase.m */; };
+		32464AAD2B7B1845006BE70E /* SDWebImageTestTransformer.m in Sources */ = {isa = PBXBuildFile; fileRef = 3264FF2E205D42CB00F6BD48 /* SDWebImageTestTransformer.m */; };
+		32464AAE2B7B1845006BE70E /* SDWebImageTestCoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 32E6F0311F3A1B4700A945E6 /* SDWebImageTestCoder.m */; };
+		32464AAF2B7B1845006BE70E /* SDWebImagePrefetcherTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 4369C1D01D97F80F007E863A /* SDWebImagePrefetcherTests.m */; };
+		32464AB02B7B1845006BE70E /* SDWebCacheCategoriesTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 4369C2731D9804B1007E863A /* SDWebCacheCategoriesTests.m */; };
+		32464AB12B7B1845006BE70E /* SDAnimatedImageTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 32A571552037DB2D002EDAAE /* SDAnimatedImageTest.m */; };
+		32464AB22B7B1845006BE70E /* SDWebImageTestCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 328BB6DC20825E9800760D6C /* SDWebImageTestCache.m */; };
+		32464AB32B7B1845006BE70E /* SDImageCacheTests.m in Sources */ = {isa = PBXBuildFile; fileRef = DA248D68195475D800390AB0 /* SDImageCacheTests.m */; };
+		32464AB42B7B1845006BE70E /* SDImageCoderTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 433BBBB41D7EF5C00086B6E9 /* SDImageCoderTests.m */; };
+		32464AB52B7B1845006BE70E /* SDCategoriesTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 32B99E8A203AF8690017FD66 /* SDCategoriesTests.m */; };
 		32515F9924AF1919005E8F79 /* TestImageStatic.webp in Resources */ = {isa = PBXBuildFile; fileRef = 32515F9724AF1919005E8F79 /* TestImageStatic.webp */; };
 		32515F9A24AF1919005E8F79 /* TestImageStatic.webp in Resources */ = {isa = PBXBuildFile; fileRef = 32515F9724AF1919005E8F79 /* TestImageStatic.webp */; };
 		32515F9B24AF1919005E8F79 /* TestImageStatic.webp in Resources */ = {isa = PBXBuildFile; fileRef = 32515F9724AF1919005E8F79 /* TestImageStatic.webp */; };
@@ -119,14 +157,15 @@
 		6B181A1B265757ED00BD06B3 /* TestAnimatedImageMemory.webp in Resources */ = {isa = PBXBuildFile; fileRef = 6B181A1A265757ED00BD06B3 /* TestAnimatedImageMemory.webp */; };
 		6BC1C20F270F0193003FFAB1 /* TestAnimatedImageMemory.webp in Resources */ = {isa = PBXBuildFile; fileRef = 6B181A1A265757ED00BD06B3 /* TestAnimatedImageMemory.webp */; };
 		6BC1C210270F073A003FFAB1 /* TestAnimatedImageMemory.webp in Resources */ = {isa = PBXBuildFile; fileRef = 6B181A1A265757ED00BD06B3 /* TestAnimatedImageMemory.webp */; };
-		770D3B9C7914D53EBA0524DB /* Pods_Tests_TV.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B73996BC299E8E0174661628 /* Pods_Tests_TV.framework */; };
-		AFDBD4044E95252B70FB85CE /* Pods_Tests_iOS.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AD1BD830DA7388EB6C110B3B /* Pods_Tests_iOS.framework */; };
+		6FD27F0B29D57A4AACB56EA8 /* Pods_Tests_TV.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5B18D772CFF936546772B836 /* Pods_Tests_TV.framework */; };
+		8C71262F36B4B9A4EA9BD000 /* Pods_Tests_iOS.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DD978FDEC70C6C3978DA4D56 /* Pods_Tests_iOS.framework */; };
+		97A6B676B89A44368345A1A0 /* Pods_Tests_Vision.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A356608C341F465A482F0D7B /* Pods_Tests_Vision.framework */; };
+		B77B223649B05D013FE6E310 /* Pods_Tests_Mac.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 61030057F379B8F1D44EBF88 /* Pods_Tests_Mac.framework */; };
 		DA248D57195472AA00390AB0 /* XCTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DA248D56195472AA00390AB0 /* XCTest.framework */; };
 		DA248D59195472AA00390AB0 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DA248D58195472AA00390AB0 /* Foundation.framework */; };
 		DA248D5B195472AA00390AB0 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DA248D5A195472AA00390AB0 /* UIKit.framework */; };
 		DA248D69195475D800390AB0 /* SDImageCacheTests.m in Sources */ = {isa = PBXBuildFile; fileRef = DA248D68195475D800390AB0 /* SDImageCacheTests.m */; };
 		DA248D6B195476AC00390AB0 /* SDWebImageManagerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = DA248D6A195476AC00390AB0 /* SDWebImageManagerTests.m */; };
-		F02C3B9D48DEEC3622E96336 /* Pods_Tests_Mac.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A39EDFED1067C297B91792CB /* Pods_Tests_Mac.framework */; };
 /* End PBXBuildFile section */
 
 /* Begin PBXFileReference section */
@@ -143,6 +182,7 @@
 		323B8E1D20862322008952BE /* SDWebImageTestLoader.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SDWebImageTestLoader.h; sourceTree = "<group>"; };
 		323B8E1E20862322008952BE /* SDWebImageTestLoader.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SDWebImageTestLoader.m; sourceTree = "<group>"; };
 		324047432271956F007C53E1 /* TestEXIF.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = TestEXIF.png; sourceTree = "<group>"; };
+		32464A892B7B0FF2006BE70E /* Tests Vision.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "Tests Vision.xctest"; sourceTree = BUILT_PRODUCTS_DIR; };
 		32515F9724AF1919005E8F79 /* TestImageStatic.webp */ = {isa = PBXFileReference; lastKnownFileType = file; path = TestImageStatic.webp; sourceTree = "<group>"; };
 		32515F9824AF1919005E8F79 /* TestImageAnimated.webp */ = {isa = PBXFileReference; lastKnownFileType = file; path = TestImageAnimated.webp; sourceTree = "<group>"; };
 		3254C31F20641077008D1022 /* SDImageTransformerTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SDImageTransformerTests.m; sourceTree = "<group>"; };
@@ -182,13 +222,14 @@
 		4835C04148C737D0FC50EF87 /* Pods-Tests Mac.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Tests Mac.release.xcconfig"; path = "../Pods/Target Support Files/Pods-Tests Mac/Pods-Tests Mac.release.xcconfig"; sourceTree = "<group>"; };
 		4DCBA1DEFE6C68C4A83C9B9E /* Pods-Tests iOS.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Tests iOS.release.xcconfig"; path = "../Pods/Target Support Files/Pods-Tests iOS/Pods-Tests iOS.release.xcconfig"; sourceTree = "<group>"; };
 		5B0011ED58CC9998E68ECCE3 /* Pods-Tests TV.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Tests TV.debug.xcconfig"; path = "../Pods/Target Support Files/Pods-Tests TV/Pods-Tests TV.debug.xcconfig"; sourceTree = "<group>"; };
+		5B18D772CFF936546772B836 /* Pods_Tests_TV.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Tests_TV.framework; sourceTree = BUILT_PRODUCTS_DIR; };
 		5F7F38AC1AE2A77A00B0E330 /* TestImage.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = TestImage.jpg; sourceTree = "<group>"; };
+		61030057F379B8F1D44EBF88 /* Pods_Tests_Mac.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Tests_Mac.framework; sourceTree = BUILT_PRODUCTS_DIR; };
 		6700DBD9C45B00AB5F77472A /* Pods-Tests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Tests.release.xcconfig"; path = "../Pods/Target Support Files/Pods-Tests/Pods-Tests.release.xcconfig"; sourceTree = "<group>"; };
 		6B181A1A265757ED00BD06B3 /* TestAnimatedImageMemory.webp */ = {isa = PBXFileReference; lastKnownFileType = file; path = TestAnimatedImageMemory.webp; sourceTree = "<group>"; };
 		6CB13D7A081654B2E4018F53 /* Pods-Tests TV.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Tests TV.release.xcconfig"; path = "../Pods/Target Support Files/Pods-Tests TV/Pods-Tests TV.release.xcconfig"; sourceTree = "<group>"; };
-		A39EDFED1067C297B91792CB /* Pods_Tests_Mac.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Tests_Mac.framework; sourceTree = BUILT_PRODUCTS_DIR; };
-		AD1BD830DA7388EB6C110B3B /* Pods_Tests_iOS.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Tests_iOS.framework; sourceTree = BUILT_PRODUCTS_DIR; };
-		B73996BC299E8E0174661628 /* Pods_Tests_TV.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Tests_TV.framework; sourceTree = BUILT_PRODUCTS_DIR; };
+		91BF87534CBFBD8B623FCB53 /* Pods-Tests Vision.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Tests Vision.release.xcconfig"; path = "../Pods/Target Support Files/Pods-Tests Vision/Pods-Tests Vision.release.xcconfig"; sourceTree = "<group>"; };
+		A356608C341F465A482F0D7B /* Pods_Tests_Vision.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Tests_Vision.framework; sourceTree = BUILT_PRODUCTS_DIR; };
 		BC6C6328775701B5AAEEF4FF /* Pods-Tests Mac.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Tests Mac.debug.xcconfig"; path = "../Pods/Target Support Files/Pods-Tests Mac/Pods-Tests Mac.debug.xcconfig"; sourceTree = "<group>"; };
 		D80C63148416AADCBDD7FABA /* Pods-Tests iOS.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Tests iOS.debug.xcconfig"; path = "../Pods/Target Support Files/Pods-Tests iOS/Pods-Tests iOS.debug.xcconfig"; sourceTree = "<group>"; };
 		DA248D53195472AA00390AB0 /* Tests iOS.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "Tests iOS.xctest"; sourceTree = BUILT_PRODUCTS_DIR; };
@@ -199,17 +240,27 @@
 		DA248D64195472AA00390AB0 /* Tests-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Tests-Prefix.pch"; sourceTree = "<group>"; };
 		DA248D68195475D800390AB0 /* SDImageCacheTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDImageCacheTests.m; sourceTree = "<group>"; };
 		DA248D6A195476AC00390AB0 /* SDWebImageManagerTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDWebImageManagerTests.m; sourceTree = "<group>"; };
+		DD978FDEC70C6C3978DA4D56 /* Pods_Tests_iOS.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Tests_iOS.framework; sourceTree = BUILT_PRODUCTS_DIR; };
 		EADD19E9219915E300804BB0 /* Module-Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Module-Release.xcconfig"; sourceTree = "<group>"; };
 		EADD19EC219915E300804BB0 /* Module-Debug.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Module-Debug.xcconfig"; sourceTree = "<group>"; };
 		EADD19EE219915E300804BB0 /* Module-Shared.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Module-Shared.xcconfig"; sourceTree = "<group>"; };
+		FBF6247C616460B91BF8C188 /* Pods-Tests Vision.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Tests Vision.debug.xcconfig"; path = "../Pods/Target Support Files/Pods-Tests Vision/Pods-Tests Vision.debug.xcconfig"; sourceTree = "<group>"; };
 /* End PBXFileReference section */
 
 /* Begin PBXFrameworksBuildPhase section */
+		32464A862B7B0FF2006BE70E /* Frameworks */ = {
+			isa = PBXFrameworksBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				97A6B676B89A44368345A1A0 /* Pods_Tests_Vision.framework in Frameworks */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
 		329922272365D9A100EAFD97 /* Frameworks */ = {
 			isa = PBXFrameworksBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
-				770D3B9C7914D53EBA0524DB /* Pods_Tests_TV.framework in Frameworks */,
+				6FD27F0B29D57A4AACB56EA8 /* Pods_Tests_TV.framework in Frameworks */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
@@ -217,7 +268,7 @@
 			isa = PBXFrameworksBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
-				F02C3B9D48DEEC3622E96336 /* Pods_Tests_Mac.framework in Frameworks */,
+				B77B223649B05D013FE6E310 /* Pods_Tests_Mac.framework in Frameworks */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
@@ -228,7 +279,7 @@
 				DA248D57195472AA00390AB0 /* XCTest.framework in Frameworks */,
 				DA248D5B195472AA00390AB0 /* UIKit.framework in Frameworks */,
 				DA248D59195472AA00390AB0 /* Foundation.framework in Frameworks */,
-				AFDBD4044E95252B70FB85CE /* Pods_Tests_iOS.framework in Frameworks */,
+				8C71262F36B4B9A4EA9BD000 /* Pods_Tests_iOS.framework in Frameworks */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
@@ -246,10 +297,19 @@
 				6CB13D7A081654B2E4018F53 /* Pods-Tests TV.release.xcconfig */,
 				D80C63148416AADCBDD7FABA /* Pods-Tests iOS.debug.xcconfig */,
 				4DCBA1DEFE6C68C4A83C9B9E /* Pods-Tests iOS.release.xcconfig */,
+				FBF6247C616460B91BF8C188 /* Pods-Tests Vision.debug.xcconfig */,
+				91BF87534CBFBD8B623FCB53 /* Pods-Tests Vision.release.xcconfig */,
 			);
 			name = Pods;
 			sourceTree = "<group>";
 		};
+		32464A8A2B7B0FF2006BE70E /* Tests Vision */ = {
+			isa = PBXGroup;
+			children = (
+			);
+			path = "Tests Vision";
+			sourceTree = "<group>";
+		};
 		3299222B2365D9A100EAFD97 /* Tests TV */ = {
 			isa = PBXGroup;
 			children = (
@@ -301,6 +361,7 @@
 				DA248D5C195472AA00390AB0 /* Tests */,
 				32B99E93203B2DF90017FD66 /* Tests Mac */,
 				3299222B2365D9A100EAFD97 /* Tests TV */,
+				32464A8A2B7B0FF2006BE70E /* Tests Vision */,
 				DA248D55195472AA00390AB0 /* Frameworks */,
 				DA248D54195472AA00390AB0 /* Products */,
 				07C2B07CECA5631B430A737D /* Pods */,
@@ -313,6 +374,7 @@
 				DA248D53195472AA00390AB0 /* Tests iOS.xctest */,
 				32B99E92203B2DF90017FD66 /* Tests Mac.xctest */,
 				3299222A2365D9A100EAFD97 /* Tests TV.xctest */,
+				32464A892B7B0FF2006BE70E /* Tests Vision.xctest */,
 			);
 			name = Products;
 			sourceTree = "<group>";
@@ -323,9 +385,10 @@
 				DA248D56195472AA00390AB0 /* XCTest.framework */,
 				DA248D58195472AA00390AB0 /* Foundation.framework */,
 				DA248D5A195472AA00390AB0 /* UIKit.framework */,
-				A39EDFED1067C297B91792CB /* Pods_Tests_Mac.framework */,
-				B73996BC299E8E0174661628 /* Pods_Tests_TV.framework */,
-				AD1BD830DA7388EB6C110B3B /* Pods_Tests_iOS.framework */,
+				61030057F379B8F1D44EBF88 /* Pods_Tests_Mac.framework */,
+				5B18D772CFF936546772B836 /* Pods_Tests_TV.framework */,
+				DD978FDEC70C6C3978DA4D56 /* Pods_Tests_iOS.framework */,
+				A356608C341F465A482F0D7B /* Pods_Tests_Vision.framework */,
 			);
 			name = Frameworks;
 			sourceTree = "<group>";
@@ -389,6 +452,25 @@
 /* End PBXGroup section */
 
 /* Begin PBXNativeTarget section */
+		32464A882B7B0FF2006BE70E /* Tests Vision */ = {
+			isa = PBXNativeTarget;
+			buildConfigurationList = 32464A8F2B7B0FF2006BE70E /* Build configuration list for PBXNativeTarget "Tests Vision" */;
+			buildPhases = (
+				16AFAEFC9D9B9B933D4D324D /* [CP] Check Pods Manifest.lock */,
+				32464A852B7B0FF2006BE70E /* Sources */,
+				32464A862B7B0FF2006BE70E /* Frameworks */,
+				32464A872B7B0FF2006BE70E /* Resources */,
+				E5421880D8024D66B726F168 /* [CP] Embed Pods Frameworks */,
+			);
+			buildRules = (
+			);
+			dependencies = (
+			);
+			name = "Tests Vision";
+			productName = "Tests Vision";
+			productReference = 32464A892B7B0FF2006BE70E /* Tests Vision.xctest */;
+			productType = "com.apple.product-type.bundle.unit-test";
+		};
 		329922292365D9A100EAFD97 /* Tests TV */ = {
 			isa = PBXNativeTarget;
 			buildConfigurationList = 329922312365D9A100EAFD97 /* Build configuration list for PBXNativeTarget "Tests TV" */;
@@ -397,7 +479,7 @@
 				329922262365D9A100EAFD97 /* Sources */,
 				329922272365D9A100EAFD97 /* Frameworks */,
 				329922282365D9A100EAFD97 /* Resources */,
-				0F96305955CD6B35DF70EEED /* [CP] Embed Pods Frameworks */,
+				9A0B0CDE809B6AE68AF1A996 /* [CP] Embed Pods Frameworks */,
 			);
 			buildRules = (
 			);
@@ -416,7 +498,7 @@
 				32B99E8E203B2DF90017FD66 /* Sources */,
 				32B99E8F203B2DF90017FD66 /* Frameworks */,
 				32B99E90203B2DF90017FD66 /* Resources */,
-				910EDDDEAAC8A165A883AD8F /* [CP] Embed Pods Frameworks */,
+				D95ECCCFAAD9FCC01EA4D3CE /* [CP] Embed Pods Frameworks */,
 			);
 			buildRules = (
 			);
@@ -435,7 +517,7 @@
 				DA248D4F195472AA00390AB0 /* Sources */,
 				DA248D50195472AA00390AB0 /* Frameworks */,
 				DA248D51195472AA00390AB0 /* Resources */,
-				A07943B19E185DC24535F340 /* [CP] Embed Pods Frameworks */,
+				0A80AC7C0571A5F8F9967E3F /* [CP] Embed Pods Frameworks */,
 			);
 			buildRules = (
 			);
@@ -454,6 +536,10 @@
 			attributes = {
 				LastUpgradeCheck = 1020;
 				TargetAttributes = {
+					32464A882B7B0FF2006BE70E = {
+						CreatedOnToolsVersion = 15.2;
+						ProvisioningStyle = Automatic;
+					};
 					329922292365D9A100EAFD97 = {
 						CreatedOnToolsVersion = 11.1;
 						ProvisioningStyle = Automatic;
@@ -480,11 +566,40 @@
 				DA248D52195472AA00390AB0 /* Tests iOS */,
 				32B99E91203B2DF90017FD66 /* Tests Mac */,
 				329922292365D9A100EAFD97 /* Tests TV */,
+				32464A882B7B0FF2006BE70E /* Tests Vision */,
 			);
 		};
 /* End PBXProject section */
 
 /* Begin PBXResourcesBuildPhase section */
+		32464A872B7B0FF2006BE70E /* Resources */ = {
+			isa = PBXResourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				32464A902B7B1833006BE70E /* 1@2x.gif in Resources */,
+				32464AA22B7B1833006BE70E /* TestImageLarge.jpg in Resources */,
+				32464A912B7B1833006BE70E /* TestImage.nef in Resources */,
+				32464A942B7B1833006BE70E /* TestJFIF.jpg in Resources */,
+				32464A9B2B7B1833006BE70E /* TestAnimatedImageMemory.webp in Resources */,
+				32464A992B7B1833006BE70E /* TestEXIF.png in Resources */,
+				32464A922B7B1833006BE70E /* TestImage.heic in Resources */,
+				32464A9D2B7B1833006BE70E /* TestImageAnimated.apng in Resources */,
+				32464A9F2B7B1833006BE70E /* IndexedPNG.png in Resources */,
+				32464AA02B7B1833006BE70E /* TestImage.jpg in Resources */,
+				32464A932B7B1833006BE70E /* TestImageAnimated.heic in Resources */,
+				32464A9A2B7B1833006BE70E /* TestImage.png in Resources */,
+				32464A9C2B7B1833006BE70E /* TestImage.pdf in Resources */,
+				32464A9E2B7B1833006BE70E /* TestImageAnimated.webp in Resources */,
+				32464A972B7B1833006BE70E /* TestImage.bmp in Resources */,
+				32464AA32B7B1833006BE70E /* TestImage.heif in Resources */,
+				32464AA12B7B1833006BE70E /* MonochromeTestImage.jpg in Resources */,
+				32464AA42B7B1833006BE70E /* TestImageLarge.png in Resources */,
+				32464A962B7B1833006BE70E /* TestImage.gif in Resources */,
+				32464A952B7B1833006BE70E /* TestImageStatic.webp in Resources */,
+				32464A982B7B1833006BE70E /* TestLoopCount.gif in Resources */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
 		329922282365D9A100EAFD97 /* Resources */ = {
 			isa = PBXResourcesBuildPhase;
 			buildActionMask = 2147483647;
@@ -590,100 +705,88 @@
 			shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n    # print error to STDERR\n    echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n    exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
 			showEnvVarsInLog = 0;
 		};
-		0F96305955CD6B35DF70EEED /* [CP] Embed Pods Frameworks */ = {
+		0A80AC7C0571A5F8F9967E3F /* [CP] Embed Pods Frameworks */ = {
 			isa = PBXShellScriptBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
 			);
 			inputPaths = (
-				"${PODS_ROOT}/Target Support Files/Pods-Tests TV/Pods-Tests TV-frameworks.sh",
-				"${BUILT_PRODUCTS_DIR}/SDWebImage-Core-MapKit-tvOS/SDWebImage.framework",
-				"${BUILT_PRODUCTS_DIR}/SDWebImageWebPCoder-tvOS/SDWebImageWebPCoder.framework",
-				"${BUILT_PRODUCTS_DIR}/libwebp-tvOS/libwebp.framework",
-				"${BUILT_PRODUCTS_DIR}/Expecta-tvOS/Expecta.framework",
-				"${BUILT_PRODUCTS_DIR}/KVOController-tvOS/KVOController.framework",
+				"${PODS_ROOT}/Target Support Files/Pods-Tests iOS/Pods-Tests iOS-frameworks.sh",
+				"${BUILT_PRODUCTS_DIR}/SDWebImage-Core-MapKit-iOS/SDWebImage.framework",
+				"${BUILT_PRODUCTS_DIR}/Expecta-iOS/Expecta.framework",
+				"${BUILT_PRODUCTS_DIR}/KVOController-iOS/KVOController.framework",
 			);
 			name = "[CP] Embed Pods Frameworks";
 			outputPaths = (
 				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SDWebImage.framework",
-				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SDWebImageWebPCoder.framework",
-				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/libwebp.framework",
 				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Expecta.framework",
 				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/KVOController.framework",
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 			shellPath = /bin/sh;
-			shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Tests TV/Pods-Tests TV-frameworks.sh\"\n";
+			shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Tests iOS/Pods-Tests iOS-frameworks.sh\"\n";
 			showEnvVarsInLog = 0;
 		};
-		3742A83C8569610075078F4D /* [CP] Check Pods Manifest.lock */ = {
+		16AFAEFC9D9B9B933D4D324D /* [CP] Check Pods Manifest.lock */ = {
 			isa = PBXShellScriptBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
 			);
+			inputFileListPaths = (
+			);
 			inputPaths = (
 				"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
 				"${PODS_ROOT}/Manifest.lock",
 			);
 			name = "[CP] Check Pods Manifest.lock";
+			outputFileListPaths = (
+			);
 			outputPaths = (
-				"$(DERIVED_FILE_DIR)/Pods-Tests Mac-checkManifestLockResult.txt",
+				"$(DERIVED_FILE_DIR)/Pods-Tests Vision-checkManifestLockResult.txt",
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 			shellPath = /bin/sh;
 			shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n    # print error to STDERR\n    echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n    exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
 			showEnvVarsInLog = 0;
 		};
-		910EDDDEAAC8A165A883AD8F /* [CP] Embed Pods Frameworks */ = {
+		3742A83C8569610075078F4D /* [CP] Check Pods Manifest.lock */ = {
 			isa = PBXShellScriptBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
 			);
 			inputPaths = (
-				"${PODS_ROOT}/Target Support Files/Pods-Tests Mac/Pods-Tests Mac-frameworks.sh",
-				"${BUILT_PRODUCTS_DIR}/SDWebImage-Core-MapKit-macOS/SDWebImage.framework",
-				"${BUILT_PRODUCTS_DIR}/SDWebImageWebPCoder-macOS/SDWebImageWebPCoder.framework",
-				"${BUILT_PRODUCTS_DIR}/libwebp-macOS/libwebp.framework",
-				"${BUILT_PRODUCTS_DIR}/Expecta-macOS/Expecta.framework",
-				"${BUILT_PRODUCTS_DIR}/KVOController-macOS/KVOController.framework",
+				"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
+				"${PODS_ROOT}/Manifest.lock",
 			);
-			name = "[CP] Embed Pods Frameworks";
+			name = "[CP] Check Pods Manifest.lock";
 			outputPaths = (
-				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SDWebImage.framework",
-				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SDWebImageWebPCoder.framework",
-				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/libwebp.framework",
-				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Expecta.framework",
-				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/KVOController.framework",
+				"$(DERIVED_FILE_DIR)/Pods-Tests Mac-checkManifestLockResult.txt",
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 			shellPath = /bin/sh;
-			shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Tests Mac/Pods-Tests Mac-frameworks.sh\"\n";
+			shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n    # print error to STDERR\n    echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n    exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
 			showEnvVarsInLog = 0;
 		};
-		A07943B19E185DC24535F340 /* [CP] Embed Pods Frameworks */ = {
+		9A0B0CDE809B6AE68AF1A996 /* [CP] Embed Pods Frameworks */ = {
 			isa = PBXShellScriptBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
 			);
 			inputPaths = (
-				"${PODS_ROOT}/Target Support Files/Pods-Tests iOS/Pods-Tests iOS-frameworks.sh",
-				"${BUILT_PRODUCTS_DIR}/SDWebImage-Core-MapKit-iOS/SDWebImage.framework",
-				"${BUILT_PRODUCTS_DIR}/SDWebImageWebPCoder-iOS/SDWebImageWebPCoder.framework",
-				"${BUILT_PRODUCTS_DIR}/libwebp-iOS/libwebp.framework",
-				"${BUILT_PRODUCTS_DIR}/Expecta-iOS/Expecta.framework",
-				"${BUILT_PRODUCTS_DIR}/KVOController-iOS/KVOController.framework",
+				"${PODS_ROOT}/Target Support Files/Pods-Tests TV/Pods-Tests TV-frameworks.sh",
+				"${BUILT_PRODUCTS_DIR}/SDWebImage-Core-MapKit-tvOS/SDWebImage.framework",
+				"${BUILT_PRODUCTS_DIR}/Expecta-tvOS/Expecta.framework",
+				"${BUILT_PRODUCTS_DIR}/KVOController-tvOS/KVOController.framework",
 			);
 			name = "[CP] Embed Pods Frameworks";
 			outputPaths = (
 				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SDWebImage.framework",
-				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SDWebImageWebPCoder.framework",
-				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/libwebp.framework",
 				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Expecta.framework",
 				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/KVOController.framework",
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 			shellPath = /bin/sh;
-			shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Tests iOS/Pods-Tests iOS-frameworks.sh\"\n";
+			shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Tests TV/Pods-Tests TV-frameworks.sh\"\n";
 			showEnvVarsInLog = 0;
 		};
 		C5CC63AFA1303DA4F45B1B0E /* [CP] Check Pods Manifest.lock */ = {
@@ -708,9 +811,77 @@
 			shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n    # print error to STDERR\n    echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n    exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
 			showEnvVarsInLog = 0;
 		};
+		D95ECCCFAAD9FCC01EA4D3CE /* [CP] Embed Pods Frameworks */ = {
+			isa = PBXShellScriptBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+			);
+			inputPaths = (
+				"${PODS_ROOT}/Target Support Files/Pods-Tests Mac/Pods-Tests Mac-frameworks.sh",
+				"${BUILT_PRODUCTS_DIR}/SDWebImage-Core-MapKit-macOS/SDWebImage.framework",
+				"${BUILT_PRODUCTS_DIR}/Expecta-macOS/Expecta.framework",
+				"${BUILT_PRODUCTS_DIR}/KVOController-macOS/KVOController.framework",
+			);
+			name = "[CP] Embed Pods Frameworks";
+			outputPaths = (
+				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SDWebImage.framework",
+				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Expecta.framework",
+				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/KVOController.framework",
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+			shellPath = /bin/sh;
+			shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Tests Mac/Pods-Tests Mac-frameworks.sh\"\n";
+			showEnvVarsInLog = 0;
+		};
+		E5421880D8024D66B726F168 /* [CP] Embed Pods Frameworks */ = {
+			isa = PBXShellScriptBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+			);
+			inputPaths = (
+				"${PODS_ROOT}/Target Support Files/Pods-Tests Vision/Pods-Tests Vision-frameworks.sh",
+				"${BUILT_PRODUCTS_DIR}/SDWebImage-Core-MapKit-visionOS/SDWebImage.framework",
+				"${BUILT_PRODUCTS_DIR}/Expecta-visionOS/Expecta.framework",
+				"${BUILT_PRODUCTS_DIR}/KVOController-visionOS/KVOController.framework",
+			);
+			name = "[CP] Embed Pods Frameworks";
+			outputPaths = (
+				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SDWebImage.framework",
+				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Expecta.framework",
+				"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/KVOController.framework",
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+			shellPath = /bin/sh;
+			shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Tests Vision/Pods-Tests Vision-frameworks.sh\"\n";
+			showEnvVarsInLog = 0;
+		};
 /* End PBXShellScriptBuildPhase section */
 
 /* Begin PBXSourcesBuildPhase section */
+		32464A852B7B0FF2006BE70E /* Sources */ = {
+			isa = PBXSourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				32464AAB2B7B1845006BE70E /* SDWebImageDownloaderTests.m in Sources */,
+				32464AAC2B7B1845006BE70E /* SDTestCase.m in Sources */,
+				32464AA72B7B1845006BE70E /* SDImageTransformerTests.m in Sources */,
+				32464AAE2B7B1845006BE70E /* SDWebImageTestCoder.m in Sources */,
+				32464AB52B7B1845006BE70E /* SDCategoriesTests.m in Sources */,
+				32464AAA2B7B1845006BE70E /* SDWebImageTestDownloadOperation.m in Sources */,
+				32464AA62B7B1845006BE70E /* SDMockFileManager.m in Sources */,
+				32464AA52B7B1845006BE70E /* SDWebImageManagerTests.m in Sources */,
+				32464AB22B7B1845006BE70E /* SDWebImageTestCache.m in Sources */,
+				32464AAD2B7B1845006BE70E /* SDWebImageTestTransformer.m in Sources */,
+				32464AAF2B7B1845006BE70E /* SDWebImagePrefetcherTests.m in Sources */,
+				32464AB02B7B1845006BE70E /* SDWebCacheCategoriesTests.m in Sources */,
+				32464AB12B7B1845006BE70E /* SDAnimatedImageTest.m in Sources */,
+				32464AB42B7B1845006BE70E /* SDImageCoderTests.m in Sources */,
+				32464AA92B7B1845006BE70E /* SDWebImageTestLoader.m in Sources */,
+				32464AA82B7B1845006BE70E /* SDUtilsTests.m in Sources */,
+				32464AB32B7B1845006BE70E /* SDImageCacheTests.m in Sources */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
 		329922262365D9A100EAFD97 /* Sources */ = {
 			isa = PBXSourcesBuildPhase;
 			buildActionMask = 2147483647;
@@ -786,6 +957,138 @@
 /* End PBXSourcesBuildPhase section */
 
 /* Begin XCBuildConfiguration section */
+		32464A8D2B7B0FF2006BE70E /* Debug */ = {
+			isa = XCBuildConfiguration;
+			baseConfigurationReference = FBF6247C616460B91BF8C188 /* Pods-Tests Vision.debug.xcconfig */;
+			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_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;
+				CODE_SIGN_STYLE = Automatic;
+				COPY_PHASE_STRIP = NO;
+				CURRENT_PROJECT_VERSION = 1;
+				DEBUG_INFORMATION_FORMAT = dwarf;
+				ENABLE_STRICT_OBJC_MSGSEND = YES;
+				ENABLE_TESTABILITY = YES;
+				GCC_C_LANGUAGE_STANDARD = gnu17;
+				GCC_DYNAMIC_NO_PIC = NO;
+				GCC_NO_COMMON_BLOCKS = YES;
+				GCC_OPTIMIZATION_LEVEL = 0;
+				GCC_PREPROCESSOR_DEFINITIONS = (
+					"DEBUG=1",
+					"$(inherited)",
+				);
+				GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+				GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+				GCC_WARN_UNDECLARED_SELECTOR = YES;
+				GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+				GCC_WARN_UNUSED_FUNCTION = YES;
+				GCC_WARN_UNUSED_VARIABLE = YES;
+				INFOPLIST_FILE = "Tests Vision/Info.plist";
+				LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
+				MARKETING_VERSION = 1.0;
+				MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
+				MTL_FAST_MATH = YES;
+				ONLY_ACTIVE_ARCH = YES;
+				PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.Tests-Vision";
+				PRODUCT_NAME = "$(TARGET_NAME)";
+				SDKROOT = xros;
+				SUPPORTED_PLATFORMS = "xros xrsimulator";
+				SWIFT_EMIT_LOC_STRINGS = NO;
+				TARGETED_DEVICE_FAMILY = "1,2,7";
+				XROS_DEPLOYMENT_TARGET = 1.0;
+			};
+			name = Debug;
+		};
+		32464A8E2B7B0FF2006BE70E /* Release */ = {
+			isa = XCBuildConfiguration;
+			baseConfigurationReference = 91BF87534CBFBD8B623FCB53 /* Pods-Tests Vision.release.xcconfig */;
+			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_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;
+				CODE_SIGN_STYLE = Automatic;
+				COPY_PHASE_STRIP = NO;
+				CURRENT_PROJECT_VERSION = 1;
+				DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+				ENABLE_NS_ASSERTIONS = NO;
+				ENABLE_STRICT_OBJC_MSGSEND = YES;
+				GCC_C_LANGUAGE_STANDARD = gnu17;
+				GCC_NO_COMMON_BLOCKS = YES;
+				GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+				GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+				GCC_WARN_UNDECLARED_SELECTOR = YES;
+				GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+				GCC_WARN_UNUSED_FUNCTION = YES;
+				GCC_WARN_UNUSED_VARIABLE = YES;
+				INFOPLIST_FILE = "Tests Vision/Info.plist";
+				LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
+				MARKETING_VERSION = 1.0;
+				MTL_ENABLE_DEBUG_INFO = NO;
+				MTL_FAST_MATH = YES;
+				PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.Tests-Vision";
+				PRODUCT_NAME = "$(TARGET_NAME)";
+				SDKROOT = xros;
+				SUPPORTED_PLATFORMS = "xros xrsimulator";
+				SWIFT_EMIT_LOC_STRINGS = NO;
+				TARGETED_DEVICE_FAMILY = "1,2,7";
+				VALIDATE_PRODUCT = YES;
+				XROS_DEPLOYMENT_TARGET = 1.0;
+			};
+			name = Release;
+		};
 		3299222F2365D9A100EAFD97 /* Debug */ = {
 			isa = XCBuildConfiguration;
 			baseConfigurationReference = 5B0011ED58CC9998E68ECCE3 /* Pods-Tests TV.debug.xcconfig */;
@@ -887,6 +1190,15 @@
 /* End XCBuildConfiguration section */
 
 /* Begin XCConfigurationList section */
+		32464A8F2B7B0FF2006BE70E /* Build configuration list for PBXNativeTarget "Tests Vision" */ = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				32464A8D2B7B0FF2006BE70E /* Debug */,
+				32464A8E2B7B0FF2006BE70E /* Release */,
+			);
+			defaultConfigurationIsVisible = 0;
+			defaultConfigurationName = Release;
+		};
 		329922312365D9A100EAFD97 /* Build configuration list for PBXNativeTarget "Tests TV" */ = {
 			isa = XCConfigurationList;
 			buildConfigurations = (

+ 74 - 0
Tests/SDWebImage Tests.xcodeproj/xcshareddata/xcschemes/Tests Vision.xcscheme

@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Scheme
+   LastUpgradeVersion = "1520"
+   version = "2.2">
+   <BuildAction
+      parallelizeBuildables = "YES"
+      buildImplicitDependencies = "YES">
+      <BuildActionEntries>
+         <BuildActionEntry
+            buildForTesting = "YES"
+            buildForRunning = "YES"
+            buildForProfiling = "YES"
+            buildForArchiving = "YES"
+            buildForAnalyzing = "YES">
+            <AutocreatedTestPlanReference>
+            </AutocreatedTestPlanReference>
+         </BuildActionEntry>
+      </BuildActionEntries>
+   </BuildAction>
+   <TestAction
+      buildConfiguration = "Debug"
+      selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
+      selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
+      shouldUseLaunchSchemeArgsEnv = "YES"
+      shouldAutocreateTestPlan = "YES">
+      <Testables>
+         <TestableReference
+            skipped = "NO"
+            parallelizable = "YES">
+            <BuildableReference
+               BuildableIdentifier = "primary"
+               BlueprintIdentifier = "32464A882B7B0FF2006BE70E"
+               BuildableName = "Tests Vision.xctest"
+               BlueprintName = "Tests Vision"
+               ReferencedContainer = "container:SDWebImage Tests.xcodeproj">
+            </BuildableReference>
+         </TestableReference>
+      </Testables>
+   </TestAction>
+   <LaunchAction
+      buildConfiguration = "Debug"
+      selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
+      selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
+      launchStyle = "0"
+      useCustomWorkingDirectory = "NO"
+      ignoresPersistentStateOnLaunch = "NO"
+      debugDocumentVersioning = "YES"
+      debugServiceExtension = "internal"
+      allowLocationSimulation = "YES">
+   </LaunchAction>
+   <ProfileAction
+      buildConfiguration = "Release"
+      shouldUseLaunchSchemeArgsEnv = "YES"
+      savedToolIdentifier = ""
+      useCustomWorkingDirectory = "NO"
+      debugDocumentVersioning = "YES">
+      <MacroExpansion>
+         <BuildableReference
+            BuildableIdentifier = "primary"
+            BlueprintIdentifier = "32464A882B7B0FF2006BE70E"
+            BuildableName = "Tests Vision.xctest"
+            BlueprintName = "Tests Vision"
+            ReferencedContainer = "container:SDWebImage Tests.xcodeproj">
+         </BuildableReference>
+      </MacroExpansion>
+   </ProfileAction>
+   <AnalyzeAction
+      buildConfiguration = "Debug">
+   </AnalyzeAction>
+   <ArchiveAction
+      buildConfiguration = "Release"
+      revealArchiveInOrganizer = "YES">
+   </ArchiveAction>
+</Scheme>

+ 22 - 0
Tests/Tests Vision/Info.plist

@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>CFBundleDevelopmentRegion</key>
+	<string>$(DEVELOPMENT_LANGUAGE)</string>
+	<key>CFBundleExecutable</key>
+	<string>$(EXECUTABLE_NAME)</string>
+	<key>CFBundleIdentifier</key>
+	<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
+	<key>CFBundleInfoDictionaryVersion</key>
+	<string>6.0</string>
+	<key>CFBundleName</key>
+	<string>$(PRODUCT_NAME)</string>
+	<key>CFBundlePackageType</key>
+	<string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>
+	<key>CFBundleShortVersionString</key>
+	<string>1.0</string>
+	<key>CFBundleVersion</key>
+	<string>1</string>
+</dict>
+</plist>

+ 0 - 19
Tests/Tests/SDAnimatedImageTest.m

@@ -11,7 +11,6 @@
 #import "SDInternalMacros.h"
 #import "SDImageFramePool.h"
 #import <KVOController/KVOController.h>
-#import <SDWebImageWebPCoder/SDWebImageWebPCoder.h>
 
 static const NSUInteger kTestGIFFrameCount = 5; // local TestImage.gif loop count
 
@@ -66,8 +65,6 @@ static BOOL _isCalled;
 
 @interface SDAnimatedImageTest : SDTestCase
 
-@property (nonatomic, strong) UIWindow *window;
-
 @end
 
 @implementation SDAnimatedImageTest
@@ -769,12 +766,7 @@ static BOOL _isCalled;
 
 - (void)test36AnimatedImageMemoryCost {
     if (@available(iOS 14, tvOS 14, macOS 11, watchOS 7, *)) {
-#if SD_TV
-        /// TV OS does not support ImageIO's webp.
-        [[SDImageCodersManager sharedManager] addCoder:[SDImageWebPCoder sharedCoder]];
-#else
         [[SDImageCodersManager sharedManager] addCoder:[SDImageAWebPCoder sharedCoder]];
-#endif
         UIImage *image = [UIImage sd_imageWithData:[NSData dataWithContentsOfFile:[self testMemotyCostImagePath]]];
         NSUInteger cost = [image sd_memoryCost];
 #if SD_UIKIT
@@ -793,17 +785,6 @@ static BOOL _isCalled;
 }
 
 #pragma mark - Helper
-- (UIWindow *)window {
-    if (!_window) {
-        UIScreen *mainScreen = [UIScreen mainScreen];
-#if SD_UIKIT
-        _window = [[UIWindow alloc] initWithFrame:mainScreen.bounds];
-#else
-        _window = [[NSWindow alloc] initWithContentRect:mainScreen.frame styleMask:0 backing:NSBackingStoreBuffered defer:NO screen:mainScreen];
-#endif
-    }
-    return _window;
-}
 
 - (NSString *)testGIFPath {
     NSBundle *testBundle = [NSBundle bundleForClass:[self class]];

+ 6 - 10
Tests/Tests/SDImageCacheTests.m

@@ -459,17 +459,13 @@ static NSString *kTestImageKeyPNG = @"TestImageKey.png";
     }];
     
     // Case 2: UIImage without `sd_imageFormat` should use JPEG for non-alpha channel
-    SDGraphicsImageRendererFormat *format = [SDGraphicsImageRendererFormat preferredFormat];
-    format.opaque = YES;
-    SDGraphicsImageRenderer *renderer = [[SDGraphicsImageRenderer alloc] initWithSize:pngImage.size format:format];
-    // Non-alpha image, also test `SDGraphicsImageRenderer` behavior here :)
-    UIImage *nonAlphaImage = [renderer imageWithActions:^(CGContextRef  _Nonnull context) {
-        [pngImage drawInRect:CGRectMake(0, 0, pngImage.size.width, pngImage.size.height)];
-    }];
-    expect(nonAlphaImage).notTo.beNil();
-    expect([SDImageCoderHelper CGImageContainsAlpha:nonAlphaImage.CGImage]).beFalsy();
+    NSData *jpegData = [NSData dataWithContentsOfFile:[self testJPEGPath]];
+    UIImage *jpegImage = [UIImage sd_imageWithData:jpegData];
+    expect(jpegImage.sd_isAnimated).beFalsy();
+    expect(jpegImage.sd_imageFormat).equal(SDImageFormatJPEG);
+    expect([SDImageCoderHelper CGImageContainsAlpha:jpegImage.CGImage]).beFalsy();
     
-    [SDImageCache.sharedImageCache storeImage:nonAlphaImage forKey:kAnimatedImageKey2 toDisk:YES completion:^{
+    [SDImageCache.sharedImageCache storeImage:jpegImage forKey:kAnimatedImageKey2 toDisk:YES completion:^{
         UIImage *diskImage = [SDImageCache.sharedImageCache imageFromDiskCacheForKey:kAnimatedImageKey2];
         // Should save to JPEG
         expect(diskImage.sd_isAnimated).beFalsy();

+ 2 - 0
Tests/Tests/SDImageCoderTests.m

@@ -9,7 +9,9 @@
 
 #import "SDTestCase.h"
 #import "UIColor+SDHexString.h"
+#if __has_include(<SDWebImageWebPCoder/SDWebImageWebPCoder.h>)
 #import <SDWebImageWebPCoder/SDWebImageWebPCoder.h>
+#endif
 
 @interface SDWebImageDecoderTests : SDTestCase
 

+ 8 - 1
Tests/Tests/SDImageTransformerTests.m

@@ -279,7 +279,14 @@ static void SDAssertCGImageFirstComponentWhite(CGImageRef image, OSType pixelTyp
     UIColor *leftColor = [filteredImage sd_colorAtPoint:CGPointMake(80, 150)];
     // Hard-code from the output
     UIColor *expectedColor = [UIColor colorWithRed:0.85098 green:0.992157 blue:0.992157 alpha:1];
-    expect([leftColor.sd_hexString isEqualToString:expectedColor.sd_hexString]).beTruthy();
+    CGFloat r1, g1, b1, a1;
+    CGFloat r2, g2, b2, a2;
+    [leftColor getRed:&r1 green:&g1 blue:&b1 alpha:&a1];
+    [expectedColor getRed:&r2 green:&g2 blue:&b2 alpha:&a2];
+    expect(r1).beCloseToWithin(r2, 0.01);
+    expect(g1).beCloseToWithin(g2, 0.01);
+    expect(b1).beCloseToWithin(b2, 0.01);
+    expect(a1).beCloseToWithin(a2, 0.01);
     // Check rounded corner operation not inversion the image
     UIColor *topCenterColor = [filteredImage sd_colorAtPoint:CGPointMake(150, 20)];
     expect([topCenterColor.sd_hexString isEqualToString:[UIColor whiteColor].sd_hexString]).beTruthy();

+ 3 - 1
Tests/Tests/SDTestCase.h

@@ -29,7 +29,9 @@ FOUNDATION_EXPORT NSString * _Nonnull const kTestAPNGPURL;
 
 @interface SDTestCase : XCTestCase
 
+@property (nonatomic, strong, null_resettable) UIWindow *window;
+
 - (void)waitForExpectationsWithCommonTimeout;
-- (void)waitForExpectationsWithCommonTimeoutUsingHandler:(nullable XCWaitCompletionHandler)handler;
+- (void)waitForExpectationsWithCommonTimeoutUsingHandler:(nullable XCWaitCompletionHandler)handler; 
 
 @end

+ 19 - 0
Tests/Tests/SDTestCase.m

@@ -27,4 +27,23 @@ NSString *const kTestAPNGPURL = @"https://upload.wikimedia.org/wikipedia/commons
     [self waitForExpectationsWithTimeout:kAsyncTestTimeout handler:handler];
 }
 
+#pragma mark - Helper
+- (UIWindow *)window {
+    if (!_window) {
+#if SD_UIKIT
+#if SD_VISION
+        CGSize screenSize = CGSizeMake(1280, 720); // https://developer.apple.com/design/human-interface-guidelines/windows#visionOS
+        CGRect screenFrame = CGRectMake(0, 0, screenSize.width, screenSize.height);
+#else
+        UIScreen *mainScreen = [UIScreen mainScreen];
+        CGRect screenFrame = mainScreen.bounds;
+#endif
+        _window = [[UIWindow alloc] initWithFrame:screenFrame];
+#else
+        _window = [[NSWindow alloc] initWithContentRect:mainScreen.frame styleMask:0 backing:NSBackingStoreBuffered defer:NO screen:mainScreen];
+#endif
+    }
+    return _window;
+}
+
 @end

+ 4 - 0
Tests/Tests/SDUtilsTests.m

@@ -113,7 +113,11 @@
     // Main Screen
     SDGraphicsImageRendererFormat *format = SDGraphicsImageRendererFormat.preferredFormat;
 #if SD_UIKIT
+#if SD_VISION
+    CGFloat screenScale = UITraitCollection.currentTraitCollection.displayScale;
+#else
     CGFloat screenScale = [UIScreen mainScreen].scale;
+#endif
 #elif SD_MAC
     CGFloat screenScale = [NSScreen mainScreen].backingScaleFactor;
 #endif

+ 1 - 14
Tests/Tests/SDWebCacheCategoriesTests.m

@@ -12,8 +12,6 @@
 
 @interface SDWebCacheCategoriesTests : SDTestCase
 
-@property (nonatomic, strong) UIWindow *window;
-
 @end
 
 @implementation SDWebCacheCategoriesTests
@@ -545,12 +543,12 @@
     XCTestExpectation *expectation = [self expectationWithDescription:@"UIView indicator does not work"];
     
     UIImageView *imageView = [[UIImageView alloc] init];
+#if SD_IOS
     imageView.sd_imageIndicator = SDWebImageActivityIndicator.grayIndicator;
     // Cover each convience method, finally use progress indicator for test
     imageView.sd_imageIndicator = SDWebImageActivityIndicator.grayLargeIndicator;
     imageView.sd_imageIndicator = SDWebImageActivityIndicator.whiteIndicator;
     imageView.sd_imageIndicator = SDWebImageActivityIndicator.whiteLargeIndicator;
-#if SD_IOS
     imageView.sd_imageIndicator = SDWebImageProgressIndicator.barIndicator;
 #endif
     imageView.sd_imageIndicator = SDWebImageProgressIndicator.defaultIndicator;
@@ -623,17 +621,6 @@
 }
 
 #pragma mark - Helper
-- (UIWindow *)window {
-    if (!_window) {
-        UIScreen *mainScreen = [UIScreen mainScreen];
-#if SD_UIKIT
-        _window = [[UIWindow alloc] initWithFrame:mainScreen.bounds];
-#else
-        _window = [[NSWindow alloc] initWithContentRect:mainScreen.frame styleMask:0 backing:NSBackingStoreBuffered defer:NO screen:mainScreen];
-#endif
-    }
-    return _window;
-}
 
 - (NSString *)testJPEGPath {
     NSBundle *testBundle = [NSBundle bundleForClass:[self class]];

+ 0 - 5
Tests/Tests/SDWebImageDownloaderTests.m

@@ -673,17 +673,12 @@
         if (@available(iOS 10.0, tvOS 10.0, macOS 10.12, *)) {
             NSURLSessionTaskMetrics *metrics = token.metrics;
             expect(metrics).notTo.beNil();
-            expect(metrics.redirectCount).equal(0);
             expect(metrics.transactionMetrics.count).equal(1);
             NSURLSessionTaskTransactionMetrics *metric = metrics.transactionMetrics.firstObject;
             // Metrcis Test
             expect(metric.fetchStartDate).notTo.beNil();
             expect(metric.connectStartDate).notTo.beNil();
             expect(metric.connectEndDate).notTo.beNil();
-            expect(metric.networkProtocolName).equal(@"h2");
-            expect(metric.resourceFetchType).equal(NSURLSessionTaskMetricsResourceFetchTypeNetworkLoad);
-            expect(metric.isProxyConnection).beFalsy();
-            expect(metric.isReusedConnection).beFalsy();
         }
         [expectation1 fulfill];
     }];

+ 4 - 0
Tests/Tests/SDWebImageManagerTests.m

@@ -10,7 +10,9 @@
 #import "SDWebImageTestTransformer.h"
 #import "SDWebImageTestCache.h"
 #import "SDWebImageTestLoader.h"
+#if __has_include(<SDWebImageWebPCoder/SDWebImageWebPCoder.h>)
 #import <SDWebImageWebPCoder/SDWebImageWebPCoder.h>
+#endif
 
 // Keep strong references for object
 @interface SDObjectContainer<ObjectType> : NSObject
@@ -644,6 +646,7 @@
     [self waitForExpectationsWithCommonTimeout];
 }
 
+#if __has_include(<SDWebImageWebPCoder/SDWebImageWebPCoder.h>)
 - (void)test22ThatForceDecodePolicyAlways {
     XCTestExpectation *expectation = [self expectationWithDescription:@"Always policy with WebP image (libwebp) should force-decode"];
     NSURL *url = [NSURL URLWithString:@"https://www.gstatic.com/webp/gallery/4.webp"];
@@ -658,6 +661,7 @@
     }];
     [self waitForExpectationsWithCommonTimeout];
 }
+#endif
 
 - (NSString *)testJPEGPath {
     NSBundle *testBundle = [NSBundle bundleForClass:[self class]];