├── .gitignore ├── .swift-version ├── DocumentClassifier.podspec ├── DocumentClassifier.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist └── xcshareddata │ └── xcschemes │ ├── DocumentClassifierMac.xcscheme │ ├── DocumentClassifierMobile.xcscheme │ ├── DocumentClassifierTV.xcscheme │ └── DocumentClassifierWatch.xcscheme ├── LICENSE ├── NewsClassifier ├── AppDelegate.swift ├── Assets.xcassets │ ├── App.colorset │ │ └── Contents.json │ ├── AppIcon.appiconset │ │ ├── Contents.json │ │ ├── icon_1024.png │ │ ├── icon_120-1.png │ │ ├── icon_120.png │ │ ├── icon_152.png │ │ ├── icon_167.png │ │ ├── icon_180.png │ │ ├── icon_20.png │ │ ├── icon_29.png │ │ ├── icon_40-1.png │ │ ├── icon_40-2.png │ │ ├── icon_40.png │ │ ├── icon_58-1.png │ │ ├── icon_58.png │ │ ├── icon_60.png │ │ ├── icon_76.png │ │ ├── icon_80-1.png │ │ ├── icon_80.png │ │ └── icon_87.png │ ├── Business.colorset │ │ └── Contents.json │ ├── Contents.json │ ├── Entertainment.colorset │ │ └── Contents.json │ ├── Politics.colorset │ │ └── Contents.json │ ├── Sports.colorset │ │ └── Contents.json │ └── Technology.colorset │ │ └── Contents.json ├── Base.lproj │ ├── LaunchScreen.storyboard │ └── Main.storyboard ├── Info.plist ├── Screenshot.png └── ViewController.swift ├── README.md ├── Sources ├── Classification.swift ├── DocumentClassification.mlmodel ├── DocumentClassifier.h ├── DocumentClassifier.swift └── Info.plist └── Tests ├── DocumentClassifierTests.swift ├── Info.plist └── Resources ├── Business.txt ├── Entertainment.txt ├── Politics.txt ├── Sports.txt └── Technology.txt /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | # 3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 4 | 5 | ## Build generated 6 | build/ 7 | DerivedData/ 8 | .DS_Store 9 | 10 | ## Various settings 11 | *.pbxuser 12 | !default.pbxuser 13 | *.mode1v3 14 | !default.mode1v3 15 | *.mode2v3 16 | !default.mode2v3 17 | *.perspectivev3 18 | !default.perspectivev3 19 | xcuserdata/ 20 | 21 | ## Other 22 | *.moved-aside 23 | *.xccheckout 24 | *.xcscmblueprint 25 | 26 | ## Obj-C/Swift specific 27 | *.hmap 28 | *.ipa 29 | *.dSYM.zip 30 | *.dSYM 31 | 32 | ## Playgrounds 33 | timeline.xctimeline 34 | playground.xcworkspace 35 | 36 | # Swift Package Manager 37 | # 38 | # Add this line if you want to avoid checking in source code from Swift Package Manager dependencies. 39 | # Packages/ 40 | # Package.pins 41 | .build/ 42 | 43 | # CocoaPods 44 | # 45 | # We recommend against adding the Pods directory to your .gitignore. However 46 | # you should judge for yourself, the pros and cons are mentioned at: 47 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 48 | # 49 | # Pods/ 50 | 51 | # Carthage 52 | # 53 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 54 | # Carthage/Checkouts 55 | 56 | Carthage/Build 57 | 58 | # fastlane 59 | # 60 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 61 | # screenshots whenever they are needed. 62 | # For more information about the recommended setup visit: 63 | # https://docs.fastlane.tools/best-practices/source-control/#source-control 64 | 65 | fastlane/report.xml 66 | fastlane/Preview.html 67 | fastlane/screenshots 68 | fastlane/test_output 69 | -------------------------------------------------------------------------------- /.swift-version: -------------------------------------------------------------------------------- 1 | 5.0 2 | -------------------------------------------------------------------------------- /DocumentClassifier.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | s.name = 'DocumentClassifier' 3 | s.version = '1.2.0' 4 | s.license = 'MIT' 5 | s.summary = 'Swift framework for document classification using a Core ML model.' 6 | s.homepage = 'https://github.com/toddkramer/DocumentClassifier' 7 | s.social_media_url = 'http://twitter.com/_toddkramer' 8 | s.author = 'Todd Kramer' 9 | s.source = { :git => 'https://github.com/toddkramer/DocumentClassifier.git', :tag => s.version } 10 | 11 | s.module_name = 'DocumentClassifier' 12 | s.ios.deployment_target = '11.0' 13 | s.osx.deployment_target = '10.13' 14 | s.tvos.deployment_target = '11.0' 15 | s.watchos.deployment_target = '4.0' 16 | 17 | s.source_files = 'Sources/*.{swift,mlmodel}' 18 | end 19 | -------------------------------------------------------------------------------- /DocumentClassifier.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 48; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 9B45DB571FEEB6A500D81C9F /* DocumentClassifier.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9B45DB4D1FEEB6A500D81C9F /* DocumentClassifier.framework */; }; 11 | 9B45DB731FEEB6BB00D81C9F /* DocumentClassifier.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9B45DB6A1FEEB6BA00D81C9F /* DocumentClassifier.framework */; }; 12 | 9B45DB8F1FEEB6CD00D81C9F /* DocumentClassifier.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9B45DB861FEEB6CD00D81C9F /* DocumentClassifier.framework */; }; 13 | 9B45DBB01FEEB87D00D81C9F /* DocumentClassifier.h in Headers */ = {isa = PBXBuildFile; fileRef = 9B45DBAB1FEEB87900D81C9F /* DocumentClassifier.h */; settings = {ATTRIBUTES = (Public, ); }; }; 14 | 9B45DBB11FEEB87E00D81C9F /* DocumentClassifier.h in Headers */ = {isa = PBXBuildFile; fileRef = 9B45DBAB1FEEB87900D81C9F /* DocumentClassifier.h */; settings = {ATTRIBUTES = (Public, ); }; }; 15 | 9B45DBB21FEEB87F00D81C9F /* DocumentClassifier.h in Headers */ = {isa = PBXBuildFile; fileRef = 9B45DBAB1FEEB87900D81C9F /* DocumentClassifier.h */; settings = {ATTRIBUTES = (Public, ); }; }; 16 | 9B45DBB31FEEB88000D81C9F /* DocumentClassifier.h in Headers */ = {isa = PBXBuildFile; fileRef = 9B45DBAB1FEEB87900D81C9F /* DocumentClassifier.h */; settings = {ATTRIBUTES = (Public, ); }; }; 17 | 9B45DBB41FEEB89000D81C9F /* DocumentClassifierTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9B45DBAE1FEEB87900D81C9F /* DocumentClassifierTests.swift */; }; 18 | 9B45DBB51FEEB89100D81C9F /* DocumentClassifierTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9B45DBAE1FEEB87900D81C9F /* DocumentClassifierTests.swift */; }; 19 | 9B45DBB61FEEB89300D81C9F /* DocumentClassifierTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9B45DBAE1FEEB87900D81C9F /* DocumentClassifierTests.swift */; }; 20 | 9B45DBB81FEEBB4200D81C9F /* Classification.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9B45DBB71FEEBB4200D81C9F /* Classification.swift */; }; 21 | 9B45DBB91FEEBB4200D81C9F /* Classification.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9B45DBB71FEEBB4200D81C9F /* Classification.swift */; }; 22 | 9B45DBBA1FEEBB4200D81C9F /* Classification.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9B45DBB71FEEBB4200D81C9F /* Classification.swift */; }; 23 | 9B45DBBB1FEEBB4200D81C9F /* Classification.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9B45DBB71FEEBB4200D81C9F /* Classification.swift */; }; 24 | 9B45DBBD1FEF28E300D81C9F /* DocumentClassifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9B45DBBC1FEF28E300D81C9F /* DocumentClassifier.swift */; }; 25 | 9B45DBBE1FEF28E300D81C9F /* DocumentClassifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9B45DBBC1FEF28E300D81C9F /* DocumentClassifier.swift */; }; 26 | 9B45DBBF1FEF28E300D81C9F /* DocumentClassifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9B45DBBC1FEF28E300D81C9F /* DocumentClassifier.swift */; }; 27 | 9B45DBC01FEF28E300D81C9F /* DocumentClassifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9B45DBBC1FEF28E300D81C9F /* DocumentClassifier.swift */; }; 28 | 9B4EEC7D1FEF3D9A009E5262 /* Business.txt in Resources */ = {isa = PBXBuildFile; fileRef = 9B45DBC81FEF3BB300D81C9F /* Business.txt */; }; 29 | 9B4EEC7E1FEF3D9A009E5262 /* Entertainment.txt in Resources */ = {isa = PBXBuildFile; fileRef = 9B45DBC91FEF3BB300D81C9F /* Entertainment.txt */; }; 30 | 9B4EEC7F1FEF3D9A009E5262 /* Politics.txt in Resources */ = {isa = PBXBuildFile; fileRef = 9B45DBCA1FEF3BB300D81C9F /* Politics.txt */; }; 31 | 9B4EEC801FEF3D9A009E5262 /* Sports.txt in Resources */ = {isa = PBXBuildFile; fileRef = 9B45DBCB1FEF3BB300D81C9F /* Sports.txt */; }; 32 | 9B4EEC811FEF3D9A009E5262 /* Technology.txt in Resources */ = {isa = PBXBuildFile; fileRef = 9B45DBCC1FEF3BB300D81C9F /* Technology.txt */; }; 33 | 9B4EEC821FEF3D9B009E5262 /* Business.txt in Resources */ = {isa = PBXBuildFile; fileRef = 9B45DBC81FEF3BB300D81C9F /* Business.txt */; }; 34 | 9B4EEC831FEF3D9B009E5262 /* Entertainment.txt in Resources */ = {isa = PBXBuildFile; fileRef = 9B45DBC91FEF3BB300D81C9F /* Entertainment.txt */; }; 35 | 9B4EEC841FEF3D9B009E5262 /* Politics.txt in Resources */ = {isa = PBXBuildFile; fileRef = 9B45DBCA1FEF3BB300D81C9F /* Politics.txt */; }; 36 | 9B4EEC851FEF3D9B009E5262 /* Sports.txt in Resources */ = {isa = PBXBuildFile; fileRef = 9B45DBCB1FEF3BB300D81C9F /* Sports.txt */; }; 37 | 9B4EEC861FEF3D9B009E5262 /* Technology.txt in Resources */ = {isa = PBXBuildFile; fileRef = 9B45DBCC1FEF3BB300D81C9F /* Technology.txt */; }; 38 | 9B4EEC871FEF3D9C009E5262 /* Business.txt in Resources */ = {isa = PBXBuildFile; fileRef = 9B45DBC81FEF3BB300D81C9F /* Business.txt */; }; 39 | 9B4EEC881FEF3D9C009E5262 /* Entertainment.txt in Resources */ = {isa = PBXBuildFile; fileRef = 9B45DBC91FEF3BB300D81C9F /* Entertainment.txt */; }; 40 | 9B4EEC891FEF3D9C009E5262 /* Politics.txt in Resources */ = {isa = PBXBuildFile; fileRef = 9B45DBCA1FEF3BB300D81C9F /* Politics.txt */; }; 41 | 9B4EEC8A1FEF3D9C009E5262 /* Sports.txt in Resources */ = {isa = PBXBuildFile; fileRef = 9B45DBCB1FEF3BB300D81C9F /* Sports.txt */; }; 42 | 9B4EEC8B1FEF3D9C009E5262 /* Technology.txt in Resources */ = {isa = PBXBuildFile; fileRef = 9B45DBCC1FEF3BB300D81C9F /* Technology.txt */; }; 43 | 9B4EEC931FEF44D2009E5262 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9B4EEC921FEF44D2009E5262 /* AppDelegate.swift */; }; 44 | 9B4EEC951FEF44D2009E5262 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9B4EEC941FEF44D2009E5262 /* ViewController.swift */; }; 45 | 9B4EEC981FEF44D2009E5262 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 9B4EEC961FEF44D2009E5262 /* Main.storyboard */; }; 46 | 9B4EEC9A1FEF44D2009E5262 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 9B4EEC991FEF44D2009E5262 /* Assets.xcassets */; }; 47 | 9B4EEC9D1FEF44D2009E5262 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 9B4EEC9B1FEF44D2009E5262 /* LaunchScreen.storyboard */; }; 48 | 9B4EECA21FEF5104009E5262 /* DocumentClassifier.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9B45DB4D1FEEB6A500D81C9F /* DocumentClassifier.framework */; }; 49 | 9B4EECA31FEF5104009E5262 /* DocumentClassifier.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 9B45DB4D1FEEB6A500D81C9F /* DocumentClassifier.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 50 | 9B4EECA81FF00382009E5262 /* DocumentClassification.mlmodel in Sources */ = {isa = PBXBuildFile; fileRef = 9B4EECA71FF00381009E5262 /* DocumentClassification.mlmodel */; }; 51 | 9B4EECA91FF00382009E5262 /* DocumentClassification.mlmodel in Sources */ = {isa = PBXBuildFile; fileRef = 9B4EECA71FF00381009E5262 /* DocumentClassification.mlmodel */; }; 52 | 9B4EECAA1FF00382009E5262 /* DocumentClassification.mlmodel in Sources */ = {isa = PBXBuildFile; fileRef = 9B4EECA71FF00381009E5262 /* DocumentClassification.mlmodel */; }; 53 | 9B4EECAB1FF00382009E5262 /* DocumentClassification.mlmodel in Sources */ = {isa = PBXBuildFile; fileRef = 9B4EECA71FF00381009E5262 /* DocumentClassification.mlmodel */; }; 54 | /* End PBXBuildFile section */ 55 | 56 | /* Begin PBXContainerItemProxy section */ 57 | 9B45DB581FEEB6A500D81C9F /* PBXContainerItemProxy */ = { 58 | isa = PBXContainerItemProxy; 59 | containerPortal = 9B45DB421FEEB64C00D81C9F /* Project object */; 60 | proxyType = 1; 61 | remoteGlobalIDString = 9B45DB4C1FEEB6A500D81C9F; 62 | remoteInfo = DocumentClassifierMobile; 63 | }; 64 | 9B45DB741FEEB6BB00D81C9F /* PBXContainerItemProxy */ = { 65 | isa = PBXContainerItemProxy; 66 | containerPortal = 9B45DB421FEEB64C00D81C9F /* Project object */; 67 | proxyType = 1; 68 | remoteGlobalIDString = 9B45DB691FEEB6BA00D81C9F; 69 | remoteInfo = DocumentClassifierMac; 70 | }; 71 | 9B45DB901FEEB6CD00D81C9F /* PBXContainerItemProxy */ = { 72 | isa = PBXContainerItemProxy; 73 | containerPortal = 9B45DB421FEEB64C00D81C9F /* Project object */; 74 | proxyType = 1; 75 | remoteGlobalIDString = 9B45DB851FEEB6CD00D81C9F; 76 | remoteInfo = DocumentClassifierTV; 77 | }; 78 | 9B4EECA41FEF5104009E5262 /* PBXContainerItemProxy */ = { 79 | isa = PBXContainerItemProxy; 80 | containerPortal = 9B45DB421FEEB64C00D81C9F /* Project object */; 81 | proxyType = 1; 82 | remoteGlobalIDString = 9B45DB4C1FEEB6A500D81C9F; 83 | remoteInfo = DocumentClassifierMobile; 84 | }; 85 | /* End PBXContainerItemProxy section */ 86 | 87 | /* Begin PBXCopyFilesBuildPhase section */ 88 | 9B4EECA61FEF5104009E5262 /* Embed Frameworks */ = { 89 | isa = PBXCopyFilesBuildPhase; 90 | buildActionMask = 2147483647; 91 | dstPath = ""; 92 | dstSubfolderSpec = 10; 93 | files = ( 94 | 9B4EECA31FEF5104009E5262 /* DocumentClassifier.framework in Embed Frameworks */, 95 | ); 96 | name = "Embed Frameworks"; 97 | runOnlyForDeploymentPostprocessing = 0; 98 | }; 99 | /* End PBXCopyFilesBuildPhase section */ 100 | 101 | /* Begin PBXFileReference section */ 102 | 9B45DB4D1FEEB6A500D81C9F /* DocumentClassifier.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = DocumentClassifier.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 103 | 9B45DB561FEEB6A500D81C9F /* DocumentClassifierMobileTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = DocumentClassifierMobileTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 104 | 9B45DB6A1FEEB6BA00D81C9F /* DocumentClassifier.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = DocumentClassifier.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 105 | 9B45DB721FEEB6BA00D81C9F /* DocumentClassifierMacTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = DocumentClassifierMacTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 106 | 9B45DB861FEEB6CD00D81C9F /* DocumentClassifier.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = DocumentClassifier.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 107 | 9B45DB8E1FEEB6CD00D81C9F /* DocumentClassifierTVTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = DocumentClassifierTVTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 108 | 9B45DBA21FEEB71100D81C9F /* DocumentClassifier.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = DocumentClassifier.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 109 | 9B45DBAB1FEEB87900D81C9F /* DocumentClassifier.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DocumentClassifier.h; sourceTree = ""; }; 110 | 9B45DBAC1FEEB87900D81C9F /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 111 | 9B45DBAE1FEEB87900D81C9F /* DocumentClassifierTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DocumentClassifierTests.swift; sourceTree = ""; }; 112 | 9B45DBAF1FEEB87900D81C9F /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 113 | 9B45DBB71FEEBB4200D81C9F /* Classification.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Classification.swift; sourceTree = ""; }; 114 | 9B45DBBC1FEF28E300D81C9F /* DocumentClassifier.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DocumentClassifier.swift; sourceTree = ""; }; 115 | 9B45DBC81FEF3BB300D81C9F /* Business.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Business.txt; sourceTree = ""; }; 116 | 9B45DBC91FEF3BB300D81C9F /* Entertainment.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Entertainment.txt; sourceTree = ""; }; 117 | 9B45DBCA1FEF3BB300D81C9F /* Politics.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Politics.txt; sourceTree = ""; }; 118 | 9B45DBCB1FEF3BB300D81C9F /* Sports.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Sports.txt; sourceTree = ""; }; 119 | 9B45DBCC1FEF3BB300D81C9F /* Technology.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Technology.txt; sourceTree = ""; }; 120 | 9B4EEC901FEF44D2009E5262 /* NewsClassifier.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = NewsClassifier.app; sourceTree = BUILT_PRODUCTS_DIR; }; 121 | 9B4EEC921FEF44D2009E5262 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 122 | 9B4EEC941FEF44D2009E5262 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; 123 | 9B4EEC971FEF44D2009E5262 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 124 | 9B4EEC991FEF44D2009E5262 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 125 | 9B4EEC9C1FEF44D2009E5262 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 126 | 9B4EEC9E1FEF44D2009E5262 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 127 | 9B4EECA71FF00381009E5262 /* DocumentClassification.mlmodel */ = {isa = PBXFileReference; lastKnownFileType = file.mlmodel; path = DocumentClassification.mlmodel; sourceTree = ""; }; 128 | /* End PBXFileReference section */ 129 | 130 | /* Begin PBXFrameworksBuildPhase section */ 131 | 9B45DB491FEEB6A500D81C9F /* Frameworks */ = { 132 | isa = PBXFrameworksBuildPhase; 133 | buildActionMask = 2147483647; 134 | files = ( 135 | ); 136 | runOnlyForDeploymentPostprocessing = 0; 137 | }; 138 | 9B45DB531FEEB6A500D81C9F /* Frameworks */ = { 139 | isa = PBXFrameworksBuildPhase; 140 | buildActionMask = 2147483647; 141 | files = ( 142 | 9B45DB571FEEB6A500D81C9F /* DocumentClassifier.framework in Frameworks */, 143 | ); 144 | runOnlyForDeploymentPostprocessing = 0; 145 | }; 146 | 9B45DB661FEEB6BA00D81C9F /* Frameworks */ = { 147 | isa = PBXFrameworksBuildPhase; 148 | buildActionMask = 2147483647; 149 | files = ( 150 | ); 151 | runOnlyForDeploymentPostprocessing = 0; 152 | }; 153 | 9B45DB6F1FEEB6BA00D81C9F /* Frameworks */ = { 154 | isa = PBXFrameworksBuildPhase; 155 | buildActionMask = 2147483647; 156 | files = ( 157 | 9B45DB731FEEB6BB00D81C9F /* DocumentClassifier.framework in Frameworks */, 158 | ); 159 | runOnlyForDeploymentPostprocessing = 0; 160 | }; 161 | 9B45DB821FEEB6CD00D81C9F /* Frameworks */ = { 162 | isa = PBXFrameworksBuildPhase; 163 | buildActionMask = 2147483647; 164 | files = ( 165 | ); 166 | runOnlyForDeploymentPostprocessing = 0; 167 | }; 168 | 9B45DB8B1FEEB6CD00D81C9F /* Frameworks */ = { 169 | isa = PBXFrameworksBuildPhase; 170 | buildActionMask = 2147483647; 171 | files = ( 172 | 9B45DB8F1FEEB6CD00D81C9F /* DocumentClassifier.framework in Frameworks */, 173 | ); 174 | runOnlyForDeploymentPostprocessing = 0; 175 | }; 176 | 9B45DB9E1FEEB71100D81C9F /* Frameworks */ = { 177 | isa = PBXFrameworksBuildPhase; 178 | buildActionMask = 2147483647; 179 | files = ( 180 | ); 181 | runOnlyForDeploymentPostprocessing = 0; 182 | }; 183 | 9B4EEC8D1FEF44D2009E5262 /* Frameworks */ = { 184 | isa = PBXFrameworksBuildPhase; 185 | buildActionMask = 2147483647; 186 | files = ( 187 | 9B4EECA21FEF5104009E5262 /* DocumentClassifier.framework in Frameworks */, 188 | ); 189 | runOnlyForDeploymentPostprocessing = 0; 190 | }; 191 | /* End PBXFrameworksBuildPhase section */ 192 | 193 | /* Begin PBXGroup section */ 194 | 9B45DB411FEEB64C00D81C9F = { 195 | isa = PBXGroup; 196 | children = ( 197 | 9B45DBAA1FEEB87900D81C9F /* Sources */, 198 | 9B45DBAD1FEEB87900D81C9F /* Tests */, 199 | 9B4EEC911FEF44D2009E5262 /* NewsClassifier */, 200 | 9B45DB4E1FEEB6A500D81C9F /* Products */, 201 | ); 202 | sourceTree = ""; 203 | }; 204 | 9B45DB4E1FEEB6A500D81C9F /* Products */ = { 205 | isa = PBXGroup; 206 | children = ( 207 | 9B45DB4D1FEEB6A500D81C9F /* DocumentClassifier.framework */, 208 | 9B45DB561FEEB6A500D81C9F /* DocumentClassifierMobileTests.xctest */, 209 | 9B45DB6A1FEEB6BA00D81C9F /* DocumentClassifier.framework */, 210 | 9B45DB721FEEB6BA00D81C9F /* DocumentClassifierMacTests.xctest */, 211 | 9B45DB861FEEB6CD00D81C9F /* DocumentClassifier.framework */, 212 | 9B45DB8E1FEEB6CD00D81C9F /* DocumentClassifierTVTests.xctest */, 213 | 9B45DBA21FEEB71100D81C9F /* DocumentClassifier.framework */, 214 | 9B4EEC901FEF44D2009E5262 /* NewsClassifier.app */, 215 | ); 216 | name = Products; 217 | sourceTree = ""; 218 | }; 219 | 9B45DBAA1FEEB87900D81C9F /* Sources */ = { 220 | isa = PBXGroup; 221 | children = ( 222 | 9B45DBAB1FEEB87900D81C9F /* DocumentClassifier.h */, 223 | 9B45DBAC1FEEB87900D81C9F /* Info.plist */, 224 | 9B45DBB71FEEBB4200D81C9F /* Classification.swift */, 225 | 9B45DBBC1FEF28E300D81C9F /* DocumentClassifier.swift */, 226 | 9B4EECA71FF00381009E5262 /* DocumentClassification.mlmodel */, 227 | ); 228 | path = Sources; 229 | sourceTree = ""; 230 | }; 231 | 9B45DBAD1FEEB87900D81C9F /* Tests */ = { 232 | isa = PBXGroup; 233 | children = ( 234 | 9B45DBAE1FEEB87900D81C9F /* DocumentClassifierTests.swift */, 235 | 9B45DBAF1FEEB87900D81C9F /* Info.plist */, 236 | 9B45DBC71FEF3BB300D81C9F /* Resources */, 237 | ); 238 | path = Tests; 239 | sourceTree = ""; 240 | }; 241 | 9B45DBC71FEF3BB300D81C9F /* Resources */ = { 242 | isa = PBXGroup; 243 | children = ( 244 | 9B45DBC81FEF3BB300D81C9F /* Business.txt */, 245 | 9B45DBC91FEF3BB300D81C9F /* Entertainment.txt */, 246 | 9B45DBCA1FEF3BB300D81C9F /* Politics.txt */, 247 | 9B45DBCB1FEF3BB300D81C9F /* Sports.txt */, 248 | 9B45DBCC1FEF3BB300D81C9F /* Technology.txt */, 249 | ); 250 | path = Resources; 251 | sourceTree = ""; 252 | }; 253 | 9B4EEC911FEF44D2009E5262 /* NewsClassifier */ = { 254 | isa = PBXGroup; 255 | children = ( 256 | 9B4EEC921FEF44D2009E5262 /* AppDelegate.swift */, 257 | 9B4EEC941FEF44D2009E5262 /* ViewController.swift */, 258 | 9B4EEC961FEF44D2009E5262 /* Main.storyboard */, 259 | 9B4EEC991FEF44D2009E5262 /* Assets.xcassets */, 260 | 9B4EEC9B1FEF44D2009E5262 /* LaunchScreen.storyboard */, 261 | 9B4EEC9E1FEF44D2009E5262 /* Info.plist */, 262 | ); 263 | path = NewsClassifier; 264 | sourceTree = ""; 265 | }; 266 | /* End PBXGroup section */ 267 | 268 | /* Begin PBXHeadersBuildPhase section */ 269 | 9B45DB4A1FEEB6A500D81C9F /* Headers */ = { 270 | isa = PBXHeadersBuildPhase; 271 | buildActionMask = 2147483647; 272 | files = ( 273 | 9B45DBB01FEEB87D00D81C9F /* DocumentClassifier.h in Headers */, 274 | ); 275 | runOnlyForDeploymentPostprocessing = 0; 276 | }; 277 | 9B45DB671FEEB6BA00D81C9F /* Headers */ = { 278 | isa = PBXHeadersBuildPhase; 279 | buildActionMask = 2147483647; 280 | files = ( 281 | 9B45DBB11FEEB87E00D81C9F /* DocumentClassifier.h in Headers */, 282 | ); 283 | runOnlyForDeploymentPostprocessing = 0; 284 | }; 285 | 9B45DB831FEEB6CD00D81C9F /* Headers */ = { 286 | isa = PBXHeadersBuildPhase; 287 | buildActionMask = 2147483647; 288 | files = ( 289 | 9B45DBB21FEEB87F00D81C9F /* DocumentClassifier.h in Headers */, 290 | ); 291 | runOnlyForDeploymentPostprocessing = 0; 292 | }; 293 | 9B45DB9F1FEEB71100D81C9F /* Headers */ = { 294 | isa = PBXHeadersBuildPhase; 295 | buildActionMask = 2147483647; 296 | files = ( 297 | 9B45DBB31FEEB88000D81C9F /* DocumentClassifier.h in Headers */, 298 | ); 299 | runOnlyForDeploymentPostprocessing = 0; 300 | }; 301 | /* End PBXHeadersBuildPhase section */ 302 | 303 | /* Begin PBXNativeTarget section */ 304 | 9B45DB4C1FEEB6A500D81C9F /* DocumentClassifierMobile */ = { 305 | isa = PBXNativeTarget; 306 | buildConfigurationList = 9B45DB5F1FEEB6A500D81C9F /* Build configuration list for PBXNativeTarget "DocumentClassifierMobile" */; 307 | buildPhases = ( 308 | 9B45DB481FEEB6A500D81C9F /* Sources */, 309 | 9B45DB491FEEB6A500D81C9F /* Frameworks */, 310 | 9B45DB4A1FEEB6A500D81C9F /* Headers */, 311 | 9B45DB4B1FEEB6A500D81C9F /* Resources */, 312 | ); 313 | buildRules = ( 314 | ); 315 | dependencies = ( 316 | ); 317 | name = DocumentClassifierMobile; 318 | productName = DocumentClassifierMobile; 319 | productReference = 9B45DB4D1FEEB6A500D81C9F /* DocumentClassifier.framework */; 320 | productType = "com.apple.product-type.framework"; 321 | }; 322 | 9B45DB551FEEB6A500D81C9F /* DocumentClassifierMobileTests */ = { 323 | isa = PBXNativeTarget; 324 | buildConfigurationList = 9B45DB621FEEB6A500D81C9F /* Build configuration list for PBXNativeTarget "DocumentClassifierMobileTests" */; 325 | buildPhases = ( 326 | 9B45DB521FEEB6A500D81C9F /* Sources */, 327 | 9B45DB531FEEB6A500D81C9F /* Frameworks */, 328 | 9B45DB541FEEB6A500D81C9F /* Resources */, 329 | ); 330 | buildRules = ( 331 | ); 332 | dependencies = ( 333 | 9B45DB591FEEB6A500D81C9F /* PBXTargetDependency */, 334 | ); 335 | name = DocumentClassifierMobileTests; 336 | productName = DocumentClassifierMobileTests; 337 | productReference = 9B45DB561FEEB6A500D81C9F /* DocumentClassifierMobileTests.xctest */; 338 | productType = "com.apple.product-type.bundle.unit-test"; 339 | }; 340 | 9B45DB691FEEB6BA00D81C9F /* DocumentClassifierMac */ = { 341 | isa = PBXNativeTarget; 342 | buildConfigurationList = 9B45DB7B1FEEB6BB00D81C9F /* Build configuration list for PBXNativeTarget "DocumentClassifierMac" */; 343 | buildPhases = ( 344 | 9B45DB651FEEB6BA00D81C9F /* Sources */, 345 | 9B45DB661FEEB6BA00D81C9F /* Frameworks */, 346 | 9B45DB671FEEB6BA00D81C9F /* Headers */, 347 | 9B45DB681FEEB6BA00D81C9F /* Resources */, 348 | ); 349 | buildRules = ( 350 | ); 351 | dependencies = ( 352 | ); 353 | name = DocumentClassifierMac; 354 | productName = DocumentClassifierMac; 355 | productReference = 9B45DB6A1FEEB6BA00D81C9F /* DocumentClassifier.framework */; 356 | productType = "com.apple.product-type.framework"; 357 | }; 358 | 9B45DB711FEEB6BA00D81C9F /* DocumentClassifierMacTests */ = { 359 | isa = PBXNativeTarget; 360 | buildConfigurationList = 9B45DB7E1FEEB6BB00D81C9F /* Build configuration list for PBXNativeTarget "DocumentClassifierMacTests" */; 361 | buildPhases = ( 362 | 9B45DB6E1FEEB6BA00D81C9F /* Sources */, 363 | 9B45DB6F1FEEB6BA00D81C9F /* Frameworks */, 364 | 9B45DB701FEEB6BA00D81C9F /* Resources */, 365 | ); 366 | buildRules = ( 367 | ); 368 | dependencies = ( 369 | 9B45DB751FEEB6BB00D81C9F /* PBXTargetDependency */, 370 | ); 371 | name = DocumentClassifierMacTests; 372 | productName = DocumentClassifierMacTests; 373 | productReference = 9B45DB721FEEB6BA00D81C9F /* DocumentClassifierMacTests.xctest */; 374 | productType = "com.apple.product-type.bundle.unit-test"; 375 | }; 376 | 9B45DB851FEEB6CD00D81C9F /* DocumentClassifierTV */ = { 377 | isa = PBXNativeTarget; 378 | buildConfigurationList = 9B45DB971FEEB6CD00D81C9F /* Build configuration list for PBXNativeTarget "DocumentClassifierTV" */; 379 | buildPhases = ( 380 | 9B45DB811FEEB6CD00D81C9F /* Sources */, 381 | 9B45DB821FEEB6CD00D81C9F /* Frameworks */, 382 | 9B45DB831FEEB6CD00D81C9F /* Headers */, 383 | 9B45DB841FEEB6CD00D81C9F /* Resources */, 384 | ); 385 | buildRules = ( 386 | ); 387 | dependencies = ( 388 | ); 389 | name = DocumentClassifierTV; 390 | productName = DocumentClassifierTV; 391 | productReference = 9B45DB861FEEB6CD00D81C9F /* DocumentClassifier.framework */; 392 | productType = "com.apple.product-type.framework"; 393 | }; 394 | 9B45DB8D1FEEB6CD00D81C9F /* DocumentClassifierTVTests */ = { 395 | isa = PBXNativeTarget; 396 | buildConfigurationList = 9B45DB9A1FEEB6CD00D81C9F /* Build configuration list for PBXNativeTarget "DocumentClassifierTVTests" */; 397 | buildPhases = ( 398 | 9B45DB8A1FEEB6CD00D81C9F /* Sources */, 399 | 9B45DB8B1FEEB6CD00D81C9F /* Frameworks */, 400 | 9B45DB8C1FEEB6CD00D81C9F /* Resources */, 401 | ); 402 | buildRules = ( 403 | ); 404 | dependencies = ( 405 | 9B45DB911FEEB6CD00D81C9F /* PBXTargetDependency */, 406 | ); 407 | name = DocumentClassifierTVTests; 408 | productName = DocumentClassifierTVTests; 409 | productReference = 9B45DB8E1FEEB6CD00D81C9F /* DocumentClassifierTVTests.xctest */; 410 | productType = "com.apple.product-type.bundle.unit-test"; 411 | }; 412 | 9B45DBA11FEEB71100D81C9F /* DocumentClassifierWatch */ = { 413 | isa = PBXNativeTarget; 414 | buildConfigurationList = 9B45DBA71FEEB71100D81C9F /* Build configuration list for PBXNativeTarget "DocumentClassifierWatch" */; 415 | buildPhases = ( 416 | 9B45DB9D1FEEB71100D81C9F /* Sources */, 417 | 9B45DB9E1FEEB71100D81C9F /* Frameworks */, 418 | 9B45DB9F1FEEB71100D81C9F /* Headers */, 419 | 9B45DBA01FEEB71100D81C9F /* Resources */, 420 | ); 421 | buildRules = ( 422 | ); 423 | dependencies = ( 424 | ); 425 | name = DocumentClassifierWatch; 426 | productName = DocumentClassifierWatch; 427 | productReference = 9B45DBA21FEEB71100D81C9F /* DocumentClassifier.framework */; 428 | productType = "com.apple.product-type.framework"; 429 | }; 430 | 9B4EEC8F1FEF44D2009E5262 /* NewsClassifier */ = { 431 | isa = PBXNativeTarget; 432 | buildConfigurationList = 9B4EEC9F1FEF44D2009E5262 /* Build configuration list for PBXNativeTarget "NewsClassifier" */; 433 | buildPhases = ( 434 | 9B4EEC8C1FEF44D2009E5262 /* Sources */, 435 | 9B4EEC8D1FEF44D2009E5262 /* Frameworks */, 436 | 9B4EEC8E1FEF44D2009E5262 /* Resources */, 437 | 9B4EECA61FEF5104009E5262 /* Embed Frameworks */, 438 | ); 439 | buildRules = ( 440 | ); 441 | dependencies = ( 442 | 9B4EECA51FEF5104009E5262 /* PBXTargetDependency */, 443 | ); 444 | name = NewsClassifier; 445 | productName = NewsClassifier; 446 | productReference = 9B4EEC901FEF44D2009E5262 /* NewsClassifier.app */; 447 | productType = "com.apple.product-type.application"; 448 | }; 449 | /* End PBXNativeTarget section */ 450 | 451 | /* Begin PBXProject section */ 452 | 9B45DB421FEEB64C00D81C9F /* Project object */ = { 453 | isa = PBXProject; 454 | attributes = { 455 | LastSwiftUpdateCheck = 0910; 456 | LastUpgradeCheck = 1010; 457 | TargetAttributes = { 458 | 9B45DB4C1FEEB6A500D81C9F = { 459 | CreatedOnToolsVersion = 9.1; 460 | LastSwiftMigration = 1020; 461 | ProvisioningStyle = Manual; 462 | }; 463 | 9B45DB551FEEB6A500D81C9F = { 464 | CreatedOnToolsVersion = 9.1; 465 | LastSwiftMigration = 1020; 466 | ProvisioningStyle = Manual; 467 | }; 468 | 9B45DB691FEEB6BA00D81C9F = { 469 | CreatedOnToolsVersion = 9.1; 470 | LastSwiftMigration = 1020; 471 | ProvisioningStyle = Manual; 472 | }; 473 | 9B45DB711FEEB6BA00D81C9F = { 474 | CreatedOnToolsVersion = 9.1; 475 | LastSwiftMigration = 1020; 476 | ProvisioningStyle = Automatic; 477 | }; 478 | 9B45DB851FEEB6CD00D81C9F = { 479 | CreatedOnToolsVersion = 9.1; 480 | LastSwiftMigration = 1020; 481 | ProvisioningStyle = Manual; 482 | }; 483 | 9B45DB8D1FEEB6CD00D81C9F = { 484 | CreatedOnToolsVersion = 9.1; 485 | LastSwiftMigration = 1020; 486 | ProvisioningStyle = Manual; 487 | }; 488 | 9B45DBA11FEEB71100D81C9F = { 489 | CreatedOnToolsVersion = 9.1; 490 | LastSwiftMigration = 1020; 491 | ProvisioningStyle = Manual; 492 | }; 493 | 9B4EEC8F1FEF44D2009E5262 = { 494 | CreatedOnToolsVersion = 9.1; 495 | LastSwiftMigration = 1020; 496 | ProvisioningStyle = Manual; 497 | }; 498 | }; 499 | }; 500 | buildConfigurationList = 9B45DB451FEEB64C00D81C9F /* Build configuration list for PBXProject "DocumentClassifier" */; 501 | compatibilityVersion = "Xcode 8.0"; 502 | developmentRegion = en; 503 | hasScannedForEncodings = 0; 504 | knownRegions = ( 505 | en, 506 | Base, 507 | ); 508 | mainGroup = 9B45DB411FEEB64C00D81C9F; 509 | productRefGroup = 9B45DB4E1FEEB6A500D81C9F /* Products */; 510 | projectDirPath = ""; 511 | projectRoot = ""; 512 | targets = ( 513 | 9B45DB4C1FEEB6A500D81C9F /* DocumentClassifierMobile */, 514 | 9B45DB551FEEB6A500D81C9F /* DocumentClassifierMobileTests */, 515 | 9B45DB691FEEB6BA00D81C9F /* DocumentClassifierMac */, 516 | 9B45DB711FEEB6BA00D81C9F /* DocumentClassifierMacTests */, 517 | 9B45DB851FEEB6CD00D81C9F /* DocumentClassifierTV */, 518 | 9B45DB8D1FEEB6CD00D81C9F /* DocumentClassifierTVTests */, 519 | 9B45DBA11FEEB71100D81C9F /* DocumentClassifierWatch */, 520 | 9B4EEC8F1FEF44D2009E5262 /* NewsClassifier */, 521 | ); 522 | }; 523 | /* End PBXProject section */ 524 | 525 | /* Begin PBXResourcesBuildPhase section */ 526 | 9B45DB4B1FEEB6A500D81C9F /* Resources */ = { 527 | isa = PBXResourcesBuildPhase; 528 | buildActionMask = 2147483647; 529 | files = ( 530 | ); 531 | runOnlyForDeploymentPostprocessing = 0; 532 | }; 533 | 9B45DB541FEEB6A500D81C9F /* Resources */ = { 534 | isa = PBXResourcesBuildPhase; 535 | buildActionMask = 2147483647; 536 | files = ( 537 | 9B4EEC8B1FEF3D9C009E5262 /* Technology.txt in Resources */, 538 | 9B4EEC891FEF3D9C009E5262 /* Politics.txt in Resources */, 539 | 9B4EEC871FEF3D9C009E5262 /* Business.txt in Resources */, 540 | 9B4EEC881FEF3D9C009E5262 /* Entertainment.txt in Resources */, 541 | 9B4EEC8A1FEF3D9C009E5262 /* Sports.txt in Resources */, 542 | ); 543 | runOnlyForDeploymentPostprocessing = 0; 544 | }; 545 | 9B45DB681FEEB6BA00D81C9F /* Resources */ = { 546 | isa = PBXResourcesBuildPhase; 547 | buildActionMask = 2147483647; 548 | files = ( 549 | ); 550 | runOnlyForDeploymentPostprocessing = 0; 551 | }; 552 | 9B45DB701FEEB6BA00D81C9F /* Resources */ = { 553 | isa = PBXResourcesBuildPhase; 554 | buildActionMask = 2147483647; 555 | files = ( 556 | 9B4EEC861FEF3D9B009E5262 /* Technology.txt in Resources */, 557 | 9B4EEC841FEF3D9B009E5262 /* Politics.txt in Resources */, 558 | 9B4EEC821FEF3D9B009E5262 /* Business.txt in Resources */, 559 | 9B4EEC831FEF3D9B009E5262 /* Entertainment.txt in Resources */, 560 | 9B4EEC851FEF3D9B009E5262 /* Sports.txt in Resources */, 561 | ); 562 | runOnlyForDeploymentPostprocessing = 0; 563 | }; 564 | 9B45DB841FEEB6CD00D81C9F /* Resources */ = { 565 | isa = PBXResourcesBuildPhase; 566 | buildActionMask = 2147483647; 567 | files = ( 568 | ); 569 | runOnlyForDeploymentPostprocessing = 0; 570 | }; 571 | 9B45DB8C1FEEB6CD00D81C9F /* Resources */ = { 572 | isa = PBXResourcesBuildPhase; 573 | buildActionMask = 2147483647; 574 | files = ( 575 | 9B4EEC811FEF3D9A009E5262 /* Technology.txt in Resources */, 576 | 9B4EEC7F1FEF3D9A009E5262 /* Politics.txt in Resources */, 577 | 9B4EEC7D1FEF3D9A009E5262 /* Business.txt in Resources */, 578 | 9B4EEC7E1FEF3D9A009E5262 /* Entertainment.txt in Resources */, 579 | 9B4EEC801FEF3D9A009E5262 /* Sports.txt in Resources */, 580 | ); 581 | runOnlyForDeploymentPostprocessing = 0; 582 | }; 583 | 9B45DBA01FEEB71100D81C9F /* Resources */ = { 584 | isa = PBXResourcesBuildPhase; 585 | buildActionMask = 2147483647; 586 | files = ( 587 | ); 588 | runOnlyForDeploymentPostprocessing = 0; 589 | }; 590 | 9B4EEC8E1FEF44D2009E5262 /* Resources */ = { 591 | isa = PBXResourcesBuildPhase; 592 | buildActionMask = 2147483647; 593 | files = ( 594 | 9B4EEC9D1FEF44D2009E5262 /* LaunchScreen.storyboard in Resources */, 595 | 9B4EEC9A1FEF44D2009E5262 /* Assets.xcassets in Resources */, 596 | 9B4EEC981FEF44D2009E5262 /* Main.storyboard in Resources */, 597 | ); 598 | runOnlyForDeploymentPostprocessing = 0; 599 | }; 600 | /* End PBXResourcesBuildPhase section */ 601 | 602 | /* Begin PBXSourcesBuildPhase section */ 603 | 9B45DB481FEEB6A500D81C9F /* Sources */ = { 604 | isa = PBXSourcesBuildPhase; 605 | buildActionMask = 2147483647; 606 | files = ( 607 | 9B45DBB81FEEBB4200D81C9F /* Classification.swift in Sources */, 608 | 9B45DBBD1FEF28E300D81C9F /* DocumentClassifier.swift in Sources */, 609 | 9B4EECA81FF00382009E5262 /* DocumentClassification.mlmodel in Sources */, 610 | ); 611 | runOnlyForDeploymentPostprocessing = 0; 612 | }; 613 | 9B45DB521FEEB6A500D81C9F /* Sources */ = { 614 | isa = PBXSourcesBuildPhase; 615 | buildActionMask = 2147483647; 616 | files = ( 617 | 9B45DBB41FEEB89000D81C9F /* DocumentClassifierTests.swift in Sources */, 618 | ); 619 | runOnlyForDeploymentPostprocessing = 0; 620 | }; 621 | 9B45DB651FEEB6BA00D81C9F /* Sources */ = { 622 | isa = PBXSourcesBuildPhase; 623 | buildActionMask = 2147483647; 624 | files = ( 625 | 9B45DBB91FEEBB4200D81C9F /* Classification.swift in Sources */, 626 | 9B45DBBE1FEF28E300D81C9F /* DocumentClassifier.swift in Sources */, 627 | 9B4EECA91FF00382009E5262 /* DocumentClassification.mlmodel in Sources */, 628 | ); 629 | runOnlyForDeploymentPostprocessing = 0; 630 | }; 631 | 9B45DB6E1FEEB6BA00D81C9F /* Sources */ = { 632 | isa = PBXSourcesBuildPhase; 633 | buildActionMask = 2147483647; 634 | files = ( 635 | 9B45DBB51FEEB89100D81C9F /* DocumentClassifierTests.swift in Sources */, 636 | ); 637 | runOnlyForDeploymentPostprocessing = 0; 638 | }; 639 | 9B45DB811FEEB6CD00D81C9F /* Sources */ = { 640 | isa = PBXSourcesBuildPhase; 641 | buildActionMask = 2147483647; 642 | files = ( 643 | 9B45DBBA1FEEBB4200D81C9F /* Classification.swift in Sources */, 644 | 9B45DBBF1FEF28E300D81C9F /* DocumentClassifier.swift in Sources */, 645 | 9B4EECAA1FF00382009E5262 /* DocumentClassification.mlmodel in Sources */, 646 | ); 647 | runOnlyForDeploymentPostprocessing = 0; 648 | }; 649 | 9B45DB8A1FEEB6CD00D81C9F /* Sources */ = { 650 | isa = PBXSourcesBuildPhase; 651 | buildActionMask = 2147483647; 652 | files = ( 653 | 9B45DBB61FEEB89300D81C9F /* DocumentClassifierTests.swift in Sources */, 654 | ); 655 | runOnlyForDeploymentPostprocessing = 0; 656 | }; 657 | 9B45DB9D1FEEB71100D81C9F /* Sources */ = { 658 | isa = PBXSourcesBuildPhase; 659 | buildActionMask = 2147483647; 660 | files = ( 661 | 9B45DBBB1FEEBB4200D81C9F /* Classification.swift in Sources */, 662 | 9B45DBC01FEF28E300D81C9F /* DocumentClassifier.swift in Sources */, 663 | 9B4EECAB1FF00382009E5262 /* DocumentClassification.mlmodel in Sources */, 664 | ); 665 | runOnlyForDeploymentPostprocessing = 0; 666 | }; 667 | 9B4EEC8C1FEF44D2009E5262 /* Sources */ = { 668 | isa = PBXSourcesBuildPhase; 669 | buildActionMask = 2147483647; 670 | files = ( 671 | 9B4EEC951FEF44D2009E5262 /* ViewController.swift in Sources */, 672 | 9B4EEC931FEF44D2009E5262 /* AppDelegate.swift in Sources */, 673 | ); 674 | runOnlyForDeploymentPostprocessing = 0; 675 | }; 676 | /* End PBXSourcesBuildPhase section */ 677 | 678 | /* Begin PBXTargetDependency section */ 679 | 9B45DB591FEEB6A500D81C9F /* PBXTargetDependency */ = { 680 | isa = PBXTargetDependency; 681 | target = 9B45DB4C1FEEB6A500D81C9F /* DocumentClassifierMobile */; 682 | targetProxy = 9B45DB581FEEB6A500D81C9F /* PBXContainerItemProxy */; 683 | }; 684 | 9B45DB751FEEB6BB00D81C9F /* PBXTargetDependency */ = { 685 | isa = PBXTargetDependency; 686 | target = 9B45DB691FEEB6BA00D81C9F /* DocumentClassifierMac */; 687 | targetProxy = 9B45DB741FEEB6BB00D81C9F /* PBXContainerItemProxy */; 688 | }; 689 | 9B45DB911FEEB6CD00D81C9F /* PBXTargetDependency */ = { 690 | isa = PBXTargetDependency; 691 | target = 9B45DB851FEEB6CD00D81C9F /* DocumentClassifierTV */; 692 | targetProxy = 9B45DB901FEEB6CD00D81C9F /* PBXContainerItemProxy */; 693 | }; 694 | 9B4EECA51FEF5104009E5262 /* PBXTargetDependency */ = { 695 | isa = PBXTargetDependency; 696 | target = 9B45DB4C1FEEB6A500D81C9F /* DocumentClassifierMobile */; 697 | targetProxy = 9B4EECA41FEF5104009E5262 /* PBXContainerItemProxy */; 698 | }; 699 | /* End PBXTargetDependency section */ 700 | 701 | /* Begin PBXVariantGroup section */ 702 | 9B4EEC961FEF44D2009E5262 /* Main.storyboard */ = { 703 | isa = PBXVariantGroup; 704 | children = ( 705 | 9B4EEC971FEF44D2009E5262 /* Base */, 706 | ); 707 | name = Main.storyboard; 708 | sourceTree = ""; 709 | }; 710 | 9B4EEC9B1FEF44D2009E5262 /* LaunchScreen.storyboard */ = { 711 | isa = PBXVariantGroup; 712 | children = ( 713 | 9B4EEC9C1FEF44D2009E5262 /* Base */, 714 | ); 715 | name = LaunchScreen.storyboard; 716 | sourceTree = ""; 717 | }; 718 | /* End PBXVariantGroup section */ 719 | 720 | /* Begin XCBuildConfiguration section */ 721 | 9B45DB461FEEB64C00D81C9F /* Debug */ = { 722 | isa = XCBuildConfiguration; 723 | buildSettings = { 724 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 725 | CLANG_WARN_BOOL_CONVERSION = YES; 726 | CLANG_WARN_COMMA = YES; 727 | CLANG_WARN_CONSTANT_CONVERSION = YES; 728 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 729 | CLANG_WARN_EMPTY_BODY = YES; 730 | CLANG_WARN_ENUM_CONVERSION = YES; 731 | CLANG_WARN_INFINITE_RECURSION = YES; 732 | CLANG_WARN_INT_CONVERSION = YES; 733 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 734 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 735 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 736 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 737 | CLANG_WARN_STRICT_PROTOTYPES = YES; 738 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 739 | CLANG_WARN_UNREACHABLE_CODE = YES; 740 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 741 | ENABLE_STRICT_OBJC_MSGSEND = YES; 742 | ENABLE_TESTABILITY = YES; 743 | GCC_NO_COMMON_BLOCKS = YES; 744 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 745 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 746 | GCC_WARN_UNDECLARED_SELECTOR = YES; 747 | GCC_WARN_UNINITIALIZED_AUTOS = YES; 748 | GCC_WARN_UNUSED_FUNCTION = YES; 749 | GCC_WARN_UNUSED_VARIABLE = YES; 750 | ONLY_ACTIVE_ARCH = YES; 751 | }; 752 | name = Debug; 753 | }; 754 | 9B45DB471FEEB64C00D81C9F /* Release */ = { 755 | isa = XCBuildConfiguration; 756 | buildSettings = { 757 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 758 | CLANG_WARN_BOOL_CONVERSION = YES; 759 | CLANG_WARN_COMMA = YES; 760 | CLANG_WARN_CONSTANT_CONVERSION = YES; 761 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 762 | CLANG_WARN_EMPTY_BODY = YES; 763 | CLANG_WARN_ENUM_CONVERSION = YES; 764 | CLANG_WARN_INFINITE_RECURSION = YES; 765 | CLANG_WARN_INT_CONVERSION = YES; 766 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 767 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 768 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 769 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 770 | CLANG_WARN_STRICT_PROTOTYPES = YES; 771 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 772 | CLANG_WARN_UNREACHABLE_CODE = YES; 773 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 774 | ENABLE_STRICT_OBJC_MSGSEND = YES; 775 | GCC_NO_COMMON_BLOCKS = YES; 776 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 777 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 778 | GCC_WARN_UNDECLARED_SELECTOR = YES; 779 | GCC_WARN_UNINITIALIZED_AUTOS = YES; 780 | GCC_WARN_UNUSED_FUNCTION = YES; 781 | GCC_WARN_UNUSED_VARIABLE = YES; 782 | }; 783 | name = Release; 784 | }; 785 | 9B45DB601FEEB6A500D81C9F /* Debug */ = { 786 | isa = XCBuildConfiguration; 787 | buildSettings = { 788 | ALWAYS_SEARCH_USER_PATHS = NO; 789 | CLANG_ANALYZER_NONNULL = YES; 790 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 791 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 792 | CLANG_CXX_LIBRARY = "libc++"; 793 | CLANG_ENABLE_MODULES = YES; 794 | CLANG_ENABLE_OBJC_ARC = YES; 795 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 796 | CLANG_WARN_BOOL_CONVERSION = YES; 797 | CLANG_WARN_COMMA = YES; 798 | CLANG_WARN_CONSTANT_CONVERSION = YES; 799 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 800 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 801 | CLANG_WARN_EMPTY_BODY = YES; 802 | CLANG_WARN_ENUM_CONVERSION = YES; 803 | CLANG_WARN_INFINITE_RECURSION = YES; 804 | CLANG_WARN_INT_CONVERSION = YES; 805 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 806 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 807 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 808 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 809 | CLANG_WARN_STRICT_PROTOTYPES = YES; 810 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 811 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 812 | CLANG_WARN_UNREACHABLE_CODE = YES; 813 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 814 | CODE_SIGN_IDENTITY = "iPhone Developer"; 815 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; 816 | CODE_SIGN_STYLE = Manual; 817 | COPY_PHASE_STRIP = NO; 818 | CURRENT_PROJECT_VERSION = 1; 819 | DEBUG_INFORMATION_FORMAT = dwarf; 820 | DEFINES_MODULE = YES; 821 | DEVELOPMENT_TEAM = ""; 822 | DYLIB_COMPATIBILITY_VERSION = 1; 823 | DYLIB_CURRENT_VERSION = 1; 824 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 825 | ENABLE_STRICT_OBJC_MSGSEND = YES; 826 | ENABLE_TESTABILITY = YES; 827 | GCC_C_LANGUAGE_STANDARD = gnu11; 828 | GCC_DYNAMIC_NO_PIC = NO; 829 | GCC_NO_COMMON_BLOCKS = YES; 830 | GCC_OPTIMIZATION_LEVEL = 0; 831 | GCC_PREPROCESSOR_DEFINITIONS = ( 832 | "DEBUG=1", 833 | "$(inherited)", 834 | ); 835 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 836 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 837 | GCC_WARN_UNDECLARED_SELECTOR = YES; 838 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 839 | GCC_WARN_UNUSED_FUNCTION = YES; 840 | GCC_WARN_UNUSED_VARIABLE = YES; 841 | INFOPLIST_FILE = Sources/Info.plist; 842 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 843 | IPHONEOS_DEPLOYMENT_TARGET = 11.0; 844 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 845 | MTL_ENABLE_DEBUG_INFO = YES; 846 | ONLY_ACTIVE_ARCH = YES; 847 | PRODUCT_BUNDLE_IDENTIFIER = com.toddkramer.DocumentClassifierMobile; 848 | PRODUCT_NAME = DocumentClassifier; 849 | PROVISIONING_PROFILE_SPECIFIER = ""; 850 | SDKROOT = iphoneos; 851 | SKIP_INSTALL = YES; 852 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 853 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 854 | SWIFT_VERSION = 5.0; 855 | TARGETED_DEVICE_FAMILY = "1,2"; 856 | VERSIONING_SYSTEM = "apple-generic"; 857 | VERSION_INFO_PREFIX = ""; 858 | }; 859 | name = Debug; 860 | }; 861 | 9B45DB611FEEB6A500D81C9F /* Release */ = { 862 | isa = XCBuildConfiguration; 863 | buildSettings = { 864 | ALWAYS_SEARCH_USER_PATHS = NO; 865 | CLANG_ANALYZER_NONNULL = YES; 866 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 867 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 868 | CLANG_CXX_LIBRARY = "libc++"; 869 | CLANG_ENABLE_MODULES = YES; 870 | CLANG_ENABLE_OBJC_ARC = YES; 871 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 872 | CLANG_WARN_BOOL_CONVERSION = YES; 873 | CLANG_WARN_COMMA = YES; 874 | CLANG_WARN_CONSTANT_CONVERSION = YES; 875 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 876 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 877 | CLANG_WARN_EMPTY_BODY = YES; 878 | CLANG_WARN_ENUM_CONVERSION = YES; 879 | CLANG_WARN_INFINITE_RECURSION = YES; 880 | CLANG_WARN_INT_CONVERSION = YES; 881 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 882 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 883 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 884 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 885 | CLANG_WARN_STRICT_PROTOTYPES = YES; 886 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 887 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 888 | CLANG_WARN_UNREACHABLE_CODE = YES; 889 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 890 | CODE_SIGN_IDENTITY = "iPhone Developer"; 891 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; 892 | CODE_SIGN_STYLE = Manual; 893 | COPY_PHASE_STRIP = NO; 894 | CURRENT_PROJECT_VERSION = 1; 895 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 896 | DEFINES_MODULE = YES; 897 | DEVELOPMENT_TEAM = ""; 898 | DYLIB_COMPATIBILITY_VERSION = 1; 899 | DYLIB_CURRENT_VERSION = 1; 900 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 901 | ENABLE_NS_ASSERTIONS = NO; 902 | ENABLE_STRICT_OBJC_MSGSEND = YES; 903 | GCC_C_LANGUAGE_STANDARD = gnu11; 904 | GCC_NO_COMMON_BLOCKS = YES; 905 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 906 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 907 | GCC_WARN_UNDECLARED_SELECTOR = YES; 908 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 909 | GCC_WARN_UNUSED_FUNCTION = YES; 910 | GCC_WARN_UNUSED_VARIABLE = YES; 911 | INFOPLIST_FILE = Sources/Info.plist; 912 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 913 | IPHONEOS_DEPLOYMENT_TARGET = 11.0; 914 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 915 | MTL_ENABLE_DEBUG_INFO = NO; 916 | PRODUCT_BUNDLE_IDENTIFIER = com.toddkramer.DocumentClassifierMobile; 917 | PRODUCT_NAME = DocumentClassifier; 918 | PROVISIONING_PROFILE_SPECIFIER = ""; 919 | SDKROOT = iphoneos; 920 | SKIP_INSTALL = YES; 921 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 922 | SWIFT_VERSION = 5.0; 923 | TARGETED_DEVICE_FAMILY = "1,2"; 924 | VALIDATE_PRODUCT = YES; 925 | VERSIONING_SYSTEM = "apple-generic"; 926 | VERSION_INFO_PREFIX = ""; 927 | }; 928 | name = Release; 929 | }; 930 | 9B45DB631FEEB6A500D81C9F /* Debug */ = { 931 | isa = XCBuildConfiguration; 932 | buildSettings = { 933 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 934 | ALWAYS_SEARCH_USER_PATHS = NO; 935 | CLANG_ANALYZER_NONNULL = YES; 936 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 937 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 938 | CLANG_CXX_LIBRARY = "libc++"; 939 | CLANG_ENABLE_MODULES = YES; 940 | CLANG_ENABLE_OBJC_ARC = YES; 941 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 942 | CLANG_WARN_BOOL_CONVERSION = YES; 943 | CLANG_WARN_COMMA = YES; 944 | CLANG_WARN_CONSTANT_CONVERSION = YES; 945 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 946 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 947 | CLANG_WARN_EMPTY_BODY = YES; 948 | CLANG_WARN_ENUM_CONVERSION = YES; 949 | CLANG_WARN_INFINITE_RECURSION = YES; 950 | CLANG_WARN_INT_CONVERSION = YES; 951 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 952 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 953 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 954 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 955 | CLANG_WARN_STRICT_PROTOTYPES = YES; 956 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 957 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 958 | CLANG_WARN_UNREACHABLE_CODE = YES; 959 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 960 | CODE_SIGN_IDENTITY = "iPhone Developer"; 961 | CODE_SIGN_STYLE = Manual; 962 | COPY_PHASE_STRIP = NO; 963 | DEBUG_INFORMATION_FORMAT = dwarf; 964 | DEVELOPMENT_TEAM = ""; 965 | ENABLE_STRICT_OBJC_MSGSEND = YES; 966 | ENABLE_TESTABILITY = YES; 967 | GCC_C_LANGUAGE_STANDARD = gnu11; 968 | GCC_DYNAMIC_NO_PIC = NO; 969 | GCC_NO_COMMON_BLOCKS = YES; 970 | GCC_OPTIMIZATION_LEVEL = 0; 971 | GCC_PREPROCESSOR_DEFINITIONS = ( 972 | "DEBUG=1", 973 | "$(inherited)", 974 | ); 975 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 976 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 977 | GCC_WARN_UNDECLARED_SELECTOR = YES; 978 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 979 | GCC_WARN_UNUSED_FUNCTION = YES; 980 | GCC_WARN_UNUSED_VARIABLE = YES; 981 | INFOPLIST_FILE = Tests/Info.plist; 982 | IPHONEOS_DEPLOYMENT_TARGET = 11.1; 983 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 984 | MTL_ENABLE_DEBUG_INFO = YES; 985 | ONLY_ACTIVE_ARCH = YES; 986 | PRODUCT_BUNDLE_IDENTIFIER = com.toddkramer.DocumentClassifierMobileTests; 987 | PRODUCT_NAME = "$(TARGET_NAME)"; 988 | PROVISIONING_PROFILE_SPECIFIER = ""; 989 | SDKROOT = iphoneos; 990 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 991 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 992 | SWIFT_VERSION = 5.0; 993 | TARGETED_DEVICE_FAMILY = "1,2"; 994 | }; 995 | name = Debug; 996 | }; 997 | 9B45DB641FEEB6A500D81C9F /* Release */ = { 998 | isa = XCBuildConfiguration; 999 | buildSettings = { 1000 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 1001 | ALWAYS_SEARCH_USER_PATHS = NO; 1002 | CLANG_ANALYZER_NONNULL = YES; 1003 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 1004 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 1005 | CLANG_CXX_LIBRARY = "libc++"; 1006 | CLANG_ENABLE_MODULES = YES; 1007 | CLANG_ENABLE_OBJC_ARC = YES; 1008 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 1009 | CLANG_WARN_BOOL_CONVERSION = YES; 1010 | CLANG_WARN_COMMA = YES; 1011 | CLANG_WARN_CONSTANT_CONVERSION = YES; 1012 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 1013 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 1014 | CLANG_WARN_EMPTY_BODY = YES; 1015 | CLANG_WARN_ENUM_CONVERSION = YES; 1016 | CLANG_WARN_INFINITE_RECURSION = YES; 1017 | CLANG_WARN_INT_CONVERSION = YES; 1018 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 1019 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 1020 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 1021 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 1022 | CLANG_WARN_STRICT_PROTOTYPES = YES; 1023 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 1024 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 1025 | CLANG_WARN_UNREACHABLE_CODE = YES; 1026 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 1027 | CODE_SIGN_IDENTITY = "iPhone Developer"; 1028 | CODE_SIGN_STYLE = Manual; 1029 | COPY_PHASE_STRIP = NO; 1030 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 1031 | DEVELOPMENT_TEAM = ""; 1032 | ENABLE_NS_ASSERTIONS = NO; 1033 | ENABLE_STRICT_OBJC_MSGSEND = YES; 1034 | GCC_C_LANGUAGE_STANDARD = gnu11; 1035 | GCC_NO_COMMON_BLOCKS = YES; 1036 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 1037 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 1038 | GCC_WARN_UNDECLARED_SELECTOR = YES; 1039 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 1040 | GCC_WARN_UNUSED_FUNCTION = YES; 1041 | GCC_WARN_UNUSED_VARIABLE = YES; 1042 | INFOPLIST_FILE = Tests/Info.plist; 1043 | IPHONEOS_DEPLOYMENT_TARGET = 11.1; 1044 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 1045 | MTL_ENABLE_DEBUG_INFO = NO; 1046 | PRODUCT_BUNDLE_IDENTIFIER = com.toddkramer.DocumentClassifierMobileTests; 1047 | PRODUCT_NAME = "$(TARGET_NAME)"; 1048 | PROVISIONING_PROFILE_SPECIFIER = ""; 1049 | SDKROOT = iphoneos; 1050 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 1051 | SWIFT_VERSION = 5.0; 1052 | TARGETED_DEVICE_FAMILY = "1,2"; 1053 | VALIDATE_PRODUCT = YES; 1054 | }; 1055 | name = Release; 1056 | }; 1057 | 9B45DB7C1FEEB6BB00D81C9F /* Debug */ = { 1058 | isa = XCBuildConfiguration; 1059 | buildSettings = { 1060 | ALWAYS_SEARCH_USER_PATHS = NO; 1061 | CLANG_ANALYZER_NONNULL = YES; 1062 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 1063 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 1064 | CLANG_CXX_LIBRARY = "libc++"; 1065 | CLANG_ENABLE_MODULES = YES; 1066 | CLANG_ENABLE_OBJC_ARC = YES; 1067 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 1068 | CLANG_WARN_BOOL_CONVERSION = YES; 1069 | CLANG_WARN_COMMA = YES; 1070 | CLANG_WARN_CONSTANT_CONVERSION = YES; 1071 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 1072 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 1073 | CLANG_WARN_EMPTY_BODY = YES; 1074 | CLANG_WARN_ENUM_CONVERSION = YES; 1075 | CLANG_WARN_INFINITE_RECURSION = YES; 1076 | CLANG_WARN_INT_CONVERSION = YES; 1077 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 1078 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 1079 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 1080 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 1081 | CLANG_WARN_STRICT_PROTOTYPES = YES; 1082 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 1083 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 1084 | CLANG_WARN_UNREACHABLE_CODE = YES; 1085 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 1086 | CODE_SIGN_IDENTITY = ""; 1087 | CODE_SIGN_STYLE = Manual; 1088 | COMBINE_HIDPI_IMAGES = YES; 1089 | COPY_PHASE_STRIP = NO; 1090 | CURRENT_PROJECT_VERSION = 1; 1091 | DEBUG_INFORMATION_FORMAT = dwarf; 1092 | DEFINES_MODULE = YES; 1093 | DEVELOPMENT_TEAM = ""; 1094 | DYLIB_COMPATIBILITY_VERSION = 1; 1095 | DYLIB_CURRENT_VERSION = 1; 1096 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 1097 | ENABLE_STRICT_OBJC_MSGSEND = YES; 1098 | ENABLE_TESTABILITY = YES; 1099 | FRAMEWORK_VERSION = A; 1100 | GCC_C_LANGUAGE_STANDARD = gnu11; 1101 | GCC_DYNAMIC_NO_PIC = NO; 1102 | GCC_NO_COMMON_BLOCKS = YES; 1103 | GCC_OPTIMIZATION_LEVEL = 0; 1104 | GCC_PREPROCESSOR_DEFINITIONS = ( 1105 | "DEBUG=1", 1106 | "$(inherited)", 1107 | ); 1108 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 1109 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 1110 | GCC_WARN_UNDECLARED_SELECTOR = YES; 1111 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 1112 | GCC_WARN_UNUSED_FUNCTION = YES; 1113 | GCC_WARN_UNUSED_VARIABLE = YES; 1114 | INFOPLIST_FILE = Sources/Info.plist; 1115 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 1116 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks"; 1117 | MACOSX_DEPLOYMENT_TARGET = 10.13; 1118 | MTL_ENABLE_DEBUG_INFO = YES; 1119 | ONLY_ACTIVE_ARCH = YES; 1120 | PRODUCT_BUNDLE_IDENTIFIER = com.toddkramer.DocumentClassifierMac; 1121 | PRODUCT_NAME = DocumentClassifier; 1122 | PROVISIONING_PROFILE_SPECIFIER = ""; 1123 | SDKROOT = macosx; 1124 | SKIP_INSTALL = YES; 1125 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 1126 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 1127 | SWIFT_VERSION = 5.0; 1128 | VERSIONING_SYSTEM = "apple-generic"; 1129 | VERSION_INFO_PREFIX = ""; 1130 | }; 1131 | name = Debug; 1132 | }; 1133 | 9B45DB7D1FEEB6BB00D81C9F /* Release */ = { 1134 | isa = XCBuildConfiguration; 1135 | buildSettings = { 1136 | ALWAYS_SEARCH_USER_PATHS = NO; 1137 | CLANG_ANALYZER_NONNULL = YES; 1138 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 1139 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 1140 | CLANG_CXX_LIBRARY = "libc++"; 1141 | CLANG_ENABLE_MODULES = YES; 1142 | CLANG_ENABLE_OBJC_ARC = YES; 1143 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 1144 | CLANG_WARN_BOOL_CONVERSION = YES; 1145 | CLANG_WARN_COMMA = YES; 1146 | CLANG_WARN_CONSTANT_CONVERSION = YES; 1147 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 1148 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 1149 | CLANG_WARN_EMPTY_BODY = YES; 1150 | CLANG_WARN_ENUM_CONVERSION = YES; 1151 | CLANG_WARN_INFINITE_RECURSION = YES; 1152 | CLANG_WARN_INT_CONVERSION = YES; 1153 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 1154 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 1155 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 1156 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 1157 | CLANG_WARN_STRICT_PROTOTYPES = YES; 1158 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 1159 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 1160 | CLANG_WARN_UNREACHABLE_CODE = YES; 1161 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 1162 | CODE_SIGN_IDENTITY = ""; 1163 | CODE_SIGN_STYLE = Manual; 1164 | COMBINE_HIDPI_IMAGES = YES; 1165 | COPY_PHASE_STRIP = NO; 1166 | CURRENT_PROJECT_VERSION = 1; 1167 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 1168 | DEFINES_MODULE = YES; 1169 | DEVELOPMENT_TEAM = ""; 1170 | DYLIB_COMPATIBILITY_VERSION = 1; 1171 | DYLIB_CURRENT_VERSION = 1; 1172 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 1173 | ENABLE_NS_ASSERTIONS = NO; 1174 | ENABLE_STRICT_OBJC_MSGSEND = YES; 1175 | FRAMEWORK_VERSION = A; 1176 | GCC_C_LANGUAGE_STANDARD = gnu11; 1177 | GCC_NO_COMMON_BLOCKS = YES; 1178 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 1179 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 1180 | GCC_WARN_UNDECLARED_SELECTOR = YES; 1181 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 1182 | GCC_WARN_UNUSED_FUNCTION = YES; 1183 | GCC_WARN_UNUSED_VARIABLE = YES; 1184 | INFOPLIST_FILE = Sources/Info.plist; 1185 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 1186 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks"; 1187 | MACOSX_DEPLOYMENT_TARGET = 10.13; 1188 | MTL_ENABLE_DEBUG_INFO = NO; 1189 | PRODUCT_BUNDLE_IDENTIFIER = com.toddkramer.DocumentClassifierMac; 1190 | PRODUCT_NAME = DocumentClassifier; 1191 | PROVISIONING_PROFILE_SPECIFIER = ""; 1192 | SDKROOT = macosx; 1193 | SKIP_INSTALL = YES; 1194 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 1195 | SWIFT_VERSION = 5.0; 1196 | VERSIONING_SYSTEM = "apple-generic"; 1197 | VERSION_INFO_PREFIX = ""; 1198 | }; 1199 | name = Release; 1200 | }; 1201 | 9B45DB7F1FEEB6BB00D81C9F /* Debug */ = { 1202 | isa = XCBuildConfiguration; 1203 | buildSettings = { 1204 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 1205 | ALWAYS_SEARCH_USER_PATHS = NO; 1206 | CLANG_ANALYZER_NONNULL = YES; 1207 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 1208 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 1209 | CLANG_CXX_LIBRARY = "libc++"; 1210 | CLANG_ENABLE_MODULES = YES; 1211 | CLANG_ENABLE_OBJC_ARC = YES; 1212 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 1213 | CLANG_WARN_BOOL_CONVERSION = YES; 1214 | CLANG_WARN_COMMA = YES; 1215 | CLANG_WARN_CONSTANT_CONVERSION = YES; 1216 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 1217 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 1218 | CLANG_WARN_EMPTY_BODY = YES; 1219 | CLANG_WARN_ENUM_CONVERSION = YES; 1220 | CLANG_WARN_INFINITE_RECURSION = YES; 1221 | CLANG_WARN_INT_CONVERSION = YES; 1222 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 1223 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 1224 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 1225 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 1226 | CLANG_WARN_STRICT_PROTOTYPES = YES; 1227 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 1228 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 1229 | CLANG_WARN_UNREACHABLE_CODE = YES; 1230 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 1231 | CODE_SIGN_IDENTITY = "Mac Developer"; 1232 | CODE_SIGN_STYLE = Automatic; 1233 | COMBINE_HIDPI_IMAGES = YES; 1234 | COPY_PHASE_STRIP = NO; 1235 | DEBUG_INFORMATION_FORMAT = dwarf; 1236 | DEVELOPMENT_TEAM = R3JQ32F9MD; 1237 | ENABLE_STRICT_OBJC_MSGSEND = YES; 1238 | ENABLE_TESTABILITY = YES; 1239 | GCC_C_LANGUAGE_STANDARD = gnu11; 1240 | GCC_DYNAMIC_NO_PIC = NO; 1241 | GCC_NO_COMMON_BLOCKS = YES; 1242 | GCC_OPTIMIZATION_LEVEL = 0; 1243 | GCC_PREPROCESSOR_DEFINITIONS = ( 1244 | "DEBUG=1", 1245 | "$(inherited)", 1246 | ); 1247 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 1248 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 1249 | GCC_WARN_UNDECLARED_SELECTOR = YES; 1250 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 1251 | GCC_WARN_UNUSED_FUNCTION = YES; 1252 | GCC_WARN_UNUSED_VARIABLE = YES; 1253 | INFOPLIST_FILE = Tests/Info.plist; 1254 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; 1255 | MACOSX_DEPLOYMENT_TARGET = 10.13; 1256 | MTL_ENABLE_DEBUG_INFO = YES; 1257 | ONLY_ACTIVE_ARCH = YES; 1258 | PRODUCT_BUNDLE_IDENTIFIER = com.toddkramer.DocumentClassifierMacTests; 1259 | PRODUCT_NAME = "$(TARGET_NAME)"; 1260 | PROVISIONING_PROFILE_SPECIFIER = ""; 1261 | SDKROOT = macosx; 1262 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 1263 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 1264 | SWIFT_VERSION = 5.0; 1265 | }; 1266 | name = Debug; 1267 | }; 1268 | 9B45DB801FEEB6BB00D81C9F /* Release */ = { 1269 | isa = XCBuildConfiguration; 1270 | buildSettings = { 1271 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 1272 | ALWAYS_SEARCH_USER_PATHS = NO; 1273 | CLANG_ANALYZER_NONNULL = YES; 1274 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 1275 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 1276 | CLANG_CXX_LIBRARY = "libc++"; 1277 | CLANG_ENABLE_MODULES = YES; 1278 | CLANG_ENABLE_OBJC_ARC = YES; 1279 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 1280 | CLANG_WARN_BOOL_CONVERSION = YES; 1281 | CLANG_WARN_COMMA = YES; 1282 | CLANG_WARN_CONSTANT_CONVERSION = YES; 1283 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 1284 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 1285 | CLANG_WARN_EMPTY_BODY = YES; 1286 | CLANG_WARN_ENUM_CONVERSION = YES; 1287 | CLANG_WARN_INFINITE_RECURSION = YES; 1288 | CLANG_WARN_INT_CONVERSION = YES; 1289 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 1290 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 1291 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 1292 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 1293 | CLANG_WARN_STRICT_PROTOTYPES = YES; 1294 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 1295 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 1296 | CLANG_WARN_UNREACHABLE_CODE = YES; 1297 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 1298 | CODE_SIGN_IDENTITY = "Mac Developer"; 1299 | CODE_SIGN_STYLE = Automatic; 1300 | COMBINE_HIDPI_IMAGES = YES; 1301 | COPY_PHASE_STRIP = NO; 1302 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 1303 | DEVELOPMENT_TEAM = R3JQ32F9MD; 1304 | ENABLE_NS_ASSERTIONS = NO; 1305 | ENABLE_STRICT_OBJC_MSGSEND = YES; 1306 | GCC_C_LANGUAGE_STANDARD = gnu11; 1307 | GCC_NO_COMMON_BLOCKS = YES; 1308 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 1309 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 1310 | GCC_WARN_UNDECLARED_SELECTOR = YES; 1311 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 1312 | GCC_WARN_UNUSED_FUNCTION = YES; 1313 | GCC_WARN_UNUSED_VARIABLE = YES; 1314 | INFOPLIST_FILE = Tests/Info.plist; 1315 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; 1316 | MACOSX_DEPLOYMENT_TARGET = 10.13; 1317 | MTL_ENABLE_DEBUG_INFO = NO; 1318 | PRODUCT_BUNDLE_IDENTIFIER = com.toddkramer.DocumentClassifierMacTests; 1319 | PRODUCT_NAME = "$(TARGET_NAME)"; 1320 | PROVISIONING_PROFILE_SPECIFIER = ""; 1321 | SDKROOT = macosx; 1322 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 1323 | SWIFT_VERSION = 5.0; 1324 | }; 1325 | name = Release; 1326 | }; 1327 | 9B45DB981FEEB6CD00D81C9F /* Debug */ = { 1328 | isa = XCBuildConfiguration; 1329 | buildSettings = { 1330 | ALWAYS_SEARCH_USER_PATHS = NO; 1331 | CLANG_ANALYZER_NONNULL = YES; 1332 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 1333 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 1334 | CLANG_CXX_LIBRARY = "libc++"; 1335 | CLANG_ENABLE_MODULES = YES; 1336 | CLANG_ENABLE_OBJC_ARC = YES; 1337 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 1338 | CLANG_WARN_BOOL_CONVERSION = YES; 1339 | CLANG_WARN_COMMA = YES; 1340 | CLANG_WARN_CONSTANT_CONVERSION = YES; 1341 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 1342 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 1343 | CLANG_WARN_EMPTY_BODY = YES; 1344 | CLANG_WARN_ENUM_CONVERSION = YES; 1345 | CLANG_WARN_INFINITE_RECURSION = YES; 1346 | CLANG_WARN_INT_CONVERSION = YES; 1347 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 1348 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 1349 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 1350 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 1351 | CLANG_WARN_STRICT_PROTOTYPES = YES; 1352 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 1353 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 1354 | CLANG_WARN_UNREACHABLE_CODE = YES; 1355 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 1356 | CODE_SIGN_IDENTITY = ""; 1357 | CODE_SIGN_STYLE = Manual; 1358 | COPY_PHASE_STRIP = NO; 1359 | CURRENT_PROJECT_VERSION = 1; 1360 | DEBUG_INFORMATION_FORMAT = dwarf; 1361 | DEFINES_MODULE = YES; 1362 | DEVELOPMENT_TEAM = ""; 1363 | DYLIB_COMPATIBILITY_VERSION = 1; 1364 | DYLIB_CURRENT_VERSION = 1; 1365 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 1366 | ENABLE_STRICT_OBJC_MSGSEND = YES; 1367 | ENABLE_TESTABILITY = YES; 1368 | GCC_C_LANGUAGE_STANDARD = gnu11; 1369 | GCC_DYNAMIC_NO_PIC = NO; 1370 | GCC_NO_COMMON_BLOCKS = YES; 1371 | GCC_OPTIMIZATION_LEVEL = 0; 1372 | GCC_PREPROCESSOR_DEFINITIONS = ( 1373 | "DEBUG=1", 1374 | "$(inherited)", 1375 | ); 1376 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 1377 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 1378 | GCC_WARN_UNDECLARED_SELECTOR = YES; 1379 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 1380 | GCC_WARN_UNUSED_FUNCTION = YES; 1381 | GCC_WARN_UNUSED_VARIABLE = YES; 1382 | INFOPLIST_FILE = Sources/Info.plist; 1383 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 1384 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 1385 | MTL_ENABLE_DEBUG_INFO = YES; 1386 | ONLY_ACTIVE_ARCH = YES; 1387 | PRODUCT_BUNDLE_IDENTIFIER = com.toddkramer.DocumentClassifierTV; 1388 | PRODUCT_NAME = DocumentClassifier; 1389 | PROVISIONING_PROFILE_SPECIFIER = ""; 1390 | SDKROOT = appletvos; 1391 | SKIP_INSTALL = YES; 1392 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 1393 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 1394 | SWIFT_VERSION = 5.0; 1395 | TARGETED_DEVICE_FAMILY = 3; 1396 | TVOS_DEPLOYMENT_TARGET = 11.0; 1397 | VERSIONING_SYSTEM = "apple-generic"; 1398 | VERSION_INFO_PREFIX = ""; 1399 | }; 1400 | name = Debug; 1401 | }; 1402 | 9B45DB991FEEB6CD00D81C9F /* Release */ = { 1403 | isa = XCBuildConfiguration; 1404 | buildSettings = { 1405 | ALWAYS_SEARCH_USER_PATHS = NO; 1406 | CLANG_ANALYZER_NONNULL = YES; 1407 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 1408 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 1409 | CLANG_CXX_LIBRARY = "libc++"; 1410 | CLANG_ENABLE_MODULES = YES; 1411 | CLANG_ENABLE_OBJC_ARC = YES; 1412 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 1413 | CLANG_WARN_BOOL_CONVERSION = YES; 1414 | CLANG_WARN_COMMA = YES; 1415 | CLANG_WARN_CONSTANT_CONVERSION = YES; 1416 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 1417 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 1418 | CLANG_WARN_EMPTY_BODY = YES; 1419 | CLANG_WARN_ENUM_CONVERSION = YES; 1420 | CLANG_WARN_INFINITE_RECURSION = YES; 1421 | CLANG_WARN_INT_CONVERSION = YES; 1422 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 1423 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 1424 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 1425 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 1426 | CLANG_WARN_STRICT_PROTOTYPES = YES; 1427 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 1428 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 1429 | CLANG_WARN_UNREACHABLE_CODE = YES; 1430 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 1431 | CODE_SIGN_IDENTITY = ""; 1432 | CODE_SIGN_STYLE = Manual; 1433 | COPY_PHASE_STRIP = NO; 1434 | CURRENT_PROJECT_VERSION = 1; 1435 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 1436 | DEFINES_MODULE = YES; 1437 | DEVELOPMENT_TEAM = ""; 1438 | DYLIB_COMPATIBILITY_VERSION = 1; 1439 | DYLIB_CURRENT_VERSION = 1; 1440 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 1441 | ENABLE_NS_ASSERTIONS = NO; 1442 | ENABLE_STRICT_OBJC_MSGSEND = YES; 1443 | GCC_C_LANGUAGE_STANDARD = gnu11; 1444 | GCC_NO_COMMON_BLOCKS = YES; 1445 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 1446 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 1447 | GCC_WARN_UNDECLARED_SELECTOR = YES; 1448 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 1449 | GCC_WARN_UNUSED_FUNCTION = YES; 1450 | GCC_WARN_UNUSED_VARIABLE = YES; 1451 | INFOPLIST_FILE = Sources/Info.plist; 1452 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 1453 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 1454 | MTL_ENABLE_DEBUG_INFO = NO; 1455 | PRODUCT_BUNDLE_IDENTIFIER = com.toddkramer.DocumentClassifierTV; 1456 | PRODUCT_NAME = DocumentClassifier; 1457 | PROVISIONING_PROFILE_SPECIFIER = ""; 1458 | SDKROOT = appletvos; 1459 | SKIP_INSTALL = YES; 1460 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 1461 | SWIFT_VERSION = 5.0; 1462 | TARGETED_DEVICE_FAMILY = 3; 1463 | TVOS_DEPLOYMENT_TARGET = 11.0; 1464 | VALIDATE_PRODUCT = YES; 1465 | VERSIONING_SYSTEM = "apple-generic"; 1466 | VERSION_INFO_PREFIX = ""; 1467 | }; 1468 | name = Release; 1469 | }; 1470 | 9B45DB9B1FEEB6CD00D81C9F /* Debug */ = { 1471 | isa = XCBuildConfiguration; 1472 | buildSettings = { 1473 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 1474 | ALWAYS_SEARCH_USER_PATHS = NO; 1475 | CLANG_ANALYZER_NONNULL = YES; 1476 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 1477 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 1478 | CLANG_CXX_LIBRARY = "libc++"; 1479 | CLANG_ENABLE_MODULES = YES; 1480 | CLANG_ENABLE_OBJC_ARC = YES; 1481 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 1482 | CLANG_WARN_BOOL_CONVERSION = YES; 1483 | CLANG_WARN_COMMA = YES; 1484 | CLANG_WARN_CONSTANT_CONVERSION = YES; 1485 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 1486 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 1487 | CLANG_WARN_EMPTY_BODY = YES; 1488 | CLANG_WARN_ENUM_CONVERSION = YES; 1489 | CLANG_WARN_INFINITE_RECURSION = YES; 1490 | CLANG_WARN_INT_CONVERSION = YES; 1491 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 1492 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 1493 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 1494 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 1495 | CLANG_WARN_STRICT_PROTOTYPES = YES; 1496 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 1497 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 1498 | CLANG_WARN_UNREACHABLE_CODE = YES; 1499 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 1500 | "CODE_SIGN_IDENTITY[sdk=appletvos*]" = "iPhone Developer"; 1501 | CODE_SIGN_STYLE = Manual; 1502 | COPY_PHASE_STRIP = NO; 1503 | DEBUG_INFORMATION_FORMAT = dwarf; 1504 | DEVELOPMENT_TEAM = ""; 1505 | ENABLE_STRICT_OBJC_MSGSEND = YES; 1506 | ENABLE_TESTABILITY = YES; 1507 | GCC_C_LANGUAGE_STANDARD = gnu11; 1508 | GCC_DYNAMIC_NO_PIC = NO; 1509 | GCC_NO_COMMON_BLOCKS = YES; 1510 | GCC_OPTIMIZATION_LEVEL = 0; 1511 | GCC_PREPROCESSOR_DEFINITIONS = ( 1512 | "DEBUG=1", 1513 | "$(inherited)", 1514 | ); 1515 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 1516 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 1517 | GCC_WARN_UNDECLARED_SELECTOR = YES; 1518 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 1519 | GCC_WARN_UNUSED_FUNCTION = YES; 1520 | GCC_WARN_UNUSED_VARIABLE = YES; 1521 | INFOPLIST_FILE = Tests/Info.plist; 1522 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 1523 | MTL_ENABLE_DEBUG_INFO = YES; 1524 | ONLY_ACTIVE_ARCH = YES; 1525 | PRODUCT_BUNDLE_IDENTIFIER = com.toddkramer.DocumentClassifierTVTests; 1526 | PRODUCT_NAME = "$(TARGET_NAME)"; 1527 | PROVISIONING_PROFILE_SPECIFIER = ""; 1528 | SDKROOT = appletvos; 1529 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 1530 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 1531 | SWIFT_VERSION = 5.0; 1532 | TARGETED_DEVICE_FAMILY = 3; 1533 | TVOS_DEPLOYMENT_TARGET = 11.1; 1534 | }; 1535 | name = Debug; 1536 | }; 1537 | 9B45DB9C1FEEB6CD00D81C9F /* Release */ = { 1538 | isa = XCBuildConfiguration; 1539 | buildSettings = { 1540 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 1541 | ALWAYS_SEARCH_USER_PATHS = NO; 1542 | CLANG_ANALYZER_NONNULL = YES; 1543 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 1544 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 1545 | CLANG_CXX_LIBRARY = "libc++"; 1546 | CLANG_ENABLE_MODULES = YES; 1547 | CLANG_ENABLE_OBJC_ARC = YES; 1548 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 1549 | CLANG_WARN_BOOL_CONVERSION = YES; 1550 | CLANG_WARN_COMMA = YES; 1551 | CLANG_WARN_CONSTANT_CONVERSION = YES; 1552 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 1553 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 1554 | CLANG_WARN_EMPTY_BODY = YES; 1555 | CLANG_WARN_ENUM_CONVERSION = YES; 1556 | CLANG_WARN_INFINITE_RECURSION = YES; 1557 | CLANG_WARN_INT_CONVERSION = YES; 1558 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 1559 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 1560 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 1561 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 1562 | CLANG_WARN_STRICT_PROTOTYPES = YES; 1563 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 1564 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 1565 | CLANG_WARN_UNREACHABLE_CODE = YES; 1566 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 1567 | "CODE_SIGN_IDENTITY[sdk=appletvos*]" = "iPhone Developer"; 1568 | CODE_SIGN_STYLE = Manual; 1569 | COPY_PHASE_STRIP = NO; 1570 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 1571 | DEVELOPMENT_TEAM = ""; 1572 | ENABLE_NS_ASSERTIONS = NO; 1573 | ENABLE_STRICT_OBJC_MSGSEND = YES; 1574 | GCC_C_LANGUAGE_STANDARD = gnu11; 1575 | GCC_NO_COMMON_BLOCKS = YES; 1576 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 1577 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 1578 | GCC_WARN_UNDECLARED_SELECTOR = YES; 1579 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 1580 | GCC_WARN_UNUSED_FUNCTION = YES; 1581 | GCC_WARN_UNUSED_VARIABLE = YES; 1582 | INFOPLIST_FILE = Tests/Info.plist; 1583 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 1584 | MTL_ENABLE_DEBUG_INFO = NO; 1585 | PRODUCT_BUNDLE_IDENTIFIER = com.toddkramer.DocumentClassifierTVTests; 1586 | PRODUCT_NAME = "$(TARGET_NAME)"; 1587 | PROVISIONING_PROFILE_SPECIFIER = ""; 1588 | SDKROOT = appletvos; 1589 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 1590 | SWIFT_VERSION = 5.0; 1591 | TARGETED_DEVICE_FAMILY = 3; 1592 | TVOS_DEPLOYMENT_TARGET = 11.1; 1593 | VALIDATE_PRODUCT = YES; 1594 | }; 1595 | name = Release; 1596 | }; 1597 | 9B45DBA81FEEB71100D81C9F /* Debug */ = { 1598 | isa = XCBuildConfiguration; 1599 | buildSettings = { 1600 | ALWAYS_SEARCH_USER_PATHS = NO; 1601 | APPLICATION_EXTENSION_API_ONLY = YES; 1602 | CLANG_ANALYZER_NONNULL = YES; 1603 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 1604 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 1605 | CLANG_CXX_LIBRARY = "libc++"; 1606 | CLANG_ENABLE_MODULES = YES; 1607 | CLANG_ENABLE_OBJC_ARC = YES; 1608 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 1609 | CLANG_WARN_BOOL_CONVERSION = YES; 1610 | CLANG_WARN_COMMA = YES; 1611 | CLANG_WARN_CONSTANT_CONVERSION = YES; 1612 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 1613 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 1614 | CLANG_WARN_EMPTY_BODY = YES; 1615 | CLANG_WARN_ENUM_CONVERSION = YES; 1616 | CLANG_WARN_INFINITE_RECURSION = YES; 1617 | CLANG_WARN_INT_CONVERSION = YES; 1618 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 1619 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 1620 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 1621 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 1622 | CLANG_WARN_STRICT_PROTOTYPES = YES; 1623 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 1624 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 1625 | CLANG_WARN_UNREACHABLE_CODE = YES; 1626 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 1627 | CODE_SIGN_IDENTITY = ""; 1628 | CODE_SIGN_STYLE = Manual; 1629 | COPY_PHASE_STRIP = NO; 1630 | CURRENT_PROJECT_VERSION = 1; 1631 | DEBUG_INFORMATION_FORMAT = dwarf; 1632 | DEFINES_MODULE = YES; 1633 | DEVELOPMENT_TEAM = ""; 1634 | DYLIB_COMPATIBILITY_VERSION = 1; 1635 | DYLIB_CURRENT_VERSION = 1; 1636 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 1637 | ENABLE_STRICT_OBJC_MSGSEND = YES; 1638 | ENABLE_TESTABILITY = YES; 1639 | GCC_C_LANGUAGE_STANDARD = gnu11; 1640 | GCC_DYNAMIC_NO_PIC = NO; 1641 | GCC_NO_COMMON_BLOCKS = YES; 1642 | GCC_OPTIMIZATION_LEVEL = 0; 1643 | GCC_PREPROCESSOR_DEFINITIONS = ( 1644 | "DEBUG=1", 1645 | "$(inherited)", 1646 | ); 1647 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 1648 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 1649 | GCC_WARN_UNDECLARED_SELECTOR = YES; 1650 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 1651 | GCC_WARN_UNUSED_FUNCTION = YES; 1652 | GCC_WARN_UNUSED_VARIABLE = YES; 1653 | INFOPLIST_FILE = Sources/Info.plist; 1654 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 1655 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 1656 | MTL_ENABLE_DEBUG_INFO = YES; 1657 | ONLY_ACTIVE_ARCH = YES; 1658 | PRODUCT_BUNDLE_IDENTIFIER = com.toddkramer.DocumentClassifierWatch; 1659 | PRODUCT_NAME = DocumentClassifier; 1660 | PROVISIONING_PROFILE_SPECIFIER = ""; 1661 | SDKROOT = watchos; 1662 | SKIP_INSTALL = YES; 1663 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 1664 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 1665 | SWIFT_VERSION = 5.0; 1666 | TARGETED_DEVICE_FAMILY = 4; 1667 | VERSIONING_SYSTEM = "apple-generic"; 1668 | VERSION_INFO_PREFIX = ""; 1669 | WATCHOS_DEPLOYMENT_TARGET = 4.0; 1670 | }; 1671 | name = Debug; 1672 | }; 1673 | 9B45DBA91FEEB71100D81C9F /* Release */ = { 1674 | isa = XCBuildConfiguration; 1675 | buildSettings = { 1676 | ALWAYS_SEARCH_USER_PATHS = NO; 1677 | APPLICATION_EXTENSION_API_ONLY = YES; 1678 | CLANG_ANALYZER_NONNULL = YES; 1679 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 1680 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 1681 | CLANG_CXX_LIBRARY = "libc++"; 1682 | CLANG_ENABLE_MODULES = YES; 1683 | CLANG_ENABLE_OBJC_ARC = YES; 1684 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 1685 | CLANG_WARN_BOOL_CONVERSION = YES; 1686 | CLANG_WARN_COMMA = YES; 1687 | CLANG_WARN_CONSTANT_CONVERSION = YES; 1688 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 1689 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 1690 | CLANG_WARN_EMPTY_BODY = YES; 1691 | CLANG_WARN_ENUM_CONVERSION = YES; 1692 | CLANG_WARN_INFINITE_RECURSION = YES; 1693 | CLANG_WARN_INT_CONVERSION = YES; 1694 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 1695 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 1696 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 1697 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 1698 | CLANG_WARN_STRICT_PROTOTYPES = YES; 1699 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 1700 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 1701 | CLANG_WARN_UNREACHABLE_CODE = YES; 1702 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 1703 | CODE_SIGN_IDENTITY = ""; 1704 | CODE_SIGN_STYLE = Manual; 1705 | COPY_PHASE_STRIP = NO; 1706 | CURRENT_PROJECT_VERSION = 1; 1707 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 1708 | DEFINES_MODULE = YES; 1709 | DEVELOPMENT_TEAM = ""; 1710 | DYLIB_COMPATIBILITY_VERSION = 1; 1711 | DYLIB_CURRENT_VERSION = 1; 1712 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 1713 | ENABLE_NS_ASSERTIONS = NO; 1714 | ENABLE_STRICT_OBJC_MSGSEND = YES; 1715 | GCC_C_LANGUAGE_STANDARD = gnu11; 1716 | GCC_NO_COMMON_BLOCKS = YES; 1717 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 1718 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 1719 | GCC_WARN_UNDECLARED_SELECTOR = YES; 1720 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 1721 | GCC_WARN_UNUSED_FUNCTION = YES; 1722 | GCC_WARN_UNUSED_VARIABLE = YES; 1723 | INFOPLIST_FILE = Sources/Info.plist; 1724 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 1725 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 1726 | MTL_ENABLE_DEBUG_INFO = NO; 1727 | PRODUCT_BUNDLE_IDENTIFIER = com.toddkramer.DocumentClassifierWatch; 1728 | PRODUCT_NAME = DocumentClassifier; 1729 | PROVISIONING_PROFILE_SPECIFIER = ""; 1730 | SDKROOT = watchos; 1731 | SKIP_INSTALL = YES; 1732 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 1733 | SWIFT_VERSION = 5.0; 1734 | TARGETED_DEVICE_FAMILY = 4; 1735 | VALIDATE_PRODUCT = YES; 1736 | VERSIONING_SYSTEM = "apple-generic"; 1737 | VERSION_INFO_PREFIX = ""; 1738 | WATCHOS_DEPLOYMENT_TARGET = 4.0; 1739 | }; 1740 | name = Release; 1741 | }; 1742 | 9B4EECA01FEF44D2009E5262 /* Debug */ = { 1743 | isa = XCBuildConfiguration; 1744 | buildSettings = { 1745 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 1746 | ALWAYS_SEARCH_USER_PATHS = NO; 1747 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 1748 | CLANG_ANALYZER_NONNULL = YES; 1749 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 1750 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 1751 | CLANG_CXX_LIBRARY = "libc++"; 1752 | CLANG_ENABLE_MODULES = YES; 1753 | CLANG_ENABLE_OBJC_ARC = YES; 1754 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 1755 | CLANG_WARN_BOOL_CONVERSION = YES; 1756 | CLANG_WARN_COMMA = YES; 1757 | CLANG_WARN_CONSTANT_CONVERSION = YES; 1758 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 1759 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 1760 | CLANG_WARN_EMPTY_BODY = YES; 1761 | CLANG_WARN_ENUM_CONVERSION = YES; 1762 | CLANG_WARN_INFINITE_RECURSION = YES; 1763 | CLANG_WARN_INT_CONVERSION = YES; 1764 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 1765 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 1766 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 1767 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 1768 | CLANG_WARN_STRICT_PROTOTYPES = YES; 1769 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 1770 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 1771 | CLANG_WARN_UNREACHABLE_CODE = YES; 1772 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 1773 | CODE_SIGN_IDENTITY = "iPhone Developer"; 1774 | CODE_SIGN_STYLE = Manual; 1775 | COPY_PHASE_STRIP = NO; 1776 | DEBUG_INFORMATION_FORMAT = dwarf; 1777 | DEVELOPMENT_TEAM = ""; 1778 | ENABLE_STRICT_OBJC_MSGSEND = YES; 1779 | ENABLE_TESTABILITY = YES; 1780 | GCC_C_LANGUAGE_STANDARD = gnu11; 1781 | GCC_DYNAMIC_NO_PIC = NO; 1782 | GCC_NO_COMMON_BLOCKS = YES; 1783 | GCC_OPTIMIZATION_LEVEL = 0; 1784 | GCC_PREPROCESSOR_DEFINITIONS = ( 1785 | "DEBUG=1", 1786 | "$(inherited)", 1787 | ); 1788 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 1789 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 1790 | GCC_WARN_UNDECLARED_SELECTOR = YES; 1791 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 1792 | GCC_WARN_UNUSED_FUNCTION = YES; 1793 | GCC_WARN_UNUSED_VARIABLE = YES; 1794 | INFOPLIST_FILE = NewsClassifier/Info.plist; 1795 | IPHONEOS_DEPLOYMENT_TARGET = 11.0; 1796 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 1797 | MTL_ENABLE_DEBUG_INFO = YES; 1798 | ONLY_ACTIVE_ARCH = YES; 1799 | PRODUCT_BUNDLE_IDENTIFIER = com.toddkramer.NewsClassifier; 1800 | PRODUCT_NAME = "$(TARGET_NAME)"; 1801 | PROVISIONING_PROFILE_SPECIFIER = ""; 1802 | SDKROOT = iphoneos; 1803 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 1804 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 1805 | SWIFT_VERSION = 5.0; 1806 | TARGETED_DEVICE_FAMILY = "1,2"; 1807 | }; 1808 | name = Debug; 1809 | }; 1810 | 9B4EECA11FEF44D2009E5262 /* Release */ = { 1811 | isa = XCBuildConfiguration; 1812 | buildSettings = { 1813 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 1814 | ALWAYS_SEARCH_USER_PATHS = NO; 1815 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 1816 | CLANG_ANALYZER_NONNULL = YES; 1817 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 1818 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 1819 | CLANG_CXX_LIBRARY = "libc++"; 1820 | CLANG_ENABLE_MODULES = YES; 1821 | CLANG_ENABLE_OBJC_ARC = YES; 1822 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 1823 | CLANG_WARN_BOOL_CONVERSION = YES; 1824 | CLANG_WARN_COMMA = YES; 1825 | CLANG_WARN_CONSTANT_CONVERSION = YES; 1826 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 1827 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 1828 | CLANG_WARN_EMPTY_BODY = YES; 1829 | CLANG_WARN_ENUM_CONVERSION = YES; 1830 | CLANG_WARN_INFINITE_RECURSION = YES; 1831 | CLANG_WARN_INT_CONVERSION = YES; 1832 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 1833 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 1834 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 1835 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 1836 | CLANG_WARN_STRICT_PROTOTYPES = YES; 1837 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 1838 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 1839 | CLANG_WARN_UNREACHABLE_CODE = YES; 1840 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 1841 | CODE_SIGN_IDENTITY = "iPhone Developer"; 1842 | CODE_SIGN_STYLE = Manual; 1843 | COPY_PHASE_STRIP = NO; 1844 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 1845 | DEVELOPMENT_TEAM = ""; 1846 | ENABLE_NS_ASSERTIONS = NO; 1847 | ENABLE_STRICT_OBJC_MSGSEND = YES; 1848 | GCC_C_LANGUAGE_STANDARD = gnu11; 1849 | GCC_NO_COMMON_BLOCKS = YES; 1850 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 1851 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 1852 | GCC_WARN_UNDECLARED_SELECTOR = YES; 1853 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 1854 | GCC_WARN_UNUSED_FUNCTION = YES; 1855 | GCC_WARN_UNUSED_VARIABLE = YES; 1856 | INFOPLIST_FILE = NewsClassifier/Info.plist; 1857 | IPHONEOS_DEPLOYMENT_TARGET = 11.0; 1858 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 1859 | MTL_ENABLE_DEBUG_INFO = NO; 1860 | PRODUCT_BUNDLE_IDENTIFIER = com.toddkramer.NewsClassifier; 1861 | PRODUCT_NAME = "$(TARGET_NAME)"; 1862 | PROVISIONING_PROFILE_SPECIFIER = ""; 1863 | SDKROOT = iphoneos; 1864 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 1865 | SWIFT_VERSION = 5.0; 1866 | TARGETED_DEVICE_FAMILY = "1,2"; 1867 | VALIDATE_PRODUCT = YES; 1868 | }; 1869 | name = Release; 1870 | }; 1871 | /* End XCBuildConfiguration section */ 1872 | 1873 | /* Begin XCConfigurationList section */ 1874 | 9B45DB451FEEB64C00D81C9F /* Build configuration list for PBXProject "DocumentClassifier" */ = { 1875 | isa = XCConfigurationList; 1876 | buildConfigurations = ( 1877 | 9B45DB461FEEB64C00D81C9F /* Debug */, 1878 | 9B45DB471FEEB64C00D81C9F /* Release */, 1879 | ); 1880 | defaultConfigurationIsVisible = 0; 1881 | defaultConfigurationName = Release; 1882 | }; 1883 | 9B45DB5F1FEEB6A500D81C9F /* Build configuration list for PBXNativeTarget "DocumentClassifierMobile" */ = { 1884 | isa = XCConfigurationList; 1885 | buildConfigurations = ( 1886 | 9B45DB601FEEB6A500D81C9F /* Debug */, 1887 | 9B45DB611FEEB6A500D81C9F /* Release */, 1888 | ); 1889 | defaultConfigurationIsVisible = 0; 1890 | defaultConfigurationName = Release; 1891 | }; 1892 | 9B45DB621FEEB6A500D81C9F /* Build configuration list for PBXNativeTarget "DocumentClassifierMobileTests" */ = { 1893 | isa = XCConfigurationList; 1894 | buildConfigurations = ( 1895 | 9B45DB631FEEB6A500D81C9F /* Debug */, 1896 | 9B45DB641FEEB6A500D81C9F /* Release */, 1897 | ); 1898 | defaultConfigurationIsVisible = 0; 1899 | defaultConfigurationName = Release; 1900 | }; 1901 | 9B45DB7B1FEEB6BB00D81C9F /* Build configuration list for PBXNativeTarget "DocumentClassifierMac" */ = { 1902 | isa = XCConfigurationList; 1903 | buildConfigurations = ( 1904 | 9B45DB7C1FEEB6BB00D81C9F /* Debug */, 1905 | 9B45DB7D1FEEB6BB00D81C9F /* Release */, 1906 | ); 1907 | defaultConfigurationIsVisible = 0; 1908 | defaultConfigurationName = Release; 1909 | }; 1910 | 9B45DB7E1FEEB6BB00D81C9F /* Build configuration list for PBXNativeTarget "DocumentClassifierMacTests" */ = { 1911 | isa = XCConfigurationList; 1912 | buildConfigurations = ( 1913 | 9B45DB7F1FEEB6BB00D81C9F /* Debug */, 1914 | 9B45DB801FEEB6BB00D81C9F /* Release */, 1915 | ); 1916 | defaultConfigurationIsVisible = 0; 1917 | defaultConfigurationName = Release; 1918 | }; 1919 | 9B45DB971FEEB6CD00D81C9F /* Build configuration list for PBXNativeTarget "DocumentClassifierTV" */ = { 1920 | isa = XCConfigurationList; 1921 | buildConfigurations = ( 1922 | 9B45DB981FEEB6CD00D81C9F /* Debug */, 1923 | 9B45DB991FEEB6CD00D81C9F /* Release */, 1924 | ); 1925 | defaultConfigurationIsVisible = 0; 1926 | defaultConfigurationName = Release; 1927 | }; 1928 | 9B45DB9A1FEEB6CD00D81C9F /* Build configuration list for PBXNativeTarget "DocumentClassifierTVTests" */ = { 1929 | isa = XCConfigurationList; 1930 | buildConfigurations = ( 1931 | 9B45DB9B1FEEB6CD00D81C9F /* Debug */, 1932 | 9B45DB9C1FEEB6CD00D81C9F /* Release */, 1933 | ); 1934 | defaultConfigurationIsVisible = 0; 1935 | defaultConfigurationName = Release; 1936 | }; 1937 | 9B45DBA71FEEB71100D81C9F /* Build configuration list for PBXNativeTarget "DocumentClassifierWatch" */ = { 1938 | isa = XCConfigurationList; 1939 | buildConfigurations = ( 1940 | 9B45DBA81FEEB71100D81C9F /* Debug */, 1941 | 9B45DBA91FEEB71100D81C9F /* Release */, 1942 | ); 1943 | defaultConfigurationIsVisible = 0; 1944 | defaultConfigurationName = Release; 1945 | }; 1946 | 9B4EEC9F1FEF44D2009E5262 /* Build configuration list for PBXNativeTarget "NewsClassifier" */ = { 1947 | isa = XCConfigurationList; 1948 | buildConfigurations = ( 1949 | 9B4EECA01FEF44D2009E5262 /* Debug */, 1950 | 9B4EECA11FEF44D2009E5262 /* Release */, 1951 | ); 1952 | defaultConfigurationIsVisible = 0; 1953 | defaultConfigurationName = Release; 1954 | }; 1955 | /* End XCConfigurationList section */ 1956 | }; 1957 | rootObject = 9B45DB421FEEB64C00D81C9F /* Project object */; 1958 | } 1959 | -------------------------------------------------------------------------------- /DocumentClassifier.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /DocumentClassifier.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /DocumentClassifier.xcodeproj/xcshareddata/xcschemes/DocumentClassifierMac.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 31 | 32 | 34 | 40 | 41 | 42 | 43 | 44 | 50 | 51 | 52 | 53 | 54 | 55 | 65 | 66 | 72 | 73 | 74 | 75 | 76 | 77 | 83 | 84 | 90 | 91 | 92 | 93 | 95 | 96 | 99 | 100 | 101 | -------------------------------------------------------------------------------- /DocumentClassifier.xcodeproj/xcshareddata/xcschemes/DocumentClassifierMobile.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 31 | 32 | 34 | 40 | 41 | 42 | 43 | 44 | 50 | 51 | 52 | 53 | 54 | 55 | 65 | 66 | 72 | 73 | 74 | 75 | 76 | 77 | 83 | 84 | 90 | 91 | 92 | 93 | 95 | 96 | 99 | 100 | 101 | -------------------------------------------------------------------------------- /DocumentClassifier.xcodeproj/xcshareddata/xcschemes/DocumentClassifierTV.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 31 | 32 | 34 | 40 | 41 | 42 | 43 | 44 | 50 | 51 | 52 | 53 | 54 | 55 | 65 | 66 | 72 | 73 | 74 | 75 | 76 | 77 | 83 | 84 | 90 | 91 | 92 | 93 | 95 | 96 | 99 | 100 | 101 | -------------------------------------------------------------------------------- /DocumentClassifier.xcodeproj/xcshareddata/xcschemes/DocumentClassifierWatch.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 34 | 35 | 45 | 46 | 52 | 53 | 54 | 55 | 56 | 57 | 63 | 64 | 70 | 71 | 72 | 73 | 75 | 76 | 79 | 80 | 81 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Todd Kramer 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 | -------------------------------------------------------------------------------- /NewsClassifier/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // 4 | // Copyright (c) 2017 Todd Kramer (http://www.tekramer.com) 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | // 24 | 25 | import UIKit 26 | 27 | @UIApplicationMain 28 | class AppDelegate: UIResponder, UIApplicationDelegate { 29 | 30 | var window: UIWindow? 31 | 32 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 33 | return true 34 | } 35 | 36 | } 37 | 38 | -------------------------------------------------------------------------------- /NewsClassifier/Assets.xcassets/App.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | }, 6 | "colors" : [ 7 | { 8 | "idiom" : "universal", 9 | "color" : { 10 | "color-space" : "srgb", 11 | "components" : { 12 | "red" : "0.000", 13 | "alpha" : "1.000", 14 | "blue" : "1.000", 15 | "green" : "0.498" 16 | } 17 | } 18 | } 19 | ] 20 | } -------------------------------------------------------------------------------- /NewsClassifier/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "20x20", 5 | "idiom" : "iphone", 6 | "filename" : "icon_40-2.png", 7 | "scale" : "2x" 8 | }, 9 | { 10 | "size" : "20x20", 11 | "idiom" : "iphone", 12 | "filename" : "icon_60.png", 13 | "scale" : "3x" 14 | }, 15 | { 16 | "size" : "29x29", 17 | "idiom" : "iphone", 18 | "filename" : "icon_58.png", 19 | "scale" : "2x" 20 | }, 21 | { 22 | "size" : "29x29", 23 | "idiom" : "iphone", 24 | "filename" : "icon_87.png", 25 | "scale" : "3x" 26 | }, 27 | { 28 | "size" : "40x40", 29 | "idiom" : "iphone", 30 | "filename" : "icon_80-1.png", 31 | "scale" : "2x" 32 | }, 33 | { 34 | "size" : "40x40", 35 | "idiom" : "iphone", 36 | "filename" : "icon_120-1.png", 37 | "scale" : "3x" 38 | }, 39 | { 40 | "size" : "60x60", 41 | "idiom" : "iphone", 42 | "filename" : "icon_120.png", 43 | "scale" : "2x" 44 | }, 45 | { 46 | "size" : "60x60", 47 | "idiom" : "iphone", 48 | "filename" : "icon_180.png", 49 | "scale" : "3x" 50 | }, 51 | { 52 | "size" : "20x20", 53 | "idiom" : "ipad", 54 | "filename" : "icon_20.png", 55 | "scale" : "1x" 56 | }, 57 | { 58 | "size" : "20x20", 59 | "idiom" : "ipad", 60 | "filename" : "icon_40-1.png", 61 | "scale" : "2x" 62 | }, 63 | { 64 | "size" : "29x29", 65 | "idiom" : "ipad", 66 | "filename" : "icon_29.png", 67 | "scale" : "1x" 68 | }, 69 | { 70 | "size" : "29x29", 71 | "idiom" : "ipad", 72 | "filename" : "icon_58-1.png", 73 | "scale" : "2x" 74 | }, 75 | { 76 | "size" : "40x40", 77 | "idiom" : "ipad", 78 | "filename" : "icon_40.png", 79 | "scale" : "1x" 80 | }, 81 | { 82 | "size" : "40x40", 83 | "idiom" : "ipad", 84 | "filename" : "icon_80.png", 85 | "scale" : "2x" 86 | }, 87 | { 88 | "size" : "76x76", 89 | "idiom" : "ipad", 90 | "filename" : "icon_76.png", 91 | "scale" : "1x" 92 | }, 93 | { 94 | "size" : "76x76", 95 | "idiom" : "ipad", 96 | "filename" : "icon_152.png", 97 | "scale" : "2x" 98 | }, 99 | { 100 | "size" : "83.5x83.5", 101 | "idiom" : "ipad", 102 | "filename" : "icon_167.png", 103 | "scale" : "2x" 104 | }, 105 | { 106 | "size" : "1024x1024", 107 | "idiom" : "ios-marketing", 108 | "filename" : "icon_1024.png", 109 | "scale" : "1x" 110 | } 111 | ], 112 | "info" : { 113 | "version" : 1, 114 | "author" : "xcode" 115 | } 116 | } -------------------------------------------------------------------------------- /NewsClassifier/Assets.xcassets/AppIcon.appiconset/icon_1024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toddkramer/DocumentClassifier/9b3e0eb2a4a219d8d392700e629e9325b3da971c/NewsClassifier/Assets.xcassets/AppIcon.appiconset/icon_1024.png -------------------------------------------------------------------------------- /NewsClassifier/Assets.xcassets/AppIcon.appiconset/icon_120-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toddkramer/DocumentClassifier/9b3e0eb2a4a219d8d392700e629e9325b3da971c/NewsClassifier/Assets.xcassets/AppIcon.appiconset/icon_120-1.png -------------------------------------------------------------------------------- /NewsClassifier/Assets.xcassets/AppIcon.appiconset/icon_120.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toddkramer/DocumentClassifier/9b3e0eb2a4a219d8d392700e629e9325b3da971c/NewsClassifier/Assets.xcassets/AppIcon.appiconset/icon_120.png -------------------------------------------------------------------------------- /NewsClassifier/Assets.xcassets/AppIcon.appiconset/icon_152.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toddkramer/DocumentClassifier/9b3e0eb2a4a219d8d392700e629e9325b3da971c/NewsClassifier/Assets.xcassets/AppIcon.appiconset/icon_152.png -------------------------------------------------------------------------------- /NewsClassifier/Assets.xcassets/AppIcon.appiconset/icon_167.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toddkramer/DocumentClassifier/9b3e0eb2a4a219d8d392700e629e9325b3da971c/NewsClassifier/Assets.xcassets/AppIcon.appiconset/icon_167.png -------------------------------------------------------------------------------- /NewsClassifier/Assets.xcassets/AppIcon.appiconset/icon_180.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toddkramer/DocumentClassifier/9b3e0eb2a4a219d8d392700e629e9325b3da971c/NewsClassifier/Assets.xcassets/AppIcon.appiconset/icon_180.png -------------------------------------------------------------------------------- /NewsClassifier/Assets.xcassets/AppIcon.appiconset/icon_20.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toddkramer/DocumentClassifier/9b3e0eb2a4a219d8d392700e629e9325b3da971c/NewsClassifier/Assets.xcassets/AppIcon.appiconset/icon_20.png -------------------------------------------------------------------------------- /NewsClassifier/Assets.xcassets/AppIcon.appiconset/icon_29.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toddkramer/DocumentClassifier/9b3e0eb2a4a219d8d392700e629e9325b3da971c/NewsClassifier/Assets.xcassets/AppIcon.appiconset/icon_29.png -------------------------------------------------------------------------------- /NewsClassifier/Assets.xcassets/AppIcon.appiconset/icon_40-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toddkramer/DocumentClassifier/9b3e0eb2a4a219d8d392700e629e9325b3da971c/NewsClassifier/Assets.xcassets/AppIcon.appiconset/icon_40-1.png -------------------------------------------------------------------------------- /NewsClassifier/Assets.xcassets/AppIcon.appiconset/icon_40-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toddkramer/DocumentClassifier/9b3e0eb2a4a219d8d392700e629e9325b3da971c/NewsClassifier/Assets.xcassets/AppIcon.appiconset/icon_40-2.png -------------------------------------------------------------------------------- /NewsClassifier/Assets.xcassets/AppIcon.appiconset/icon_40.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toddkramer/DocumentClassifier/9b3e0eb2a4a219d8d392700e629e9325b3da971c/NewsClassifier/Assets.xcassets/AppIcon.appiconset/icon_40.png -------------------------------------------------------------------------------- /NewsClassifier/Assets.xcassets/AppIcon.appiconset/icon_58-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toddkramer/DocumentClassifier/9b3e0eb2a4a219d8d392700e629e9325b3da971c/NewsClassifier/Assets.xcassets/AppIcon.appiconset/icon_58-1.png -------------------------------------------------------------------------------- /NewsClassifier/Assets.xcassets/AppIcon.appiconset/icon_58.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toddkramer/DocumentClassifier/9b3e0eb2a4a219d8d392700e629e9325b3da971c/NewsClassifier/Assets.xcassets/AppIcon.appiconset/icon_58.png -------------------------------------------------------------------------------- /NewsClassifier/Assets.xcassets/AppIcon.appiconset/icon_60.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toddkramer/DocumentClassifier/9b3e0eb2a4a219d8d392700e629e9325b3da971c/NewsClassifier/Assets.xcassets/AppIcon.appiconset/icon_60.png -------------------------------------------------------------------------------- /NewsClassifier/Assets.xcassets/AppIcon.appiconset/icon_76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toddkramer/DocumentClassifier/9b3e0eb2a4a219d8d392700e629e9325b3da971c/NewsClassifier/Assets.xcassets/AppIcon.appiconset/icon_76.png -------------------------------------------------------------------------------- /NewsClassifier/Assets.xcassets/AppIcon.appiconset/icon_80-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toddkramer/DocumentClassifier/9b3e0eb2a4a219d8d392700e629e9325b3da971c/NewsClassifier/Assets.xcassets/AppIcon.appiconset/icon_80-1.png -------------------------------------------------------------------------------- /NewsClassifier/Assets.xcassets/AppIcon.appiconset/icon_80.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toddkramer/DocumentClassifier/9b3e0eb2a4a219d8d392700e629e9325b3da971c/NewsClassifier/Assets.xcassets/AppIcon.appiconset/icon_80.png -------------------------------------------------------------------------------- /NewsClassifier/Assets.xcassets/AppIcon.appiconset/icon_87.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toddkramer/DocumentClassifier/9b3e0eb2a4a219d8d392700e629e9325b3da971c/NewsClassifier/Assets.xcassets/AppIcon.appiconset/icon_87.png -------------------------------------------------------------------------------- /NewsClassifier/Assets.xcassets/Business.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | }, 6 | "colors" : [ 7 | { 8 | "idiom" : "universal", 9 | "color" : { 10 | "color-space" : "srgb", 11 | "components" : { 12 | "red" : "0.000", 13 | "alpha" : "1.000", 14 | "blue" : "0.000", 15 | "green" : "0.357" 16 | } 17 | } 18 | } 19 | ] 20 | } -------------------------------------------------------------------------------- /NewsClassifier/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /NewsClassifier/Assets.xcassets/Entertainment.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | }, 6 | "colors" : [ 7 | { 8 | "idiom" : "universal", 9 | "color" : { 10 | "color-space" : "srgb", 11 | "components" : { 12 | "red" : "0.373", 13 | "alpha" : "1.000", 14 | "blue" : "0.749", 15 | "green" : "0.000" 16 | } 17 | } 18 | } 19 | ] 20 | } -------------------------------------------------------------------------------- /NewsClassifier/Assets.xcassets/Politics.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | }, 6 | "colors" : [ 7 | { 8 | "idiom" : "universal", 9 | "color" : { 10 | "color-space" : "srgb", 11 | "components" : { 12 | "red" : "0.889", 13 | "alpha" : "1.000", 14 | "blue" : "0.000", 15 | "green" : "0.789" 16 | } 17 | } 18 | } 19 | ] 20 | } -------------------------------------------------------------------------------- /NewsClassifier/Assets.xcassets/Sports.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | }, 6 | "colors" : [ 7 | { 8 | "idiom" : "universal", 9 | "color" : { 10 | "color-space" : "srgb", 11 | "components" : { 12 | "red" : "0.608", 13 | "alpha" : "1.000", 14 | "blue" : "0.000", 15 | "green" : "0.000" 16 | } 17 | } 18 | } 19 | ] 20 | } -------------------------------------------------------------------------------- /NewsClassifier/Assets.xcassets/Technology.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | }, 6 | "colors" : [ 7 | { 8 | "idiom" : "universal", 9 | "color" : { 10 | "color-space" : "srgb", 11 | "components" : { 12 | "red" : "1.000", 13 | "alpha" : "1.000", 14 | "blue" : "0.000", 15 | "green" : "0.498" 16 | } 17 | } 18 | } 19 | ] 20 | } -------------------------------------------------------------------------------- /NewsClassifier/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /NewsClassifier/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | -------------------------------------------------------------------------------- /NewsClassifier/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | NSAppTransportSecurity 20 | 21 | NSAllowsArbitraryLoadsInWebContent 22 | 23 | 24 | CFBundleVersion 25 | 1 26 | LSRequiresIPhoneOS 27 | 28 | UILaunchStoryboardName 29 | LaunchScreen 30 | UIMainStoryboardFile 31 | Main 32 | UIRequiredDeviceCapabilities 33 | 34 | armv7 35 | 36 | UISupportedInterfaceOrientations 37 | 38 | UIInterfaceOrientationPortrait 39 | UIInterfaceOrientationLandscapeLeft 40 | UIInterfaceOrientationLandscapeRight 41 | 42 | UISupportedInterfaceOrientations~ipad 43 | 44 | UIInterfaceOrientationPortrait 45 | UIInterfaceOrientationPortraitUpsideDown 46 | UIInterfaceOrientationLandscapeLeft 47 | UIInterfaceOrientationLandscapeRight 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /NewsClassifier/Screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toddkramer/DocumentClassifier/9b3e0eb2a4a219d8d392700e629e9325b3da971c/NewsClassifier/Screenshot.png -------------------------------------------------------------------------------- /NewsClassifier/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // 4 | // Copyright (c) 2017 Todd Kramer (http://www.tekramer.com) 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | // 24 | 25 | import UIKit 26 | import WebKit 27 | import DocumentClassifier 28 | 29 | extension Classification.Category { 30 | 31 | var color: UIColor { 32 | return UIColor(named: rawValue) ?? UIColor(named: "App") ?? .darkGray 33 | } 34 | 35 | } 36 | 37 | class ViewController: UIViewController { 38 | 39 | @IBOutlet weak var textView: UITextView! 40 | @IBOutlet weak var classificationLabel: UILabel! 41 | @IBOutlet weak var classificationLabelBottomConstraint: NSLayoutConstraint! 42 | 43 | let classifier = DocumentClassifier() 44 | 45 | lazy var percentFormatter: NumberFormatter = { 46 | let formatter = NumberFormatter() 47 | formatter.numberStyle = .percent 48 | formatter.maximumFractionDigits = 1 49 | return formatter 50 | }() 51 | 52 | override func viewDidLoad() { 53 | super.viewDidLoad() 54 | 55 | addKeyboardObservers() 56 | configureTextView() 57 | } 58 | 59 | func classify(_ text: String) { 60 | guard let classification = classifier.classify(text) else { return } 61 | let prediction = classification.prediction 62 | updateInterface(for: prediction) 63 | } 64 | 65 | func updateInterface(for prediction: Classification.Result) { 66 | guard let percent = percentFormatter.string(from: NSNumber(value: prediction.probability)) else { return } 67 | classificationLabel.text = prediction.category.rawValue + " " + "(\(percent))" 68 | changeInterfaceColor(to: prediction.category.color) 69 | } 70 | 71 | func configureTextView() { 72 | textView.layer.cornerRadius = 8 73 | textView.layer.borderWidth = 1 74 | textView.layer.borderColor = UIColor.black.cgColor 75 | } 76 | 77 | @IBAction func clearButtonTapped(_ sender: Any) { 78 | textView.text = "" 79 | classificationLabel.text = "None" 80 | changeInterfaceColor(to: UIColor(named: "App")) 81 | } 82 | 83 | func changeInterfaceColor(to color: UIColor?) { 84 | classificationLabel.backgroundColor = color 85 | navigationController?.navigationBar.barTintColor = color 86 | } 87 | 88 | } 89 | 90 | // MARK: - UITextViewDelegate 91 | 92 | extension ViewController: UITextViewDelegate { 93 | 94 | func textViewDidChange(_ textView: UITextView) { 95 | classify(textView.text) 96 | } 97 | 98 | } 99 | 100 | // MARK: - Keyboard 101 | 102 | extension ViewController { 103 | 104 | func addKeyboardObservers() { 105 | NotificationCenter.default.addObserver(self, selector: #selector(toggleKeyboard), name: UIResponder.keyboardWillShowNotification, object: nil) 106 | NotificationCenter.default.addObserver(self, selector: #selector(toggleKeyboard), name: UIResponder.keyboardWillHideNotification, object: nil) 107 | } 108 | 109 | @objc private func toggleKeyboard(for notification: Notification) { 110 | guard let attributes = keyboardAttributes(for: notification) else { return } 111 | UIView.animate(withDuration: attributes.animationDuration) { 112 | self.classificationLabelBottomConstraint.constant = -attributes.size.height 113 | self.view.layoutIfNeeded() 114 | } 115 | } 116 | 117 | private func keyboardAttributes(for notification: Notification) -> (size: CGSize, animationDuration: Double)? { 118 | guard 119 | let keyboardSize = (notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as AnyObject).cgRectValue?.size, 120 | let animationDuration = (notification.userInfo?[UIResponder.keyboardAnimationDurationUserInfoKey] as AnyObject).doubleValue 121 | else { return nil } 122 | return (keyboardSize, animationDuration) 123 | } 124 | 125 | } 126 | 127 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # DocumentClassifier 2 | 3 | ![CocoaPods Version](https://cocoapod-badges.herokuapp.com/v/DocumentClassifier/badge.png) [![Swift](https://img.shields.io/badge/swift-5.0-orange.svg?style=flat)](https://developer.apple.com/swift/) ![Platform](https://cocoapod-badges.herokuapp.com/p/DocumentClassifier/badge.png) 4 | 5 | ## Overview 6 | 7 | DocumentClassifier is a Swift framework for classifying documents into one of five categories (Business, Entertainment, Politics, Sports, and Technology). It uses a CoreML model trained with 1,500 news articles from the BBC. 8 | 9 | ## Features 10 | 11 | - iOS 11.0+, macOS 10.13+, tvOS 11.0+, watchOS 4.0+ 12 | - 100% Test Coverage 13 | - Best CV Score: 0.965333333333 14 | 15 | ## Usage 16 | 17 | [Swift 4 Released (Sample Article](https://swift.org/blog/swift-4-0-released/)) 18 | 19 | ```swift 20 | let text = articleText 21 | guard let classification = classifier.classify(text) else { return } 22 | print(classification.prediction) // Technology: 0.42115752953489294 23 | print(classification.allResults) // Business: 0.141, Entertainment: 0.138, Politics: 0.113, Sports: 0.187, Technology: 0.421 24 | ``` 25 | 26 | ## Installation 27 | 28 | ### CocoaPods 29 | 30 | [CocoaPods][] is a centralized dependency manager for Cocoa projects. To install 31 | DocumentClassifier with CocoaPods: 32 | 33 | 1. Make sure the latest version of CocoaPods is [installed](https://guides.cocoapods.org/using/getting-started.html#getting-started). 34 | 35 | 36 | 2. Add DocumentClassifier to your Podfile: 37 | 38 | ``` ruby 39 | use_frameworks! 40 | 41 | pod 'DocumentClassifier', '1.2.0' 42 | ``` 43 | 44 | 3. Run `pod install`. 45 | 46 | [CocoaPods]: https://cocoapods.org 47 | 48 | ## Example App 49 | 50 | NewsClassifier is an example app using the framework. 51 | 52 |
53 | NewsClassifierExample 54 |
55 | 56 | ## Model 57 | 58 | - [Model Link](https://github.com/toddkramer/DocumentClassifier/blob/master/Sources/DocumentClassification.mlmodel) 59 | - Best CV Score: 0.965333333333 60 | - Trained using 1,500 news articles from the BBC from 2004-2005 (see references) 61 | - Converted from [scikit-learn Pipeline](http://scikit-learn.org/stable/modules/generated/sklearn.pipeline.Pipeline.html) using [coremltools](https://pypi.python.org/pypi/coremltools). 62 | - Based on the [LinearSVC](http://scikit-learn.org/stable/modules/generated/sklearn.svm.LinearSVC.html) classifier. 63 | 64 | ## Author 65 | 66 | Todd Kramer, todd@tekramer.com 67 | 68 | ## References 69 | - [BBC Datasets](http://mlg.ucd.ie/datasets/bbc.html) 70 | - D. Greene and P. Cunningham. "Practical Solutions to the Problem of Diagonal Dominance in Kernel Document Clustering", Proc. ICML 2006. [link](http://mlg.ucd.ie/files/publications/greene06icml.pdf) 71 | - Vadym Markov, [SentimentPolarity](https://github.com/cocoa-ai/SentimentCoreMLDemo) 72 | - [Awesome Core ML Models](https://github.com/likedan/Awesome-CoreML-Models) 73 | - [scikit-learn](http://scikit-learn.org/stable/) 74 | - [Apple Machine Learning](https://developer.apple.com/machine-learning/) 75 | - [CoreML Framework](https://developer.apple.com/documentation/coreml) 76 | - [coremltools](https://pypi.python.org/pypi/coremltools) 77 | -------------------------------------------------------------------------------- /Sources/Classification.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Classification.swift 3 | // 4 | // Copyright (c) 2017 Todd Kramer (http://www.tekramer.com) 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | // 24 | 25 | import Foundation 26 | 27 | public struct Classification { 28 | 29 | public enum Category: String { 30 | case business = "Business" 31 | case entertainment = "Entertainment" 32 | case politics = "Politics" 33 | case sports = "Sports" 34 | case technology = "Technology" 35 | } 36 | 37 | public struct Result { 38 | public let category: Category 39 | public let probability: Double 40 | } 41 | 42 | public let prediction: Result 43 | public let allResults: [Result] 44 | 45 | } 46 | 47 | extension Classification { 48 | 49 | init?(output: DocumentClassificationOutput) { 50 | guard let category = Category(rawValue: output.classLabel), 51 | let probability = output.classProbability[output.classLabel] 52 | else { return nil } 53 | let prediction = Result(category: category, probability: probability) 54 | let allResults = output.classProbability.compactMap(Classification.result) 55 | self.init(prediction: prediction, allResults: allResults) 56 | } 57 | 58 | static func result(from classProbability: (key: String, value: Double)) -> Result? { 59 | guard let category = Category(rawValue: classProbability.key) else { return nil } 60 | return Result(category: category, probability: classProbability.value) 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /Sources/DocumentClassification.mlmodel: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/toddkramer/DocumentClassifier/9b3e0eb2a4a219d8d392700e629e9325b3da971c/Sources/DocumentClassification.mlmodel -------------------------------------------------------------------------------- /Sources/DocumentClassifier.h: -------------------------------------------------------------------------------- 1 | // 2 | // DocumentClassifier.h 3 | // 4 | // Copyright (c) 2017 Todd Kramer (http://www.tekramer.com) 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | // 24 | 25 | @import Foundation; 26 | 27 | FOUNDATION_EXPORT double DocumentClassifierVersionNumber; 28 | FOUNDATION_EXPORT const unsigned char DocumentClassifierVersionString[]; 29 | -------------------------------------------------------------------------------- /Sources/DocumentClassifier.swift: -------------------------------------------------------------------------------- 1 | // 2 | // DocumentClassifier.swift 3 | // 4 | // Copyright (c) 2017 Todd Kramer (http://www.tekramer.com) 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | // 24 | 25 | import Foundation 26 | 27 | public final class DocumentClassifier { 28 | 29 | public init() {} 30 | 31 | private let model = DocumentClassification() 32 | private let options: NSLinguisticTagger.Options = [.omitWhitespace, .omitPunctuation, .omitOther] 33 | private lazy var tagger: NSLinguisticTagger = { 34 | let tagSchemes = NSLinguisticTagger.availableTagSchemes(forLanguage: "en") 35 | return NSLinguisticTagger(tagSchemes: tagSchemes, options: Int(self.options.rawValue)) 36 | }() 37 | 38 | public func classify(_ text: String) -> Classification? { 39 | let features = extractFeatures(from: text) 40 | guard 41 | features.count > 2, 42 | let output = try? model.prediction(input: features) else { return nil } 43 | return Classification(output: output) 44 | } 45 | 46 | func extractFeatures(from text: String) -> [String: Double] { 47 | var wordCounts = [String: Double]() 48 | tagger.string = text 49 | let range = NSRange(location: 0, length: text.count) 50 | tagger.enumerateTags(in: range, scheme: .tokenType, options: options) { _, tokenRange, _, _ in 51 | let token = (text as NSString).substring(with: tokenRange).lowercased() 52 | guard token.count >= 3 else { return } 53 | guard let value = wordCounts[token] else { 54 | wordCounts[token] = 1.0 55 | return 56 | } 57 | wordCounts[token] = value + 1.0 58 | } 59 | return wordCounts 60 | } 61 | 62 | } 63 | -------------------------------------------------------------------------------- /Sources/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.2.0 19 | CFBundleVersion 20 | $(CURRENT_PROJECT_VERSION) 21 | NSPrincipalClass 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /Tests/DocumentClassifierTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // DocumentClassifierTests.swift 3 | // 4 | // Copyright (c) 2017 Todd Kramer (http://www.tekramer.com) 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | // 24 | 25 | import XCTest 26 | @testable import DocumentClassifier 27 | 28 | class DocumentClassifierTests: XCTestCase { 29 | 30 | let classifier = DocumentClassifier() 31 | let categories = ["Business", "Entertainment", "Politics", "Sports", "Technology"] 32 | 33 | let bundle = Bundle(for: DocumentClassifierTests.self) 34 | 35 | func testClassifiy() { 36 | categories.forEach { 37 | let path = bundle.path(forResource: $0, ofType: "txt")! 38 | let url = URL(fileURLWithPath: path) 39 | let text = try! String(contentsOf: url) 40 | let classification = classifier.classify(text)! 41 | let expectedCategory = Classification.Category(rawValue: $0)! 42 | XCTAssertEqual(classification.prediction.category, expectedCategory) 43 | } 44 | XCTAssertNil(classifier.classify("technology")) 45 | } 46 | 47 | func testNilClassificationFromOutput() { 48 | let output = DocumentClassificationOutput(classLabel: "random", classProbability: ["random": 0.4]) 49 | XCTAssertNil(Classification(output: output)) 50 | } 51 | 52 | func testNilResultFromClassProbability() { 53 | XCTAssertNil(Classification.result(from: ("random", 0.4))) 54 | } 55 | 56 | } 57 | -------------------------------------------------------------------------------- /Tests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /Tests/Resources/Business.txt: -------------------------------------------------------------------------------- 1 | Brazil plays down Varig rescue 2 | 3 | The Brazilian government has played down claims that it could step in to save the country's biggest airline. 4 | 5 | Brazil's airport authority chief Carlos Wilson had claimed the government was on the brink of stepping in to save Varig, Brazil's flagship airline. However, the country's vice president Jose Alencar has said the government still is looking for a solution. Varig is struggling under a huge debt burden of an estimated debt of 6.5 billion reais ($2.3bn or £1.2bn). Asked whether a rescue was on the cards following a meeting of the country's Congress to discuss the airline's crisis, Mr Alencar replied: "No, I don't think so. We will see." 6 | 7 | Earlier, Mr Wilson had said that president Luiz Inacio Lula da Silva has decided to step in and a decree of some kind of intervention could be signed this week. "In practice, it will be an intervention, although this is not the technical name used", he said. An intervention means that the government would take administrative control of the company and its finances. For that to happen Varig's main shareholder, the non-profit Ruben Berta Foundation which represents the airline's employees, would have to be removed, Mr Wilson said. However, no jobs would be lost and the airline would keep on flying, he added. Varig, which operates in 18 countries apart from Brazil, has been driven to the brink of collapse because of the country's economic downturn. 8 | 9 | The depreciation of Brazil's currency has had a direct impact on the airline's dollar debt as well as some of its costs. Business has improved recently with demand for air travel increasing and a recovery in the Brazilian economy. The airline could also win a sizeable windfall from a compensation claim against the government. On Tuesday the courts awarded Varig 2bn reais ($725m), after ruling in favour of its compensation claim against the government for freezing tariffs from 1985 to 1992. But the government can appeal the decision. 10 | -------------------------------------------------------------------------------- /Tests/Resources/Entertainment.txt: -------------------------------------------------------------------------------- 1 | Hollywood hunts hits at Sundance 2 | 3 | The Sundance Film Festival, the movie industry's top destination for uncovering the next independent hits and new talent, opens on Thursday. 4 | 5 | The event will see screen executives decamp from Hollywood to Park City, Utah, for 11 days to search for low-key movies that could make it big in 2005. Open Water, Napoleon Dynamite, Garden State and Super-Size Me were all snapped up at last year's festival. But stars like Keanu Reeves and Pierce Brosnan also have films showing there. The festival is being opened by a screening of quirky comedy Happy Endings, starring former Friends actress Lisa Kudrow and Maggie Gyllenhaal, on Thursday. 6 | 7 | Kudrow's Friends co-star, David Schwimmer, plays a divorced drunkard in Duane Hopwood, while Brosnan stars as a hit man in comedy The Matador. Keanu Reeves appears in coming-of-age tale Thumbsucker while Kevin Costner and Michael Keaton are among the other big names whose films are involved. Robert Redford founded Sundance in 1981 and it has gone on to showcase future successes such as Reservoir Dogs, The Blair Witch Project and The Full Monty. But it has received criticism that it has become more commercial and mainstream over the years. "As much as the press argues that Sundance has completely changed, it hasn't changed that much," festival director Geoffrey Gilmore said. "It's still a place for discovery. It's a place for common ground among film-makers and audiences more than it is the celebrity stuff." Other films generating interest before this year's festival include Hustle & Flow, about an aspiring rapper, The Squid and the Whale, an autobiographical film by writer-director Noah Baumbach, and comedy/drama Pretty Persuasion. It also has two new international cinema competitions. 8 | -------------------------------------------------------------------------------- /Tests/Resources/Politics.txt: -------------------------------------------------------------------------------- 1 | Taxes must be trusted - Kennedy 2 | 3 | Public trust in taxes is breaking down because Labour and Tories are not being straight with people on the issue, Lib Dem leader Charles Kennedy has said. 4 | 5 | A day ahead of the government's pre-Budget report, Mr Kennedy used a speech to say his party was facing up to "painful economic realities". He said the current level of taxation was about right, although he would put a new 50% tax on top earners. Other parties have accused the Lib Dems of making uncosted promises. Mr Kennedy made it clear he was determined to counter that accusation. The Lib Dems have already published what they say are the full costings for all their plans and Wednesday's speech did not announce new policies. 6 | 7 | Speaking at the Commonwealth Club, Mr Kennedy said it was critical for a political party to have economic credibility, both on what it promised and what it was expected to deliver. He said. "Budgets have to add up. Tough choices are needed in public spending." The Lib Dems would cut "low priority" spending, including the government's ID cards scheme and the Child Trust Fund. 8 | 9 | Those cutbacks would free up funds for increasing basic state pensions for over-75s, putting more police on the streets and reintroducing fee eye and dental checks, he said. The Lib Dems argue they were honest about taxes in the past by calling for a 1p rise on income tax. Now they say the only simple tax rise they want is a new 50% tax band for top earners to pay for scrapping university tuition fees, providing free personal care for elderly and disabled people and keeping local taxes down. There would also be a local income tax to replace council tax and a number of changes to environmental taxes to ensure it is the "polluter who pays". 10 | 11 | The Lib Dems say the Tories have only laid out possible options for cutting taxes to grab headlines while Labour has hidden most of its tax rises. Mr Kennedy said: "That contract with the people - that the government will only tax fairly and will spend their money wisely - can only be sustained if the political parties are straightforward about their plans. "With the stealth tax strategy of Gordon Brown, the obvious unfairness of our current tax system - especially the council tax, and the empty promises of the Conservative party on this issue - it is no wonder that trust in taxation is breaking down." He challenged the Treasury to open up its books so the National Audit Office can report on the government's performance. 12 | 13 | Conservative co-chairman Liam Fox said: Liam Fox said "If Charles Kennedy is serious about making his budgets add up he should start by explaining how they would fund their 100 spending commitments. "The reality is, the Lib Dems lack the courage to tackle waste and bureaucracy, and the only people who would face 'tough choices' would be the families who would be £630 worse off a year. " And Chancellor Gordon Brown said the Lib Dem figures did not add up. He accused the party of claiming it would spend less while across the country committing itself to spend more. 14 | -------------------------------------------------------------------------------- /Tests/Resources/Sports.txt: -------------------------------------------------------------------------------- 1 | Jones happy with Henson heroics 2 | 3 | Wales fly-half Stephen Jones admitted he was happy to hand Gavin Henson responsibility for taking the match-winning kick against England. 4 | 5 | Jones had missed three earlier shots at goal when Wales, 9-8 down, were awarded a long-range penalty with four minutes left in Cardiff. "I knew the percentages of Gavin reaching it were far higher than me," Jones said. "When he said he wanted it, there were no problems." Jones had seen a long-range effort fall a whisker under the crossbar on the hour, before Charlie Hodgson put England in front with 10 minutes left. "I looked at where it was and I knew I was going to struggle to make it," Jones added. "I said to Gareth (Thomas, the Wales captain) 'This is touch and go.' It was out of my range and obviously Gavin is phenomenal when it comes to distance. He was confident and fancied it. "There were no questions that he'd miss it the way he was playing. He had a superb game." Jones was happy to hail Henson's heroic contribution to Wales' first win over England in Cardiff since 1993. "Physically he's a specimen: he's a balanced player, he glides when he runs and obviously he's got a great kicking game as well," Jones said. 6 | 7 | "His defence was superb, he made some great hits and he had a great game. "I'm glad he's Welsh." Victory over England for the first time since 1999 will no doubt fuel expectations of what Wales might achieve in this year's Six Nations. But they now face three away fixtures in Italy, France and Scotland before completing their campaign against Ireland in Cardiff. "People all over the world want to see Wales back at the top table of world rugby," said a proud coach Mike Ruddock. "But we are not there yet. The next step is finding the consistency to get further wins. "We have to travel this week and we can't afford to get too giddy about this result. "We have got to be professional and keep focused on facing Italy." 8 | 9 | None more so than Henson, who can now expect to have the same sort of spotlight thrust upon him as the likes of Jonny Wilkinson and Brian O'Driscoll. The confident 23-year-old is undaunted by the prospect of dealing with such weighty expectations however. "I'm the sort of player who likes pressure on me," he said. "It makes me more concentrated and I think I perform better under more pressure. "I set a high standard against England and I've got to back it up next week. "Two years ago when we played Italy I wasn't involved and we lost, so we've got to put that right next week." 10 | -------------------------------------------------------------------------------- /Tests/Resources/Technology.txt: -------------------------------------------------------------------------------- 1 | Rivals of the £400 Apple... 2 | 3 | The Mac mini is the cheapest Apple computer ever. But though it is cheap for a Mac how does it compare to PCs that cost about the same amount? Dot.life tries to find out if you can you get more for your money if you stick with the beige box. 4 | 5 | 6 | 7 | 8 | 9 | An extremely small computer that is designed to bring the Macintosh to the masses. 10 | 11 | Apple offer a less powerful Mac Mini for £339 but the £399 models has a 1.4ghz Power PC chip, 80 gigabyte hard drive, combined CD burner/DVD player. It comes equipped with USB and Firewire ports for peripheral connections, Ethernet port for broadband, a port for standard video output and an audio/headphone jack.The machine comes with Mac OS X, the Apple operating system, the software suite iLife, which includes iTunes, iPhoto, iMovie, iDVD and GarageBand. 12 | 13 | A monitor, keyboard or mouse. There is also no built-in support for wireless technology or any speakers. The lack of a DVD burner is an omission in the age of backing-up important software. Wireless and a dvd burner can be added at extra cost. 14 | 15 | Apple are targeting people who already have a main computer and want to upgrade - especially PC users who have used an Apple iPod. 16 | 17 | Compact and stylish, the Mac mini would not look out of place in any home. Apple computers are famously user friendly and offer much better network security, which means fewer viruses. The package of software that comes with the machine is the best money can buy. 18 | 19 | The Mac mini is just a box. If you don't already have a monitor etc, adding them to the package sees the value for money begin to dwindle. Macs don't offer the upgrade flexibility of a PC and the machine's specifications lack the horse power for tasks such as high-end video editing or games. 20 | 21 | "The Mac Mini puts the Macintosh within the reach of everyone," an Apple spokesman said. "It will bring more customers to the platform, especially PC users and owners." 22 | 23 | 24 | 25 | An entry-level machine designed for basic home use. 26 | 27 | A 2.6ghz Intel Celeron chip, 40 gigabyte hard drive, 256mb, combined CD burner/DVD player. It comes equipped with a 17 inch monitor, keyboard and mouse. The machine has 6 USB ports and an Ethernet port for broadband connection. There's also a port for standard video output. The machine comes with Windows XP home edition. It provides basic home tools such as a media player and word processor. 28 | 29 | A DVD burner, or any wireless components built in. Wireless and a dvd burner can be added at extra cost. 30 | 31 | Homes and small offices, including those looking to add a low cost second computer. 32 | 33 | Cost is the clear advantage. The Dell provides enough power and software for basic gaming and internet surfing. It's easily upgradeable so a bigger hard drive, better sound and graphics cards can be added. 34 | 35 | The Dell is hardly stylish and the hard drive is on the small size for anyone wanting to store photos or a decent sized digital music collection. 36 | 37 | "This machine is for small businesses and for people who want a second computer for basic home use, perhaps in a kids bedroom," a spokesman for Dell said. "I think we offer better value once you realise all the extras needed for the Mac Mini." 38 | 39 | 40 | 41 | A desktop computer that PC Pro magazine dubbed best performer in a group test of machines that cost only £399 (£469 including VAT). 42 | 43 | A good basic PC that, according to PC Pro, has "superb upgrade potential". For your money you get a 1.8GHz AMD Sempron processor, 512MB of Ram, 120GB hard drive, DVD writer, 16-inch monitor, mouse, keyboard and Windows XP2 44 | 45 | Much more than the basics. It cannot handle 3D graphics and has no Firewire slots. 46 | 47 | Those on a limited budget who want a machine they can add to and improve as their cash allows. 48 | 49 | It's cheap and has plenty of room to improve but that could end up making it expensive in the long run. It's a good basic workhorse. 50 | 51 | It's not pretty and has a monitor rather than a flat-panel display. Some of the upgrades offered by JAL to the basic model are pricey. You might find that you want to chop and change quite quickly. 52 | 53 | Nick Ross, deputy labs editor at PC Pro, said the important point about buying a cheap and cheerful PC is the upgrade path. Interest has switched from processor power to graphics and sound cards as that's what makes the difference in games. "Even manufacturers are not going to be marketing machines as faster," he said, "they'll emphasise the different features." 54 | 55 | 56 | 57 | A computer built from bits you buy and put together yourself. 58 | 59 | A surprisingly good PC sporting an AMD Athlon XP 2500 processor, 512 megabytes Ram, a graphics card with 128 Ram on board plus TV out, a 40 GB hard drive, CD-writer and DVD player, Windows XP Home. 60 | 61 | Anything else. You're building it so you have to buy all the software you want to install and do your own trouble-shooting and tech support. Building your own machine is easier than it used to be but you need to read specifications carefully to make sure all parts work together. 62 | 63 | Experienced and keen PC users. Building your own PC, or upgrading the one you have, is a great way to improve your understanding of how it all works. 64 | 65 | It's cheap, you can specify exactly what you want and you get the thrill of putting it together yourself. And a bigger thrill if everything works as it should. 66 | 67 | Once it's built you won't be able to do much with it until you start buying software for it. If it starts to go wrong it might take a lot of fixing. As Gavin Cox of the excellent buildyourown.org.uk website put it: "It will be tough to obtain/build a PC to ever be as compact and charming as the Mac mini." 68 | 69 | "Performance-wise, it's not 'cutting edge' and is barely entry-level by today's market, but up against the Mac mini, I believe it will hold its own and even pull a few more tricks," says Gavin Cox. The good news is that the machine is eminently expandable. By contrast, says Mr Cox, the Mac mini is almost disposable. 70 | --------------------------------------------------------------------------------