diff --git a/.github/workflows/format.yml b/.github/workflows/format.yml index f988ad3..5b39b9b 100644 --- a/.github/workflows/format.yml +++ b/.github/workflows/format.yml @@ -13,7 +13,7 @@ on: jobs: format: - runs-on: ubuntu-latest + runs-on: macos-latest steps: - name: Run Ultralytics Formatting uses: ultralytics/actions@main @@ -23,6 +23,7 @@ jobs: python: true # format Python code and docstrings markdown: true # format Markdown prettier: true # format YAML + swift: true # format Swift spelling: false # check spelling links: false # check broken links summary: true # print PR summary with GPT4 (requires 'openai_api_key' or 'openai_azure_api_key' and 'openai_azure_endpoint') diff --git a/YOLO.xcodeproj/project.pbxproj b/YOLO.xcodeproj/project.pbxproj index ddcf965..7176d44 100644 --- a/YOLO.xcodeproj/project.pbxproj +++ b/YOLO.xcodeproj/project.pbxproj @@ -13,14 +13,12 @@ 636EFCAF21E62DD300DE43BC /* VideoCapture.swift in Sources */ = {isa = PBXBuildFile; fileRef = 636EFCA221E62DD300DE43BC /* VideoCapture.swift */; }; 636EFCB321E62DD300DE43BC /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 636EFCA721E62DD300DE43BC /* AppDelegate.swift */; }; 636EFCB921E62E3900DE43BC /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 636EFCB821E62E3900DE43BC /* Assets.xcassets */; }; - 6381D2182B7817C200ABA4E8 /* yolov8l.mlpackage in Sources */ = {isa = PBXBuildFile; fileRef = 6381D2132B7817C200ABA4E8 /* yolov8l.mlpackage */; }; - 6381D2192B7817C200ABA4E8 /* yolov8x.mlpackage in Sources */ = {isa = PBXBuildFile; fileRef = 6381D2142B7817C200ABA4E8 /* yolov8x.mlpackage */; }; - 6381D21A2B7817C200ABA4E8 /* yolov8s.mlpackage in Sources */ = {isa = PBXBuildFile; fileRef = 6381D2152B7817C200ABA4E8 /* yolov8s.mlpackage */; }; - 6381D21B2B7817C200ABA4E8 /* yolov8m.mlpackage in Sources */ = {isa = PBXBuildFile; fileRef = 6381D2162B7817C200ABA4E8 /* yolov8m.mlpackage */; }; - 6381D21C2B7817C200ABA4E8 /* yolov8n.mlpackage in Sources */ = {isa = PBXBuildFile; fileRef = 6381D2172B7817C200ABA4E8 /* yolov8n.mlpackage */; }; 63CF371F2514455300E2DEA1 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 6323C44D22186177008AE681 /* LaunchScreen.storyboard */; }; 63CF37202514455300E2DEA1 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 6323C44F22186177008AE681 /* Main.storyboard */; }; 63CF37212514455300E2DEA1 /* ultralytics_yolo_logotype.png in Resources */ = {isa = PBXBuildFile; fileRef = 6323C45122186177008AE681 /* ultralytics_yolo_logotype.png */; }; + 73FD886D2C5931B700CFF647 /* Models.swift in Sources */ = {isa = PBXBuildFile; fileRef = 73FD886B2C5931B700CFF647 /* Models.swift */; }; + 73FD886E2C5931B700CFF647 /* ModelChacheManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 73FD886C2C5931B700CFF647 /* ModelChacheManager.swift */; }; + 73FD88752C59411600CFF647 /* ZIPFoundation in Frameworks */ = {isa = PBXBuildFile; productRef = 73FD88742C59411600CFF647 /* ZIPFoundation */; }; 8EDAA33950796844333D60A7 /* BoundingBoxView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8EDAA633C1F2B50286D16008 /* BoundingBoxView.swift */; }; /* End PBXBuildFile section */ @@ -35,12 +33,9 @@ 636EFCA221E62DD300DE43BC /* VideoCapture.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = VideoCapture.swift; sourceTree = ""; }; 636EFCA721E62DD300DE43BC /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 636EFCB821E62E3900DE43BC /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; - 6381D2132B7817C200ABA4E8 /* yolov8l.mlpackage */ = {isa = PBXFileReference; lastKnownFileType = folder.mlpackage; path = yolov8l.mlpackage; sourceTree = ""; }; - 6381D2142B7817C200ABA4E8 /* yolov8x.mlpackage */ = {isa = PBXFileReference; lastKnownFileType = folder.mlpackage; path = yolov8x.mlpackage; sourceTree = ""; }; - 6381D2152B7817C200ABA4E8 /* yolov8s.mlpackage */ = {isa = PBXFileReference; lastKnownFileType = folder.mlpackage; path = yolov8s.mlpackage; sourceTree = ""; }; - 6381D2162B7817C200ABA4E8 /* yolov8m.mlpackage */ = {isa = PBXFileReference; lastKnownFileType = folder.mlpackage; path = yolov8m.mlpackage; sourceTree = ""; }; - 6381D2172B7817C200ABA4E8 /* yolov8n.mlpackage */ = {isa = PBXFileReference; lastKnownFileType = folder.mlpackage; path = yolov8n.mlpackage; sourceTree = ""; }; 63B8B0A821E62A890026FBC3 /* .gitignore */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = .gitignore; sourceTree = ""; }; + 73FD886B2C5931B700CFF647 /* Models.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Models.swift; sourceTree = ""; }; + 73FD886C2C5931B700CFF647 /* ModelChacheManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ModelChacheManager.swift; sourceTree = ""; }; 7BCB411721C3096100BFC4D0 /* YOLO.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = YOLO.app; sourceTree = BUILT_PRODUCTS_DIR; }; 8EDAA633C1F2B50286D16008 /* BoundingBoxView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BoundingBoxView.swift; sourceTree = ""; }; 8EDAAA4507D2D23D7FAB827F /* README.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = ""; }; @@ -51,6 +46,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 73FD88752C59411600CFF647 /* ZIPFoundation in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -62,6 +58,8 @@ children = ( 636166E9251443B20054FA7E /* ThresholdProvider.swift */, 8EDAA633C1F2B50286D16008 /* BoundingBoxView.swift */, + 73FD886C2C5931B700CFF647 /* ModelChacheManager.swift */, + 73FD886B2C5931B700CFF647 /* Models.swift */, ); path = Utilities; sourceTree = ""; @@ -87,11 +85,6 @@ 63A946D8271800E20001C3ED /* Models */ = { isa = PBXGroup; children = ( - 6381D2132B7817C200ABA4E8 /* yolov8l.mlpackage */, - 6381D2162B7817C200ABA4E8 /* yolov8m.mlpackage */, - 6381D2172B7817C200ABA4E8 /* yolov8n.mlpackage */, - 6381D2152B7817C200ABA4E8 /* yolov8s.mlpackage */, - 6381D2142B7817C200ABA4E8 /* yolov8x.mlpackage */, ); path = Models; sourceTree = ""; @@ -131,6 +124,9 @@ dependencies = ( ); name = YOLO; + packageProductDependencies = ( + 73FD88742C59411600CFF647 /* ZIPFoundation */, + ); productName = YOLO; productReference = 7BCB411721C3096100BFC4D0 /* YOLO.app */; productType = "com.apple.product-type.application"; @@ -160,6 +156,9 @@ Base, ); mainGroup = 7BCB410E21C3096100BFC4D0; + packageReferences = ( + 73FD88732C59411600CFF647 /* XCRemoteSwiftPackageReference "ZIPFoundation" */, + ); productRefGroup = 7BCB411821C3096100BFC4D0 /* Products */; projectDirPath = ""; projectRoot = ""; @@ -210,13 +209,10 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 6381D21B2B7817C200ABA4E8 /* yolov8m.mlpackage in Sources */, - 6381D21C2B7817C200ABA4E8 /* yolov8n.mlpackage in Sources */, + 73FD886D2C5931B700CFF647 /* Models.swift in Sources */, 636EFCAF21E62DD300DE43BC /* VideoCapture.swift in Sources */, 636166EA251443B20054FA7E /* ThresholdProvider.swift in Sources */, - 6381D2182B7817C200ABA4E8 /* yolov8l.mlpackage in Sources */, - 6381D21A2B7817C200ABA4E8 /* yolov8s.mlpackage in Sources */, - 6381D2192B7817C200ABA4E8 /* yolov8x.mlpackage in Sources */, + 73FD886E2C5931B700CFF647 /* ModelChacheManager.swift in Sources */, 636EFCB321E62DD300DE43BC /* AppDelegate.swift in Sources */, 636EFCAA21E62DD300DE43BC /* ViewController.swift in Sources */, 8EDAA33950796844333D60A7 /* BoundingBoxView.swift in Sources */, @@ -351,7 +347,7 @@ ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = NO; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 0; - DEVELOPMENT_TEAM = 3MR4P6CL3X; + DEVELOPMENT_TEAM = MFN25KNUGJ; INFOPLIST_FILE = YOLO/Info.plist; INFOPLIST_KEY_CFBundleDisplayName = "Ultralytics YOLO"; INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.developer-tools"; @@ -379,7 +375,7 @@ ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = NO; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 0; - DEVELOPMENT_TEAM = 3MR4P6CL3X; + DEVELOPMENT_TEAM = MFN25KNUGJ; INFOPLIST_FILE = YOLO/Info.plist; INFOPLIST_KEY_CFBundleDisplayName = "Ultralytics YOLO"; INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.developer-tools"; @@ -422,6 +418,25 @@ defaultConfigurationName = Release; }; /* End XCConfigurationList section */ + +/* Begin XCRemoteSwiftPackageReference section */ + 73FD88732C59411600CFF647 /* XCRemoteSwiftPackageReference "ZIPFoundation" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/weichsel/ZIPFoundation.git"; + requirement = { + kind = upToNextMajorVersion; + minimumVersion = 0.9.19; + }; + }; +/* End XCRemoteSwiftPackageReference section */ + +/* Begin XCSwiftPackageProductDependency section */ + 73FD88742C59411600CFF647 /* ZIPFoundation */ = { + isa = XCSwiftPackageProductDependency; + package = 73FD88732C59411600CFF647 /* XCRemoteSwiftPackageReference "ZIPFoundation" */; + productName = ZIPFoundation; + }; +/* End XCSwiftPackageProductDependency section */ }; rootObject = 7BCB410F21C3096100BFC4D0 /* Project object */; } diff --git a/YOLO.xcodeproj/xcshareddata/xcschemes/YOLO.xcscheme b/YOLO.xcodeproj/xcshareddata/xcschemes/YOLO.xcscheme new file mode 100644 index 0000000..3bb677d --- /dev/null +++ b/YOLO.xcodeproj/xcshareddata/xcschemes/YOLO.xcscheme @@ -0,0 +1,78 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/YOLO/AppDelegate.swift b/YOLO/AppDelegate.swift index fe2f900..d9b8711 100644 --- a/YOLO/AppDelegate.swift +++ b/YOLO/AppDelegate.swift @@ -17,49 +17,53 @@ import UIKit /// The main application delegate, handling global app behavior and configuration. @UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate { - var window: UIWindow? + var window: UIWindow? - /// Called when the app finishes launching, used here to set global app settings. - func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { - // Disable screen dimming and auto-lock to keep the app active during long operations. - UIApplication.shared.isIdleTimerDisabled = true + /// Called when the app finishes launching, used here to set global app settings. + func application( + _ application: UIApplication, + didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? + ) -> Bool { + // Disable screen dimming and auto-lock to keep the app active during long operations. + UIApplication.shared.isIdleTimerDisabled = true - // Enable battery monitoring to allow the app to adapt its behavior based on battery level. - UIDevice.current.isBatteryMonitoringEnabled = true + // Enable battery monitoring to allow the app to adapt its behavior based on battery level. + UIDevice.current.isBatteryMonitoringEnabled = true - // Store the app version and build version in UserDefaults for easy access elsewhere in the app. - if let appVersion = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String, - let buildVersion = Bundle.main.infoDictionary?["CFBundleVersion"] as? String { - UserDefaults.standard.set("\(appVersion) (\(buildVersion))", forKey: "app_version") - } + // Store the app version and build version in UserDefaults for easy access elsewhere in the app. + if let appVersion = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String, + let buildVersion = Bundle.main.infoDictionary?["CFBundleVersion"] as? String + { + UserDefaults.standard.set("\(appVersion) (\(buildVersion))", forKey: "app_version") + } - // Store the device's UUID in UserDefaults for identification purposes. - if let uuid = UIDevice.current.identifierForVendor?.uuidString { - UserDefaults.standard.set(uuid, forKey: "uuid") - } + // Store the device's UUID in UserDefaults for identification purposes. + if let uuid = UIDevice.current.identifierForVendor?.uuidString { + UserDefaults.standard.set(uuid, forKey: "uuid") + } - // Ensure UserDefaults changes are immediately saved. - UserDefaults.standard.synchronize() + // Ensure UserDefaults changes are immediately saved. + UserDefaults.standard.synchronize() - return true - } + return true + } } /// Extension to CALayer to add functionality for generating screenshots of any layer. extension CALayer { - var screenShot: UIImage? { - // Begin a new image context, using the device's screen scale to ensure high-resolution output. - UIGraphicsBeginImageContextWithOptions(frame.size, false, UIScreen.main.scale) - defer { - UIGraphicsEndImageContext() - } // Ensure the image context is cleaned up correctly. + var screenShot: UIImage? { + // Begin a new image context, using the device's screen scale to ensure high-resolution output. + UIGraphicsBeginImageContextWithOptions(frame.size, false, UIScreen.main.scale) + defer { + UIGraphicsEndImageContext() + } // Ensure the image context is cleaned up correctly. - if let context = UIGraphicsGetCurrentContext() { - // Render the layer into the current context. - render(in: context) - // Attempt to generate an image from the current context. - return UIGraphicsGetImageFromCurrentImageContext() - } - return nil // Return nil if the operation fails. + if let context = UIGraphicsGetCurrentContext() { + // Render the layer into the current context. + render(in: context) + // Attempt to generate an image from the current context. + return UIGraphicsGetImageFromCurrentImageContext() } + return nil // Return nil if the operation fails. + } } diff --git a/YOLO/Info.plist b/YOLO/Info.plist index c36dbc0..5489cfb 100644 --- a/YOLO/Info.plist +++ b/YOLO/Info.plist @@ -21,7 +21,7 @@ CFBundleShortVersionString $(MARKETING_VERSION) CFBundleVersion - 24 + 78 ITSAppUsesNonExemptEncryption LSRequiresIPhoneOS diff --git a/YOLO/Main.storyboard b/YOLO/Main.storyboard index 048e9f6..24a9283 100644 --- a/YOLO/Main.storyboard +++ b/YOLO/Main.storyboard @@ -1,9 +1,9 @@ - + - + @@ -34,16 +34,14 @@ -