├── .gitattributes ├── .gitignore ├── .swift-format ├── LICENSE ├── Package.swift ├── README.md ├── Sources └── CoreMLCompiler │ ├── Assets.xcassets │ ├── AccentColor.colorset │ │ └── Contents.json │ ├── AppIcon.appiconset │ │ ├── Contents.json │ │ ├── PlaceholderAppIcon-magic-wand-1024.png │ │ ├── PlaceholderAppIcon-magic-wand-60@2x.png │ │ ├── PlaceholderAppIcon-magic-wand-60@3x.png │ │ ├── PlaceholderAppIcon-magic-wand-76@2x.png │ │ └── PlaceholderAppIcon-magic-wand-83.5@2x.png │ └── Contents.json │ ├── ContentView.swift │ ├── CoreMLCompilerApp.swift │ └── QLView.swift └── screenshot.png /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto eol=lf 2 | Package.resolved text linguist-language=json linguist-generated=false 3 | .swift-format text linguist-language=json 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | # Created by https://www.toptal.com/developers/gitignore/api/swift 3 | # Edit at https://www.toptal.com/developers/gitignore?templates=swift 4 | 5 | ### Swift ### 6 | # Xcode 7 | # 8 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 9 | 10 | ## User settings 11 | xcuserdata/ 12 | 13 | ## compatibility with Xcode 8 and earlier (ignoring not required starting Xcode 9) 14 | *.xcscmblueprint 15 | *.xccheckout 16 | 17 | ## compatibility with Xcode 3 and earlier (ignoring not required starting Xcode 4) 18 | build/ 19 | DerivedData/ 20 | *.moved-aside 21 | *.pbxuser 22 | !default.pbxuser 23 | *.mode1v3 24 | !default.mode1v3 25 | *.mode2v3 26 | !default.mode2v3 27 | *.perspectivev3 28 | !default.perspectivev3 29 | 30 | ## Obj-C/Swift specific 31 | *.hmap 32 | 33 | ## App packaging 34 | *.ipa 35 | *.dSYM.zip 36 | *.dSYM 37 | 38 | ## Playgrounds 39 | timeline.xctimeline 40 | playground.xcworkspace 41 | 42 | # Swift Package Manager 43 | # Add this line if you want to avoid checking in source code from Swift Package Manager dependencies. 44 | # Packages/ 45 | # Package.pins 46 | # Package.resolved 47 | # *.xcodeproj 48 | # Xcode automatically generates this directory with a .xcworkspacedata file and xcuserdata 49 | # hence it is not needed unless you have added a package configuration file to your project 50 | .swiftpm 51 | 52 | .build/ 53 | 54 | # CocoaPods 55 | # We recommend against adding the Pods directory to your .gitignore. However 56 | # you should judge for yourself, the pros and cons are mentioned at: 57 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 58 | # Pods/ 59 | # Add this line if you want to avoid checking in source code from the Xcode workspace 60 | # *.xcworkspace 61 | 62 | # Carthage 63 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 64 | # Carthage/Checkouts 65 | 66 | Carthage/Build/ 67 | 68 | # Accio dependency management 69 | Dependencies/ 70 | .accio/ 71 | 72 | # fastlane 73 | # It is recommended to not store the screenshots in the git repo. 74 | # Instead, use fastlane to re-generate the screenshots whenever they are needed. 75 | # For more information about the recommended setup visit: 76 | # https://docs.fastlane.tools/best-practices/source-control/#source-control 77 | 78 | fastlane/report.xml 79 | fastlane/Preview.html 80 | fastlane/screenshots/**/*.png 81 | fastlane/test_output 82 | 83 | # Code Injection 84 | # After new code Injection tools there's a generated folder /iOSInjectionProject 85 | # https://github.com/johnno1962/injectionforxcode 86 | 87 | iOSInjectionProject/ 88 | 89 | # End of https://www.toptal.com/developers/gitignore/api/swift 90 | -------------------------------------------------------------------------------- /.swift-format: -------------------------------------------------------------------------------- 1 | { 2 | "fileScopedDeclarationPrivacy" : { 3 | "accessLevel" : "private" 4 | }, 5 | "indentConditionalCompilationBlocks" : true, 6 | "indentSwitchCaseLabels" : false, 7 | "indentation" : { 8 | "spaces" : 4 9 | }, 10 | "lineBreakAroundMultilineExpressionChainComponents" : true, 11 | "lineBreakBeforeControlFlowKeywords" : false, 12 | "lineBreakBeforeEachArgument" : true, 13 | "lineBreakBeforeEachGenericRequirement" : true, 14 | "lineLength" : 120, 15 | "maximumBlankLines" : 1, 16 | "multiElementCollectionTrailingCommas" : true, 17 | "noAssignmentInExpressions" : { 18 | "allowedFunctions" : [ 19 | "XCTAssertNoThrow" 20 | ] 21 | }, 22 | "prioritizeKeepingFunctionOutputTogether" : true, 23 | "respectsExistingLineBreaks" : true, 24 | "rules" : { 25 | "AllPublicDeclarationsHaveDocumentation" : true, 26 | "AlwaysUseLiteralForEmptyCollectionInit" : true, 27 | "AlwaysUseLowerCamelCase" : true, 28 | "AmbiguousTrailingClosureOverload" : true, 29 | "BeginDocumentationCommentWithOneLineSummary" : true, 30 | "DoNotUseSemicolons" : true, 31 | "DontRepeatTypeInStaticProperties" : true, 32 | "FileScopedDeclarationPrivacy" : true, 33 | "FullyIndirectEnum" : true, 34 | "GroupNumericLiterals" : true, 35 | "IdentifiersMustBeASCII" : true, 36 | "NeverForceUnwrap" : false, 37 | "NeverUseForceTry" : true, 38 | "NeverUseImplicitlyUnwrappedOptionals" : true, 39 | "NoAccessLevelOnExtensionDeclaration" : true, 40 | "NoAssignmentInExpressions" : true, 41 | "NoBlockComments" : true, 42 | "NoCasesWithOnlyFallthrough" : true, 43 | "NoEmptyTrailingClosureParentheses" : true, 44 | "NoLabelsInCasePatterns" : true, 45 | "NoLeadingUnderscores" : true, 46 | "NoParensAroundConditions" : true, 47 | "NoPlaygroundLiterals" : true, 48 | "NoVoidReturnOnFunctionSignature" : true, 49 | "OmitExplicitReturns" : true, 50 | "OneCasePerLine" : true, 51 | "OneVariableDeclarationPerLine" : true, 52 | "OnlyOneTrailingClosureArgument" : true, 53 | "OrderedImports" : true, 54 | "ReplaceForEachWithForLoop" : true, 55 | "ReturnVoidInsteadOfEmptyTuple" : true, 56 | "TypeNamesShouldBeCapitalized" : true, 57 | "UseEarlyExits" : true, 58 | "UseExplicitNilCheckInConditions" : true, 59 | "UseLetInEveryBoundCaseVariable" : true, 60 | "UseShorthandTypeNames" : true, 61 | "UseSingleLinePropertyGetter" : true, 62 | "UseSynthesizedInitializer" : true, 63 | "UseTripleSlashForDocumentationComments" : true, 64 | "UseWhereClausesInForLoops" : false, 65 | "ValidateDocumentationComments" : true 66 | }, 67 | "spacesAroundRangeFormationOperators" : false, 68 | "tabWidth" : 4, 69 | "version" : 1 70 | } 71 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021-2025 Kenta Kubo 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Package.swift: -------------------------------------------------------------------------------- 1 | // swift-tools-version: 5.7 2 | 3 | // WARNING: 4 | // This file is automatically generated. 5 | // Do not edit it by hand because the contents will be replaced. 6 | 7 | import AppleProductTypes 8 | import PackageDescription 9 | 10 | let package = Package( 11 | name: "CoreMLCompiler.swiftpm", 12 | platforms: [ 13 | .iOS("16.0") 14 | ], 15 | products: [ 16 | .iOSApplication( 17 | name: "Core ML Compiler", 18 | targets: ["CoreMLCompiler"], 19 | bundleIdentifier: "xyz.kebo.CoreMLCompiler", 20 | teamIdentifier: "X4678G5DL2", 21 | displayVersion: "1.0", 22 | bundleVersion: "1", 23 | iconAssetName: "AppIcon", 24 | accentColorAssetName: "AccentColor", 25 | supportedDeviceFamilies: [ 26 | .pad, 27 | .phone, 28 | ], 29 | supportedInterfaceOrientations: [ 30 | .portrait, 31 | .landscapeRight, 32 | .landscapeLeft, 33 | .portraitUpsideDown(.when(deviceFamilies: [.pad])), 34 | ] 35 | ) 36 | ], 37 | targets: [ 38 | .executableTarget( 39 | name: "CoreMLCompiler" 40 | ) 41 | ] 42 | ) 43 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Core ML Compiler 2 | 3 | [![Swift](https://img.shields.io/badge/Swift-5.7-orange.svg)](https://www.swift.org) 4 | [![Swift Playgrounds](https://img.shields.io/badge/Swift%20Playgrounds-4.2-orange.svg)](https://itunes.apple.com/jp/app/swift-playgrounds/id908519492) 5 | ![Platform](https://img.shields.io/badge/platform-ipados%20%7C%20ios-lightgrey.svg) 6 | [![License](https://img.shields.io/github/license/kkebo/CoreMLCompiler.swiftpm.svg)](LICENSE) 7 | 8 | Core ML Compiler is an iPadOS/iOS app to convert a .mlmodel file into a .mlmodelc file. 9 | 10 | screenshot 11 | 12 | ## Target platforms 13 | 14 | - iPadOS 16.1 or later 15 | - iOS 16.0 or later 16 | 17 | ## Build requirements 18 | 19 | - Swift Playgrounds 4.2 or later (iPadOS 16.0 or later) 20 | - Xcode 14.0 or later (macOS 12.5 or later) 21 | 22 | ## Get Started 23 | 24 | 1. Clone this repository 25 | - To clone, I recommend using [Working Copy](https://workingcopyapp.com) or [a-Shell](https://holzschu.github.io/a-Shell_iOS/) (`lg2` command). 26 | 2. Open CoreMLCompiler.swiftpm 27 | 3. Run 28 | -------------------------------------------------------------------------------- /Sources/CoreMLCompiler/Assets.xcassets/AccentColor.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "color" : { 5 | "platform" : "universal", 6 | "reference" : "systemGreenColor" 7 | }, 8 | "idiom" : "universal" 9 | } 10 | ], 11 | "info" : { 12 | "author" : "xcode", 13 | "version" : 1 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Sources/CoreMLCompiler/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "PlaceholderAppIcon-magic-wand-60@2x.png", 5 | "idiom" : "iphone", 6 | "scale" : "2x", 7 | "size" : "60x60" 8 | }, 9 | { 10 | "filename" : "PlaceholderAppIcon-magic-wand-60@3x.png", 11 | "idiom" : "iphone", 12 | "scale" : "3x", 13 | "size" : "60x60" 14 | }, 15 | { 16 | "filename" : "PlaceholderAppIcon-magic-wand-76@2x.png", 17 | "idiom" : "ipad", 18 | "scale" : "2x", 19 | "size" : "76x76" 20 | }, 21 | { 22 | "filename" : "PlaceholderAppIcon-magic-wand-83.5@2x.png", 23 | "idiom" : "ipad", 24 | "scale" : "2x", 25 | "size" : "83.5x83.5" 26 | }, 27 | { 28 | "filename" : "PlaceholderAppIcon-magic-wand-1024.png", 29 | "idiom" : "ios-marketing", 30 | "scale" : "1x", 31 | "size" : "1024x1024" 32 | } 33 | ], 34 | "info" : { 35 | "author" : "xcode", 36 | "version" : 1 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Sources/CoreMLCompiler/Assets.xcassets/AppIcon.appiconset/PlaceholderAppIcon-magic-wand-1024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kkebo/CoreMLCompiler.swiftpm/440a37747819b2ae0ab2f294a5e8c81c487a83dc/Sources/CoreMLCompiler/Assets.xcassets/AppIcon.appiconset/PlaceholderAppIcon-magic-wand-1024.png -------------------------------------------------------------------------------- /Sources/CoreMLCompiler/Assets.xcassets/AppIcon.appiconset/PlaceholderAppIcon-magic-wand-60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kkebo/CoreMLCompiler.swiftpm/440a37747819b2ae0ab2f294a5e8c81c487a83dc/Sources/CoreMLCompiler/Assets.xcassets/AppIcon.appiconset/PlaceholderAppIcon-magic-wand-60@2x.png -------------------------------------------------------------------------------- /Sources/CoreMLCompiler/Assets.xcassets/AppIcon.appiconset/PlaceholderAppIcon-magic-wand-60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kkebo/CoreMLCompiler.swiftpm/440a37747819b2ae0ab2f294a5e8c81c487a83dc/Sources/CoreMLCompiler/Assets.xcassets/AppIcon.appiconset/PlaceholderAppIcon-magic-wand-60@3x.png -------------------------------------------------------------------------------- /Sources/CoreMLCompiler/Assets.xcassets/AppIcon.appiconset/PlaceholderAppIcon-magic-wand-76@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kkebo/CoreMLCompiler.swiftpm/440a37747819b2ae0ab2f294a5e8c81c487a83dc/Sources/CoreMLCompiler/Assets.xcassets/AppIcon.appiconset/PlaceholderAppIcon-magic-wand-76@2x.png -------------------------------------------------------------------------------- /Sources/CoreMLCompiler/Assets.xcassets/AppIcon.appiconset/PlaceholderAppIcon-magic-wand-83.5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kkebo/CoreMLCompiler.swiftpm/440a37747819b2ae0ab2f294a5e8c81c487a83dc/Sources/CoreMLCompiler/Assets.xcassets/AppIcon.appiconset/PlaceholderAppIcon-magic-wand-83.5@2x.png -------------------------------------------------------------------------------- /Sources/CoreMLCompiler/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /Sources/CoreMLCompiler/ContentView.swift: -------------------------------------------------------------------------------- 1 | import CoreML 2 | import SwiftUI 3 | import UniformTypeIdentifiers 4 | 5 | struct ContentView { 6 | @State private var inputURL: URL? 7 | @State private var compiledURL: URL? 8 | @State private var isImporterPresented = false 9 | @State private var isCompiling = false 10 | } 11 | 12 | extension ContentView: View { 13 | var body: some View { 14 | NavigationStack { 15 | QLView(url: self.inputURL) 16 | .fileImporter( 17 | isPresented: self.$isImporterPresented, 18 | allowedContentTypes: [ 19 | .init(filenameExtension: "mlmodel")! 20 | ] 21 | ) { result in 22 | switch result { 23 | case .success(let url): 24 | self.inputURL = url 25 | case .failure(let error): 26 | print("\(error.localizedDescription)") 27 | } 28 | } 29 | .onChange(of: self.inputURL) { url in 30 | if let url { 31 | Task { 32 | self.isCompiling = true 33 | self.compiledURL = try await MLModel.compileModel(at: url) 34 | self.isCompiling = false 35 | } 36 | } else { 37 | self.compiledURL = nil 38 | } 39 | } 40 | .navigationBarTitleDisplayMode(.inline) 41 | .toolbar { 42 | ToolbarItem(placement: .navigation) { 43 | Button("Open") { 44 | self.isImporterPresented = true 45 | } 46 | } 47 | ToolbarItem(placement: .primaryAction) { 48 | if let compiledURL { 49 | ShareLink(item: compiledURL) 50 | .labelStyle(.iconOnly) 51 | } else if self.isCompiling { 52 | ProgressView() 53 | } 54 | } 55 | } 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /Sources/CoreMLCompiler/CoreMLCompilerApp.swift: -------------------------------------------------------------------------------- 1 | import SwiftUI 2 | 3 | @main 4 | struct CoreMLCompilerApp {} 5 | 6 | extension CoreMLCompilerApp: App { 7 | var body: some Scene { 8 | WindowGroup { 9 | ContentView() 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Sources/CoreMLCompiler/QLView.swift: -------------------------------------------------------------------------------- 1 | import QuickLook 2 | import SwiftUI 3 | 4 | struct QLView { 5 | let url: URL? 6 | } 7 | 8 | extension QLView: UIViewControllerRepresentable { 9 | typealias UIViewControllerType = QLPreviewController 10 | 11 | func makeUIViewController( 12 | context: Self.Context 13 | ) -> Self.UIViewControllerType { 14 | let vc = Self.UIViewControllerType() 15 | vc.dataSource = context.coordinator 16 | return vc 17 | } 18 | 19 | func makeCoordinator() -> Self.Coordinator { 20 | .init() 21 | } 22 | 23 | func updateUIViewController( 24 | _ uiViewController: Self.UIViewControllerType, 25 | context: Self.Context 26 | ) { 27 | context.coordinator.url = self.url 28 | uiViewController.reloadData() 29 | } 30 | } 31 | 32 | extension QLView { 33 | final class Coordinator: NSObject { 34 | var url: URL? 35 | } 36 | } 37 | 38 | extension QLView.Coordinator: QLPreviewControllerDataSource { 39 | func numberOfPreviewItems( 40 | in controller: QLPreviewController 41 | ) -> Int { 42 | self.url != nil ? 1 : 0 43 | } 44 | 45 | func previewController( 46 | _ controller: QLPreviewController, 47 | previewItemAt index: Int 48 | ) -> QLPreviewItem { 49 | PreviewItem(url: self.url) 50 | } 51 | } 52 | 53 | private final class PreviewItem: NSObject { 54 | let previewItemURL: URL? 55 | 56 | init(url: URL?) { 57 | self.previewItemURL = url 58 | } 59 | } 60 | 61 | extension PreviewItem: QLPreviewItem {} 62 | -------------------------------------------------------------------------------- /screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kkebo/CoreMLCompiler.swiftpm/440a37747819b2ae0ab2f294a5e8c81c487a83dc/screenshot.png --------------------------------------------------------------------------------