diff --git a/mobile/README.md b/mobile/README.md
index 03178d486..91ce98d8b 100644
--- a/mobile/README.md
+++ b/mobile/README.md
@@ -49,6 +49,12 @@ The example app uses object detection which is able to continuously detect the o
- [iOS Object Detection](examples/object_detection/ios)
- [Android Object Detection](examples/object_detection/android)
+### Object Detection using yolov8
+
+This example app use yolov8 model to identify objects in images and provides bounding boxes, identified class and score.
+
+- [iOS Object Detection (yolov8)](examples/object_detection_yolov8/ios)
+
### Xamarin VisionSample
The [Xamarin.Forms](https://dotnet.microsoft.com/apps/xamarin/xamarin-forms) example app demonstrates the use of several vision-related models, from the ONNX Model Zoo collection.
diff --git a/mobile/examples/object_detection_yolov8/ios/LICENSE b/mobile/examples/object_detection_yolov8/ios/LICENSE
new file mode 100644
index 000000000..869273edf
--- /dev/null
+++ b/mobile/examples/object_detection_yolov8/ios/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2024 Eumentis
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/mobile/examples/object_detection_yolov8/ios/README.md b/mobile/examples/object_detection_yolov8/ios/README.md
new file mode 100644
index 000000000..891e882c0
--- /dev/null
+++ b/mobile/examples/object_detection_yolov8/ios/README.md
@@ -0,0 +1,41 @@
+## ONNX Runtime Mobile object detection iOS sample application
+
+This sample application makes use of Yolov8 object detection model to identify objects in images and provides identified class, bounding boxes and score as a result.
+
+
+### Model
+We use pre-trained yolov8 model in this sample app. The original yolov8n.pt model can be downloaded. [Here](https://github.com/ultralytics/assets/releases/download/v8.1.0/yolov8n.pt)
+- We converted this yolov8n.pt model to yolov8n.onnx using https://docs.ultralytics.com/modes/export/#usage-examples
+- Generated yolov8n.ort from yolov8n.onnx using https://onnxruntime.ai/docs/performance/model-optimizations/ort-format-models.html#convert-onnx-models-to-ort-format
+
+### Requirements
+- Install Xcode 12.5 and above (preferably latest version)
+
+### Steps to build and run
+
+#### Step 1: Clone the ONNX runtime mobile examples source code
+
+Clone this repository to get the sample application. Then open the project under the folder `mobile\examples\object_detection_yolov8\ios`.
+
+
+#### Step 2: Install app
+
+1. In terminal, run pod install under onnxruntime-object-detection-yolo-ios/yolo-ios to generate the workspace file.
+ - At the end of this step, you should get a file called yolo-ios.xcworkspace.
+2. Open onnxruntime-object-detection-yolo-ios/yolo-ios/yolo-ios.xcworkspace in Xcode and make sure to select your corresponding development team under Target-General-Signing for a proper codesign
+
+#### Step 3: Connect IOS Device and Run the app
+ Connect your IOS Device to your computer or select the IOS Simulator in Xcode.
+
+ Then after running this app it will be installed on your device or simulator.
+
+ Now you can try and test the object detection IOS app by
+ 1. Click the "+" button from top, it will open your photo album, pick any image that you want to test.
+ 2. Your selected image will be shown on the screen. Then click the "Start Processing" button, and it will begin identifying objects in the image/photo. The loader will appear on the screen while the image is being processed.
+ 3. After completion, you'll see an image with bounding boxes and the identified class name.
+
+#
+Here are some sample example screenshots of the app.
+
+
+
\ No newline at end of file
diff --git a/mobile/examples/object_detection_yolov8/ios/yolo-ios/.gitignore b/mobile/examples/object_detection_yolov8/ios/yolo-ios/.gitignore
new file mode 100644
index 000000000..c7b68fbe4
--- /dev/null
+++ b/mobile/examples/object_detection_yolov8/ios/yolo-ios/.gitignore
@@ -0,0 +1,2 @@
+/Pods/
+.DS_Store
\ No newline at end of file
diff --git a/mobile/examples/object_detection_yolov8/ios/yolo-ios/Podfile b/mobile/examples/object_detection_yolov8/ios/yolo-ios/Podfile
new file mode 100644
index 000000000..483cdaa58
--- /dev/null
+++ b/mobile/examples/object_detection_yolov8/ios/yolo-ios/Podfile
@@ -0,0 +1,22 @@
+# Uncomment the next line to define a global platform for your project
+# platform :ios, '9.0'
+
+target 'yolo-ios' do
+ # Comment the next line if you don't want to use dynamic frameworks
+ use_frameworks!
+
+ # Pods for yolo-ios
+
+ target 'yolo-iosTests' do
+ inherit! :search_paths
+ # Pods for testing
+ end
+
+ target 'yolo-iosUITests' do
+ # Pods for testing
+ end
+
+ # Pods for ORTObjectDetection
+ pod 'onnxruntime-objc'
+
+end
diff --git a/mobile/examples/object_detection_yolov8/ios/yolo-ios/Podfile.lock b/mobile/examples/object_detection_yolov8/ios/yolo-ios/Podfile.lock
new file mode 100644
index 000000000..eeefb0f98
--- /dev/null
+++ b/mobile/examples/object_detection_yolov8/ios/yolo-ios/Podfile.lock
@@ -0,0 +1,22 @@
+PODS:
+ - onnxruntime-c (1.17.1)
+ - onnxruntime-objc (1.17.1):
+ - onnxruntime-objc/Core (= 1.17.1)
+ - onnxruntime-objc/Core (1.17.1):
+ - onnxruntime-c (= 1.17.1)
+
+DEPENDENCIES:
+ - onnxruntime-objc
+
+SPEC REPOS:
+ trunk:
+ - onnxruntime-c
+ - onnxruntime-objc
+
+SPEC CHECKSUMS:
+ onnxruntime-c: 58803cb3fcc1fb0a7baa9b16b2bad119d6e3eb78
+ onnxruntime-objc: 089530244113a131305642b7e03fa6f8a9ee9ae6
+
+PODFILE CHECKSUM: 9379fba48d706acf709a30decc58da0f9ab2b681
+
+COCOAPODS: 1.14.3
diff --git a/mobile/examples/object_detection_yolov8/ios/yolo-ios/yolo-ios.xcodeproj/project.pbxproj b/mobile/examples/object_detection_yolov8/ios/yolo-ios/yolo-ios.xcodeproj/project.pbxproj
new file mode 100644
index 000000000..dffdb8eef
--- /dev/null
+++ b/mobile/examples/object_detection_yolov8/ios/yolo-ios/yolo-ios.xcodeproj/project.pbxproj
@@ -0,0 +1,772 @@
+// !$*UTF8*$!
+{
+ archiveVersion = 1;
+ classes = {
+ };
+ objectVersion = 56;
+ objects = {
+
+/* Begin PBXBuildFile section */
+ 260737CF2B9060DD008014F5 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 260737CE2B9060DD008014F5 /* AppDelegate.swift */; };
+ 260737D12B9060DD008014F5 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 260737D02B9060DD008014F5 /* SceneDelegate.swift */; };
+ 260737D32B9060DD008014F5 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 260737D22B9060DD008014F5 /* ViewController.swift */; };
+ 260737D62B9060DD008014F5 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 260737D42B9060DD008014F5 /* Main.storyboard */; };
+ 260737D92B9060DD008014F5 /* yolo_ios.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = 260737D72B9060DD008014F5 /* yolo_ios.xcdatamodeld */; };
+ 260737DB2B9060DF008014F5 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 260737DA2B9060DF008014F5 /* Assets.xcassets */; };
+ 260737DE2B9060DF008014F5 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 260737DC2B9060DF008014F5 /* LaunchScreen.storyboard */; };
+ 260737E92B9060DF008014F5 /* yolo_iosTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 260737E82B9060DF008014F5 /* yolo_iosTests.swift */; };
+ 260737F32B9060DF008014F5 /* yolo_iosUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 260737F22B9060DF008014F5 /* yolo_iosUITests.swift */; };
+ 260737F52B9060DF008014F5 /* yolo_iosUITestsLaunchTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 260737F42B9060DF008014F5 /* yolo_iosUITestsLaunchTests.swift */; };
+ 260738062B91AF68008014F5 /* ModelHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 260738052B91AF68008014F5 /* ModelHandler.swift */; };
+ 260738082B91DFDA008014F5 /* labelmap.txt in Resources */ = {isa = PBXBuildFile; fileRef = 260738072B91DFDA008014F5 /* labelmap.txt */; };
+ 2607380E2B95D207008014F5 /* yolov8n.ort in Resources */ = {isa = PBXBuildFile; fileRef = 2607380D2B95D207008014F5 /* yolov8n.ort */; };
+ 26CBC3682BBEB44E0036B7D0 /* IMG_1139.PNG in Resources */ = {isa = PBXBuildFile; fileRef = 26CBC3662BBEB44E0036B7D0 /* IMG_1139.PNG */; };
+ 26CBC3692BBEB44E0036B7D0 /* IMG_1140.PNG in Resources */ = {isa = PBXBuildFile; fileRef = 26CBC3672BBEB44E0036B7D0 /* IMG_1140.PNG */; };
+ 33DF679EE66C3F4F44099B56 /* Pods_yolo_ios.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BD344AB12C4F1A281D7F46D4 /* Pods_yolo_ios.framework */; };
+ 67122ED79DB36FAB7237C91B /* Pods_yolo_ios_yolo_iosUITests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7B39F828D374AE21FA8D60CC /* Pods_yolo_ios_yolo_iosUITests.framework */; };
+ BAC5AD988782414116DDEF0D /* Pods_yolo_iosTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F99F4EFF9BEDCC528BF35BA1 /* Pods_yolo_iosTests.framework */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXContainerItemProxy section */
+ 260737E52B9060DF008014F5 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 260737C32B9060DD008014F5 /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = 260737CA2B9060DD008014F5;
+ remoteInfo = "yolo-ios";
+ };
+ 260737EF2B9060DF008014F5 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 260737C32B9060DD008014F5 /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = 260737CA2B9060DD008014F5;
+ remoteInfo = "yolo-ios";
+ };
+/* End PBXContainerItemProxy section */
+
+/* Begin PBXFileReference section */
+ 21D39772E8C24CA9AFF7241A /* Pods-yolo-ios.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-yolo-ios.release.xcconfig"; path = "Target Support Files/Pods-yolo-ios/Pods-yolo-ios.release.xcconfig"; sourceTree = ""; };
+ 260737CB2B9060DD008014F5 /* yolo-ios.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "yolo-ios.app"; sourceTree = BUILT_PRODUCTS_DIR; };
+ 260737CE2B9060DD008014F5 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
+ 260737D02B9060DD008014F5 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; };
+ 260737D22B9060DD008014F5 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; };
+ 260737D52B9060DD008014F5 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; };
+ 260737D82B9060DD008014F5 /* yolo_ios.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = yolo_ios.xcdatamodel; sourceTree = ""; };
+ 260737DA2B9060DF008014F5 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
+ 260737DD2B9060DF008014F5 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; };
+ 260737DF2B9060DF008014F5 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
+ 260737E42B9060DF008014F5 /* yolo-iosTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "yolo-iosTests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; };
+ 260737E82B9060DF008014F5 /* yolo_iosTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = yolo_iosTests.swift; sourceTree = ""; };
+ 260737EE2B9060DF008014F5 /* yolo-iosUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "yolo-iosUITests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; };
+ 260737F22B9060DF008014F5 /* yolo_iosUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = yolo_iosUITests.swift; sourceTree = ""; };
+ 260737F42B9060DF008014F5 /* yolo_iosUITestsLaunchTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = yolo_iosUITestsLaunchTests.swift; sourceTree = ""; };
+ 260738052B91AF68008014F5 /* ModelHandler.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ModelHandler.swift; sourceTree = ""; };
+ 260738072B91DFDA008014F5 /* labelmap.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = labelmap.txt; sourceTree = ""; };
+ 2607380D2B95D207008014F5 /* yolov8n.ort */ = {isa = PBXFileReference; lastKnownFileType = file; path = yolov8n.ort; sourceTree = ""; };
+ 26CBC3662BBEB44E0036B7D0 /* IMG_1139.PNG */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = IMG_1139.PNG; sourceTree = ""; };
+ 26CBC3672BBEB44E0036B7D0 /* IMG_1140.PNG */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = IMG_1140.PNG; sourceTree = ""; };
+ 7B39F828D374AE21FA8D60CC /* Pods_yolo_ios_yolo_iosUITests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_yolo_ios_yolo_iosUITests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
+ 8BF2D4F5AD65BC5CCBF3C000 /* Pods-yolo-ios-yolo-iosUITests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-yolo-ios-yolo-iosUITests.release.xcconfig"; path = "Target Support Files/Pods-yolo-ios-yolo-iosUITests/Pods-yolo-ios-yolo-iosUITests.release.xcconfig"; sourceTree = ""; };
+ 91F5FA3C325DCAE34C72FD4B /* Pods-yolo-iosTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-yolo-iosTests.release.xcconfig"; path = "Target Support Files/Pods-yolo-iosTests/Pods-yolo-iosTests.release.xcconfig"; sourceTree = ""; };
+ A13564A3432619E01192466A /* Pods-yolo-ios-yolo-iosUITests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-yolo-ios-yolo-iosUITests.debug.xcconfig"; path = "Target Support Files/Pods-yolo-ios-yolo-iosUITests/Pods-yolo-ios-yolo-iosUITests.debug.xcconfig"; sourceTree = ""; };
+ BD344AB12C4F1A281D7F46D4 /* Pods_yolo_ios.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_yolo_ios.framework; sourceTree = BUILT_PRODUCTS_DIR; };
+ DACA119BA0146A276BB1E39D /* Pods-yolo-iosTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-yolo-iosTests.debug.xcconfig"; path = "Target Support Files/Pods-yolo-iosTests/Pods-yolo-iosTests.debug.xcconfig"; sourceTree = ""; };
+ E84D5AB9FA971128AE91BFF6 /* Pods-yolo-ios.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-yolo-ios.debug.xcconfig"; path = "Target Support Files/Pods-yolo-ios/Pods-yolo-ios.debug.xcconfig"; sourceTree = ""; };
+ F99F4EFF9BEDCC528BF35BA1 /* Pods_yolo_iosTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_yolo_iosTests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+ 260737C82B9060DD008014F5 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 33DF679EE66C3F4F44099B56 /* Pods_yolo_ios.framework in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ 260737E12B9060DF008014F5 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ BAC5AD988782414116DDEF0D /* Pods_yolo_iosTests.framework in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ 260737EB2B9060DF008014F5 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 67122ED79DB36FAB7237C91B /* Pods_yolo_ios_yolo_iosUITests.framework in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+ 260737C22B9060DD008014F5 = {
+ isa = PBXGroup;
+ children = (
+ 260737CD2B9060DD008014F5 /* yolo-ios */,
+ 260737E72B9060DF008014F5 /* yolo-iosTests */,
+ 260737F12B9060DF008014F5 /* yolo-iosUITests */,
+ 260737CC2B9060DD008014F5 /* Products */,
+ A60814F2EF9C6B88BBB139F3 /* Pods */,
+ CCD5EFFC179C062EF9454FC0 /* Frameworks */,
+ );
+ sourceTree = "";
+ };
+ 260737CC2B9060DD008014F5 /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ 260737CB2B9060DD008014F5 /* yolo-ios.app */,
+ 260737E42B9060DF008014F5 /* yolo-iosTests.xctest */,
+ 260737EE2B9060DF008014F5 /* yolo-iosUITests.xctest */,
+ );
+ name = Products;
+ sourceTree = "";
+ };
+ 260737CD2B9060DD008014F5 /* yolo-ios */ = {
+ isa = PBXGroup;
+ children = (
+ 26CBC3652BBEB42D0036B7D0 /* images */,
+ 2607380D2B95D207008014F5 /* yolov8n.ort */,
+ 260738052B91AF68008014F5 /* ModelHandler.swift */,
+ 260737CE2B9060DD008014F5 /* AppDelegate.swift */,
+ 260737D02B9060DD008014F5 /* SceneDelegate.swift */,
+ 260737D22B9060DD008014F5 /* ViewController.swift */,
+ 260738072B91DFDA008014F5 /* labelmap.txt */,
+ 260737D42B9060DD008014F5 /* Main.storyboard */,
+ 260737DA2B9060DF008014F5 /* Assets.xcassets */,
+ 260737DC2B9060DF008014F5 /* LaunchScreen.storyboard */,
+ 260737DF2B9060DF008014F5 /* Info.plist */,
+ 260737D72B9060DD008014F5 /* yolo_ios.xcdatamodeld */,
+ );
+ path = "yolo-ios";
+ sourceTree = "";
+ };
+ 260737E72B9060DF008014F5 /* yolo-iosTests */ = {
+ isa = PBXGroup;
+ children = (
+ 260737E82B9060DF008014F5 /* yolo_iosTests.swift */,
+ );
+ path = "yolo-iosTests";
+ sourceTree = "";
+ };
+ 260737F12B9060DF008014F5 /* yolo-iosUITests */ = {
+ isa = PBXGroup;
+ children = (
+ 260737F22B9060DF008014F5 /* yolo_iosUITests.swift */,
+ 260737F42B9060DF008014F5 /* yolo_iosUITestsLaunchTests.swift */,
+ );
+ path = "yolo-iosUITests";
+ sourceTree = "";
+ };
+ 26CBC3652BBEB42D0036B7D0 /* images */ = {
+ isa = PBXGroup;
+ children = (
+ 26CBC3662BBEB44E0036B7D0 /* IMG_1139.PNG */,
+ 26CBC3672BBEB44E0036B7D0 /* IMG_1140.PNG */,
+ );
+ path = images;
+ sourceTree = "";
+ };
+ A60814F2EF9C6B88BBB139F3 /* Pods */ = {
+ isa = PBXGroup;
+ children = (
+ E84D5AB9FA971128AE91BFF6 /* Pods-yolo-ios.debug.xcconfig */,
+ 21D39772E8C24CA9AFF7241A /* Pods-yolo-ios.release.xcconfig */,
+ A13564A3432619E01192466A /* Pods-yolo-ios-yolo-iosUITests.debug.xcconfig */,
+ 8BF2D4F5AD65BC5CCBF3C000 /* Pods-yolo-ios-yolo-iosUITests.release.xcconfig */,
+ DACA119BA0146A276BB1E39D /* Pods-yolo-iosTests.debug.xcconfig */,
+ 91F5FA3C325DCAE34C72FD4B /* Pods-yolo-iosTests.release.xcconfig */,
+ );
+ path = Pods;
+ sourceTree = "";
+ };
+ CCD5EFFC179C062EF9454FC0 /* Frameworks */ = {
+ isa = PBXGroup;
+ children = (
+ BD344AB12C4F1A281D7F46D4 /* Pods_yolo_ios.framework */,
+ 7B39F828D374AE21FA8D60CC /* Pods_yolo_ios_yolo_iosUITests.framework */,
+ F99F4EFF9BEDCC528BF35BA1 /* Pods_yolo_iosTests.framework */,
+ );
+ name = Frameworks;
+ sourceTree = "";
+ };
+/* End PBXGroup section */
+
+/* Begin PBXNativeTarget section */
+ 260737CA2B9060DD008014F5 /* yolo-ios */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = 260737F82B9060DF008014F5 /* Build configuration list for PBXNativeTarget "yolo-ios" */;
+ buildPhases = (
+ EA5E84B964AF64467FBA5A1A /* [CP] Check Pods Manifest.lock */,
+ 260737C72B9060DD008014F5 /* Sources */,
+ 260737C82B9060DD008014F5 /* Frameworks */,
+ 260737C92B9060DD008014F5 /* Resources */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = "yolo-ios";
+ productName = "yolo-ios";
+ productReference = 260737CB2B9060DD008014F5 /* yolo-ios.app */;
+ productType = "com.apple.product-type.application";
+ };
+ 260737E32B9060DF008014F5 /* yolo-iosTests */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = 260737FB2B9060DF008014F5 /* Build configuration list for PBXNativeTarget "yolo-iosTests" */;
+ buildPhases = (
+ D781FFE0881D9C7660F7E33F /* [CP] Check Pods Manifest.lock */,
+ 260737E02B9060DF008014F5 /* Sources */,
+ 260737E12B9060DF008014F5 /* Frameworks */,
+ 260737E22B9060DF008014F5 /* Resources */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ 260737E62B9060DF008014F5 /* PBXTargetDependency */,
+ );
+ name = "yolo-iosTests";
+ productName = "yolo-iosTests";
+ productReference = 260737E42B9060DF008014F5 /* yolo-iosTests.xctest */;
+ productType = "com.apple.product-type.bundle.unit-test";
+ };
+ 260737ED2B9060DF008014F5 /* yolo-iosUITests */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = 260737FE2B9060DF008014F5 /* Build configuration list for PBXNativeTarget "yolo-iosUITests" */;
+ buildPhases = (
+ E0A4CA617FC2EA4E0CA2ACFE /* [CP] Check Pods Manifest.lock */,
+ 260737EA2B9060DF008014F5 /* Sources */,
+ 260737EB2B9060DF008014F5 /* Frameworks */,
+ 260737EC2B9060DF008014F5 /* Resources */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ 260737F02B9060DF008014F5 /* PBXTargetDependency */,
+ );
+ name = "yolo-iosUITests";
+ productName = "yolo-iosUITests";
+ productReference = 260737EE2B9060DF008014F5 /* yolo-iosUITests.xctest */;
+ productType = "com.apple.product-type.bundle.ui-testing";
+ };
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+ 260737C32B9060DD008014F5 /* Project object */ = {
+ isa = PBXProject;
+ attributes = {
+ BuildIndependentTargetsInParallel = 1;
+ LastSwiftUpdateCheck = 1420;
+ LastUpgradeCheck = 1420;
+ TargetAttributes = {
+ 260737CA2B9060DD008014F5 = {
+ CreatedOnToolsVersion = 14.2;
+ };
+ 260737E32B9060DF008014F5 = {
+ CreatedOnToolsVersion = 14.2;
+ TestTargetID = 260737CA2B9060DD008014F5;
+ };
+ 260737ED2B9060DF008014F5 = {
+ CreatedOnToolsVersion = 14.2;
+ TestTargetID = 260737CA2B9060DD008014F5;
+ };
+ };
+ };
+ buildConfigurationList = 260737C62B9060DD008014F5 /* Build configuration list for PBXProject "yolo-ios" */;
+ compatibilityVersion = "Xcode 14.0";
+ developmentRegion = en;
+ hasScannedForEncodings = 0;
+ knownRegions = (
+ en,
+ Base,
+ );
+ mainGroup = 260737C22B9060DD008014F5;
+ productRefGroup = 260737CC2B9060DD008014F5 /* Products */;
+ projectDirPath = "";
+ projectRoot = "";
+ targets = (
+ 260737CA2B9060DD008014F5 /* yolo-ios */,
+ 260737E32B9060DF008014F5 /* yolo-iosTests */,
+ 260737ED2B9060DF008014F5 /* yolo-iosUITests */,
+ );
+ };
+/* End PBXProject section */
+
+/* Begin PBXResourcesBuildPhase section */
+ 260737C92B9060DD008014F5 /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 260737DE2B9060DF008014F5 /* LaunchScreen.storyboard in Resources */,
+ 26CBC3682BBEB44E0036B7D0 /* IMG_1139.PNG in Resources */,
+ 2607380E2B95D207008014F5 /* yolov8n.ort in Resources */,
+ 26CBC3692BBEB44E0036B7D0 /* IMG_1140.PNG in Resources */,
+ 260737DB2B9060DF008014F5 /* Assets.xcassets in Resources */,
+ 260737D62B9060DD008014F5 /* Main.storyboard in Resources */,
+ 260738082B91DFDA008014F5 /* labelmap.txt in Resources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ 260737E22B9060DF008014F5 /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ 260737EC2B9060DF008014F5 /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXResourcesBuildPhase section */
+
+/* Begin PBXShellScriptBuildPhase section */
+ D781FFE0881D9C7660F7E33F /* [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-yolo-iosTests-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;
+ };
+ E0A4CA617FC2EA4E0CA2ACFE /* [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-yolo-ios-yolo-iosUITests-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;
+ };
+ EA5E84B964AF64467FBA5A1A /* [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-yolo-ios-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;
+ };
+/* End PBXShellScriptBuildPhase section */
+
+/* Begin PBXSourcesBuildPhase section */
+ 260737C72B9060DD008014F5 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 260737D32B9060DD008014F5 /* ViewController.swift in Sources */,
+ 260738062B91AF68008014F5 /* ModelHandler.swift in Sources */,
+ 260737CF2B9060DD008014F5 /* AppDelegate.swift in Sources */,
+ 260737D92B9060DD008014F5 /* yolo_ios.xcdatamodeld in Sources */,
+ 260737D12B9060DD008014F5 /* SceneDelegate.swift in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ 260737E02B9060DF008014F5 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 260737E92B9060DF008014F5 /* yolo_iosTests.swift in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ 260737EA2B9060DF008014F5 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 260737F52B9060DF008014F5 /* yolo_iosUITestsLaunchTests.swift in Sources */,
+ 260737F32B9060DF008014F5 /* yolo_iosUITests.swift in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXSourcesBuildPhase section */
+
+/* Begin PBXTargetDependency section */
+ 260737E62B9060DF008014F5 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = 260737CA2B9060DD008014F5 /* yolo-ios */;
+ targetProxy = 260737E52B9060DF008014F5 /* PBXContainerItemProxy */;
+ };
+ 260737F02B9060DF008014F5 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = 260737CA2B9060DD008014F5 /* yolo-ios */;
+ targetProxy = 260737EF2B9060DF008014F5 /* PBXContainerItemProxy */;
+ };
+/* End PBXTargetDependency section */
+
+/* Begin PBXVariantGroup section */
+ 260737D42B9060DD008014F5 /* Main.storyboard */ = {
+ isa = PBXVariantGroup;
+ children = (
+ 260737D52B9060DD008014F5 /* Base */,
+ );
+ name = Main.storyboard;
+ sourceTree = "";
+ };
+ 260737DC2B9060DF008014F5 /* LaunchScreen.storyboard */ = {
+ isa = PBXVariantGroup;
+ children = (
+ 260737DD2B9060DF008014F5 /* Base */,
+ );
+ name = LaunchScreen.storyboard;
+ sourceTree = "";
+ };
+/* End PBXVariantGroup section */
+
+/* Begin XCBuildConfiguration section */
+ 260737F62B9060DF008014F5 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_ENABLE_OBJC_WEAK = YES;
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_COMMA = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INFINITE_RECURSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
+ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ COPY_PHASE_STRIP = NO;
+ DEBUG_INFORMATION_FORMAT = dwarf;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ ENABLE_TESTABILITY = YES;
+ GCC_C_LANGUAGE_STANDARD = gnu11;
+ 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;
+ IPHONEOS_DEPLOYMENT_TARGET = 16.2;
+ MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
+ MTL_FAST_MATH = YES;
+ ONLY_ACTIVE_ARCH = YES;
+ SDKROOT = iphoneos;
+ SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
+ SWIFT_OPTIMIZATION_LEVEL = "-Onone";
+ };
+ name = Debug;
+ };
+ 260737F72B9060DF008014F5 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_ENABLE_OBJC_WEAK = YES;
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_COMMA = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INFINITE_RECURSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
+ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ COPY_PHASE_STRIP = NO;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ ENABLE_NS_ASSERTIONS = NO;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ GCC_C_LANGUAGE_STANDARD = gnu11;
+ 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;
+ IPHONEOS_DEPLOYMENT_TARGET = 16.2;
+ MTL_ENABLE_DEBUG_INFO = NO;
+ MTL_FAST_MATH = YES;
+ SDKROOT = iphoneos;
+ SWIFT_COMPILATION_MODE = wholemodule;
+ SWIFT_OPTIMIZATION_LEVEL = "-O";
+ VALIDATE_PRODUCT = YES;
+ };
+ name = Release;
+ };
+ 260737F92B9060DF008014F5 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = E84D5AB9FA971128AE91BFF6 /* Pods-yolo-ios.debug.xcconfig */;
+ buildSettings = {
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
+ CODE_SIGN_STYLE = Automatic;
+ CURRENT_PROJECT_VERSION = 1;
+ DEVELOPMENT_TEAM = NP2KX7H5FT;
+ GENERATE_INFOPLIST_FILE = YES;
+ INFOPLIST_FILE = "yolo-ios/Info.plist";
+ INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
+ INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen;
+ INFOPLIST_KEY_UIMainStoryboardFile = Main;
+ INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
+ INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
+ IPHONEOS_DEPLOYMENT_TARGET = 15.1;
+ LD_RUNPATH_SEARCH_PATHS = (
+ "$(inherited)",
+ "@executable_path/Frameworks",
+ );
+ MARKETING_VERSION = 1.0;
+ PRODUCT_BUNDLE_IDENTIFIER = "com.eumentis.cloud.yolo-ios";
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SWIFT_EMIT_LOC_STRINGS = YES;
+ SWIFT_VERSION = 5.0;
+ TARGETED_DEVICE_FAMILY = "1,2";
+ };
+ name = Debug;
+ };
+ 260737FA2B9060DF008014F5 /* Release */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 21D39772E8C24CA9AFF7241A /* Pods-yolo-ios.release.xcconfig */;
+ buildSettings = {
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
+ CODE_SIGN_STYLE = Automatic;
+ CURRENT_PROJECT_VERSION = 1;
+ DEVELOPMENT_TEAM = NP2KX7H5FT;
+ GENERATE_INFOPLIST_FILE = YES;
+ INFOPLIST_FILE = "yolo-ios/Info.plist";
+ INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
+ INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen;
+ INFOPLIST_KEY_UIMainStoryboardFile = Main;
+ INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
+ INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
+ IPHONEOS_DEPLOYMENT_TARGET = 15.1;
+ LD_RUNPATH_SEARCH_PATHS = (
+ "$(inherited)",
+ "@executable_path/Frameworks",
+ );
+ MARKETING_VERSION = 1.0;
+ PRODUCT_BUNDLE_IDENTIFIER = "com.eumentis.cloud.yolo-ios";
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SWIFT_EMIT_LOC_STRINGS = YES;
+ SWIFT_VERSION = 5.0;
+ TARGETED_DEVICE_FAMILY = "1,2";
+ };
+ name = Release;
+ };
+ 260737FC2B9060DF008014F5 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = DACA119BA0146A276BB1E39D /* Pods-yolo-iosTests.debug.xcconfig */;
+ buildSettings = {
+ ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
+ BUNDLE_LOADER = "$(TEST_HOST)";
+ CODE_SIGN_STYLE = Automatic;
+ CURRENT_PROJECT_VERSION = 1;
+ DEVELOPMENT_TEAM = NP2KX7H5FT;
+ GENERATE_INFOPLIST_FILE = YES;
+ IPHONEOS_DEPLOYMENT_TARGET = 16.2;
+ MARKETING_VERSION = 1.0;
+ PRODUCT_BUNDLE_IDENTIFIER = "com.eumentis.cloud.yolo-iosTests";
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SWIFT_EMIT_LOC_STRINGS = NO;
+ SWIFT_VERSION = 5.0;
+ TARGETED_DEVICE_FAMILY = "1,2";
+ TEST_HOST = "$(BUILT_PRODUCTS_DIR)/yolo-ios.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/yolo-ios";
+ };
+ name = Debug;
+ };
+ 260737FD2B9060DF008014F5 /* Release */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 91F5FA3C325DCAE34C72FD4B /* Pods-yolo-iosTests.release.xcconfig */;
+ buildSettings = {
+ ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
+ BUNDLE_LOADER = "$(TEST_HOST)";
+ CODE_SIGN_STYLE = Automatic;
+ CURRENT_PROJECT_VERSION = 1;
+ DEVELOPMENT_TEAM = NP2KX7H5FT;
+ GENERATE_INFOPLIST_FILE = YES;
+ IPHONEOS_DEPLOYMENT_TARGET = 16.2;
+ MARKETING_VERSION = 1.0;
+ PRODUCT_BUNDLE_IDENTIFIER = "com.eumentis.cloud.yolo-iosTests";
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SWIFT_EMIT_LOC_STRINGS = NO;
+ SWIFT_VERSION = 5.0;
+ TARGETED_DEVICE_FAMILY = "1,2";
+ TEST_HOST = "$(BUILT_PRODUCTS_DIR)/yolo-ios.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/yolo-ios";
+ };
+ name = Release;
+ };
+ 260737FF2B9060DF008014F5 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = A13564A3432619E01192466A /* Pods-yolo-ios-yolo-iosUITests.debug.xcconfig */;
+ buildSettings = {
+ ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
+ CODE_SIGN_STYLE = Automatic;
+ CURRENT_PROJECT_VERSION = 1;
+ DEVELOPMENT_TEAM = NP2KX7H5FT;
+ GENERATE_INFOPLIST_FILE = YES;
+ MARKETING_VERSION = 1.0;
+ PRODUCT_BUNDLE_IDENTIFIER = "com.eumentis.cloud.yolo-iosUITests";
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SWIFT_EMIT_LOC_STRINGS = NO;
+ SWIFT_VERSION = 5.0;
+ TARGETED_DEVICE_FAMILY = "1,2";
+ TEST_TARGET_NAME = "yolo-ios";
+ };
+ name = Debug;
+ };
+ 260738002B9060DF008014F5 /* Release */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 8BF2D4F5AD65BC5CCBF3C000 /* Pods-yolo-ios-yolo-iosUITests.release.xcconfig */;
+ buildSettings = {
+ ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
+ CODE_SIGN_STYLE = Automatic;
+ CURRENT_PROJECT_VERSION = 1;
+ DEVELOPMENT_TEAM = NP2KX7H5FT;
+ GENERATE_INFOPLIST_FILE = YES;
+ MARKETING_VERSION = 1.0;
+ PRODUCT_BUNDLE_IDENTIFIER = "com.eumentis.cloud.yolo-iosUITests";
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SWIFT_EMIT_LOC_STRINGS = NO;
+ SWIFT_VERSION = 5.0;
+ TARGETED_DEVICE_FAMILY = "1,2";
+ TEST_TARGET_NAME = "yolo-ios";
+ };
+ name = Release;
+ };
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+ 260737C62B9060DD008014F5 /* Build configuration list for PBXProject "yolo-ios" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 260737F62B9060DF008014F5 /* Debug */,
+ 260737F72B9060DF008014F5 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ 260737F82B9060DF008014F5 /* Build configuration list for PBXNativeTarget "yolo-ios" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 260737F92B9060DF008014F5 /* Debug */,
+ 260737FA2B9060DF008014F5 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ 260737FB2B9060DF008014F5 /* Build configuration list for PBXNativeTarget "yolo-iosTests" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 260737FC2B9060DF008014F5 /* Debug */,
+ 260737FD2B9060DF008014F5 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ 260737FE2B9060DF008014F5 /* Build configuration list for PBXNativeTarget "yolo-iosUITests" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 260737FF2B9060DF008014F5 /* Debug */,
+ 260738002B9060DF008014F5 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+/* End XCConfigurationList section */
+
+/* Begin XCVersionGroup section */
+ 260737D72B9060DD008014F5 /* yolo_ios.xcdatamodeld */ = {
+ isa = XCVersionGroup;
+ children = (
+ 260737D82B9060DD008014F5 /* yolo_ios.xcdatamodel */,
+ );
+ currentVersion = 260737D82B9060DD008014F5 /* yolo_ios.xcdatamodel */;
+ path = yolo_ios.xcdatamodeld;
+ sourceTree = "";
+ versionGroupType = wrapper.xcdatamodel;
+ };
+/* End XCVersionGroup section */
+ };
+ rootObject = 260737C32B9060DD008014F5 /* Project object */;
+}
diff --git a/mobile/examples/object_detection_yolov8/ios/yolo-ios/yolo-ios.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/mobile/examples/object_detection_yolov8/ios/yolo-ios/yolo-ios.xcodeproj/project.xcworkspace/contents.xcworkspacedata
new file mode 100644
index 000000000..919434a62
--- /dev/null
+++ b/mobile/examples/object_detection_yolov8/ios/yolo-ios/yolo-ios.xcodeproj/project.xcworkspace/contents.xcworkspacedata
@@ -0,0 +1,7 @@
+
+
+
+
+
diff --git a/mobile/examples/object_detection_yolov8/ios/yolo-ios/yolo-ios.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/mobile/examples/object_detection_yolov8/ios/yolo-ios/yolo-ios.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
new file mode 100644
index 000000000..18d981003
--- /dev/null
+++ b/mobile/examples/object_detection_yolov8/ios/yolo-ios/yolo-ios.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
@@ -0,0 +1,8 @@
+
+
+
+
+ IDEDidComputeMac32BitWarning
+
+
+
diff --git a/mobile/examples/object_detection_yolov8/ios/yolo-ios/yolo-ios.xcworkspace/contents.xcworkspacedata b/mobile/examples/object_detection_yolov8/ios/yolo-ios/yolo-ios.xcworkspace/contents.xcworkspacedata
new file mode 100644
index 000000000..d2ecf11bd
--- /dev/null
+++ b/mobile/examples/object_detection_yolov8/ios/yolo-ios/yolo-ios.xcworkspace/contents.xcworkspacedata
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
diff --git a/mobile/examples/object_detection_yolov8/ios/yolo-ios/yolo-ios.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/mobile/examples/object_detection_yolov8/ios/yolo-ios/yolo-ios.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
new file mode 100644
index 000000000..18d981003
--- /dev/null
+++ b/mobile/examples/object_detection_yolov8/ios/yolo-ios/yolo-ios.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
@@ -0,0 +1,8 @@
+
+
+
+
+ IDEDidComputeMac32BitWarning
+
+
+
diff --git a/mobile/examples/object_detection_yolov8/ios/yolo-ios/yolo-ios/AppDelegate.swift b/mobile/examples/object_detection_yolov8/ios/yolo-ios/yolo-ios/AppDelegate.swift
new file mode 100644
index 000000000..978a10924
--- /dev/null
+++ b/mobile/examples/object_detection_yolov8/ios/yolo-ios/yolo-ios/AppDelegate.swift
@@ -0,0 +1,81 @@
+//
+// AppDelegate.swift
+// yolo-ios
+//
+// Created by Jayashree Patil on 29/02/24.
+//
+
+import UIKit
+import CoreData
+
+@main
+class AppDelegate: UIResponder, UIApplicationDelegate {
+
+
+
+ func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
+ // Override point for customization after application launch.
+ return true
+ }
+
+ // MARK: UISceneSession Lifecycle
+
+ func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
+ // Called when a new scene session is being created.
+ // Use this method to select a configuration to create the new scene with.
+ return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
+ }
+
+ func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set) {
+ // Called when the user discards a scene session.
+ // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions.
+ // Use this method to release any resources that were specific to the discarded scenes, as they will not return.
+ }
+
+ // MARK: - Core Data stack
+
+ lazy var persistentContainer: NSPersistentContainer = {
+ /*
+ The persistent container for the application. This implementation
+ creates and returns a container, having loaded the store for the
+ application to it. This property is optional since there are legitimate
+ error conditions that could cause the creation of the store to fail.
+ */
+ let container = NSPersistentContainer(name: "yolo_ios")
+ container.loadPersistentStores(completionHandler: { (storeDescription, error) in
+ if let error = error as NSError? {
+ // Replace this implementation with code to handle the error appropriately.
+ // fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
+
+ /*
+ Typical reasons for an error here include:
+ * The parent directory does not exist, cannot be created, or disallows writing.
+ * The persistent store is not accessible, due to permissions or data protection when the device is locked.
+ * The device is out of space.
+ * The store could not be migrated to the current model version.
+ Check the error message to determine what the actual problem was.
+ */
+ fatalError("Unresolved error \(error), \(error.userInfo)")
+ }
+ })
+ return container
+ }()
+
+ // MARK: - Core Data Saving support
+
+ func saveContext () {
+ let context = persistentContainer.viewContext
+ if context.hasChanges {
+ do {
+ try context.save()
+ } catch {
+ // Replace this implementation with code to handle the error appropriately.
+ // fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
+ let nserror = error as NSError
+ fatalError("Unresolved error \(nserror), \(nserror.userInfo)")
+ }
+ }
+ }
+
+}
+
diff --git a/mobile/examples/object_detection_yolov8/ios/yolo-ios/yolo-ios/Assets.xcassets/AccentColor.colorset/Contents.json b/mobile/examples/object_detection_yolov8/ios/yolo-ios/yolo-ios/Assets.xcassets/AccentColor.colorset/Contents.json
new file mode 100644
index 000000000..eb8789700
--- /dev/null
+++ b/mobile/examples/object_detection_yolov8/ios/yolo-ios/yolo-ios/Assets.xcassets/AccentColor.colorset/Contents.json
@@ -0,0 +1,11 @@
+{
+ "colors" : [
+ {
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/mobile/examples/object_detection_yolov8/ios/yolo-ios/yolo-ios/Assets.xcassets/AppIcon.appiconset/Contents.json b/mobile/examples/object_detection_yolov8/ios/yolo-ios/yolo-ios/Assets.xcassets/AppIcon.appiconset/Contents.json
new file mode 100644
index 000000000..13613e3ee
--- /dev/null
+++ b/mobile/examples/object_detection_yolov8/ios/yolo-ios/yolo-ios/Assets.xcassets/AppIcon.appiconset/Contents.json
@@ -0,0 +1,13 @@
+{
+ "images" : [
+ {
+ "idiom" : "universal",
+ "platform" : "ios",
+ "size" : "1024x1024"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/mobile/examples/object_detection_yolov8/ios/yolo-ios/yolo-ios/Assets.xcassets/Contents.json b/mobile/examples/object_detection_yolov8/ios/yolo-ios/yolo-ios/Assets.xcassets/Contents.json
new file mode 100644
index 000000000..73c00596a
--- /dev/null
+++ b/mobile/examples/object_detection_yolov8/ios/yolo-ios/yolo-ios/Assets.xcassets/Contents.json
@@ -0,0 +1,6 @@
+{
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/mobile/examples/object_detection_yolov8/ios/yolo-ios/yolo-ios/Base.lproj/LaunchScreen.storyboard b/mobile/examples/object_detection_yolov8/ios/yolo-ios/yolo-ios/Base.lproj/LaunchScreen.storyboard
new file mode 100644
index 000000000..865e9329f
--- /dev/null
+++ b/mobile/examples/object_detection_yolov8/ios/yolo-ios/yolo-ios/Base.lproj/LaunchScreen.storyboard
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/mobile/examples/object_detection_yolov8/ios/yolo-ios/yolo-ios/Base.lproj/Main.storyboard b/mobile/examples/object_detection_yolov8/ios/yolo-ios/yolo-ios/Base.lproj/Main.storyboard
new file mode 100644
index 000000000..cf7c6a1fb
--- /dev/null
+++ b/mobile/examples/object_detection_yolov8/ios/yolo-ios/yolo-ios/Base.lproj/Main.storyboard
@@ -0,0 +1,88 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/mobile/examples/object_detection_yolov8/ios/yolo-ios/yolo-ios/Info.plist b/mobile/examples/object_detection_yolov8/ios/yolo-ios/yolo-ios/Info.plist
new file mode 100644
index 000000000..984b935d4
--- /dev/null
+++ b/mobile/examples/object_detection_yolov8/ios/yolo-ios/yolo-ios/Info.plist
@@ -0,0 +1,31 @@
+
+
+
+
+ LSSupportsOpeningDocumentsInPlace
+
+ UIFileSharingEnabled
+
+ UIApplicationSceneManifest
+
+ UIApplicationSupportsMultipleScenes
+
+ UISceneConfigurations
+
+ UIWindowSceneSessionRoleApplication
+
+
+ UISceneConfigurationName
+ Default Configuration
+ UISceneDelegateClassName
+ $(PRODUCT_MODULE_NAME).SceneDelegate
+ UISceneStoryboardFile
+ Main
+ NSPhotoLibraryAddUsageDescription
+ Your explanation for why the app needs access to the photo library.
+
+
+
+
+
+
diff --git a/mobile/examples/object_detection_yolov8/ios/yolo-ios/yolo-ios/ModelHandler.swift b/mobile/examples/object_detection_yolov8/ios/yolo-ios/yolo-ios/ModelHandler.swift
new file mode 100644
index 000000000..4c143f268
--- /dev/null
+++ b/mobile/examples/object_detection_yolov8/ios/yolo-ios/yolo-ios/ModelHandler.swift
@@ -0,0 +1,533 @@
+//
+// ModelHandler.swift
+// PHPickerDemo
+//
+// Created by Jayashree Patil on 27/11/23.
+// Copyright © 2023 Apple. All rights reserved.
+//
+
+import Foundation
+import onnxruntime_objc
+import UIKit
+import CoreImage
+import Accelerate.vImage
+import CoreML
+
+// struct to shape data
+struct ShapeData {
+ var shape: [Int]
+ var data: [T]
+
+ subscript(indices: Int...) -> T? {
+ guard indices.count == shape.count else {
+ print("Invalid number of indices provided")
+ return nil
+ }
+ var index = 0
+ var stride = 1
+ for (dimensionIndex, dimensionSize) in zip(indices, shape).reversed() {
+ if dimensionIndex >= dimensionSize || dimensionIndex < 0 {
+ print("Index out of range")
+ return nil
+ }
+ index += dimensionIndex * stride
+ stride *= dimensionSize
+ }
+ return data[index]
+ }
+
+ subscript(index: Int) -> [T]? {
+ guard index < shape[0] else {
+ print("Index out of range for accessing row")
+ return nil
+ }
+ let rowStart = index * shape[1] * shape[2]
+ let rowEnd = (index + 1) * shape[1] * shape[2]
+ return Array(data[rowStart.. T? {
+ let index = row * shape[2] + column
+ guard index < shape[1] * shape[2] else {
+ print("Index out of range for accessing column")
+ return nil
+ }
+ return data[row * shape[1] * shape[2] + column]
+ }
+
+ // get total row count
+ func getRowCount() -> Int? {
+ return shape.count > 1 ? shape[1] : nil
+ }
+
+ // get total columnn count
+ func getColCount() -> Int? {
+ return shape.count > 1 ? shape[2] : nil
+ }
+}
+
+// detection object struct
+struct DetectionObject {
+ var className: String
+ var score: Float?
+ var bounds: [Float?]
+}
+
+enum OrtModelError: Error {
+ case error(_ message: String)
+}
+
+class ModelHandler: NSObject {
+
+ // MARK: - Inference Properties
+ let threadCount: Int32
+ let threshold: Float = 0.5
+ let iouThreshold = 0.45
+
+ // MARK: - Model Parameters
+ let inputWidth = 640
+ let inputHeight = 640
+
+ private var labels: [String] = []
+
+ // Information about a model file or labels file.
+ typealias FileInfo = (name: String, extension: String)
+
+ // ORT inference session and environment object for performing inference on the given ssd model
+ private var session: ORTSession
+ private var env: ORTEnv
+
+ // MARK: - Initialization of ModelHandler
+ init?(modelFileInfo: FileInfo, labelsFileInfo: FileInfo, threadCount: Int32 = 1) {
+
+ // store model file name
+ let modelFilename = modelFileInfo.name
+
+ // store model file path
+ guard let modelPath = Bundle.main.path(
+ forResource: modelFilename,
+ ofType: modelFileInfo.extension
+ ) else {
+ print("Failed to get model file path with name: \(modelFilename).")
+ return nil
+ }
+
+ self.threadCount = threadCount
+
+ // creating ORT session
+ do {
+ // Start the ORT inference environment and specify the options for session
+ env = try ORTEnv(loggingLevel: ORTLoggingLevel.verbose)
+ let options = try ORTSessionOptions()
+ try options.setLogSeverityLevel(ORTLoggingLevel.verbose)
+ try options.setIntraOpNumThreads(threadCount)
+
+ // Create the ORTSession
+ session = try ORTSession(env: env, modelPath: modelPath, sessionOptions: options)
+ } catch let error as NSError{
+ print("Failed to create ORTSession")
+ print(error)
+ return nil
+ }
+
+ super.init()
+
+ labels = loadLabels(fileInfo: labelsFileInfo)
+ }
+
+ // This method preprocesses the image, runs the ort inferencesession and returns the tensor result
+ func runModel(cgImage: CGImage) -> UIImage?{
+ // scale image to 640 * 640
+ guard let image = resizeCgImage(cgImage) else { return nil }
+
+ guard let format = vImage_CGImageFormat(bitsPerComponent: 8, bitsPerPixel: 24, colorSpace: CGColorSpaceCreateDeviceRGB(), bitmapInfo: CGBitmapInfo(rawValue: CGImageAlphaInfo.none.rawValue)) else { return nil }
+
+ var buffer = try! vImage_Buffer(cgImage: image, format: format)
+
+ defer {
+ buffer.free()
+ }
+
+ let height = Int(buffer.height)
+
+ let width = Int(buffer.width)
+
+ let bufData = buffer.data.assumingMemoryBound(to: UInt8.self)
+ for i in 0...allocate(capacity: alignmentAndRowBytes.rowBytes * height * 3)
+
+ for i in 0.. [Float] in
+ let floatBuffer = buffer.bindMemory(to: Float.self)
+ let count = rawOutputData.count / MemoryLayout.stride
+ return Array(UnsafeBufferPointer(start: floatBuffer.baseAddress, count: count))
+ }
+
+
+ // shape tensor data and store result
+ let resultArray = shapeTensorData(shape: [1, 84, 8400], data: floatValues, labels : labels, image: image)
+
+ // run nonMaxSuppression algorithm
+ let finalBoxes = nonMaxSuppression(boxes: resultArray, threshold: Float(iouThreshold))
+
+ print("*******************************************************************")
+ print("Result : ", finalBoxes)
+
+ let (imageWithRectangles) = drawBoundingBoxes(on: image, with: finalBoxes)
+
+ if let imageWithRectangles {
+
+ print("uiImage: \(imageWithRectangles)")
+
+ let uiImageWithRectangles = UIImage(cgImage: imageWithRectangles)
+
+ return uiImageWithRectangles
+ } else {
+ print("Failed to draw rectangles on the image.")
+ return nil
+ }
+
+ }catch {
+ // Handle the error here
+ print("Error occurred: \(error)")
+ return nil
+ }
+ }
+
+
+ // MARK: - Helper Methods
+
+ // load labels
+ private func loadLabels(fileInfo: FileInfo) -> [String] {
+ var labelData: [String] = []
+ let filename = fileInfo.name
+ let fileExtension = fileInfo.extension
+ guard let fileURL = Bundle.main.url(forResource: filename, withExtension: fileExtension) else {
+ print("Labels file not found in bundle. Please add a labels file with name " +
+ "\(filename).\(fileExtension)")
+ return labelData
+ }
+ do {
+ let contents = try String(contentsOf: fileURL, encoding: .utf8)
+ labelData = contents.components(separatedBy: .newlines)
+ } catch {
+ print("Labels file named \(filename).\(fileExtension) cannot be read.")
+ }
+
+ return labelData
+ }
+
+ // function used to resize image to 640 * 640
+ func resizeCgImage(_ image: CGImage) -> CGImage? {
+
+ guard let colorSpace = image.colorSpace else { return nil }
+
+ guard let context = CGContext(data: nil, width: Int(inputWidth), height: Int(inputHeight), bitsPerComponent: image.bitsPerComponent, bytesPerRow: image.bytesPerRow, space: colorSpace, bitmapInfo: image.alphaInfo.rawValue) else { return nil }
+
+ // draw image to context (resizing it)
+ context.interpolationQuality = .high
+ context.draw(image, in: CGRect(x: 0, y: 0, width: Int(inputWidth), height: Int(inputHeight)))
+
+ // extract resulting image from context
+ return context.makeImage()
+ }
+}
+
+// postproccess - this method shape the tensor result and return bounding boxes with score and class
+func shapeTensorData(shape: [Int],data: [Float32], labels: [String], image: CGImage) -> [DetectionObject]{
+
+ // create data of the given shape
+ let data = ShapeData(shape: shape, data: data)
+
+ // Create an array of DetectionObject
+ var resultsArray: [DetectionObject] = []
+
+ if let columns = data.getColCount() {
+ for colIndex in 0.. maxScore){
+ maxScore = score
+ maxIndex = rowIndex
+ }
+ }else{
+ print("Unable to determine score")
+ }
+
+ }
+
+ // get scores greter than 0.25
+ if(maxScore > 0.25){
+ // creating bounding box
+ let boundingBox = [xAxis, yAxis, width, height]
+
+ // store result
+ let result = DetectionObject(className: labels[maxIndex-4], score: maxScore, bounds: boundingBox)
+
+ resultsArray.append(result)
+ }
+
+ }else{
+ print("Unable to determine the number of rows.")
+ }
+
+ }
+ } else {
+ print("Unable to determine the number of columns.")
+ }
+
+ return resultsArray
+}
+
+// calculate IOU
+func calculateIOU(_ a: [Float?], _ b: [Float?]) -> Float {
+ let areaA = (a[2] ?? 0) * (a[3] ?? 0)
+ let areaABottomRightX = (a[0] ?? 0) + (a[2] ?? 0)
+ let areaABottomRightY = (a[1] ?? 0) + (a[3] ?? 0)
+
+ if areaA <= 0.0 {
+ return 0.0
+ }
+
+ let areaB = (b[2] ?? 0) * (b[3] ?? 0)
+
+ if areaB <= 0.0 {
+ return 0.0
+ }
+
+ let areaBBottomRightX = (b[0] ?? 0) + (b[2] ?? 0)
+ let areaBBottomRightY = (b[1] ?? 0) + (b[3] ?? 0)
+
+ let intersectionLeftX = max(a[0] ?? 0, b[0] ?? 0)
+ let intersectionLeftY = max(a[1] ?? 0, b[1] ?? 0)
+ let intersectionBottomX = min(areaABottomRightX, areaBBottomRightX)
+ let intersectionBottomY = min(areaABottomRightY, areaBBottomRightY)
+
+ let intersectionWidth = max(intersectionBottomX - intersectionLeftX, 0)
+ let intersectionHeight = max(intersectionBottomY - intersectionLeftY, 0)
+ let intersectionArea = intersectionWidth * intersectionHeight
+
+ return intersectionArea / (areaA + areaB - intersectionArea)
+}
+
+// used to remove overlapping bounding boxes.
+func nonMaxSuppression(boxes: [DetectionObject], threshold: Float) -> [DetectionObject] {
+ let newBoxes = boxes.sorted { $0.score ?? 0.0 > $1.score ?? 0.0 }
+
+ var selected: [DetectionObject] = []
+ var active = [Bool](repeating: true, count: boxes.count)
+ var numActive = active.count
+
+ var done = false
+ for i in 0.. threshold {
+ active[j] = false
+ numActive -= 1
+
+ if numActive <= 0 {
+ done = true
+ break
+ }
+ }}
+ }
+ }
+ if done {
+ break
+ }
+ }
+ }
+ return selected
+}
+
+// Define a function to draw bounding boxes for detected objects with classname.
+func drawBoundingBoxes(on image: CGImage, with detectionObjects: [DetectionObject]) -> (CGImage?) {
+ print("Original image width In Draw Reactangle :: \(image.width), Original image height In Draw Reactangle :: \(image.height)")
+ let colorSpace = CGColorSpaceCreateDeviceRGB()
+ // 1. Calculate scaling for image height and width according to original image height width and resized image height and width
+ let imgScaleX = Float(image.width)/Float(640);
+ let imgScaleY = Float(image.height)/Float(640) ;
+ print("Image scale X : \(imgScaleX), image scale Y : \(imgScaleY)")
+
+ // 2. Create image context from original image
+ guard let context = CGContext(data: nil,
+ width: image.width,
+ height: image.height,
+ bitsPerComponent: image.bitsPerComponent,
+ bytesPerRow: image.bytesPerRow,
+ space: colorSpace,
+ bitmapInfo: image.bitmapInfo.rawValue) else {
+ return nil
+ }
+ context.draw(image, in: CGRect(x: 0, y: 0, width: image.width, height: image.height))
+ print("Context created for image : \(context)")
+
+ // 3. Draw bounding boxes
+ for detectionObject in detectionObjects {
+ guard detectionObject.bounds.count == 4,
+ let x = detectionObject.bounds[0],
+ let y = detectionObject.bounds[1],
+ let width = detectionObject.bounds[2],
+ let height = detectionObject.bounds[3] else {
+ continue
+ }
+
+ let startX = imgScaleX * (x - (width/2));
+ let startY = imgScaleY * (y + ( height/2));
+ let rectWidth = imgScaleX * width;
+ let rectHeight = imgScaleY * height;
+ print("Scaled dimensions : tempX: \(startX), tempY: \(startY) rectW: \(rectWidth), rectH : \(rectHeight)")
+
+ // create react from x,y, height and width coordinates
+ let rect = CGRect(x: CGFloat(startX), y: CGFloat(Float(image.height) - startY), width: CGFloat(rectWidth), height: CGFloat(rectHeight))
+
+ print("React we Draw: \(rect)")
+ context.setStrokeColor(UIColor.red.cgColor)
+ context.setLineWidth(2.0)
+ // add rect to the image context
+ context.addRect(rect)
+ context.drawPath(using: .stroke)
+
+ // 4. draw classname for bounding box
+ // assign font
+ let myfont = CTFontCreateWithName("Apple Braille" as CFString, 20, nil)
+
+ // create string
+ let attributedString = NSAttributedString(string: detectionObject.className, attributes: [NSAttributedString.Key.font: myfont, NSAttributedString.Key.foregroundColor: UIColor.green])
+
+ // create rect for class name text
+ let textRect = CGRect(x: CGFloat(startX), y: CGFloat(Float(image.height) - startY + 40), width: CGFloat(rectWidth), height: CGFloat(rectHeight))
+
+ // calculate text frame
+ let framesetter = CTFramesetterCreateWithAttributedString(attributedString)
+ let textFrame = CTFramesetterCreateFrame(framesetter, CFRange(), CGPath(rect: textRect, transform: nil), nil)
+
+ CTFrameDraw(textFrame, context)
+ }
+
+ return context.makeImage()
+}
+
+// MARK: - Extensions
+extension Data {
+ // Create a new buffer by copying the buffer pointer of the given array.
+ init(copyingBufferOf array: [T]) {
+ self = array.withUnsafeBufferPointer(Data.init)
+ }
+ }
+
+extension Array {
+ // Create a new array from the bytes of the given unsafe data.
+ init?(unsafeData: Data) {
+ guard unsafeData.count % MemoryLayout.stride == 0 else { return nil }
+#if swift(>=5.0)
+ self = unsafeData.withUnsafeBytes { .init($0.bindMemory(to: Element.self)) }
+#else
+ self = unsafeData.withUnsafeBytes {
+ .init(UnsafeBufferPointer(
+ start: $0,
+ count: unsafeData.count / MemoryLayout.stride
+ ))
+ }
+#endif // swift(>=5.0)
+ }
+ }
diff --git a/mobile/examples/object_detection_yolov8/ios/yolo-ios/yolo-ios/SceneDelegate.swift b/mobile/examples/object_detection_yolov8/ios/yolo-ios/yolo-ios/SceneDelegate.swift
new file mode 100644
index 000000000..6c479df4b
--- /dev/null
+++ b/mobile/examples/object_detection_yolov8/ios/yolo-ios/yolo-ios/SceneDelegate.swift
@@ -0,0 +1,55 @@
+//
+// SceneDelegate.swift
+// yolo-ios
+//
+// Created by Jayashree Patil on 29/02/24.
+//
+
+import UIKit
+
+class SceneDelegate: UIResponder, UIWindowSceneDelegate {
+
+ var window: UIWindow?
+
+
+ func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
+ // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.
+ // If using a storyboard, the `window` property will automatically be initialized and attached to the scene.
+ // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).
+ guard let _ = (scene as? UIWindowScene) else { return }
+ }
+
+ func sceneDidDisconnect(_ scene: UIScene) {
+ // Called as the scene is being released by the system.
+ // This occurs shortly after the scene enters the background, or when its session is discarded.
+ // Release any resources associated with this scene that can be re-created the next time the scene connects.
+ // The scene may re-connect later, as its session was not necessarily discarded (see `application:didDiscardSceneSessions` instead).
+ }
+
+ func sceneDidBecomeActive(_ scene: UIScene) {
+ // Called when the scene has moved from an inactive state to an active state.
+ // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive.
+ }
+
+ func sceneWillResignActive(_ scene: UIScene) {
+ // Called when the scene will move from an active state to an inactive state.
+ // This may occur due to temporary interruptions (ex. an incoming phone call).
+ }
+
+ func sceneWillEnterForeground(_ scene: UIScene) {
+ // Called as the scene transitions from the background to the foreground.
+ // Use this method to undo the changes made on entering the background.
+ }
+
+ func sceneDidEnterBackground(_ scene: UIScene) {
+ // Called as the scene transitions from the foreground to the background.
+ // Use this method to save data, release shared resources, and store enough scene-specific state information
+ // to restore the scene back to its current state.
+
+ // Save changes in the application's managed object context when the application transitions to the background.
+ (UIApplication.shared.delegate as? AppDelegate)?.saveContext()
+ }
+
+
+}
+
diff --git a/mobile/examples/object_detection_yolov8/ios/yolo-ios/yolo-ios/ViewController.swift b/mobile/examples/object_detection_yolov8/ios/yolo-ios/yolo-ios/ViewController.swift
new file mode 100644
index 000000000..dbdb422d4
--- /dev/null
+++ b/mobile/examples/object_detection_yolov8/ios/yolo-ios/yolo-ios/ViewController.swift
@@ -0,0 +1,160 @@
+//
+// ViewController.swift
+// yolo-ios
+//
+// Created by Jayashree Patil on 29/02/24.
+//
+
+import UIKit
+import PhotosUI
+import AVKit
+import CoreImage
+import Accelerate
+import Accelerate.vImage
+import onnxruntime_objc
+
+private var session: ORTSession?
+private var env: ORTEnv?
+
+class ViewController: UIViewController , PHPickerViewControllerDelegate {
+ @IBOutlet weak var spinner: UIActivityIndicatorView!
+ @IBOutlet weak var start: UIButton!
+ @IBOutlet weak var errorText: UILabel!
+ @IBOutlet weak var uiImageView: UIImageView!
+
+ private var selectedImage: UIImage!
+ private var selectedImageAsset: PHPickerResult!
+ private var selectedImageAssetIdentifier: String!
+
+ // Handle all model and data preprocessing and run inference
+ private var modelHandler: ModelHandler? = ModelHandler(
+ modelFileInfo: (name: "yolov8n", extension: "ort"),
+ labelsFileInfo: (name: "labelmap", extension: "txt"))
+
+ // view did load
+ override func viewDidLoad() {
+ super.viewDidLoad()
+ // spinner view
+ spinner.hidesWhenStopped = true
+ spinner.style = .large
+ spinner.color = .darkGray
+
+ // Do any additional setup after loading the view.
+ title = "Object Detection"
+ // adding add image "+" button
+ navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .add , target: self, action: #selector(didTapAdd))
+ }
+
+ // config PHPicker on add image ("+" icon onPress)
+ @objc private func didTapAdd(){
+ var config = PHPickerConfiguration(photoLibrary: .shared())
+ config.selectionLimit = 1
+ config.filter = .images
+ let phViewController = PHPickerViewController(configuration: config)
+ phViewController.delegate = self
+ present(phViewController, animated: true)
+ }
+
+ // call image picker method
+ func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) {
+ errorText.text = " "
+ picker.dismiss(animated: true)
+
+ // create group to select images
+ let group = DispatchGroup()
+
+ // used to store image result selected by PHPicker
+ var phImageResult : PHPickerResult!
+
+ // this will print result data
+ results.forEach { result in
+ group.enter()
+ result.itemProvider.loadObject(ofClass: UIImage.self) { [weak self] reading, error in
+ defer {
+ group.leave()
+ }
+
+ // assign selected image asset indentifier
+ self?.selectedImageAssetIdentifier = result.assetIdentifier!
+
+ // store PH image result
+ phImageResult = result
+
+ // store image
+ guard let image = reading as? UIImage, error == nil else{
+ return
+ }
+
+ // assign image selected by user
+ self?.selectedImage = image
+ }
+ }
+
+ // after selecting images show images to the user
+ group.notify(queue: .main){
+ // assign selected image ph result
+ self.selectedImageAsset = phImageResult
+
+ if self.selectedImageAsset == nil {
+ return
+ } else {
+ // display selected image
+ self.selectedImage.prepareForDisplay { [weak self] preparedImage in
+ DispatchQueue.main.async {
+ self?.uiImageView.image = preparedImage
+ }
+ }
+ }
+ }
+ }
+
+
+ // handle "Start Processing" button click
+ @IBAction func startProcessing(_ sender: UIButton) {
+ spinner.startAnimating()
+ self.processSingleImageUsingIndentifier(assetIdentifier: self.selectedImageAssetIdentifier)
+ }
+
+ // process image
+ func processSingleImageUsingIndentifier(assetIdentifier: String){
+ let itemProvider = self.selectedImageAsset.itemProvider
+
+ // access image data using item provider method
+ if itemProvider.hasItemConformingToTypeIdentifier(UTType.image.identifier) {
+ itemProvider.loadDataRepresentation(forTypeIdentifier: UTType.image.identifier) { data, error in
+
+ // image data (buffer data)
+ guard let data = data,
+ // create cgImage from buffer data
+ let cgImageSource = CGImageSourceCreateWithData(data as CFData, nil) else { return}
+
+ // Convert CgImageSource to CGImage
+ guard let cgImage = CGImageSourceCreateImageAtIndex(cgImageSource, 0, nil) else { return }
+
+ // run model
+ let processedImage = self.modelHandler?.runModel(cgImage: cgImage)
+
+ // show processed image to the user
+ self.stopLoaderAndShowProcessedImage(image: processedImage)
+ }
+ }
+ }
+
+ // show processed image to the user
+ func stopLoaderAndShowProcessedImage(image: UIImage?) {
+ if(image == nil){
+ DispatchQueue.main.async {
+ self.spinner.stopAnimating();
+ self.errorText.text = "Error accoured while processing"
+ }
+ }else{
+ image?.prepareForDisplay { [weak self] preparedImage in
+ DispatchQueue.main.async {
+ self?.spinner.stopAnimating();
+ self?.uiImageView.image = preparedImage
+ }
+ }
+ }
+ }
+}
+
diff --git a/mobile/examples/object_detection_yolov8/ios/yolo-ios/yolo-ios/images/IMG_1139.PNG b/mobile/examples/object_detection_yolov8/ios/yolo-ios/yolo-ios/images/IMG_1139.PNG
new file mode 100644
index 000000000..4ce9b9a2f
Binary files /dev/null and b/mobile/examples/object_detection_yolov8/ios/yolo-ios/yolo-ios/images/IMG_1139.PNG differ
diff --git a/mobile/examples/object_detection_yolov8/ios/yolo-ios/yolo-ios/images/IMG_1140.PNG b/mobile/examples/object_detection_yolov8/ios/yolo-ios/yolo-ios/images/IMG_1140.PNG
new file mode 100644
index 000000000..aadd85b7c
Binary files /dev/null and b/mobile/examples/object_detection_yolov8/ios/yolo-ios/yolo-ios/images/IMG_1140.PNG differ
diff --git a/mobile/examples/object_detection_yolov8/ios/yolo-ios/yolo-ios/labelmap.txt b/mobile/examples/object_detection_yolov8/ios/yolo-ios/yolo-ios/labelmap.txt
new file mode 100644
index 000000000..941cb4e13
--- /dev/null
+++ b/mobile/examples/object_detection_yolov8/ios/yolo-ios/yolo-ios/labelmap.txt
@@ -0,0 +1,80 @@
+person
+bicycle
+car
+motorcycle
+airplane
+bus
+train
+truck
+boat
+traffic light
+fire hydrant
+stop sign
+parking meter
+bench
+bird
+cat
+dog
+horse
+sheep
+cow
+elephant
+bear
+zebra
+giraffe
+backpack
+umbrella
+handbag
+tie
+suitcase
+frisbee
+skis
+snowboard
+sports ball
+kite
+baseball bat
+baseball glove
+skateboard
+surfboard
+tennis racket
+bottle
+wine glass
+cup
+fork
+knife
+spoon
+bowl
+banana
+apple
+sandwich
+orange
+broccoli
+carrot
+hot dog
+pizza
+donut
+cake
+chair
+couch
+potted plant
+bed
+dining table
+toilet
+tv
+laptop
+mouse
+remote
+keyboard
+cell phone
+microwave
+oven
+toaster
+sink
+refrigerator
+book
+clock
+vase
+scissors
+teddy bear
+hair drier
+toothbrush
diff --git a/mobile/examples/object_detection_yolov8/ios/yolo-ios/yolo-ios/yolo_ios.xcdatamodeld/.xccurrentversion b/mobile/examples/object_detection_yolov8/ios/yolo-ios/yolo-ios/yolo_ios.xcdatamodeld/.xccurrentversion
new file mode 100644
index 000000000..d1787c45a
--- /dev/null
+++ b/mobile/examples/object_detection_yolov8/ios/yolo-ios/yolo-ios/yolo_ios.xcdatamodeld/.xccurrentversion
@@ -0,0 +1,8 @@
+
+
+
+
+ _XCCurrentVersionName
+ yolo_ios.xcdatamodel
+
+
diff --git a/mobile/examples/object_detection_yolov8/ios/yolo-ios/yolo-ios/yolo_ios.xcdatamodeld/yolo_ios.xcdatamodel/contents b/mobile/examples/object_detection_yolov8/ios/yolo-ios/yolo-ios/yolo_ios.xcdatamodeld/yolo_ios.xcdatamodel/contents
new file mode 100644
index 000000000..50d2514e8
--- /dev/null
+++ b/mobile/examples/object_detection_yolov8/ios/yolo-ios/yolo-ios/yolo_ios.xcdatamodeld/yolo_ios.xcdatamodel/contents
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/mobile/examples/object_detection_yolov8/ios/yolo-ios/yolo-iosTests/yolo_iosTests.swift b/mobile/examples/object_detection_yolov8/ios/yolo-ios/yolo-iosTests/yolo_iosTests.swift
new file mode 100644
index 000000000..b69711def
--- /dev/null
+++ b/mobile/examples/object_detection_yolov8/ios/yolo-ios/yolo-iosTests/yolo_iosTests.swift
@@ -0,0 +1,36 @@
+//
+// yolo_iosTests.swift
+// yolo-iosTests
+//
+// Created by Jayashree Patil on 29/02/24.
+//
+
+import XCTest
+@testable import yolo_ios
+
+final class yolo_iosTests: XCTestCase {
+
+ override func setUpWithError() throws {
+ // Put setup code here. This method is called before the invocation of each test method in the class.
+ }
+
+ override func tearDownWithError() throws {
+ // Put teardown code here. This method is called after the invocation of each test method in the class.
+ }
+
+ func testExample() throws {
+ // This is an example of a functional test case.
+ // Use XCTAssert and related functions to verify your tests produce the correct results.
+ // Any test you write for XCTest can be annotated as throws and async.
+ // Mark your test throws to produce an unexpected failure when your test encounters an uncaught error.
+ // Mark your test async to allow awaiting for asynchronous code to complete. Check the results with assertions afterwards.
+ }
+
+ func testPerformanceExample() throws {
+ // This is an example of a performance test case.
+ self.measure {
+ // Put the code you want to measure the time of here.
+ }
+ }
+
+}
diff --git a/mobile/examples/object_detection_yolov8/ios/yolo-ios/yolo-iosUITests/yolo_iosUITests.swift b/mobile/examples/object_detection_yolov8/ios/yolo-ios/yolo-iosUITests/yolo_iosUITests.swift
new file mode 100644
index 000000000..eb60fabd5
--- /dev/null
+++ b/mobile/examples/object_detection_yolov8/ios/yolo-ios/yolo-iosUITests/yolo_iosUITests.swift
@@ -0,0 +1,41 @@
+//
+// yolo_iosUITests.swift
+// yolo-iosUITests
+//
+// Created by Jayashree Patil on 29/02/24.
+//
+
+import XCTest
+
+final class yolo_iosUITests: XCTestCase {
+
+ override func setUpWithError() throws {
+ // Put setup code here. This method is called before the invocation of each test method in the class.
+
+ // In UI tests it is usually best to stop immediately when a failure occurs.
+ continueAfterFailure = false
+
+ // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this.
+ }
+
+ override func tearDownWithError() throws {
+ // Put teardown code here. This method is called after the invocation of each test method in the class.
+ }
+
+ func testExample() throws {
+ // UI tests must launch the application that they test.
+ let app = XCUIApplication()
+ app.launch()
+
+ // Use XCTAssert and related functions to verify your tests produce the correct results.
+ }
+
+ func testLaunchPerformance() throws {
+ if #available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 7.0, *) {
+ // This measures how long it takes to launch your application.
+ measure(metrics: [XCTApplicationLaunchMetric()]) {
+ XCUIApplication().launch()
+ }
+ }
+ }
+}
diff --git a/mobile/examples/object_detection_yolov8/ios/yolo-ios/yolo-iosUITests/yolo_iosUITestsLaunchTests.swift b/mobile/examples/object_detection_yolov8/ios/yolo-ios/yolo-iosUITests/yolo_iosUITestsLaunchTests.swift
new file mode 100644
index 000000000..5e8b5c9bc
--- /dev/null
+++ b/mobile/examples/object_detection_yolov8/ios/yolo-ios/yolo-iosUITests/yolo_iosUITestsLaunchTests.swift
@@ -0,0 +1,32 @@
+//
+// yolo_iosUITestsLaunchTests.swift
+// yolo-iosUITests
+//
+// Created by Jayashree Patil on 29/02/24.
+//
+
+import XCTest
+
+final class yolo_iosUITestsLaunchTests: XCTestCase {
+
+ override class var runsForEachTargetApplicationUIConfiguration: Bool {
+ true
+ }
+
+ override func setUpWithError() throws {
+ continueAfterFailure = false
+ }
+
+ func testLaunch() throws {
+ let app = XCUIApplication()
+ app.launch()
+
+ // Insert steps here to perform after app launch but before taking a screenshot,
+ // such as logging into a test account or navigating somewhere in the app
+
+ let attachment = XCTAttachment(screenshot: app.screenshot())
+ attachment.name = "Launch Screen"
+ attachment.lifetime = .keepAlways
+ add(attachment)
+ }
+}