├── .github └── FUNDING.yml ├── .gitignore ├── .travis.yml ├── CHANGELOG.md ├── Example ├── Fuse.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ └── xcshareddata │ │ ├── xcbaselines │ │ └── 607FACE41AFB9204008FA782.xcbaseline │ │ │ ├── A2C327BE-B522-4045-BDF0-E578A6EF0914.plist │ │ │ └── Info.plist │ │ └── xcschemes │ │ └── Fuse-Example.xcscheme ├── Fuse.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist ├── Fuse │ ├── AppDelegate.swift │ ├── Base.lproj │ │ ├── LaunchScreen.xib │ │ └── Main.storyboard │ ├── Images.xcassets │ │ └── AppIcon.appiconset │ │ │ └── Contents.json │ ├── Info.plist │ └── ViewController.swift ├── Podfile ├── Podfile.lock ├── Pods │ ├── Local Podspecs │ │ └── Fuse.podspec.json │ ├── Manifest.lock │ ├── Pods.xcodeproj │ │ ├── project.pbxproj │ │ └── xcshareddata │ │ │ └── xcschemes │ │ │ └── Fuse.xcscheme │ └── Target Support Files │ │ ├── Fuse │ │ ├── Fuse-dummy.m │ │ ├── Fuse-prefix.pch │ │ ├── Fuse-umbrella.h │ │ ├── Fuse.modulemap │ │ ├── Fuse.xcconfig │ │ └── Info.plist │ │ ├── Pods-Fuse_Example │ │ ├── Info.plist │ │ ├── Pods-Fuse_Example-acknowledgements.markdown │ │ ├── Pods-Fuse_Example-acknowledgements.plist │ │ ├── Pods-Fuse_Example-dummy.m │ │ ├── Pods-Fuse_Example-frameworks.sh │ │ ├── Pods-Fuse_Example-resources.sh │ │ ├── Pods-Fuse_Example-umbrella.h │ │ ├── Pods-Fuse_Example.debug.xcconfig │ │ ├── Pods-Fuse_Example.modulemap │ │ └── Pods-Fuse_Example.release.xcconfig │ │ └── Pods-Fuse_Tests │ │ ├── Info.plist │ │ ├── Pods-Fuse_Tests-acknowledgements.markdown │ │ ├── Pods-Fuse_Tests-acknowledgements.plist │ │ ├── Pods-Fuse_Tests-dummy.m │ │ ├── Pods-Fuse_Tests-frameworks.sh │ │ ├── Pods-Fuse_Tests-resources.sh │ │ ├── Pods-Fuse_Tests-umbrella.h │ │ ├── Pods-Fuse_Tests.debug.xcconfig │ │ ├── Pods-Fuse_Tests.modulemap │ │ └── Pods-Fuse_Tests.release.xcconfig └── Tests │ ├── Info.plist │ ├── Tests.swift │ └── books.txt ├── Fuse.podspec ├── Fuse ├── Assets │ └── .gitkeep └── Classes │ ├── .gitkeep │ ├── Fuse.swift │ ├── FuseUtilities.swift │ └── String+Fuse.swift ├── LICENSE ├── Package.swift ├── README.md └── _Pods.xcodeproj /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: krisk 2 | patreon: fusejs 3 | custom: "https://www.paypal.com/paypalme2/kirorisk" 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # OS X 2 | .DS_Store 3 | 4 | # Xcode 5 | build/ 6 | *.pbxuser 7 | !default.pbxuser 8 | *.mode1v3 9 | !default.mode1v3 10 | *.mode2v3 11 | !default.mode2v3 12 | *.perspectivev3 13 | !default.perspectivev3 14 | xcuserdata/ 15 | *.xccheckout 16 | profile 17 | *.moved-aside 18 | DerivedData 19 | *.hmap 20 | *.ipa 21 | 22 | # Bundler 23 | .bundle 24 | 25 | Carthage 26 | # We recommend against adding the Pods directory to your .gitignore. However 27 | # you should judge for yourself, the pros and cons are mentioned at: 28 | # http://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control 29 | # 30 | # Note: if you ignore the Pods directory, make sure to uncomment 31 | # `pod install` in .travis.yml 32 | # 33 | # Pods/ 34 | 35 | # Swift PM 36 | .swiftpm 37 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | # references: 2 | # * http://www.objc.io/issue-6/travis-ci.html 3 | # * https://github.com/supermarin/xcpretty#usage 4 | 5 | osx_image: xcode10.2 6 | language: objective-c 7 | # cache: cocoapods 8 | # podfile: Example/Podfile 9 | # before_install: 10 | # - gem install cocoapods # Since Travis is not always on latest version 11 | # - pod install --project-directory=Example 12 | script: 13 | - set -o pipefail && xcodebuild build test -workspace Example/Fuse.xcworkspace -scheme Fuse-Example -destination 'platform=iOS Simulator,name=iPhone 6' ONLY_ACTIVE_ARCH=NO | xcpretty 14 | - pod lib lint 15 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Version 1.1.0 2 | 3 | - Added asynchronous searching in both `[String]` and `[Fusable]`. 4 | 5 | ### Results: 6 | 7 | Tests based on searching over 1,303 book titles. 8 | 9 | Using `func search(_ text: String, in aList: [String]) -> [Fuse.SearchResult]`: 10 | 11 | - *Average*: 0.437 12 | - *Relative standard deviation*: 1.931% 13 | - *Values*: [0.459132, 0.427943, 0.432988, 0.443308, 0.437132, 0.432230, 0.434008, 0.435256, 0.436999, 0.429986] 14 | 15 | Using `func search(_ text: String, in aList: [String], completion: @escaping ([Fuse.SearchResult]) -> Void)`: 16 | 17 | - *Average*: 0.161 18 | - *Relative standard deviation*: 2.073% 19 | - *Values*: [0.155997, 0.157061, 0.161730, 0.158362, 0.161959, 0.167433, 0.162196, 0.165532, 0.161298, 0.161767] 20 | 21 | **Improvement of ~ 65%** 22 | 23 | # Version 1.0.0 24 | 25 | - Changed ranges of matched characters to be represented by `CountableClosedRange` (#2). Thank you @gravicle 26 | -------------------------------------------------------------------------------- /Example/Fuse.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 4844BD6B1EB943E7001795FB /* Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 607FACEB1AFB9204008FA782 /* Tests.swift */; }; 11 | 48921A8A1EDDB274009C962E /* books.txt in Resources */ = {isa = PBXBuildFile; fileRef = 48921A891EDDB274009C962E /* books.txt */; }; 12 | 48921A8B1EDDB274009C962E /* books.txt in Resources */ = {isa = PBXBuildFile; fileRef = 48921A891EDDB274009C962E /* books.txt */; }; 13 | 607FACD61AFB9204008FA782 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 607FACD51AFB9204008FA782 /* AppDelegate.swift */; }; 14 | 607FACD81AFB9204008FA782 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 607FACD71AFB9204008FA782 /* ViewController.swift */; }; 15 | 607FACDB1AFB9204008FA782 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 607FACD91AFB9204008FA782 /* Main.storyboard */; }; 16 | 607FACDD1AFB9204008FA782 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 607FACDC1AFB9204008FA782 /* Images.xcassets */; }; 17 | 607FACE01AFB9204008FA782 /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 607FACDE1AFB9204008FA782 /* LaunchScreen.xib */; }; 18 | 673C817ED447EF9636FA6E1C /* Pods_Fuse_Tests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 887716DF2D960084FF97151A /* Pods_Fuse_Tests.framework */; }; 19 | 94F2A9AE868F6D9EAE484302 /* Pods_Fuse_Example.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A23791F8CFBC46AC8C79E65E /* Pods_Fuse_Example.framework */; }; 20 | /* End PBXBuildFile section */ 21 | 22 | /* Begin PBXContainerItemProxy section */ 23 | 607FACE61AFB9204008FA782 /* PBXContainerItemProxy */ = { 24 | isa = PBXContainerItemProxy; 25 | containerPortal = 607FACC81AFB9204008FA782 /* Project object */; 26 | proxyType = 1; 27 | remoteGlobalIDString = 607FACCF1AFB9204008FA782; 28 | remoteInfo = Fuse; 29 | }; 30 | /* End PBXContainerItemProxy section */ 31 | 32 | /* Begin PBXFileReference section */ 33 | 18B8BF7FB99669010251081B /* README.md */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = net.daringfireball.markdown; name = README.md; path = ../README.md; sourceTree = ""; }; 34 | 24C0655B65E36704B5A61F1D /* Pods-Fuse_Tests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Fuse_Tests.release.xcconfig"; path = "Pods/Target Support Files/Pods-Fuse_Tests/Pods-Fuse_Tests.release.xcconfig"; sourceTree = ""; }; 35 | 48921A891EDDB274009C962E /* books.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = books.txt; sourceTree = ""; }; 36 | 48EC96821F0E897C0095023A /* CHANGELOG.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; name = CHANGELOG.md; path = ../CHANGELOG.md; sourceTree = ""; }; 37 | 607FACD01AFB9204008FA782 /* Fuse_Example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Fuse_Example.app; sourceTree = BUILT_PRODUCTS_DIR; }; 38 | 607FACD41AFB9204008FA782 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 39 | 607FACD51AFB9204008FA782 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 40 | 607FACD71AFB9204008FA782 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; 41 | 607FACDA1AFB9204008FA782 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 42 | 607FACDC1AFB9204008FA782 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; 43 | 607FACDF1AFB9204008FA782 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; }; 44 | 607FACE51AFB9204008FA782 /* Fuse_Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = Fuse_Tests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 45 | 607FACEA1AFB9204008FA782 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 46 | 607FACEB1AFB9204008FA782 /* Tests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Tests.swift; sourceTree = ""; }; 47 | 6984CC3FED9508E14D3E7291 /* Pods-Fuse_Example.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Fuse_Example.release.xcconfig"; path = "Pods/Target Support Files/Pods-Fuse_Example/Pods-Fuse_Example.release.xcconfig"; sourceTree = ""; }; 48 | 7B52258F584C287095B35C30 /* Pods-Fuse_Example.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Fuse_Example.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Fuse_Example/Pods-Fuse_Example.debug.xcconfig"; sourceTree = ""; }; 49 | 80DCC2C583B59F5B7FB974F3 /* LICENSE */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = LICENSE; path = ../LICENSE; sourceTree = ""; }; 50 | 887716DF2D960084FF97151A /* Pods_Fuse_Tests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Fuse_Tests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 51 | A23791F8CFBC46AC8C79E65E /* Pods_Fuse_Example.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Fuse_Example.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 52 | C309EAED0BB1FAEB482B6657 /* Pods-Fuse_Tests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Fuse_Tests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Fuse_Tests/Pods-Fuse_Tests.debug.xcconfig"; sourceTree = ""; }; 53 | F32F7457861B8DDBDD449A66 /* Fuse.podspec */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = Fuse.podspec; path = ../Fuse.podspec; sourceTree = ""; }; 54 | /* End PBXFileReference section */ 55 | 56 | /* Begin PBXFrameworksBuildPhase section */ 57 | 607FACCD1AFB9204008FA782 /* Frameworks */ = { 58 | isa = PBXFrameworksBuildPhase; 59 | buildActionMask = 2147483647; 60 | files = ( 61 | 94F2A9AE868F6D9EAE484302 /* Pods_Fuse_Example.framework in Frameworks */, 62 | ); 63 | runOnlyForDeploymentPostprocessing = 0; 64 | }; 65 | 607FACE21AFB9204008FA782 /* Frameworks */ = { 66 | isa = PBXFrameworksBuildPhase; 67 | buildActionMask = 2147483647; 68 | files = ( 69 | 673C817ED447EF9636FA6E1C /* Pods_Fuse_Tests.framework in Frameworks */, 70 | ); 71 | runOnlyForDeploymentPostprocessing = 0; 72 | }; 73 | /* End PBXFrameworksBuildPhase section */ 74 | 75 | /* Begin PBXGroup section */ 76 | 09BBE8EAA9405F34378B0169 /* Pods */ = { 77 | isa = PBXGroup; 78 | children = ( 79 | 7B52258F584C287095B35C30 /* Pods-Fuse_Example.debug.xcconfig */, 80 | 6984CC3FED9508E14D3E7291 /* Pods-Fuse_Example.release.xcconfig */, 81 | C309EAED0BB1FAEB482B6657 /* Pods-Fuse_Tests.debug.xcconfig */, 82 | 24C0655B65E36704B5A61F1D /* Pods-Fuse_Tests.release.xcconfig */, 83 | ); 84 | name = Pods; 85 | sourceTree = ""; 86 | }; 87 | 607FACC71AFB9204008FA782 = { 88 | isa = PBXGroup; 89 | children = ( 90 | 607FACF51AFB993E008FA782 /* Podspec Metadata */, 91 | 607FACD21AFB9204008FA782 /* Example for Fuse */, 92 | 607FACE81AFB9204008FA782 /* Tests */, 93 | 607FACD11AFB9204008FA782 /* Products */, 94 | 09BBE8EAA9405F34378B0169 /* Pods */, 95 | 70A98FF472A30122FB42E5A1 /* Frameworks */, 96 | ); 97 | sourceTree = ""; 98 | }; 99 | 607FACD11AFB9204008FA782 /* Products */ = { 100 | isa = PBXGroup; 101 | children = ( 102 | 607FACD01AFB9204008FA782 /* Fuse_Example.app */, 103 | 607FACE51AFB9204008FA782 /* Fuse_Tests.xctest */, 104 | ); 105 | name = Products; 106 | sourceTree = ""; 107 | }; 108 | 607FACD21AFB9204008FA782 /* Example for Fuse */ = { 109 | isa = PBXGroup; 110 | children = ( 111 | 607FACD51AFB9204008FA782 /* AppDelegate.swift */, 112 | 607FACD71AFB9204008FA782 /* ViewController.swift */, 113 | 607FACD91AFB9204008FA782 /* Main.storyboard */, 114 | 607FACDC1AFB9204008FA782 /* Images.xcassets */, 115 | 607FACDE1AFB9204008FA782 /* LaunchScreen.xib */, 116 | 607FACD31AFB9204008FA782 /* Supporting Files */, 117 | ); 118 | name = "Example for Fuse"; 119 | path = Fuse; 120 | sourceTree = ""; 121 | }; 122 | 607FACD31AFB9204008FA782 /* Supporting Files */ = { 123 | isa = PBXGroup; 124 | children = ( 125 | 607FACD41AFB9204008FA782 /* Info.plist */, 126 | ); 127 | name = "Supporting Files"; 128 | sourceTree = ""; 129 | }; 130 | 607FACE81AFB9204008FA782 /* Tests */ = { 131 | isa = PBXGroup; 132 | children = ( 133 | 607FACEB1AFB9204008FA782 /* Tests.swift */, 134 | 48921A891EDDB274009C962E /* books.txt */, 135 | 607FACE91AFB9204008FA782 /* Supporting Files */, 136 | ); 137 | path = Tests; 138 | sourceTree = ""; 139 | }; 140 | 607FACE91AFB9204008FA782 /* Supporting Files */ = { 141 | isa = PBXGroup; 142 | children = ( 143 | 607FACEA1AFB9204008FA782 /* Info.plist */, 144 | ); 145 | name = "Supporting Files"; 146 | sourceTree = ""; 147 | }; 148 | 607FACF51AFB993E008FA782 /* Podspec Metadata */ = { 149 | isa = PBXGroup; 150 | children = ( 151 | F32F7457861B8DDBDD449A66 /* Fuse.podspec */, 152 | 18B8BF7FB99669010251081B /* README.md */, 153 | 80DCC2C583B59F5B7FB974F3 /* LICENSE */, 154 | 48EC96821F0E897C0095023A /* CHANGELOG.md */, 155 | ); 156 | name = "Podspec Metadata"; 157 | sourceTree = ""; 158 | }; 159 | 70A98FF472A30122FB42E5A1 /* Frameworks */ = { 160 | isa = PBXGroup; 161 | children = ( 162 | A23791F8CFBC46AC8C79E65E /* Pods_Fuse_Example.framework */, 163 | 887716DF2D960084FF97151A /* Pods_Fuse_Tests.framework */, 164 | ); 165 | name = Frameworks; 166 | sourceTree = ""; 167 | }; 168 | /* End PBXGroup section */ 169 | 170 | /* Begin PBXNativeTarget section */ 171 | 607FACCF1AFB9204008FA782 /* Fuse_Example */ = { 172 | isa = PBXNativeTarget; 173 | buildConfigurationList = 607FACEF1AFB9204008FA782 /* Build configuration list for PBXNativeTarget "Fuse_Example" */; 174 | buildPhases = ( 175 | 66196B6FD127DADFD4AE26F3 /* [CP] Check Pods Manifest.lock */, 176 | 607FACCC1AFB9204008FA782 /* Sources */, 177 | 607FACCD1AFB9204008FA782 /* Frameworks */, 178 | 607FACCE1AFB9204008FA782 /* Resources */, 179 | C7173CF9B695D206E94B8099 /* [CP] Embed Pods Frameworks */, 180 | 5F1DE9207259937DD137CB0A /* [CP] Copy Pods Resources */, 181 | ); 182 | buildRules = ( 183 | ); 184 | dependencies = ( 185 | ); 186 | name = Fuse_Example; 187 | productName = Fuse; 188 | productReference = 607FACD01AFB9204008FA782 /* Fuse_Example.app */; 189 | productType = "com.apple.product-type.application"; 190 | }; 191 | 607FACE41AFB9204008FA782 /* Fuse_Tests */ = { 192 | isa = PBXNativeTarget; 193 | buildConfigurationList = 607FACF21AFB9204008FA782 /* Build configuration list for PBXNativeTarget "Fuse_Tests" */; 194 | buildPhases = ( 195 | B8BCA300EF0D6CF885B39503 /* [CP] Check Pods Manifest.lock */, 196 | 607FACE11AFB9204008FA782 /* Sources */, 197 | 607FACE21AFB9204008FA782 /* Frameworks */, 198 | 607FACE31AFB9204008FA782 /* Resources */, 199 | 7BC6319D659B2E8E3EAD2906 /* [CP] Embed Pods Frameworks */, 200 | 3B04A25986E9E887F3ED6B3E /* [CP] Copy Pods Resources */, 201 | ); 202 | buildRules = ( 203 | ); 204 | dependencies = ( 205 | 607FACE71AFB9204008FA782 /* PBXTargetDependency */, 206 | ); 207 | name = Fuse_Tests; 208 | productName = Tests; 209 | productReference = 607FACE51AFB9204008FA782 /* Fuse_Tests.xctest */; 210 | productType = "com.apple.product-type.bundle.unit-test"; 211 | }; 212 | /* End PBXNativeTarget section */ 213 | 214 | /* Begin PBXProject section */ 215 | 607FACC81AFB9204008FA782 /* Project object */ = { 216 | isa = PBXProject; 217 | attributes = { 218 | LastSwiftUpdateCheck = 0720; 219 | LastUpgradeCheck = 1130; 220 | ORGANIZATIONNAME = CocoaPods; 221 | TargetAttributes = { 222 | 607FACCF1AFB9204008FA782 = { 223 | CreatedOnToolsVersion = 6.3.1; 224 | LastSwiftMigration = 1130; 225 | }; 226 | 607FACE41AFB9204008FA782 = { 227 | CreatedOnToolsVersion = 6.3.1; 228 | LastSwiftMigration = 1130; 229 | TestTargetID = 607FACCF1AFB9204008FA782; 230 | }; 231 | }; 232 | }; 233 | buildConfigurationList = 607FACCB1AFB9204008FA782 /* Build configuration list for PBXProject "Fuse" */; 234 | compatibilityVersion = "Xcode 3.2"; 235 | developmentRegion = en; 236 | hasScannedForEncodings = 0; 237 | knownRegions = ( 238 | en, 239 | Base, 240 | ); 241 | mainGroup = 607FACC71AFB9204008FA782; 242 | productRefGroup = 607FACD11AFB9204008FA782 /* Products */; 243 | projectDirPath = ""; 244 | projectRoot = ""; 245 | targets = ( 246 | 607FACCF1AFB9204008FA782 /* Fuse_Example */, 247 | 607FACE41AFB9204008FA782 /* Fuse_Tests */, 248 | ); 249 | }; 250 | /* End PBXProject section */ 251 | 252 | /* Begin PBXResourcesBuildPhase section */ 253 | 607FACCE1AFB9204008FA782 /* Resources */ = { 254 | isa = PBXResourcesBuildPhase; 255 | buildActionMask = 2147483647; 256 | files = ( 257 | 607FACDB1AFB9204008FA782 /* Main.storyboard in Resources */, 258 | 48921A8A1EDDB274009C962E /* books.txt in Resources */, 259 | 607FACE01AFB9204008FA782 /* LaunchScreen.xib in Resources */, 260 | 607FACDD1AFB9204008FA782 /* Images.xcassets in Resources */, 261 | ); 262 | runOnlyForDeploymentPostprocessing = 0; 263 | }; 264 | 607FACE31AFB9204008FA782 /* Resources */ = { 265 | isa = PBXResourcesBuildPhase; 266 | buildActionMask = 2147483647; 267 | files = ( 268 | 48921A8B1EDDB274009C962E /* books.txt in Resources */, 269 | ); 270 | runOnlyForDeploymentPostprocessing = 0; 271 | }; 272 | /* End PBXResourcesBuildPhase section */ 273 | 274 | /* Begin PBXShellScriptBuildPhase section */ 275 | 3B04A25986E9E887F3ED6B3E /* [CP] Copy Pods Resources */ = { 276 | isa = PBXShellScriptBuildPhase; 277 | buildActionMask = 2147483647; 278 | files = ( 279 | ); 280 | inputPaths = ( 281 | ); 282 | name = "[CP] Copy Pods Resources"; 283 | outputPaths = ( 284 | ); 285 | runOnlyForDeploymentPostprocessing = 0; 286 | shellPath = /bin/sh; 287 | shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-Fuse_Tests/Pods-Fuse_Tests-resources.sh\"\n"; 288 | showEnvVarsInLog = 0; 289 | }; 290 | 5F1DE9207259937DD137CB0A /* [CP] Copy Pods Resources */ = { 291 | isa = PBXShellScriptBuildPhase; 292 | buildActionMask = 2147483647; 293 | files = ( 294 | ); 295 | inputPaths = ( 296 | ); 297 | name = "[CP] Copy Pods Resources"; 298 | outputPaths = ( 299 | ); 300 | runOnlyForDeploymentPostprocessing = 0; 301 | shellPath = /bin/sh; 302 | shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-Fuse_Example/Pods-Fuse_Example-resources.sh\"\n"; 303 | showEnvVarsInLog = 0; 304 | }; 305 | 66196B6FD127DADFD4AE26F3 /* [CP] Check Pods Manifest.lock */ = { 306 | isa = PBXShellScriptBuildPhase; 307 | buildActionMask = 2147483647; 308 | files = ( 309 | ); 310 | inputPaths = ( 311 | ); 312 | name = "[CP] Check Pods Manifest.lock"; 313 | outputPaths = ( 314 | ); 315 | runOnlyForDeploymentPostprocessing = 0; 316 | shellPath = /bin/sh; 317 | shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n"; 318 | showEnvVarsInLog = 0; 319 | }; 320 | 7BC6319D659B2E8E3EAD2906 /* [CP] Embed Pods Frameworks */ = { 321 | isa = PBXShellScriptBuildPhase; 322 | buildActionMask = 2147483647; 323 | files = ( 324 | ); 325 | inputPaths = ( 326 | ); 327 | name = "[CP] Embed Pods Frameworks"; 328 | outputPaths = ( 329 | ); 330 | runOnlyForDeploymentPostprocessing = 0; 331 | shellPath = /bin/sh; 332 | shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-Fuse_Tests/Pods-Fuse_Tests-frameworks.sh\"\n"; 333 | showEnvVarsInLog = 0; 334 | }; 335 | B8BCA300EF0D6CF885B39503 /* [CP] Check Pods Manifest.lock */ = { 336 | isa = PBXShellScriptBuildPhase; 337 | buildActionMask = 2147483647; 338 | files = ( 339 | ); 340 | inputPaths = ( 341 | ); 342 | name = "[CP] Check Pods Manifest.lock"; 343 | outputPaths = ( 344 | ); 345 | runOnlyForDeploymentPostprocessing = 0; 346 | shellPath = /bin/sh; 347 | shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n"; 348 | showEnvVarsInLog = 0; 349 | }; 350 | C7173CF9B695D206E94B8099 /* [CP] Embed Pods Frameworks */ = { 351 | isa = PBXShellScriptBuildPhase; 352 | buildActionMask = 2147483647; 353 | files = ( 354 | ); 355 | inputPaths = ( 356 | ); 357 | name = "[CP] Embed Pods Frameworks"; 358 | outputPaths = ( 359 | ); 360 | runOnlyForDeploymentPostprocessing = 0; 361 | shellPath = /bin/sh; 362 | shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-Fuse_Example/Pods-Fuse_Example-frameworks.sh\"\n"; 363 | showEnvVarsInLog = 0; 364 | }; 365 | /* End PBXShellScriptBuildPhase section */ 366 | 367 | /* Begin PBXSourcesBuildPhase section */ 368 | 607FACCC1AFB9204008FA782 /* Sources */ = { 369 | isa = PBXSourcesBuildPhase; 370 | buildActionMask = 2147483647; 371 | files = ( 372 | 607FACD81AFB9204008FA782 /* ViewController.swift in Sources */, 373 | 607FACD61AFB9204008FA782 /* AppDelegate.swift in Sources */, 374 | ); 375 | runOnlyForDeploymentPostprocessing = 0; 376 | }; 377 | 607FACE11AFB9204008FA782 /* Sources */ = { 378 | isa = PBXSourcesBuildPhase; 379 | buildActionMask = 2147483647; 380 | files = ( 381 | 4844BD6B1EB943E7001795FB /* Tests.swift in Sources */, 382 | ); 383 | runOnlyForDeploymentPostprocessing = 0; 384 | }; 385 | /* End PBXSourcesBuildPhase section */ 386 | 387 | /* Begin PBXTargetDependency section */ 388 | 607FACE71AFB9204008FA782 /* PBXTargetDependency */ = { 389 | isa = PBXTargetDependency; 390 | target = 607FACCF1AFB9204008FA782 /* Fuse_Example */; 391 | targetProxy = 607FACE61AFB9204008FA782 /* PBXContainerItemProxy */; 392 | }; 393 | /* End PBXTargetDependency section */ 394 | 395 | /* Begin PBXVariantGroup section */ 396 | 607FACD91AFB9204008FA782 /* Main.storyboard */ = { 397 | isa = PBXVariantGroup; 398 | children = ( 399 | 607FACDA1AFB9204008FA782 /* Base */, 400 | ); 401 | name = Main.storyboard; 402 | sourceTree = ""; 403 | }; 404 | 607FACDE1AFB9204008FA782 /* LaunchScreen.xib */ = { 405 | isa = PBXVariantGroup; 406 | children = ( 407 | 607FACDF1AFB9204008FA782 /* Base */, 408 | ); 409 | name = LaunchScreen.xib; 410 | sourceTree = ""; 411 | }; 412 | /* End PBXVariantGroup section */ 413 | 414 | /* Begin XCBuildConfiguration section */ 415 | 607FACED1AFB9204008FA782 /* Debug */ = { 416 | isa = XCBuildConfiguration; 417 | buildSettings = { 418 | ALWAYS_SEARCH_USER_PATHS = NO; 419 | CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; 420 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 421 | CLANG_CXX_LIBRARY = "libc++"; 422 | CLANG_ENABLE_MODULES = YES; 423 | CLANG_ENABLE_OBJC_ARC = YES; 424 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 425 | CLANG_WARN_BOOL_CONVERSION = YES; 426 | CLANG_WARN_COMMA = YES; 427 | CLANG_WARN_CONSTANT_CONVERSION = YES; 428 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 429 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 430 | CLANG_WARN_EMPTY_BODY = YES; 431 | CLANG_WARN_ENUM_CONVERSION = YES; 432 | CLANG_WARN_INFINITE_RECURSION = YES; 433 | CLANG_WARN_INT_CONVERSION = YES; 434 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 435 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 436 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 437 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 438 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 439 | CLANG_WARN_STRICT_PROTOTYPES = YES; 440 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 441 | CLANG_WARN_UNREACHABLE_CODE = YES; 442 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 443 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 444 | COPY_PHASE_STRIP = NO; 445 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 446 | ENABLE_STRICT_OBJC_MSGSEND = YES; 447 | ENABLE_TESTABILITY = YES; 448 | GCC_C_LANGUAGE_STANDARD = gnu99; 449 | GCC_DYNAMIC_NO_PIC = NO; 450 | GCC_NO_COMMON_BLOCKS = YES; 451 | GCC_OPTIMIZATION_LEVEL = 0; 452 | GCC_PREPROCESSOR_DEFINITIONS = ( 453 | "DEBUG=1", 454 | "$(inherited)", 455 | ); 456 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 457 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 458 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 459 | GCC_WARN_UNDECLARED_SELECTOR = YES; 460 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 461 | GCC_WARN_UNUSED_FUNCTION = YES; 462 | GCC_WARN_UNUSED_VARIABLE = YES; 463 | IPHONEOS_DEPLOYMENT_TARGET = 8.3; 464 | MTL_ENABLE_DEBUG_INFO = YES; 465 | ONLY_ACTIVE_ARCH = YES; 466 | SDKROOT = iphoneos; 467 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 468 | SWIFT_SWIFT3_OBJC_INFERENCE = Default; 469 | SWIFT_VERSION = 5.0; 470 | }; 471 | name = Debug; 472 | }; 473 | 607FACEE1AFB9204008FA782 /* Release */ = { 474 | isa = XCBuildConfiguration; 475 | buildSettings = { 476 | ALWAYS_SEARCH_USER_PATHS = NO; 477 | CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; 478 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 479 | CLANG_CXX_LIBRARY = "libc++"; 480 | CLANG_ENABLE_MODULES = YES; 481 | CLANG_ENABLE_OBJC_ARC = YES; 482 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 483 | CLANG_WARN_BOOL_CONVERSION = YES; 484 | CLANG_WARN_COMMA = YES; 485 | CLANG_WARN_CONSTANT_CONVERSION = YES; 486 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 487 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 488 | CLANG_WARN_EMPTY_BODY = YES; 489 | CLANG_WARN_ENUM_CONVERSION = YES; 490 | CLANG_WARN_INFINITE_RECURSION = YES; 491 | CLANG_WARN_INT_CONVERSION = YES; 492 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 493 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 494 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 495 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 496 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 497 | CLANG_WARN_STRICT_PROTOTYPES = YES; 498 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 499 | CLANG_WARN_UNREACHABLE_CODE = YES; 500 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 501 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 502 | COPY_PHASE_STRIP = NO; 503 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 504 | ENABLE_NS_ASSERTIONS = NO; 505 | ENABLE_STRICT_OBJC_MSGSEND = YES; 506 | GCC_C_LANGUAGE_STANDARD = gnu99; 507 | GCC_NO_COMMON_BLOCKS = YES; 508 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 509 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 510 | GCC_WARN_UNDECLARED_SELECTOR = YES; 511 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 512 | GCC_WARN_UNUSED_FUNCTION = YES; 513 | GCC_WARN_UNUSED_VARIABLE = YES; 514 | IPHONEOS_DEPLOYMENT_TARGET = 8.3; 515 | MTL_ENABLE_DEBUG_INFO = NO; 516 | SDKROOT = iphoneos; 517 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 518 | SWIFT_SWIFT3_OBJC_INFERENCE = Default; 519 | SWIFT_VERSION = 5.0; 520 | VALIDATE_PRODUCT = YES; 521 | }; 522 | name = Release; 523 | }; 524 | 607FACF01AFB9204008FA782 /* Debug */ = { 525 | isa = XCBuildConfiguration; 526 | baseConfigurationReference = 7B52258F584C287095B35C30 /* Pods-Fuse_Example.debug.xcconfig */; 527 | buildSettings = { 528 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 529 | INFOPLIST_FILE = Fuse/Info.plist; 530 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 531 | MODULE_NAME = ExampleApp; 532 | PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.demo.$(PRODUCT_NAME:rfc1034identifier)"; 533 | PRODUCT_NAME = "$(TARGET_NAME)"; 534 | SWIFT_SWIFT3_OBJC_INFERENCE = Default; 535 | SWIFT_VERSION = 5.0; 536 | }; 537 | name = Debug; 538 | }; 539 | 607FACF11AFB9204008FA782 /* Release */ = { 540 | isa = XCBuildConfiguration; 541 | baseConfigurationReference = 6984CC3FED9508E14D3E7291 /* Pods-Fuse_Example.release.xcconfig */; 542 | buildSettings = { 543 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 544 | INFOPLIST_FILE = Fuse/Info.plist; 545 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 546 | MODULE_NAME = ExampleApp; 547 | PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.demo.$(PRODUCT_NAME:rfc1034identifier)"; 548 | PRODUCT_NAME = "$(TARGET_NAME)"; 549 | SWIFT_SWIFT3_OBJC_INFERENCE = Default; 550 | SWIFT_VERSION = 5.0; 551 | }; 552 | name = Release; 553 | }; 554 | 607FACF31AFB9204008FA782 /* Debug */ = { 555 | isa = XCBuildConfiguration; 556 | baseConfigurationReference = C309EAED0BB1FAEB482B6657 /* Pods-Fuse_Tests.debug.xcconfig */; 557 | buildSettings = { 558 | FRAMEWORK_SEARCH_PATHS = ( 559 | "$(SDKROOT)/Developer/Library/Frameworks", 560 | "$(inherited)", 561 | ); 562 | GCC_PREPROCESSOR_DEFINITIONS = ( 563 | "DEBUG=1", 564 | "$(inherited)", 565 | ); 566 | INFOPLIST_FILE = Tests/Info.plist; 567 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 568 | PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.$(PRODUCT_NAME:rfc1034identifier)"; 569 | PRODUCT_NAME = "$(TARGET_NAME)"; 570 | SWIFT_SWIFT3_OBJC_INFERENCE = Default; 571 | SWIFT_VERSION = 5.0; 572 | }; 573 | name = Debug; 574 | }; 575 | 607FACF41AFB9204008FA782 /* Release */ = { 576 | isa = XCBuildConfiguration; 577 | baseConfigurationReference = 24C0655B65E36704B5A61F1D /* Pods-Fuse_Tests.release.xcconfig */; 578 | buildSettings = { 579 | FRAMEWORK_SEARCH_PATHS = ( 580 | "$(SDKROOT)/Developer/Library/Frameworks", 581 | "$(inherited)", 582 | ); 583 | INFOPLIST_FILE = Tests/Info.plist; 584 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 585 | PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.$(PRODUCT_NAME:rfc1034identifier)"; 586 | PRODUCT_NAME = "$(TARGET_NAME)"; 587 | SWIFT_SWIFT3_OBJC_INFERENCE = Default; 588 | SWIFT_VERSION = 5.0; 589 | }; 590 | name = Release; 591 | }; 592 | /* End XCBuildConfiguration section */ 593 | 594 | /* Begin XCConfigurationList section */ 595 | 607FACCB1AFB9204008FA782 /* Build configuration list for PBXProject "Fuse" */ = { 596 | isa = XCConfigurationList; 597 | buildConfigurations = ( 598 | 607FACED1AFB9204008FA782 /* Debug */, 599 | 607FACEE1AFB9204008FA782 /* Release */, 600 | ); 601 | defaultConfigurationIsVisible = 0; 602 | defaultConfigurationName = Release; 603 | }; 604 | 607FACEF1AFB9204008FA782 /* Build configuration list for PBXNativeTarget "Fuse_Example" */ = { 605 | isa = XCConfigurationList; 606 | buildConfigurations = ( 607 | 607FACF01AFB9204008FA782 /* Debug */, 608 | 607FACF11AFB9204008FA782 /* Release */, 609 | ); 610 | defaultConfigurationIsVisible = 0; 611 | defaultConfigurationName = Release; 612 | }; 613 | 607FACF21AFB9204008FA782 /* Build configuration list for PBXNativeTarget "Fuse_Tests" */ = { 614 | isa = XCConfigurationList; 615 | buildConfigurations = ( 616 | 607FACF31AFB9204008FA782 /* Debug */, 617 | 607FACF41AFB9204008FA782 /* Release */, 618 | ); 619 | defaultConfigurationIsVisible = 0; 620 | defaultConfigurationName = Release; 621 | }; 622 | /* End XCConfigurationList section */ 623 | }; 624 | rootObject = 607FACC81AFB9204008FA782 /* Project object */; 625 | } 626 | -------------------------------------------------------------------------------- /Example/Fuse.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Example/Fuse.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Example/Fuse.xcodeproj/xcshareddata/xcbaselines/607FACE41AFB9204008FA782.xcbaseline/A2C327BE-B522-4045-BDF0-E578A6EF0914.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | classNames 6 | 7 | Tests 8 | 9 | testPerformanceAsync() 10 | 11 | com.apple.XCTPerformanceMetric_WallClockTime 12 | 13 | baselineAverage 14 | 0.441 15 | baselineIntegrationDisplayName 16 | Local Baseline 17 | 18 | 19 | testPerformanceSync() 20 | 21 | com.apple.XCTPerformanceMetric_WallClockTime 22 | 23 | baselineAverage 24 | 0.441 25 | baselineIntegrationDisplayName 26 | Local Baseline 27 | 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /Example/Fuse.xcodeproj/xcshareddata/xcbaselines/607FACE41AFB9204008FA782.xcbaseline/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | runDestinationsByUUID 6 | 7 | A2C327BE-B522-4045-BDF0-E578A6EF0914 8 | 9 | localComputer 10 | 11 | busSpeedInMHz 12 | 100 13 | cpuCount 14 | 1 15 | cpuKind 16 | Intel Core i7 17 | cpuSpeedInMHz 18 | 2800 19 | logicalCPUCoresPerPackage 20 | 8 21 | modelCode 22 | MacBookPro11,3 23 | physicalCPUCoresPerPackage 24 | 4 25 | platformIdentifier 26 | com.apple.platform.macosx 27 | 28 | targetArchitecture 29 | x86_64 30 | targetDevice 31 | 32 | modelCode 33 | iPhone9,2 34 | platformIdentifier 35 | com.apple.platform.iphonesimulator 36 | 37 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /Example/Fuse.xcodeproj/xcshareddata/xcschemes/Fuse-Example.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 29 | 35 | 36 | 37 | 38 | 39 | 44 | 45 | 51 | 52 | 53 | 54 | 56 | 62 | 63 | 64 | 65 | 66 | 76 | 78 | 84 | 85 | 86 | 87 | 93 | 95 | 101 | 102 | 103 | 104 | 106 | 107 | 110 | 111 | 112 | -------------------------------------------------------------------------------- /Example/Fuse.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /Example/Fuse.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Example/Fuse/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // Fuse 4 | // 5 | // Created by Kirollos Risk on 05/02/2017. 6 | // Copyright (c) 2017 Kirollos Risk. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | @UIApplicationMain 12 | class AppDelegate: UIResponder, UIApplicationDelegate { 13 | 14 | var window: UIWindow? 15 | 16 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 17 | UISearchBar.appearance().barTintColor = UIColor.candyGreen() 18 | UISearchBar.appearance().tintColor = UIColor.white 19 | 20 | return true 21 | } 22 | } 23 | 24 | extension UIColor { 25 | static func candyGreen() -> UIColor { 26 | return UIColor(red: 67.0/255.0, green: 205.0/255.0, blue: 135.0/255.0, alpha: 1.0) 27 | } 28 | } 29 | 30 | -------------------------------------------------------------------------------- /Example/Fuse/Base.lproj/LaunchScreen.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 20 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /Example/Fuse/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 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 | -------------------------------------------------------------------------------- /Example/Fuse/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "29x29", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "29x29", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "40x40", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "40x40", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "60x60", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "60x60", 31 | "scale" : "3x" 32 | } 33 | ], 34 | "info" : { 35 | "version" : 1, 36 | "author" : "xcode" 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Example/Fuse/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 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 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIMainStoryboardFile 28 | Main 29 | UIRequiredDeviceCapabilities 30 | 31 | armv7 32 | 33 | UISupportedInterfaceOrientations 34 | 35 | UIInterfaceOrientationPortrait 36 | UIInterfaceOrientationLandscapeLeft 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /Example/Fuse/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // Fuse 4 | // 5 | // Created by Kirollos Risk on 05/02/2017. 6 | // Copyright (c) 2017 Kirollos Risk. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import Fuse 11 | 12 | struct Item { 13 | let name : String 14 | } 15 | 16 | class ViewController: UITableViewController { 17 | 18 | // MARK: - Properties 19 | var books = [String]() 20 | var filteredBooks = [NSAttributedString]() 21 | let fuse = Fuse() 22 | 23 | let searchController = UISearchController(searchResultsController: nil) 24 | 25 | // MARK: - View Setup 26 | override func viewDidLoad() { 27 | super.viewDidLoad() 28 | 29 | // Setup the Search Controller 30 | searchController.searchResultsUpdater = self 31 | searchController.searchBar.delegate = self 32 | definesPresentationContext = true 33 | searchController.dimsBackgroundDuringPresentation = false 34 | 35 | // Setup the Scope Bar 36 | tableView.tableHeaderView = searchController.searchBar 37 | 38 | books = [ 39 | "Angels & Demons", 40 | "Old Man's War", 41 | "The Lock Artist", 42 | "HTML5", 43 | "Right Ho Jeeves", 44 | "The Code of the Wooster", 45 | "Thank You Jeeves", 46 | "The DaVinci Code", 47 | "The Silmarillion", 48 | "Syrup", 49 | "The Lost Symbol", 50 | "The Book of Lies", 51 | "Lamb", 52 | "Fool", 53 | "Incompetence", 54 | "Fat", 55 | "Colony", 56 | "Backwards, Red Dwarf", 57 | "The Grand Design", 58 | "The Book of Samson", 59 | "The Preservationist", 60 | "Fallen", 61 | "Monster 1959" 62 | ] 63 | } 64 | 65 | override func didReceiveMemoryWarning() { 66 | super.didReceiveMemoryWarning() 67 | } 68 | 69 | // MARK: - Table View 70 | override func numberOfSections(in tableView: UITableView) -> Int { 71 | return 1 72 | } 73 | 74 | override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 75 | if searchController.isActive && searchController.searchBar.text != "" { 76 | return filteredBooks.count 77 | } 78 | return books.count 79 | } 80 | 81 | override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 82 | let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) 83 | let item: NSAttributedString 84 | 85 | if searchController.isActive && searchController.searchBar.text != "" { 86 | item = filteredBooks[indexPath.row] 87 | } else { 88 | item = NSAttributedString(string: books[indexPath.row]) 89 | } 90 | 91 | cell.textLabel!.attributedText = item 92 | 93 | return cell 94 | } 95 | 96 | func filterContentForSearchText(_ searchText: String) { 97 | let boldAttrs = [ 98 | NSAttributedString.Key.font : UIFont.boldSystemFont(ofSize: 17), 99 | NSAttributedString.Key.foregroundColor: UIColor.blue 100 | ] 101 | 102 | let results = fuse.search(searchText, in: books) 103 | 104 | filteredBooks = results.map { (index, _, matchedRanges) in 105 | let book = books[index] 106 | 107 | let attributedString = NSMutableAttributedString(string: book) 108 | matchedRanges 109 | .map(Range.init) 110 | .map(NSRange.init) 111 | .forEach { 112 | attributedString.addAttributes(boldAttrs, range: $0) 113 | } 114 | 115 | return attributedString 116 | } 117 | 118 | tableView.reloadData() 119 | } 120 | 121 | } 122 | 123 | extension ViewController: UISearchBarDelegate { 124 | // MARK: - UISearchBar Delegate 125 | func searchBar(_ searchBar: UISearchBar, selectedScopeButtonIndexDidChange selectedScope: Int) { 126 | // TODO: can run this on a background queue, and then reload the tableview back on the main queue 127 | filterContentForSearchText(searchBar.text!) 128 | } 129 | } 130 | 131 | extension ViewController: UISearchResultsUpdating { 132 | // MARK: - UISearchResultsUpdating Delegate 133 | func updateSearchResults(for searchController: UISearchController) { 134 | filterContentForSearchText(searchController.searchBar.text!) 135 | } 136 | } 137 | -------------------------------------------------------------------------------- /Example/Podfile: -------------------------------------------------------------------------------- 1 | use_frameworks! 2 | 3 | target 'Fuse_Example' do 4 | pod 'Fuse', :path => '../' 5 | end 6 | 7 | target 'Fuse_Tests' do 8 | pod 'Fuse', :path => '../' 9 | end 10 | 11 | -------------------------------------------------------------------------------- /Example/Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - Fuse (0.2.0) 3 | 4 | DEPENDENCIES: 5 | - Fuse (from `../`) 6 | 7 | EXTERNAL SOURCES: 8 | Fuse: 9 | :path: "../" 10 | 11 | SPEC CHECKSUMS: 12 | Fuse: 7ed32f81c57006ade4221cf8d74ebf2b0d98df89 13 | 14 | PODFILE CHECKSUM: c8375e5aa0cd9dce10b0f856724ebce2798b66d3 15 | 16 | COCOAPODS: 1.2.1 17 | -------------------------------------------------------------------------------- /Example/Pods/Local Podspecs/Fuse.podspec.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Fuse", 3 | "version": "0.2.0", 4 | "summary": "Fuzzy searching.", 5 | "description": "A lightweight fuzzy-search library, with zero dependencies", 6 | "homepage": "https://github.com/krisk/fuse-swift", 7 | "license": { 8 | "type": "MIT", 9 | "file": "LICENSE" 10 | }, 11 | "authors": { 12 | "Kirollos Risk": "kirollos@gmail.com" 13 | }, 14 | "source": { 15 | "git": "https://github.com/krisk/fuse-swift.git", 16 | "tag": "0.2.0" 17 | }, 18 | "social_media_url": "https://twitter.com/kirorisk", 19 | "platforms": { 20 | "ios": "8.0" 21 | }, 22 | "source_files": "Fuse/Classes/**/*" 23 | } 24 | -------------------------------------------------------------------------------- /Example/Pods/Manifest.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - Fuse (0.2.0) 3 | 4 | DEPENDENCIES: 5 | - Fuse (from `../`) 6 | 7 | EXTERNAL SOURCES: 8 | Fuse: 9 | :path: "../" 10 | 11 | SPEC CHECKSUMS: 12 | Fuse: 7ed32f81c57006ade4221cf8d74ebf2b0d98df89 13 | 14 | PODFILE CHECKSUM: c8375e5aa0cd9dce10b0f856724ebce2798b66d3 15 | 16 | COCOAPODS: 1.2.1 17 | -------------------------------------------------------------------------------- /Example/Pods/Pods.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 0A7AE8C8C9B97E81A8730E3439CC640C /* FuseUtilities.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1CBCA0A350935B7FE455D78D583A3647 /* FuseUtilities.swift */; }; 11 | 2FA058DDF27CFCAA6C3EDCC3E011DB28 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6604A7D69453B4569E4E4827FB9155A9 /* Foundation.framework */; }; 12 | 37E129C05FAB8D7464E78B59B8D9B278 /* String+Fuse.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9ADB0803F026CFBC246952510AD8A8B2 /* String+Fuse.swift */; }; 13 | 540AC6DBBBE501625C893A538711B0AA /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6604A7D69453B4569E4E4827FB9155A9 /* Foundation.framework */; }; 14 | 54CC484509F64F7CD992A7F84D309C4D /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6604A7D69453B4569E4E4827FB9155A9 /* Foundation.framework */; }; 15 | 5694BF7EB997C802B20912A8AA5D5E83 /* Fuse-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 8E382BC5FD9069251E07719075FAAA2F /* Fuse-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; 16 | 7E0A401710560F686B743A74BA473119 /* Pods-Fuse_Example-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 419D9AFED7E7FE6FA2EA5F0036D3B83E /* Pods-Fuse_Example-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; 17 | 925C053E3781A9FE4360557296CD10CA /* Pods-Fuse_Tests-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 08791F25287CF5ABE72A1149C6151107 /* Pods-Fuse_Tests-dummy.m */; }; 18 | AC936D4C5B825DBD4003B0421E820EEE /* Fuse.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7ABB1DE6B2E1A7DA89DC01335DEB28C1 /* Fuse.swift */; }; 19 | C612183500C54DC7D2F07F8D768EE3D4 /* Fuse-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 528D3A8E625E7EF6007E9D70CF9B4D0B /* Fuse-dummy.m */; }; 20 | CB51FA52485D63BD4D99CEA63AD8F280 /* Pods-Fuse_Tests-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = E71B65143B2DC9A5BCA25E14CEDDCC25 /* Pods-Fuse_Tests-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; 21 | DB7173C1B5D97758CD783151BAE04D2D /* Pods-Fuse_Example-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 986155D8D829D88F72C6D4191F3E772B /* Pods-Fuse_Example-dummy.m */; }; 22 | /* End PBXBuildFile section */ 23 | 24 | /* Begin PBXContainerItemProxy section */ 25 | 50ABAE40C87D337524215E9B541D6C58 /* PBXContainerItemProxy */ = { 26 | isa = PBXContainerItemProxy; 27 | containerPortal = D41D8CD98F00B204E9800998ECF8427E /* Project object */; 28 | proxyType = 1; 29 | remoteGlobalIDString = B8CD3B3EDB42EEABB2D487F8706AF6BB; 30 | remoteInfo = Fuse; 31 | }; 32 | 9F466D6708503C8577FEEDFFCD87FDA9 /* PBXContainerItemProxy */ = { 33 | isa = PBXContainerItemProxy; 34 | containerPortal = D41D8CD98F00B204E9800998ECF8427E /* Project object */; 35 | proxyType = 1; 36 | remoteGlobalIDString = B8CD3B3EDB42EEABB2D487F8706AF6BB; 37 | remoteInfo = Fuse; 38 | }; 39 | /* End PBXContainerItemProxy section */ 40 | 41 | /* Begin PBXFileReference section */ 42 | 08791F25287CF5ABE72A1149C6151107 /* Pods-Fuse_Tests-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Pods-Fuse_Tests-dummy.m"; sourceTree = ""; }; 43 | 0F2A2853D335DDFDFF81C6CFC354E42D /* Fuse.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = "sourcecode.module-map"; path = Fuse.modulemap; sourceTree = ""; }; 44 | 1CBCA0A350935B7FE455D78D583A3647 /* FuseUtilities.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = FuseUtilities.swift; sourceTree = ""; }; 45 | 2D4CC22E8530C8ACC0306265C571D4E5 /* Pods_Fuse_Tests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Fuse_Tests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 46 | 3873A13FD660FBEAE3C468C0ED27AE48 /* Pods-Fuse_Tests.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = "sourcecode.module-map"; path = "Pods-Fuse_Tests.modulemap"; sourceTree = ""; }; 47 | 40ABE245F79C0F86BAC208D0B0E01C39 /* Pods-Fuse_Example-acknowledgements.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-Fuse_Example-acknowledgements.plist"; sourceTree = ""; }; 48 | 4110AA0D8B7F7A89858EAD985A37C370 /* Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 49 | 419D9AFED7E7FE6FA2EA5F0036D3B83E /* Pods-Fuse_Example-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Pods-Fuse_Example-umbrella.h"; sourceTree = ""; }; 50 | 43156C42100B06C82754BCD27E07BC31 /* Pods-Fuse_Example.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-Fuse_Example.release.xcconfig"; sourceTree = ""; }; 51 | 4EF9D76133B72D6D143DDB49D5A9D91F /* Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 52 | 514C5646826A7D65032B772A5D8662C8 /* Pods-Fuse_Example.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-Fuse_Example.debug.xcconfig"; sourceTree = ""; }; 53 | 51CD0AE6796F692A063F33632D47C923 /* Fuse.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Fuse.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 54 | 528D3A8E625E7EF6007E9D70CF9B4D0B /* Fuse-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Fuse-dummy.m"; sourceTree = ""; }; 55 | 54DBC22221D1AE1479A57A8A9AE40651 /* Pods-Fuse_Tests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-Fuse_Tests.debug.xcconfig"; sourceTree = ""; }; 56 | 5A8A4322643A7898CE6D1EEEB5D190D2 /* Pods-Fuse_Tests-acknowledgements.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-Fuse_Tests-acknowledgements.plist"; sourceTree = ""; }; 57 | 6604A7D69453B4569E4E4827FB9155A9 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS10.3.sdk/System/Library/Frameworks/Foundation.framework; sourceTree = DEVELOPER_DIR; }; 58 | 6614B36C19D0EA2C208303F68C5C0BDA /* Pods-Fuse_Tests-acknowledgements.markdown */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; path = "Pods-Fuse_Tests-acknowledgements.markdown"; sourceTree = ""; }; 59 | 720A29575E509191EF365EFDFE1727C1 /* Fuse-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Fuse-prefix.pch"; sourceTree = ""; }; 60 | 7ABB1DE6B2E1A7DA89DC01335DEB28C1 /* Fuse.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = Fuse.swift; sourceTree = ""; }; 61 | 8E382BC5FD9069251E07719075FAAA2F /* Fuse-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Fuse-umbrella.h"; sourceTree = ""; }; 62 | 93A4A3777CF96A4AAC1D13BA6DCCEA73 /* Podfile */ = {isa = PBXFileReference; explicitFileType = text.script.ruby; includeInIndex = 1; name = Podfile; path = ../Podfile; sourceTree = SOURCE_ROOT; xcLanguageSpecificationIdentifier = xcode.lang.ruby; }; 63 | 986155D8D829D88F72C6D4191F3E772B /* Pods-Fuse_Example-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Pods-Fuse_Example-dummy.m"; sourceTree = ""; }; 64 | 9985815ABFAB434360A5E2F63DD215EC /* Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 65 | 9ADB0803F026CFBC246952510AD8A8B2 /* String+Fuse.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = "String+Fuse.swift"; sourceTree = ""; }; 66 | 9C78C50C1DE0FC52741C43C19AD80C73 /* Pods-Fuse_Example-resources.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-Fuse_Example-resources.sh"; sourceTree = ""; }; 67 | B0B8F6D471015A67024C81799119CFB3 /* Pods_Fuse_Example.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Fuse_Example.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 68 | C2EB5403E6B47B2806CBC65F3CBDDAA5 /* Pods-Fuse_Tests-frameworks.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-Fuse_Tests-frameworks.sh"; sourceTree = ""; }; 69 | C91E4CE35FA0BCA0B50B002BD5A8A19A /* Pods-Fuse_Example-acknowledgements.markdown */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; path = "Pods-Fuse_Example-acknowledgements.markdown"; sourceTree = ""; }; 70 | E71B65143B2DC9A5BCA25E14CEDDCC25 /* Pods-Fuse_Tests-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Pods-Fuse_Tests-umbrella.h"; sourceTree = ""; }; 71 | E72A3AA42A4A288299C681729E573094 /* Pods-Fuse_Tests-resources.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-Fuse_Tests-resources.sh"; sourceTree = ""; }; 72 | F16B6C5BB2B14864ECC251E4362FB486 /* Pods-Fuse_Example-frameworks.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-Fuse_Example-frameworks.sh"; sourceTree = ""; }; 73 | F3AE3F0DB9C00C7D3096AD5FBE449CE7 /* Fuse.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = Fuse.xcconfig; sourceTree = ""; }; 74 | F70AD514E9EEFDA8C64AF436C5D0D846 /* Pods-Fuse_Tests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-Fuse_Tests.release.xcconfig"; sourceTree = ""; }; 75 | FEF00D3642DEEC49401DE31CC3730433 /* Pods-Fuse_Example.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = "sourcecode.module-map"; path = "Pods-Fuse_Example.modulemap"; sourceTree = ""; }; 76 | /* End PBXFileReference section */ 77 | 78 | /* Begin PBXFrameworksBuildPhase section */ 79 | 1AA3A7E7F474091D9C8DEA7660452876 /* Frameworks */ = { 80 | isa = PBXFrameworksBuildPhase; 81 | buildActionMask = 2147483647; 82 | files = ( 83 | 2FA058DDF27CFCAA6C3EDCC3E011DB28 /* Foundation.framework in Frameworks */, 84 | ); 85 | runOnlyForDeploymentPostprocessing = 0; 86 | }; 87 | A94CAD7E49ECDD8E93EE196BE511610A /* Frameworks */ = { 88 | isa = PBXFrameworksBuildPhase; 89 | buildActionMask = 2147483647; 90 | files = ( 91 | 54CC484509F64F7CD992A7F84D309C4D /* Foundation.framework in Frameworks */, 92 | ); 93 | runOnlyForDeploymentPostprocessing = 0; 94 | }; 95 | F1F8437982E2BB266852BCC20F123B1C /* Frameworks */ = { 96 | isa = PBXFrameworksBuildPhase; 97 | buildActionMask = 2147483647; 98 | files = ( 99 | 540AC6DBBBE501625C893A538711B0AA /* Foundation.framework in Frameworks */, 100 | ); 101 | runOnlyForDeploymentPostprocessing = 0; 102 | }; 103 | /* End PBXFrameworksBuildPhase section */ 104 | 105 | /* Begin PBXGroup section */ 106 | 0680A6F20918637DFF2DE668098F9B3A /* Pods-Fuse_Example */ = { 107 | isa = PBXGroup; 108 | children = ( 109 | 4110AA0D8B7F7A89858EAD985A37C370 /* Info.plist */, 110 | FEF00D3642DEEC49401DE31CC3730433 /* Pods-Fuse_Example.modulemap */, 111 | C91E4CE35FA0BCA0B50B002BD5A8A19A /* Pods-Fuse_Example-acknowledgements.markdown */, 112 | 40ABE245F79C0F86BAC208D0B0E01C39 /* Pods-Fuse_Example-acknowledgements.plist */, 113 | 986155D8D829D88F72C6D4191F3E772B /* Pods-Fuse_Example-dummy.m */, 114 | F16B6C5BB2B14864ECC251E4362FB486 /* Pods-Fuse_Example-frameworks.sh */, 115 | 9C78C50C1DE0FC52741C43C19AD80C73 /* Pods-Fuse_Example-resources.sh */, 116 | 419D9AFED7E7FE6FA2EA5F0036D3B83E /* Pods-Fuse_Example-umbrella.h */, 117 | 514C5646826A7D65032B772A5D8662C8 /* Pods-Fuse_Example.debug.xcconfig */, 118 | 43156C42100B06C82754BCD27E07BC31 /* Pods-Fuse_Example.release.xcconfig */, 119 | ); 120 | name = "Pods-Fuse_Example"; 121 | path = "Target Support Files/Pods-Fuse_Example"; 122 | sourceTree = ""; 123 | }; 124 | 0A3D56A1BB75EAD8366954B7757AD77F /* Fuse */ = { 125 | isa = PBXGroup; 126 | children = ( 127 | 0CCC024961F45B6A915FF1294D06A0AF /* Classes */, 128 | ); 129 | path = Fuse; 130 | sourceTree = ""; 131 | }; 132 | 0CCC024961F45B6A915FF1294D06A0AF /* Classes */ = { 133 | isa = PBXGroup; 134 | children = ( 135 | 7ABB1DE6B2E1A7DA89DC01335DEB28C1 /* Fuse.swift */, 136 | 1CBCA0A350935B7FE455D78D583A3647 /* FuseUtilities.swift */, 137 | 9ADB0803F026CFBC246952510AD8A8B2 /* String+Fuse.swift */, 138 | ); 139 | path = Classes; 140 | sourceTree = ""; 141 | }; 142 | 0F29081034F9160F5BEB300C07687117 /* Development Pods */ = { 143 | isa = PBXGroup; 144 | children = ( 145 | F40BF506B6F14142D33981A74BFC718D /* Fuse */, 146 | ); 147 | name = "Development Pods"; 148 | sourceTree = ""; 149 | }; 150 | 19A033A8998E9295ABF3FDB0EA1DA5B9 /* Targets Support Files */ = { 151 | isa = PBXGroup; 152 | children = ( 153 | 0680A6F20918637DFF2DE668098F9B3A /* Pods-Fuse_Example */, 154 | EEDD85C09BFC6C8F53DDC9DED37FEA30 /* Pods-Fuse_Tests */, 155 | ); 156 | name = "Targets Support Files"; 157 | sourceTree = ""; 158 | }; 159 | 3E67CB8AE63537296A06953357B839EA /* Products */ = { 160 | isa = PBXGroup; 161 | children = ( 162 | 51CD0AE6796F692A063F33632D47C923 /* Fuse.framework */, 163 | B0B8F6D471015A67024C81799119CFB3 /* Pods_Fuse_Example.framework */, 164 | 2D4CC22E8530C8ACC0306265C571D4E5 /* Pods_Fuse_Tests.framework */, 165 | ); 166 | name = Products; 167 | sourceTree = ""; 168 | }; 169 | 7DB346D0F39D3F0E887471402A8071AB = { 170 | isa = PBXGroup; 171 | children = ( 172 | 93A4A3777CF96A4AAC1D13BA6DCCEA73 /* Podfile */, 173 | 0F29081034F9160F5BEB300C07687117 /* Development Pods */, 174 | BC3CA7F9E30CC8F7E2DD044DD34432FC /* Frameworks */, 175 | 3E67CB8AE63537296A06953357B839EA /* Products */, 176 | 19A033A8998E9295ABF3FDB0EA1DA5B9 /* Targets Support Files */, 177 | ); 178 | sourceTree = ""; 179 | }; 180 | BC3CA7F9E30CC8F7E2DD044DD34432FC /* Frameworks */ = { 181 | isa = PBXGroup; 182 | children = ( 183 | D35AF013A5F0BAD4F32504907A52519E /* iOS */, 184 | ); 185 | name = Frameworks; 186 | sourceTree = ""; 187 | }; 188 | D35AF013A5F0BAD4F32504907A52519E /* iOS */ = { 189 | isa = PBXGroup; 190 | children = ( 191 | 6604A7D69453B4569E4E4827FB9155A9 /* Foundation.framework */, 192 | ); 193 | name = iOS; 194 | sourceTree = ""; 195 | }; 196 | EEDD85C09BFC6C8F53DDC9DED37FEA30 /* Pods-Fuse_Tests */ = { 197 | isa = PBXGroup; 198 | children = ( 199 | 9985815ABFAB434360A5E2F63DD215EC /* Info.plist */, 200 | 3873A13FD660FBEAE3C468C0ED27AE48 /* Pods-Fuse_Tests.modulemap */, 201 | 6614B36C19D0EA2C208303F68C5C0BDA /* Pods-Fuse_Tests-acknowledgements.markdown */, 202 | 5A8A4322643A7898CE6D1EEEB5D190D2 /* Pods-Fuse_Tests-acknowledgements.plist */, 203 | 08791F25287CF5ABE72A1149C6151107 /* Pods-Fuse_Tests-dummy.m */, 204 | C2EB5403E6B47B2806CBC65F3CBDDAA5 /* Pods-Fuse_Tests-frameworks.sh */, 205 | E72A3AA42A4A288299C681729E573094 /* Pods-Fuse_Tests-resources.sh */, 206 | E71B65143B2DC9A5BCA25E14CEDDCC25 /* Pods-Fuse_Tests-umbrella.h */, 207 | 54DBC22221D1AE1479A57A8A9AE40651 /* Pods-Fuse_Tests.debug.xcconfig */, 208 | F70AD514E9EEFDA8C64AF436C5D0D846 /* Pods-Fuse_Tests.release.xcconfig */, 209 | ); 210 | name = "Pods-Fuse_Tests"; 211 | path = "Target Support Files/Pods-Fuse_Tests"; 212 | sourceTree = ""; 213 | }; 214 | F3BFF3C824F0BA2D758C78EF16640B82 /* Support Files */ = { 215 | isa = PBXGroup; 216 | children = ( 217 | 0F2A2853D335DDFDFF81C6CFC354E42D /* Fuse.modulemap */, 218 | F3AE3F0DB9C00C7D3096AD5FBE449CE7 /* Fuse.xcconfig */, 219 | 528D3A8E625E7EF6007E9D70CF9B4D0B /* Fuse-dummy.m */, 220 | 720A29575E509191EF365EFDFE1727C1 /* Fuse-prefix.pch */, 221 | 8E382BC5FD9069251E07719075FAAA2F /* Fuse-umbrella.h */, 222 | 4EF9D76133B72D6D143DDB49D5A9D91F /* Info.plist */, 223 | ); 224 | name = "Support Files"; 225 | path = "Example/Pods/Target Support Files/Fuse"; 226 | sourceTree = ""; 227 | }; 228 | F40BF506B6F14142D33981A74BFC718D /* Fuse */ = { 229 | isa = PBXGroup; 230 | children = ( 231 | 0A3D56A1BB75EAD8366954B7757AD77F /* Fuse */, 232 | F3BFF3C824F0BA2D758C78EF16640B82 /* Support Files */, 233 | ); 234 | name = Fuse; 235 | path = ../..; 236 | sourceTree = ""; 237 | }; 238 | /* End PBXGroup section */ 239 | 240 | /* Begin PBXHeadersBuildPhase section */ 241 | 28B0B78FDEAD0AC5F73A5B133C01CC6C /* Headers */ = { 242 | isa = PBXHeadersBuildPhase; 243 | buildActionMask = 2147483647; 244 | files = ( 245 | 7E0A401710560F686B743A74BA473119 /* Pods-Fuse_Example-umbrella.h in Headers */, 246 | ); 247 | runOnlyForDeploymentPostprocessing = 0; 248 | }; 249 | 9E82A732E35B78D317C7C28C9F1D76F1 /* Headers */ = { 250 | isa = PBXHeadersBuildPhase; 251 | buildActionMask = 2147483647; 252 | files = ( 253 | CB51FA52485D63BD4D99CEA63AD8F280 /* Pods-Fuse_Tests-umbrella.h in Headers */, 254 | ); 255 | runOnlyForDeploymentPostprocessing = 0; 256 | }; 257 | EF915F26D356D8646E7A5F32B05ED231 /* Headers */ = { 258 | isa = PBXHeadersBuildPhase; 259 | buildActionMask = 2147483647; 260 | files = ( 261 | 5694BF7EB997C802B20912A8AA5D5E83 /* Fuse-umbrella.h in Headers */, 262 | ); 263 | runOnlyForDeploymentPostprocessing = 0; 264 | }; 265 | /* End PBXHeadersBuildPhase section */ 266 | 267 | /* Begin PBXNativeTarget section */ 268 | 66AF68834C251AEE0F9505FA7C8821A0 /* Pods-Fuse_Tests */ = { 269 | isa = PBXNativeTarget; 270 | buildConfigurationList = C2EA0F5D870CFA9FB951DDF35550CC9D /* Build configuration list for PBXNativeTarget "Pods-Fuse_Tests" */; 271 | buildPhases = ( 272 | DF27198730D0F157908A2F7181D7EBA4 /* Sources */, 273 | F1F8437982E2BB266852BCC20F123B1C /* Frameworks */, 274 | 9E82A732E35B78D317C7C28C9F1D76F1 /* Headers */, 275 | ); 276 | buildRules = ( 277 | ); 278 | dependencies = ( 279 | 82A06321603742379EF9612AD0C8C689 /* PBXTargetDependency */, 280 | ); 281 | name = "Pods-Fuse_Tests"; 282 | productName = "Pods-Fuse_Tests"; 283 | productReference = 2D4CC22E8530C8ACC0306265C571D4E5 /* Pods_Fuse_Tests.framework */; 284 | productType = "com.apple.product-type.framework"; 285 | }; 286 | B8CD3B3EDB42EEABB2D487F8706AF6BB /* Fuse */ = { 287 | isa = PBXNativeTarget; 288 | buildConfigurationList = 0E0B582D8D2B0C67CCE334212F4831C7 /* Build configuration list for PBXNativeTarget "Fuse" */; 289 | buildPhases = ( 290 | B1CAADBCBF079B8445FF823400A55A38 /* Sources */, 291 | A94CAD7E49ECDD8E93EE196BE511610A /* Frameworks */, 292 | EF915F26D356D8646E7A5F32B05ED231 /* Headers */, 293 | ); 294 | buildRules = ( 295 | ); 296 | dependencies = ( 297 | ); 298 | name = Fuse; 299 | productName = Fuse; 300 | productReference = 51CD0AE6796F692A063F33632D47C923 /* Fuse.framework */; 301 | productType = "com.apple.product-type.framework"; 302 | }; 303 | EFCF59957162A5D66FB1342620599CBA /* Pods-Fuse_Example */ = { 304 | isa = PBXNativeTarget; 305 | buildConfigurationList = 9772EA0366DBD1DF61CBE629A87AC764 /* Build configuration list for PBXNativeTarget "Pods-Fuse_Example" */; 306 | buildPhases = ( 307 | F402B797E10C6F8FB10A2EDAA64A1069 /* Sources */, 308 | 1AA3A7E7F474091D9C8DEA7660452876 /* Frameworks */, 309 | 28B0B78FDEAD0AC5F73A5B133C01CC6C /* Headers */, 310 | ); 311 | buildRules = ( 312 | ); 313 | dependencies = ( 314 | FF6BFF8E613ABCBFCE88991D42BCC298 /* PBXTargetDependency */, 315 | ); 316 | name = "Pods-Fuse_Example"; 317 | productName = "Pods-Fuse_Example"; 318 | productReference = B0B8F6D471015A67024C81799119CFB3 /* Pods_Fuse_Example.framework */; 319 | productType = "com.apple.product-type.framework"; 320 | }; 321 | /* End PBXNativeTarget section */ 322 | 323 | /* Begin PBXProject section */ 324 | D41D8CD98F00B204E9800998ECF8427E /* Project object */ = { 325 | isa = PBXProject; 326 | attributes = { 327 | LastSwiftUpdateCheck = 0830; 328 | LastUpgradeCheck = 1130; 329 | TargetAttributes = { 330 | B8CD3B3EDB42EEABB2D487F8706AF6BB = { 331 | LastSwiftMigration = 1130; 332 | }; 333 | }; 334 | }; 335 | buildConfigurationList = 2D8E8EC45A3A1A1D94AE762CB5028504 /* Build configuration list for PBXProject "Pods" */; 336 | compatibilityVersion = "Xcode 3.2"; 337 | developmentRegion = en; 338 | hasScannedForEncodings = 0; 339 | knownRegions = ( 340 | en, 341 | Base, 342 | ); 343 | mainGroup = 7DB346D0F39D3F0E887471402A8071AB; 344 | productRefGroup = 3E67CB8AE63537296A06953357B839EA /* Products */; 345 | projectDirPath = ""; 346 | projectRoot = ""; 347 | targets = ( 348 | B8CD3B3EDB42EEABB2D487F8706AF6BB /* Fuse */, 349 | EFCF59957162A5D66FB1342620599CBA /* Pods-Fuse_Example */, 350 | 66AF68834C251AEE0F9505FA7C8821A0 /* Pods-Fuse_Tests */, 351 | ); 352 | }; 353 | /* End PBXProject section */ 354 | 355 | /* Begin PBXSourcesBuildPhase section */ 356 | B1CAADBCBF079B8445FF823400A55A38 /* Sources */ = { 357 | isa = PBXSourcesBuildPhase; 358 | buildActionMask = 2147483647; 359 | files = ( 360 | C612183500C54DC7D2F07F8D768EE3D4 /* Fuse-dummy.m in Sources */, 361 | AC936D4C5B825DBD4003B0421E820EEE /* Fuse.swift in Sources */, 362 | 0A7AE8C8C9B97E81A8730E3439CC640C /* FuseUtilities.swift in Sources */, 363 | 37E129C05FAB8D7464E78B59B8D9B278 /* String+Fuse.swift in Sources */, 364 | ); 365 | runOnlyForDeploymentPostprocessing = 0; 366 | }; 367 | DF27198730D0F157908A2F7181D7EBA4 /* Sources */ = { 368 | isa = PBXSourcesBuildPhase; 369 | buildActionMask = 2147483647; 370 | files = ( 371 | 925C053E3781A9FE4360557296CD10CA /* Pods-Fuse_Tests-dummy.m in Sources */, 372 | ); 373 | runOnlyForDeploymentPostprocessing = 0; 374 | }; 375 | F402B797E10C6F8FB10A2EDAA64A1069 /* Sources */ = { 376 | isa = PBXSourcesBuildPhase; 377 | buildActionMask = 2147483647; 378 | files = ( 379 | DB7173C1B5D97758CD783151BAE04D2D /* Pods-Fuse_Example-dummy.m in Sources */, 380 | ); 381 | runOnlyForDeploymentPostprocessing = 0; 382 | }; 383 | /* End PBXSourcesBuildPhase section */ 384 | 385 | /* Begin PBXTargetDependency section */ 386 | 82A06321603742379EF9612AD0C8C689 /* PBXTargetDependency */ = { 387 | isa = PBXTargetDependency; 388 | name = Fuse; 389 | target = B8CD3B3EDB42EEABB2D487F8706AF6BB /* Fuse */; 390 | targetProxy = 50ABAE40C87D337524215E9B541D6C58 /* PBXContainerItemProxy */; 391 | }; 392 | FF6BFF8E613ABCBFCE88991D42BCC298 /* PBXTargetDependency */ = { 393 | isa = PBXTargetDependency; 394 | name = Fuse; 395 | target = B8CD3B3EDB42EEABB2D487F8706AF6BB /* Fuse */; 396 | targetProxy = 9F466D6708503C8577FEEDFFCD87FDA9 /* PBXContainerItemProxy */; 397 | }; 398 | /* End PBXTargetDependency section */ 399 | 400 | /* Begin XCBuildConfiguration section */ 401 | 33837CC8EA81977293CA460CD87D3A39 /* Release */ = { 402 | isa = XCBuildConfiguration; 403 | baseConfigurationReference = F3AE3F0DB9C00C7D3096AD5FBE449CE7 /* Fuse.xcconfig */; 404 | buildSettings = { 405 | CODE_SIGN_IDENTITY = ""; 406 | "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; 407 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; 408 | "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; 409 | CURRENT_PROJECT_VERSION = 1; 410 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 411 | DEFINES_MODULE = YES; 412 | DYLIB_COMPATIBILITY_VERSION = 1; 413 | DYLIB_CURRENT_VERSION = 1; 414 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 415 | ENABLE_STRICT_OBJC_MSGSEND = YES; 416 | GCC_NO_COMMON_BLOCKS = YES; 417 | GCC_PREFIX_HEADER = "Target Support Files/Fuse/Fuse-prefix.pch"; 418 | INFOPLIST_FILE = "Target Support Files/Fuse/Info.plist"; 419 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 420 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 421 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 422 | MODULEMAP_FILE = "Target Support Files/Fuse/Fuse.modulemap"; 423 | MTL_ENABLE_DEBUG_INFO = NO; 424 | PRODUCT_NAME = Fuse; 425 | SDKROOT = iphoneos; 426 | SKIP_INSTALL = YES; 427 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 428 | SWIFT_SWIFT3_OBJC_INFERENCE = Default; 429 | SWIFT_VERSION = 5.0; 430 | TARGETED_DEVICE_FAMILY = "1,2"; 431 | VERSIONING_SYSTEM = "apple-generic"; 432 | VERSION_INFO_PREFIX = ""; 433 | }; 434 | name = Release; 435 | }; 436 | 345CC476DF4A7516DBD2220CF5035FF3 /* Debug */ = { 437 | isa = XCBuildConfiguration; 438 | buildSettings = { 439 | ALWAYS_SEARCH_USER_PATHS = NO; 440 | CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; 441 | CLANG_ANALYZER_NONNULL = YES; 442 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES; 443 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 444 | CLANG_CXX_LIBRARY = "libc++"; 445 | CLANG_ENABLE_MODULES = YES; 446 | CLANG_ENABLE_OBJC_ARC = YES; 447 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 448 | CLANG_WARN_BOOL_CONVERSION = YES; 449 | CLANG_WARN_COMMA = YES; 450 | CLANG_WARN_CONSTANT_CONVERSION = YES; 451 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 452 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES; 453 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 454 | CLANG_WARN_EMPTY_BODY = YES; 455 | CLANG_WARN_ENUM_CONVERSION = YES; 456 | CLANG_WARN_INFINITE_RECURSION = YES; 457 | CLANG_WARN_INT_CONVERSION = YES; 458 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 459 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 460 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 461 | CLANG_WARN_OBJC_ROOT_CLASS = YES; 462 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 463 | CLANG_WARN_STRICT_PROTOTYPES = YES; 464 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 465 | CLANG_WARN_UNREACHABLE_CODE = YES; 466 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 467 | CODE_SIGNING_REQUIRED = NO; 468 | COPY_PHASE_STRIP = NO; 469 | ENABLE_STRICT_OBJC_MSGSEND = YES; 470 | ENABLE_TESTABILITY = YES; 471 | GCC_C_LANGUAGE_STANDARD = gnu99; 472 | GCC_DYNAMIC_NO_PIC = NO; 473 | GCC_NO_COMMON_BLOCKS = YES; 474 | GCC_OPTIMIZATION_LEVEL = 0; 475 | GCC_PREPROCESSOR_DEFINITIONS = ( 476 | "POD_CONFIGURATION_DEBUG=1", 477 | "DEBUG=1", 478 | "$(inherited)", 479 | ); 480 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 481 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 482 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 483 | GCC_WARN_UNDECLARED_SELECTOR = YES; 484 | GCC_WARN_UNINITIALIZED_AUTOS = YES; 485 | GCC_WARN_UNUSED_FUNCTION = YES; 486 | GCC_WARN_UNUSED_VARIABLE = YES; 487 | IPHONEOS_DEPLOYMENT_TARGET = 8.3; 488 | ONLY_ACTIVE_ARCH = YES; 489 | PROVISIONING_PROFILE_SPECIFIER = NO_SIGNING/; 490 | STRIP_INSTALLED_PRODUCT = NO; 491 | SWIFT_VERSION = 5.0; 492 | SYMROOT = "${SRCROOT}/../build"; 493 | }; 494 | name = Debug; 495 | }; 496 | 46C4474BE775758EA55046FC7030B3F1 /* Debug */ = { 497 | isa = XCBuildConfiguration; 498 | baseConfigurationReference = 514C5646826A7D65032B772A5D8662C8 /* Pods-Fuse_Example.debug.xcconfig */; 499 | buildSettings = { 500 | CODE_SIGN_IDENTITY = ""; 501 | "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; 502 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; 503 | "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; 504 | CURRENT_PROJECT_VERSION = 1; 505 | DEBUG_INFORMATION_FORMAT = dwarf; 506 | DEFINES_MODULE = YES; 507 | DYLIB_COMPATIBILITY_VERSION = 1; 508 | DYLIB_CURRENT_VERSION = 1; 509 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 510 | ENABLE_STRICT_OBJC_MSGSEND = YES; 511 | GCC_NO_COMMON_BLOCKS = YES; 512 | INFOPLIST_FILE = "Target Support Files/Pods-Fuse_Example/Info.plist"; 513 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 514 | IPHONEOS_DEPLOYMENT_TARGET = 8.3; 515 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 516 | MACH_O_TYPE = staticlib; 517 | MODULEMAP_FILE = "Target Support Files/Pods-Fuse_Example/Pods-Fuse_Example.modulemap"; 518 | MTL_ENABLE_DEBUG_INFO = YES; 519 | OTHER_LDFLAGS = ""; 520 | OTHER_LIBTOOLFLAGS = ""; 521 | PODS_ROOT = "$(SRCROOT)"; 522 | PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; 523 | PRODUCT_NAME = Pods_Fuse_Example; 524 | SDKROOT = iphoneos; 525 | SKIP_INSTALL = YES; 526 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 527 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 528 | SWIFT_VERSION = 5.0; 529 | TARGETED_DEVICE_FAMILY = "1,2"; 530 | VERSIONING_SYSTEM = "apple-generic"; 531 | VERSION_INFO_PREFIX = ""; 532 | }; 533 | name = Debug; 534 | }; 535 | 4FAD02392C959146E413726EC69F9A51 /* Release */ = { 536 | isa = XCBuildConfiguration; 537 | baseConfigurationReference = 43156C42100B06C82754BCD27E07BC31 /* Pods-Fuse_Example.release.xcconfig */; 538 | buildSettings = { 539 | CODE_SIGN_IDENTITY = ""; 540 | "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; 541 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; 542 | "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; 543 | CURRENT_PROJECT_VERSION = 1; 544 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 545 | DEFINES_MODULE = YES; 546 | DYLIB_COMPATIBILITY_VERSION = 1; 547 | DYLIB_CURRENT_VERSION = 1; 548 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 549 | ENABLE_STRICT_OBJC_MSGSEND = YES; 550 | GCC_NO_COMMON_BLOCKS = YES; 551 | INFOPLIST_FILE = "Target Support Files/Pods-Fuse_Example/Info.plist"; 552 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 553 | IPHONEOS_DEPLOYMENT_TARGET = 8.3; 554 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 555 | MACH_O_TYPE = staticlib; 556 | MODULEMAP_FILE = "Target Support Files/Pods-Fuse_Example/Pods-Fuse_Example.modulemap"; 557 | MTL_ENABLE_DEBUG_INFO = NO; 558 | OTHER_LDFLAGS = ""; 559 | OTHER_LIBTOOLFLAGS = ""; 560 | PODS_ROOT = "$(SRCROOT)"; 561 | PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; 562 | PRODUCT_NAME = Pods_Fuse_Example; 563 | SDKROOT = iphoneos; 564 | SKIP_INSTALL = YES; 565 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 566 | SWIFT_VERSION = 5.0; 567 | TARGETED_DEVICE_FAMILY = "1,2"; 568 | VERSIONING_SYSTEM = "apple-generic"; 569 | VERSION_INFO_PREFIX = ""; 570 | }; 571 | name = Release; 572 | }; 573 | 6FF3B7FBAE986F21964A8E6EF64E8CE1 /* Release */ = { 574 | isa = XCBuildConfiguration; 575 | baseConfigurationReference = F70AD514E9EEFDA8C64AF436C5D0D846 /* Pods-Fuse_Tests.release.xcconfig */; 576 | buildSettings = { 577 | CODE_SIGN_IDENTITY = ""; 578 | "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; 579 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; 580 | "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; 581 | CURRENT_PROJECT_VERSION = 1; 582 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 583 | DEFINES_MODULE = YES; 584 | DYLIB_COMPATIBILITY_VERSION = 1; 585 | DYLIB_CURRENT_VERSION = 1; 586 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 587 | ENABLE_STRICT_OBJC_MSGSEND = YES; 588 | GCC_NO_COMMON_BLOCKS = YES; 589 | INFOPLIST_FILE = "Target Support Files/Pods-Fuse_Tests/Info.plist"; 590 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 591 | IPHONEOS_DEPLOYMENT_TARGET = 8.3; 592 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 593 | MACH_O_TYPE = staticlib; 594 | MODULEMAP_FILE = "Target Support Files/Pods-Fuse_Tests/Pods-Fuse_Tests.modulemap"; 595 | MTL_ENABLE_DEBUG_INFO = NO; 596 | OTHER_LDFLAGS = ""; 597 | OTHER_LIBTOOLFLAGS = ""; 598 | PODS_ROOT = "$(SRCROOT)"; 599 | PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; 600 | PRODUCT_NAME = Pods_Fuse_Tests; 601 | SDKROOT = iphoneos; 602 | SKIP_INSTALL = YES; 603 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 604 | SWIFT_VERSION = 5.0; 605 | TARGETED_DEVICE_FAMILY = "1,2"; 606 | VERSIONING_SYSTEM = "apple-generic"; 607 | VERSION_INFO_PREFIX = ""; 608 | }; 609 | name = Release; 610 | }; 611 | 717E77604BFBB04BEAF56608A1CB2EDE /* Release */ = { 612 | isa = XCBuildConfiguration; 613 | buildSettings = { 614 | ALWAYS_SEARCH_USER_PATHS = NO; 615 | CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; 616 | CLANG_ANALYZER_NONNULL = YES; 617 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES; 618 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 619 | CLANG_CXX_LIBRARY = "libc++"; 620 | CLANG_ENABLE_MODULES = YES; 621 | CLANG_ENABLE_OBJC_ARC = YES; 622 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 623 | CLANG_WARN_BOOL_CONVERSION = YES; 624 | CLANG_WARN_COMMA = YES; 625 | CLANG_WARN_CONSTANT_CONVERSION = YES; 626 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 627 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES; 628 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 629 | CLANG_WARN_EMPTY_BODY = YES; 630 | CLANG_WARN_ENUM_CONVERSION = YES; 631 | CLANG_WARN_INFINITE_RECURSION = YES; 632 | CLANG_WARN_INT_CONVERSION = YES; 633 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 634 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 635 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 636 | CLANG_WARN_OBJC_ROOT_CLASS = YES; 637 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 638 | CLANG_WARN_STRICT_PROTOTYPES = YES; 639 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 640 | CLANG_WARN_UNREACHABLE_CODE = YES; 641 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 642 | CODE_SIGNING_REQUIRED = NO; 643 | COPY_PHASE_STRIP = YES; 644 | ENABLE_NS_ASSERTIONS = NO; 645 | ENABLE_STRICT_OBJC_MSGSEND = YES; 646 | GCC_C_LANGUAGE_STANDARD = gnu99; 647 | GCC_NO_COMMON_BLOCKS = YES; 648 | GCC_PREPROCESSOR_DEFINITIONS = ( 649 | "POD_CONFIGURATION_RELEASE=1", 650 | "$(inherited)", 651 | ); 652 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 653 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 654 | GCC_WARN_UNDECLARED_SELECTOR = YES; 655 | GCC_WARN_UNINITIALIZED_AUTOS = YES; 656 | GCC_WARN_UNUSED_FUNCTION = YES; 657 | GCC_WARN_UNUSED_VARIABLE = YES; 658 | IPHONEOS_DEPLOYMENT_TARGET = 8.3; 659 | PROVISIONING_PROFILE_SPECIFIER = NO_SIGNING/; 660 | STRIP_INSTALLED_PRODUCT = NO; 661 | SWIFT_VERSION = 5.0; 662 | SYMROOT = "${SRCROOT}/../build"; 663 | VALIDATE_PRODUCT = YES; 664 | }; 665 | name = Release; 666 | }; 667 | A3650AFF399DE49AB0D8199E745161F2 /* Debug */ = { 668 | isa = XCBuildConfiguration; 669 | baseConfigurationReference = F3AE3F0DB9C00C7D3096AD5FBE449CE7 /* Fuse.xcconfig */; 670 | buildSettings = { 671 | CODE_SIGN_IDENTITY = ""; 672 | "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; 673 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; 674 | "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; 675 | CURRENT_PROJECT_VERSION = 1; 676 | DEBUG_INFORMATION_FORMAT = dwarf; 677 | DEFINES_MODULE = YES; 678 | DYLIB_COMPATIBILITY_VERSION = 1; 679 | DYLIB_CURRENT_VERSION = 1; 680 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 681 | ENABLE_STRICT_OBJC_MSGSEND = YES; 682 | GCC_NO_COMMON_BLOCKS = YES; 683 | GCC_PREFIX_HEADER = "Target Support Files/Fuse/Fuse-prefix.pch"; 684 | INFOPLIST_FILE = "Target Support Files/Fuse/Info.plist"; 685 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 686 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 687 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 688 | MODULEMAP_FILE = "Target Support Files/Fuse/Fuse.modulemap"; 689 | MTL_ENABLE_DEBUG_INFO = YES; 690 | PRODUCT_NAME = Fuse; 691 | SDKROOT = iphoneos; 692 | SKIP_INSTALL = YES; 693 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 694 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 695 | SWIFT_SWIFT3_OBJC_INFERENCE = Default; 696 | SWIFT_VERSION = 5.0; 697 | TARGETED_DEVICE_FAMILY = "1,2"; 698 | VERSIONING_SYSTEM = "apple-generic"; 699 | VERSION_INFO_PREFIX = ""; 700 | }; 701 | name = Debug; 702 | }; 703 | B0D3640E17A90DF8F3B682B3E1BEE17F /* Debug */ = { 704 | isa = XCBuildConfiguration; 705 | baseConfigurationReference = 54DBC22221D1AE1479A57A8A9AE40651 /* Pods-Fuse_Tests.debug.xcconfig */; 706 | buildSettings = { 707 | CODE_SIGN_IDENTITY = ""; 708 | "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; 709 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; 710 | "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; 711 | CURRENT_PROJECT_VERSION = 1; 712 | DEBUG_INFORMATION_FORMAT = dwarf; 713 | DEFINES_MODULE = YES; 714 | DYLIB_COMPATIBILITY_VERSION = 1; 715 | DYLIB_CURRENT_VERSION = 1; 716 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 717 | ENABLE_STRICT_OBJC_MSGSEND = YES; 718 | GCC_NO_COMMON_BLOCKS = YES; 719 | INFOPLIST_FILE = "Target Support Files/Pods-Fuse_Tests/Info.plist"; 720 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 721 | IPHONEOS_DEPLOYMENT_TARGET = 8.3; 722 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 723 | MACH_O_TYPE = staticlib; 724 | MODULEMAP_FILE = "Target Support Files/Pods-Fuse_Tests/Pods-Fuse_Tests.modulemap"; 725 | MTL_ENABLE_DEBUG_INFO = YES; 726 | OTHER_LDFLAGS = ""; 727 | OTHER_LIBTOOLFLAGS = ""; 728 | PODS_ROOT = "$(SRCROOT)"; 729 | PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; 730 | PRODUCT_NAME = Pods_Fuse_Tests; 731 | SDKROOT = iphoneos; 732 | SKIP_INSTALL = YES; 733 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 734 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 735 | SWIFT_VERSION = 5.0; 736 | TARGETED_DEVICE_FAMILY = "1,2"; 737 | VERSIONING_SYSTEM = "apple-generic"; 738 | VERSION_INFO_PREFIX = ""; 739 | }; 740 | name = Debug; 741 | }; 742 | /* End XCBuildConfiguration section */ 743 | 744 | /* Begin XCConfigurationList section */ 745 | 0E0B582D8D2B0C67CCE334212F4831C7 /* Build configuration list for PBXNativeTarget "Fuse" */ = { 746 | isa = XCConfigurationList; 747 | buildConfigurations = ( 748 | A3650AFF399DE49AB0D8199E745161F2 /* Debug */, 749 | 33837CC8EA81977293CA460CD87D3A39 /* Release */, 750 | ); 751 | defaultConfigurationIsVisible = 0; 752 | defaultConfigurationName = Release; 753 | }; 754 | 2D8E8EC45A3A1A1D94AE762CB5028504 /* Build configuration list for PBXProject "Pods" */ = { 755 | isa = XCConfigurationList; 756 | buildConfigurations = ( 757 | 345CC476DF4A7516DBD2220CF5035FF3 /* Debug */, 758 | 717E77604BFBB04BEAF56608A1CB2EDE /* Release */, 759 | ); 760 | defaultConfigurationIsVisible = 0; 761 | defaultConfigurationName = Release; 762 | }; 763 | 9772EA0366DBD1DF61CBE629A87AC764 /* Build configuration list for PBXNativeTarget "Pods-Fuse_Example" */ = { 764 | isa = XCConfigurationList; 765 | buildConfigurations = ( 766 | 46C4474BE775758EA55046FC7030B3F1 /* Debug */, 767 | 4FAD02392C959146E413726EC69F9A51 /* Release */, 768 | ); 769 | defaultConfigurationIsVisible = 0; 770 | defaultConfigurationName = Release; 771 | }; 772 | C2EA0F5D870CFA9FB951DDF35550CC9D /* Build configuration list for PBXNativeTarget "Pods-Fuse_Tests" */ = { 773 | isa = XCConfigurationList; 774 | buildConfigurations = ( 775 | B0D3640E17A90DF8F3B682B3E1BEE17F /* Debug */, 776 | 6FF3B7FBAE986F21964A8E6EF64E8CE1 /* Release */, 777 | ); 778 | defaultConfigurationIsVisible = 0; 779 | defaultConfigurationName = Release; 780 | }; 781 | /* End XCConfigurationList section */ 782 | }; 783 | rootObject = D41D8CD98F00B204E9800998ECF8427E /* Project object */; 784 | } 785 | -------------------------------------------------------------------------------- /Example/Pods/Pods.xcodeproj/xcshareddata/xcschemes/Fuse.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 43 | 44 | 50 | 51 | 52 | 53 | 59 | 60 | 66 | 67 | 68 | 69 | 71 | 72 | 75 | 76 | 77 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Fuse/Fuse-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_Fuse : NSObject 3 | @end 4 | @implementation PodsDummy_Fuse 5 | @end 6 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Fuse/Fuse-prefix.pch: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Fuse/Fuse-umbrella.h: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | 14 | FOUNDATION_EXPORT double FuseVersionNumber; 15 | FOUNDATION_EXPORT const unsigned char FuseVersionString[]; 16 | 17 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Fuse/Fuse.modulemap: -------------------------------------------------------------------------------- 1 | framework module Fuse { 2 | umbrella header "Fuse-umbrella.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Fuse/Fuse.xcconfig: -------------------------------------------------------------------------------- 1 | CONFIGURATION_BUILD_DIR = $PODS_CONFIGURATION_BUILD_DIR/Fuse 2 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 3 | HEADER_SEARCH_PATHS = "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Public" 4 | OTHER_SWIFT_FLAGS = $(inherited) "-D" "COCOAPODS" 5 | PODS_BUILD_DIR = $BUILD_DIR 6 | PODS_CONFIGURATION_BUILD_DIR = $PODS_BUILD_DIR/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 7 | PODS_ROOT = ${SRCROOT} 8 | PODS_TARGET_SRCROOT = ${PODS_ROOT}/../.. 9 | PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} 10 | SKIP_INSTALL = YES 11 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Fuse/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 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 | 0.2.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-Fuse_Example/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 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.0.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-Fuse_Example/Pods-Fuse_Example-acknowledgements.markdown: -------------------------------------------------------------------------------- 1 | # Acknowledgements 2 | This application makes use of the following third party libraries: 3 | 4 | ## Fuse 5 | 6 | Copyright (c) 2017 Kirollos Risk 7 | 8 | Permission is hereby granted, free of charge, to any person obtaining a copy 9 | of this software and associated documentation files (the "Software"), to deal 10 | in the Software without restriction, including without limitation the rights 11 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | copies of the Software, and to permit persons to whom the Software is 13 | furnished to do so, subject to the following conditions: 14 | 15 | The above copyright notice and this permission notice shall be included in 16 | all copies or substantial portions of the Software. 17 | 18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 | THE SOFTWARE. 25 | 26 | Generated by CocoaPods - https://cocoapods.org 27 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-Fuse_Example/Pods-Fuse_Example-acknowledgements.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreferenceSpecifiers 6 | 7 | 8 | FooterText 9 | This application makes use of the following third party libraries: 10 | Title 11 | Acknowledgements 12 | Type 13 | PSGroupSpecifier 14 | 15 | 16 | FooterText 17 | Copyright (c) 2017 Kirollos Risk <kirollos@gmail.com> 18 | 19 | Permission is hereby granted, free of charge, to any person obtaining a copy 20 | of this software and associated documentation files (the "Software"), to deal 21 | in the Software without restriction, including without limitation the rights 22 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 23 | copies of the Software, and to permit persons to whom the Software is 24 | furnished to do so, subject to the following conditions: 25 | 26 | The above copyright notice and this permission notice shall be included in 27 | all copies or substantial portions of the Software. 28 | 29 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 30 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 31 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 32 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 33 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 34 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 35 | THE SOFTWARE. 36 | 37 | License 38 | MIT 39 | Title 40 | Fuse 41 | Type 42 | PSGroupSpecifier 43 | 44 | 45 | FooterText 46 | Generated by CocoaPods - https://cocoapods.org 47 | Title 48 | 49 | Type 50 | PSGroupSpecifier 51 | 52 | 53 | StringsTable 54 | Acknowledgements 55 | Title 56 | Acknowledgements 57 | 58 | 59 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-Fuse_Example/Pods-Fuse_Example-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_Pods_Fuse_Example : NSObject 3 | @end 4 | @implementation PodsDummy_Pods_Fuse_Example 5 | @end 6 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-Fuse_Example/Pods-Fuse_Example-frameworks.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | echo "mkdir -p ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 5 | mkdir -p "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 6 | 7 | SWIFT_STDLIB_PATH="${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" 8 | 9 | install_framework() 10 | { 11 | if [ -r "${BUILT_PRODUCTS_DIR}/$1" ]; then 12 | local source="${BUILT_PRODUCTS_DIR}/$1" 13 | elif [ -r "${BUILT_PRODUCTS_DIR}/$(basename "$1")" ]; then 14 | local source="${BUILT_PRODUCTS_DIR}/$(basename "$1")" 15 | elif [ -r "$1" ]; then 16 | local source="$1" 17 | fi 18 | 19 | local destination="${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 20 | 21 | if [ -L "${source}" ]; then 22 | echo "Symlinked..." 23 | source="$(readlink "${source}")" 24 | fi 25 | 26 | # use filter instead of exclude so missing patterns dont' throw errors 27 | echo "rsync -av --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${destination}\"" 28 | rsync -av --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${destination}" 29 | 30 | local basename 31 | basename="$(basename -s .framework "$1")" 32 | binary="${destination}/${basename}.framework/${basename}" 33 | if ! [ -r "$binary" ]; then 34 | binary="${destination}/${basename}" 35 | fi 36 | 37 | # Strip invalid architectures so "fat" simulator / device frameworks work on device 38 | if [[ "$(file "$binary")" == *"dynamically linked shared library"* ]]; then 39 | strip_invalid_archs "$binary" 40 | fi 41 | 42 | # Resign the code if required by the build settings to avoid unstable apps 43 | code_sign_if_enabled "${destination}/$(basename "$1")" 44 | 45 | # Embed linked Swift runtime libraries. No longer necessary as of Xcode 7. 46 | if [ "${XCODE_VERSION_MAJOR}" -lt 7 ]; then 47 | local swift_runtime_libs 48 | swift_runtime_libs=$(xcrun otool -LX "$binary" | grep --color=never @rpath/libswift | sed -E s/@rpath\\/\(.+dylib\).*/\\1/g | uniq -u && exit ${PIPESTATUS[0]}) 49 | for lib in $swift_runtime_libs; do 50 | echo "rsync -auv \"${SWIFT_STDLIB_PATH}/${lib}\" \"${destination}\"" 51 | rsync -auv "${SWIFT_STDLIB_PATH}/${lib}" "${destination}" 52 | code_sign_if_enabled "${destination}/${lib}" 53 | done 54 | fi 55 | } 56 | 57 | # Signs a framework with the provided identity 58 | code_sign_if_enabled() { 59 | if [ -n "${EXPANDED_CODE_SIGN_IDENTITY}" -a "${CODE_SIGNING_REQUIRED}" != "NO" -a "${CODE_SIGNING_ALLOWED}" != "NO" ]; then 60 | # Use the current code_sign_identitiy 61 | echo "Code Signing $1 with Identity ${EXPANDED_CODE_SIGN_IDENTITY_NAME}" 62 | local code_sign_cmd="/usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} ${OTHER_CODE_SIGN_FLAGS} --preserve-metadata=identifier,entitlements '$1'" 63 | 64 | if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then 65 | code_sign_cmd="$code_sign_cmd &" 66 | fi 67 | echo "$code_sign_cmd" 68 | eval "$code_sign_cmd" 69 | fi 70 | } 71 | 72 | # Strip invalid architectures 73 | strip_invalid_archs() { 74 | binary="$1" 75 | # Get architectures for current file 76 | archs="$(lipo -info "$binary" | rev | cut -d ':' -f1 | rev)" 77 | stripped="" 78 | for arch in $archs; do 79 | if ! [[ "${VALID_ARCHS}" == *"$arch"* ]]; then 80 | # Strip non-valid architectures in-place 81 | lipo -remove "$arch" -output "$binary" "$binary" || exit 1 82 | stripped="$stripped $arch" 83 | fi 84 | done 85 | if [[ "$stripped" ]]; then 86 | echo "Stripped $binary of architectures:$stripped" 87 | fi 88 | } 89 | 90 | 91 | if [[ "$CONFIGURATION" == "Debug" ]]; then 92 | install_framework "$BUILT_PRODUCTS_DIR/Fuse/Fuse.framework" 93 | fi 94 | if [[ "$CONFIGURATION" == "Release" ]]; then 95 | install_framework "$BUILT_PRODUCTS_DIR/Fuse/Fuse.framework" 96 | fi 97 | if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then 98 | wait 99 | fi 100 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-Fuse_Example/Pods-Fuse_Example-resources.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | mkdir -p "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 5 | 6 | RESOURCES_TO_COPY=${PODS_ROOT}/resources-to-copy-${TARGETNAME}.txt 7 | > "$RESOURCES_TO_COPY" 8 | 9 | XCASSET_FILES=() 10 | 11 | case "${TARGETED_DEVICE_FAMILY}" in 12 | 1,2) 13 | TARGET_DEVICE_ARGS="--target-device ipad --target-device iphone" 14 | ;; 15 | 1) 16 | TARGET_DEVICE_ARGS="--target-device iphone" 17 | ;; 18 | 2) 19 | TARGET_DEVICE_ARGS="--target-device ipad" 20 | ;; 21 | 3) 22 | TARGET_DEVICE_ARGS="--target-device tv" 23 | ;; 24 | 4) 25 | TARGET_DEVICE_ARGS="--target-device watch" 26 | ;; 27 | *) 28 | TARGET_DEVICE_ARGS="--target-device mac" 29 | ;; 30 | esac 31 | 32 | install_resource() 33 | { 34 | if [[ "$1" = /* ]] ; then 35 | RESOURCE_PATH="$1" 36 | else 37 | RESOURCE_PATH="${PODS_ROOT}/$1" 38 | fi 39 | if [[ ! -e "$RESOURCE_PATH" ]] ; then 40 | cat << EOM 41 | error: Resource "$RESOURCE_PATH" not found. Run 'pod install' to update the copy resources script. 42 | EOM 43 | exit 1 44 | fi 45 | case $RESOURCE_PATH in 46 | *.storyboard) 47 | echo "ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile ${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .storyboard`.storyboardc $RESOURCE_PATH --sdk ${SDKROOT} ${TARGET_DEVICE_ARGS}" 48 | ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .storyboard`.storyboardc" "$RESOURCE_PATH" --sdk "${SDKROOT}" ${TARGET_DEVICE_ARGS} 49 | ;; 50 | *.xib) 51 | echo "ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile ${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .xib`.nib $RESOURCE_PATH --sdk ${SDKROOT} ${TARGET_DEVICE_ARGS}" 52 | ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .xib`.nib" "$RESOURCE_PATH" --sdk "${SDKROOT}" ${TARGET_DEVICE_ARGS} 53 | ;; 54 | *.framework) 55 | echo "mkdir -p ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 56 | mkdir -p "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 57 | echo "rsync -av $RESOURCE_PATH ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 58 | rsync -av "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 59 | ;; 60 | *.xcdatamodel) 61 | echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH"`.mom\"" 62 | xcrun momc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodel`.mom" 63 | ;; 64 | *.xcdatamodeld) 65 | echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd\"" 66 | xcrun momc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd" 67 | ;; 68 | *.xcmappingmodel) 69 | echo "xcrun mapc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm\"" 70 | xcrun mapc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm" 71 | ;; 72 | *.xcassets) 73 | ABSOLUTE_XCASSET_FILE="$RESOURCE_PATH" 74 | XCASSET_FILES+=("$ABSOLUTE_XCASSET_FILE") 75 | ;; 76 | *) 77 | echo "$RESOURCE_PATH" 78 | echo "$RESOURCE_PATH" >> "$RESOURCES_TO_COPY" 79 | ;; 80 | esac 81 | } 82 | 83 | mkdir -p "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 84 | rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 85 | if [[ "${ACTION}" == "install" ]] && [[ "${SKIP_INSTALL}" == "NO" ]]; then 86 | mkdir -p "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 87 | rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 88 | fi 89 | rm -f "$RESOURCES_TO_COPY" 90 | 91 | if [[ -n "${WRAPPER_EXTENSION}" ]] && [ "`xcrun --find actool`" ] && [ -n "$XCASSET_FILES" ] 92 | then 93 | # Find all other xcassets (this unfortunately includes those of path pods and other targets). 94 | OTHER_XCASSETS=$(find "$PWD" -iname "*.xcassets" -type d) 95 | while read line; do 96 | if [[ $line != "${PODS_ROOT}*" ]]; then 97 | XCASSET_FILES+=("$line") 98 | fi 99 | done <<<"$OTHER_XCASSETS" 100 | 101 | printf "%s\0" "${XCASSET_FILES[@]}" | xargs -0 xcrun actool --output-format human-readable-text --notices --warnings --platform "${PLATFORM_NAME}" --minimum-deployment-target "${!DEPLOYMENT_TARGET_SETTING_NAME}" ${TARGET_DEVICE_ARGS} --compress-pngs --compile "${BUILT_PRODUCTS_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 102 | fi 103 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-Fuse_Example/Pods-Fuse_Example-umbrella.h: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | 14 | FOUNDATION_EXPORT double Pods_Fuse_ExampleVersionNumber; 15 | FOUNDATION_EXPORT const unsigned char Pods_Fuse_ExampleVersionString[]; 16 | 17 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-Fuse_Example/Pods-Fuse_Example.debug.xcconfig: -------------------------------------------------------------------------------- 1 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES 2 | FRAMEWORK_SEARCH_PATHS = $(inherited) "$PODS_CONFIGURATION_BUILD_DIR/Fuse" 3 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 4 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' 5 | OTHER_CFLAGS = $(inherited) -iquote "$PODS_CONFIGURATION_BUILD_DIR/Fuse/Fuse.framework/Headers" 6 | OTHER_LDFLAGS = $(inherited) -framework "Fuse" 7 | OTHER_SWIFT_FLAGS = $(inherited) "-D" "COCOAPODS" 8 | PODS_BUILD_DIR = $BUILD_DIR 9 | PODS_CONFIGURATION_BUILD_DIR = $PODS_BUILD_DIR/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 10 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/. 11 | PODS_ROOT = ${SRCROOT}/Pods 12 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-Fuse_Example/Pods-Fuse_Example.modulemap: -------------------------------------------------------------------------------- 1 | framework module Pods_Fuse_Example { 2 | umbrella header "Pods-Fuse_Example-umbrella.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-Fuse_Example/Pods-Fuse_Example.release.xcconfig: -------------------------------------------------------------------------------- 1 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES 2 | FRAMEWORK_SEARCH_PATHS = $(inherited) "$PODS_CONFIGURATION_BUILD_DIR/Fuse" 3 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 4 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' 5 | OTHER_CFLAGS = $(inherited) -iquote "$PODS_CONFIGURATION_BUILD_DIR/Fuse/Fuse.framework/Headers" 6 | OTHER_LDFLAGS = $(inherited) -framework "Fuse" 7 | OTHER_SWIFT_FLAGS = $(inherited) "-D" "COCOAPODS" 8 | PODS_BUILD_DIR = $BUILD_DIR 9 | PODS_CONFIGURATION_BUILD_DIR = $PODS_BUILD_DIR/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 10 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/. 11 | PODS_ROOT = ${SRCROOT}/Pods 12 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-Fuse_Tests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 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.0.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-Fuse_Tests/Pods-Fuse_Tests-acknowledgements.markdown: -------------------------------------------------------------------------------- 1 | # Acknowledgements 2 | This application makes use of the following third party libraries: 3 | 4 | ## Fuse 5 | 6 | Copyright (c) 2017 Kirollos Risk 7 | 8 | Permission is hereby granted, free of charge, to any person obtaining a copy 9 | of this software and associated documentation files (the "Software"), to deal 10 | in the Software without restriction, including without limitation the rights 11 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | copies of the Software, and to permit persons to whom the Software is 13 | furnished to do so, subject to the following conditions: 14 | 15 | The above copyright notice and this permission notice shall be included in 16 | all copies or substantial portions of the Software. 17 | 18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 | THE SOFTWARE. 25 | 26 | Generated by CocoaPods - https://cocoapods.org 27 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-Fuse_Tests/Pods-Fuse_Tests-acknowledgements.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreferenceSpecifiers 6 | 7 | 8 | FooterText 9 | This application makes use of the following third party libraries: 10 | Title 11 | Acknowledgements 12 | Type 13 | PSGroupSpecifier 14 | 15 | 16 | FooterText 17 | Copyright (c) 2017 Kirollos Risk <kirollos@gmail.com> 18 | 19 | Permission is hereby granted, free of charge, to any person obtaining a copy 20 | of this software and associated documentation files (the "Software"), to deal 21 | in the Software without restriction, including without limitation the rights 22 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 23 | copies of the Software, and to permit persons to whom the Software is 24 | furnished to do so, subject to the following conditions: 25 | 26 | The above copyright notice and this permission notice shall be included in 27 | all copies or substantial portions of the Software. 28 | 29 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 30 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 31 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 32 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 33 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 34 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 35 | THE SOFTWARE. 36 | 37 | License 38 | MIT 39 | Title 40 | Fuse 41 | Type 42 | PSGroupSpecifier 43 | 44 | 45 | FooterText 46 | Generated by CocoaPods - https://cocoapods.org 47 | Title 48 | 49 | Type 50 | PSGroupSpecifier 51 | 52 | 53 | StringsTable 54 | Acknowledgements 55 | Title 56 | Acknowledgements 57 | 58 | 59 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-Fuse_Tests/Pods-Fuse_Tests-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_Pods_Fuse_Tests : NSObject 3 | @end 4 | @implementation PodsDummy_Pods_Fuse_Tests 5 | @end 6 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-Fuse_Tests/Pods-Fuse_Tests-frameworks.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | echo "mkdir -p ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 5 | mkdir -p "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 6 | 7 | SWIFT_STDLIB_PATH="${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" 8 | 9 | install_framework() 10 | { 11 | if [ -r "${BUILT_PRODUCTS_DIR}/$1" ]; then 12 | local source="${BUILT_PRODUCTS_DIR}/$1" 13 | elif [ -r "${BUILT_PRODUCTS_DIR}/$(basename "$1")" ]; then 14 | local source="${BUILT_PRODUCTS_DIR}/$(basename "$1")" 15 | elif [ -r "$1" ]; then 16 | local source="$1" 17 | fi 18 | 19 | local destination="${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 20 | 21 | if [ -L "${source}" ]; then 22 | echo "Symlinked..." 23 | source="$(readlink "${source}")" 24 | fi 25 | 26 | # use filter instead of exclude so missing patterns dont' throw errors 27 | echo "rsync -av --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${destination}\"" 28 | rsync -av --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${destination}" 29 | 30 | local basename 31 | basename="$(basename -s .framework "$1")" 32 | binary="${destination}/${basename}.framework/${basename}" 33 | if ! [ -r "$binary" ]; then 34 | binary="${destination}/${basename}" 35 | fi 36 | 37 | # Strip invalid architectures so "fat" simulator / device frameworks work on device 38 | if [[ "$(file "$binary")" == *"dynamically linked shared library"* ]]; then 39 | strip_invalid_archs "$binary" 40 | fi 41 | 42 | # Resign the code if required by the build settings to avoid unstable apps 43 | code_sign_if_enabled "${destination}/$(basename "$1")" 44 | 45 | # Embed linked Swift runtime libraries. No longer necessary as of Xcode 7. 46 | if [ "${XCODE_VERSION_MAJOR}" -lt 7 ]; then 47 | local swift_runtime_libs 48 | swift_runtime_libs=$(xcrun otool -LX "$binary" | grep --color=never @rpath/libswift | sed -E s/@rpath\\/\(.+dylib\).*/\\1/g | uniq -u && exit ${PIPESTATUS[0]}) 49 | for lib in $swift_runtime_libs; do 50 | echo "rsync -auv \"${SWIFT_STDLIB_PATH}/${lib}\" \"${destination}\"" 51 | rsync -auv "${SWIFT_STDLIB_PATH}/${lib}" "${destination}" 52 | code_sign_if_enabled "${destination}/${lib}" 53 | done 54 | fi 55 | } 56 | 57 | # Signs a framework with the provided identity 58 | code_sign_if_enabled() { 59 | if [ -n "${EXPANDED_CODE_SIGN_IDENTITY}" -a "${CODE_SIGNING_REQUIRED}" != "NO" -a "${CODE_SIGNING_ALLOWED}" != "NO" ]; then 60 | # Use the current code_sign_identitiy 61 | echo "Code Signing $1 with Identity ${EXPANDED_CODE_SIGN_IDENTITY_NAME}" 62 | local code_sign_cmd="/usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} ${OTHER_CODE_SIGN_FLAGS} --preserve-metadata=identifier,entitlements '$1'" 63 | 64 | if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then 65 | code_sign_cmd="$code_sign_cmd &" 66 | fi 67 | echo "$code_sign_cmd" 68 | eval "$code_sign_cmd" 69 | fi 70 | } 71 | 72 | # Strip invalid architectures 73 | strip_invalid_archs() { 74 | binary="$1" 75 | # Get architectures for current file 76 | archs="$(lipo -info "$binary" | rev | cut -d ':' -f1 | rev)" 77 | stripped="" 78 | for arch in $archs; do 79 | if ! [[ "${VALID_ARCHS}" == *"$arch"* ]]; then 80 | # Strip non-valid architectures in-place 81 | lipo -remove "$arch" -output "$binary" "$binary" || exit 1 82 | stripped="$stripped $arch" 83 | fi 84 | done 85 | if [[ "$stripped" ]]; then 86 | echo "Stripped $binary of architectures:$stripped" 87 | fi 88 | } 89 | 90 | 91 | if [[ "$CONFIGURATION" == "Debug" ]]; then 92 | install_framework "$BUILT_PRODUCTS_DIR/Fuse/Fuse.framework" 93 | fi 94 | if [[ "$CONFIGURATION" == "Release" ]]; then 95 | install_framework "$BUILT_PRODUCTS_DIR/Fuse/Fuse.framework" 96 | fi 97 | if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then 98 | wait 99 | fi 100 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-Fuse_Tests/Pods-Fuse_Tests-resources.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | mkdir -p "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 5 | 6 | RESOURCES_TO_COPY=${PODS_ROOT}/resources-to-copy-${TARGETNAME}.txt 7 | > "$RESOURCES_TO_COPY" 8 | 9 | XCASSET_FILES=() 10 | 11 | case "${TARGETED_DEVICE_FAMILY}" in 12 | 1,2) 13 | TARGET_DEVICE_ARGS="--target-device ipad --target-device iphone" 14 | ;; 15 | 1) 16 | TARGET_DEVICE_ARGS="--target-device iphone" 17 | ;; 18 | 2) 19 | TARGET_DEVICE_ARGS="--target-device ipad" 20 | ;; 21 | 3) 22 | TARGET_DEVICE_ARGS="--target-device tv" 23 | ;; 24 | 4) 25 | TARGET_DEVICE_ARGS="--target-device watch" 26 | ;; 27 | *) 28 | TARGET_DEVICE_ARGS="--target-device mac" 29 | ;; 30 | esac 31 | 32 | install_resource() 33 | { 34 | if [[ "$1" = /* ]] ; then 35 | RESOURCE_PATH="$1" 36 | else 37 | RESOURCE_PATH="${PODS_ROOT}/$1" 38 | fi 39 | if [[ ! -e "$RESOURCE_PATH" ]] ; then 40 | cat << EOM 41 | error: Resource "$RESOURCE_PATH" not found. Run 'pod install' to update the copy resources script. 42 | EOM 43 | exit 1 44 | fi 45 | case $RESOURCE_PATH in 46 | *.storyboard) 47 | echo "ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile ${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .storyboard`.storyboardc $RESOURCE_PATH --sdk ${SDKROOT} ${TARGET_DEVICE_ARGS}" 48 | ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .storyboard`.storyboardc" "$RESOURCE_PATH" --sdk "${SDKROOT}" ${TARGET_DEVICE_ARGS} 49 | ;; 50 | *.xib) 51 | echo "ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile ${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .xib`.nib $RESOURCE_PATH --sdk ${SDKROOT} ${TARGET_DEVICE_ARGS}" 52 | ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .xib`.nib" "$RESOURCE_PATH" --sdk "${SDKROOT}" ${TARGET_DEVICE_ARGS} 53 | ;; 54 | *.framework) 55 | echo "mkdir -p ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 56 | mkdir -p "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 57 | echo "rsync -av $RESOURCE_PATH ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 58 | rsync -av "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 59 | ;; 60 | *.xcdatamodel) 61 | echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH"`.mom\"" 62 | xcrun momc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodel`.mom" 63 | ;; 64 | *.xcdatamodeld) 65 | echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd\"" 66 | xcrun momc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd" 67 | ;; 68 | *.xcmappingmodel) 69 | echo "xcrun mapc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm\"" 70 | xcrun mapc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm" 71 | ;; 72 | *.xcassets) 73 | ABSOLUTE_XCASSET_FILE="$RESOURCE_PATH" 74 | XCASSET_FILES+=("$ABSOLUTE_XCASSET_FILE") 75 | ;; 76 | *) 77 | echo "$RESOURCE_PATH" 78 | echo "$RESOURCE_PATH" >> "$RESOURCES_TO_COPY" 79 | ;; 80 | esac 81 | } 82 | 83 | mkdir -p "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 84 | rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 85 | if [[ "${ACTION}" == "install" ]] && [[ "${SKIP_INSTALL}" == "NO" ]]; then 86 | mkdir -p "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 87 | rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 88 | fi 89 | rm -f "$RESOURCES_TO_COPY" 90 | 91 | if [[ -n "${WRAPPER_EXTENSION}" ]] && [ "`xcrun --find actool`" ] && [ -n "$XCASSET_FILES" ] 92 | then 93 | # Find all other xcassets (this unfortunately includes those of path pods and other targets). 94 | OTHER_XCASSETS=$(find "$PWD" -iname "*.xcassets" -type d) 95 | while read line; do 96 | if [[ $line != "${PODS_ROOT}*" ]]; then 97 | XCASSET_FILES+=("$line") 98 | fi 99 | done <<<"$OTHER_XCASSETS" 100 | 101 | printf "%s\0" "${XCASSET_FILES[@]}" | xargs -0 xcrun actool --output-format human-readable-text --notices --warnings --platform "${PLATFORM_NAME}" --minimum-deployment-target "${!DEPLOYMENT_TARGET_SETTING_NAME}" ${TARGET_DEVICE_ARGS} --compress-pngs --compile "${BUILT_PRODUCTS_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 102 | fi 103 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-Fuse_Tests/Pods-Fuse_Tests-umbrella.h: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | 14 | FOUNDATION_EXPORT double Pods_Fuse_TestsVersionNumber; 15 | FOUNDATION_EXPORT const unsigned char Pods_Fuse_TestsVersionString[]; 16 | 17 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-Fuse_Tests/Pods-Fuse_Tests.debug.xcconfig: -------------------------------------------------------------------------------- 1 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES 2 | FRAMEWORK_SEARCH_PATHS = $(inherited) "$PODS_CONFIGURATION_BUILD_DIR/Fuse" 3 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 4 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' 5 | OTHER_CFLAGS = $(inherited) -iquote "$PODS_CONFIGURATION_BUILD_DIR/Fuse/Fuse.framework/Headers" 6 | OTHER_LDFLAGS = $(inherited) -framework "Fuse" 7 | OTHER_SWIFT_FLAGS = $(inherited) "-D" "COCOAPODS" 8 | PODS_BUILD_DIR = $BUILD_DIR 9 | PODS_CONFIGURATION_BUILD_DIR = $PODS_BUILD_DIR/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 10 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/. 11 | PODS_ROOT = ${SRCROOT}/Pods 12 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-Fuse_Tests/Pods-Fuse_Tests.modulemap: -------------------------------------------------------------------------------- 1 | framework module Pods_Fuse_Tests { 2 | umbrella header "Pods-Fuse_Tests-umbrella.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-Fuse_Tests/Pods-Fuse_Tests.release.xcconfig: -------------------------------------------------------------------------------- 1 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES 2 | FRAMEWORK_SEARCH_PATHS = $(inherited) "$PODS_CONFIGURATION_BUILD_DIR/Fuse" 3 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 4 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' 5 | OTHER_CFLAGS = $(inherited) -iquote "$PODS_CONFIGURATION_BUILD_DIR/Fuse/Fuse.framework/Headers" 6 | OTHER_LDFLAGS = $(inherited) -framework "Fuse" 7 | OTHER_SWIFT_FLAGS = $(inherited) "-D" "COCOAPODS" 8 | PODS_BUILD_DIR = $BUILD_DIR 9 | PODS_CONFIGURATION_BUILD_DIR = $PODS_BUILD_DIR/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 10 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/. 11 | PODS_ROOT = ${SRCROOT}/Pods 12 | -------------------------------------------------------------------------------- /Example/Tests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 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 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /Example/Tests/Tests.swift: -------------------------------------------------------------------------------- 1 | import UIKit 2 | import XCTest 3 | import Fuse 4 | 5 | class Tests: XCTestCase { 6 | 7 | override func setUp() { 8 | super.setUp() 9 | // Put setup code here. This method is called before the invocation of each test method in the class. 10 | } 11 | 12 | override func tearDown() { 13 | // Put teardown code here. This method is called after the invocation of each test method in the class. 14 | super.tearDown() 15 | } 16 | 17 | //MARK: - Basic Tests 18 | func testBasic() { 19 | let fuse = Fuse() 20 | 21 | var pattern = fuse.createPattern(from: "od mn war") 22 | var result = fuse.search(pattern, in: "Old Man's War") 23 | 24 | XCTAssert(result?.score == 0.44444444444444442, "Score is good") 25 | XCTAssert(result?.ranges.count == 3, "Found the correct number of ranges") 26 | 27 | pattern = fuse.createPattern(from: "uni manheim") 28 | result = fuse.search(pattern, in: "university manheim") 29 | XCTAssert(result?.ranges.count == 4, "Found the correct number of ranges") 30 | 31 | pattern = fuse.createPattern(from: "unimanheim") 32 | result = fuse.search(pattern, in: "university manheim") 33 | XCTAssert(result?.ranges.count == 4, "Found the correct number of ranges") 34 | 35 | pattern = fuse.createPattern(from: "xyz") 36 | result = fuse.search(pattern, in: "abc") 37 | XCTAssert(result == nil, "No result") 38 | 39 | pattern = fuse.createPattern(from: "") 40 | result = fuse.search(pattern, in: "abc") 41 | XCTAssert(result == nil, "No result") 42 | } 43 | 44 | func testSequence() { 45 | let books = ["The Lock Artist", "The Lost Symbol", "The Silmarillion", "xyz", "fga"] 46 | 47 | let fuse = Fuse() 48 | let results = fuse.search("Te silm", in: books) 49 | 50 | XCTAssert(results.count > 0, "There are results") 51 | XCTAssert(results[0].index == 2, "The first result is the third book") 52 | XCTAssert(results[1].index == 1, "The second result is the second book") 53 | } 54 | 55 | func testRange() { 56 | let books = ["The Lock Artist", "The Lost Symbol", "The Silmarillion", "xyz", "fga"] 57 | 58 | let fuse = Fuse() 59 | let results = fuse.search("silm", in: books) 60 | 61 | XCTAssert(results[0].ranges.count == 1, "There is a matching range in the first result") 62 | XCTAssert(results[0].ranges[0] == 4...7, "The range goes over the matched substring") 63 | } 64 | 65 | func testProtocolWeightedSearch1() { 66 | struct Book: Fuseable { 67 | let author: String 68 | let title: String 69 | 70 | public init (author: String, title: String) { 71 | self.author = author 72 | self.title = title 73 | } 74 | 75 | var properties: [FuseProperty] { 76 | return [ 77 | FuseProperty(name: title, weight: 0.7), 78 | FuseProperty(name: author, weight: 0.3), 79 | ] 80 | } 81 | } 82 | 83 | let books: [Book] = [ 84 | Book(author: "John X", title: "Old Man's War fiction"), 85 | Book(author: "P.D. Mans", title: "Right Ho Jeeves") 86 | ] 87 | 88 | let fuse = Fuse() 89 | let results = fuse.search("man", in: books) 90 | 91 | XCTAssert(results.count > 0, "There are results") 92 | XCTAssert(results[0].index == 0, "The first result is the first book") 93 | XCTAssert(results[1].index == 1, "The second result is the second book") 94 | } 95 | 96 | func testProtocolWeightedSearch2() { 97 | struct Book: Fuseable { 98 | let author: String 99 | let title: String 100 | 101 | public init (author: String, title: String) { 102 | self.author = author 103 | self.title = title 104 | } 105 | 106 | var properties: [FuseProperty] { 107 | return [ 108 | FuseProperty(name: title, weight: 0.3), 109 | FuseProperty(name: author, weight: 0.7), 110 | ] 111 | } 112 | } 113 | 114 | let books: [Book] = [ 115 | Book(author: "John X", title: "Old Man's War fiction"), 116 | Book(author: "P.D. Mans", title: "Right Ho Jeeves") 117 | ] 118 | 119 | let fuse = Fuse() 120 | let results = fuse.search("man", in: books) 121 | 122 | XCTAssert(results.count > 0, "There are results") 123 | XCTAssert(results[0].index == 1, "The first result is the second book") 124 | XCTAssert(results[1].index == 0, "The second result is the first book") 125 | } 126 | 127 | //MARK: - Tokenize Tests 128 | func testBasicTokenized() { 129 | let fuse = Fuse(tokenize: true) 130 | 131 | var pattern = fuse.createPattern(from: "od mn war") 132 | var result = fuse.search(pattern, in: "Old Man's War") 133 | 134 | XCTAssert(result?.score == 0.39611111111111114, "Score is good \(String(describing: result?.score))") 135 | XCTAssert(result?.ranges.count == 8, "Found the correct number of ranges \(String(describing: result?.ranges))") 136 | 137 | pattern = fuse.createPattern(from: "uni manheim") 138 | result = fuse.search(pattern, in: "university manheim") 139 | XCTAssert(result?.ranges.count == 6, "Found the correct number of ranges \(String(describing: result?.ranges.count))") 140 | 141 | pattern = fuse.createPattern(from: "unimanheim") 142 | result = fuse.search(pattern, in: "university manheim") 143 | XCTAssert(result?.ranges.count == 4, "Found the correct number of ranges \(String(describing: result?.ranges.count))") 144 | 145 | pattern = fuse.createPattern(from: "tuv xyz") 146 | result = fuse.search(pattern, in: "abc") 147 | XCTAssert(result == nil, "No result") 148 | 149 | pattern = fuse.createPattern(from: "") 150 | result = fuse.search(pattern, in: "abc") 151 | XCTAssert(result == nil, "No result") 152 | } 153 | 154 | func testSequenceTokenized() { 155 | let books = ["The Lock Artist", "The Lost Symbol", "The Silmarillion", "xyz", "fga"] 156 | 157 | let fuse = Fuse(tokenize: true) 158 | let results = fuse.search("Te silm", in: books) 159 | 160 | XCTAssert(results.count > 0, "There are results") 161 | XCTAssert(results[0].index == 2, "The first result is the third book") 162 | XCTAssert(results[1].index == 1, "The second result is the second book") 163 | } 164 | 165 | func testSequenceTokenized2() { 166 | let books = ["The Lock Artist", "The Lost Symbol", "The Silmarillion", "xyz", "fga"] 167 | 168 | let fuse = Fuse(tokenize: true) 169 | let results = fuse.search("The Loc", in: books) 170 | 171 | XCTAssert(results.count > 0, "There are results") 172 | XCTAssert(results[0].index == 0, "The first result is the first book") 173 | XCTAssert(results[1].index == 1, "The second result is the second book") 174 | } 175 | 176 | func testRangeTokenized() { 177 | let books = ["The Lock Artist", "The Lost Symbol", "The Silmarillion", "xyz", "fga"] 178 | 179 | let fuse = Fuse(tokenize: true) 180 | let results = fuse.search("silm", in: books) 181 | 182 | XCTAssert(results[0].ranges.count == 1, "There is a matching range in the first result") 183 | XCTAssert(results[0].ranges[0] == 4...7, "The range goes over the matched substring") 184 | } 185 | 186 | func testProtocolWeightedSearchTokenized() { 187 | struct Book: Fuseable { 188 | let author: String 189 | let title: String 190 | 191 | public init (author: String, title: String) { 192 | self.author = author 193 | self.title = title 194 | } 195 | 196 | var properties: [FuseProperty] { 197 | return [ 198 | FuseProperty(name: title, weight: 0.5), 199 | FuseProperty(name: author, weight: 0.5), 200 | ] 201 | } 202 | } 203 | 204 | let books: [Book] = [ 205 | Book(author: "John X", title: "Old Man's War fiction"), 206 | Book(author: "P.D. Mans", title: "Right Ho Jeeves") 207 | ] 208 | 209 | let fuse = Fuse(tokenize: true) 210 | let results = fuse.search("man right", in: books) 211 | 212 | XCTAssert(results.count > 0, "There are results") 213 | XCTAssert(results[0].index == 0, "The first result is the first book") 214 | XCTAssert(results[1].index == 1, "The second result is the second book") 215 | } 216 | 217 | func testProtocolWeightedSearchTokenized2() { 218 | struct Book: Fuseable { 219 | let author: String 220 | let title: String 221 | 222 | public init (author: String, title: String) { 223 | self.author = author 224 | self.title = title 225 | } 226 | 227 | var properties: [FuseProperty] { 228 | return [ 229 | FuseProperty(name: title, weight: 0.5), 230 | FuseProperty(name: author, weight: 0.5), 231 | ] 232 | } 233 | } 234 | 235 | let books: [Book] = [ 236 | Book(author: "John X", title: "Old Man's War fiction"), 237 | Book(author: "John X", title: "Man's Old War fiction") 238 | ] 239 | 240 | let fuse = Fuse(tokenize: true) 241 | let results = fuse.search("john man", in: books) 242 | 243 | XCTAssert(results.count > 0, "There are results") 244 | XCTAssert(results[0].index == 0, "The first result is the first book") 245 | XCTAssert(results[1].index == 1, "The second result is the second book") 246 | } 247 | 248 | //MARK: - Performance Tests 249 | func testPerformanceSync() { 250 | if let path = Bundle(for: type(of: self)).path(forResource: "books", ofType: "txt") { 251 | do { 252 | let data = try String(contentsOfFile: path, encoding: .utf8) 253 | let books = data.components(separatedBy: .newlines) 254 | let fuse = Fuse() 255 | 256 | self.measure { 257 | _ = fuse.search("Th tinsg", in: books) 258 | } 259 | } catch { 260 | print(error) 261 | } 262 | } 263 | } 264 | 265 | func testPerformanceAsync() { 266 | if let path = Bundle(for: type(of: self)).path(forResource: "books", ofType: "txt") { 267 | do { 268 | let data = try String(contentsOfFile: path, encoding: .utf8) 269 | let books = data.components(separatedBy: .newlines) 270 | let fuse = Fuse() 271 | 272 | self.measure { 273 | let expect = self.expectation(description: "searching") 274 | fuse.search("Th tinsg", in: books, completion: { results in 275 | expect.fulfill() 276 | }) 277 | self.wait(for: [expect], timeout: 20000000) 278 | } 279 | } catch { 280 | print(error) 281 | } 282 | } 283 | } 284 | } 285 | -------------------------------------------------------------------------------- /Example/Tests/books.txt: -------------------------------------------------------------------------------- 1 | Never Let Me Go 2 | Animal’s People 3 | The Elegance of the Hedgehog 4 | Saturday 5 | Falling Man 6 | The Children’s Book 7 | On Beauty 8 | The Reluctant Fundamentalist 9 | Invisible 10 | Slow Man 11 | Half of a Yellow Sun 12 | American Rust 13 | Adjunct: An Undigest 14 | The Kindly Ones 15 | Cost: A Novel 16 | The Sea 17 | The Inheritance of Loss 18 | The White Tiger 19 | The Red Queen 20 | Against the Day 21 | Home 22 | The Plot Against America 23 | Carry Me Down 24 | 8Kieron Smith, Boy 25 | The Master 26 | Mother’s Milk 27 | The Gathering 28 | Vanishing Point 29 | Measuring the World 30 | The Blind Side Of The Heart 31 | The Lambs of London 32 | A Short History of Tractors in Ukrainian 33 | The Brief Wondrous Life of Oscar Wao 34 | Dining on Stones 35 | Cloud Atlas 36 | The Accidental 37 | Drop City 38 | The Line of Beauty 39 | The Colour 40 | 2666 41 | Thursbitch 42 | Small Island 43 | The Light of Day 44 | The Book about Blanche and Marie 45 | What I Loved 46 | The Curious Incident of the Dog in the Night-Time 47 | Islands 48 | Suite Francaise 49 | Elizabeth Costello 50 | The Swarm 51 | London Orbital 52 | Family Matters 53 | Your Face Tomorrow 54 | Fingersmith 55 | A Tale of Love and Darkness 56 | The Double 57 | Everything is Illuminated 58 | Unless 59 | Lady Number Thirteen 60 | Kafka on the Shore 61 | The Successor 62 | The Story of Lucy Gault 63 | Vernon God Little 64 | That They May Face the Rising Sun 65 | The Namesake 66 | In the Forest 67 | Shroud 68 | Middlesex 69 | Youth 70 | Dead Air 71 | Snow 72 | Nowhere Man 73 | he Book of Illusions 74 | Gabriel’s Gift 75 | Austerlitz 76 | Platform 77 | Schooling 78 | Soldiers of Salamis 79 | Atonement 80 | I’m Not Scared 81 | The Corrections 82 | Don’t Move 83 | The Amazing Adventures of Kavalier & Clay 84 | The Body Artist 85 | Fury 86 | At Swim, Two Boys 87 | Choke 88 | Life of Pi 89 | The Feast of the Goat 90 | An Obedient Father 91 | The Devil and Miss Prym 92 | Spring Flowers, Spring Frost 93 | Bartleby and Co. 94 | White Teeth 95 | The Heart of Redness 96 | See under the 1900s 97 | Under the Skin 98 | See under the 1900s 99 | Ignorance 100 | See under the 1900s 101 | Nineteen Seventy Seven 102 | Celestial Harmonies 103 | City of God 104 | See under the 1900s 105 | How the Dead Live 106 | See under the 1900s 107 | The Human Stain 108 | The Blind Assassin 109 | After the Quake 110 | See under the 1900s 111 | Small Remedies 112 | Super-Cannes 113 | House of Leaves 114 | Blonde 115 | Pastoralia 116 | See under the 1900s 117 | The Museum of Unconditional Surrender 118 | In Search of Klingsor 119 | Pavel’s Letters 120 | Savage Detectives 121 | Dirty Havana Trilogy 122 | The Heretic 123 | Crossfire 124 | Timbuktu 125 | The Romantics 126 | Cryptonomicon 127 | As If I Am Not There 128 | Money to Burn 129 | Everything You Need 130 | Fear and Trembling 131 | Margot and the Angels 132 | The Ground Beneath Her Feet 133 | Disgrace 134 | Sputnik Sweetheart 135 | Fall on Your Knees 136 | Elementary Particles 137 | A Light Comedy 138 | Intimacy 139 | Amsterdam 140 | Cloudsplitter 141 | All Souls Day 142 | The Talk of the Town 143 | Tipping the Velvet 144 | The Poisonwood Bible 145 | Glamorama 146 | Another World 147 | The Hours 148 | Santa Evita 149 | Veronika Decides to Die 150 | Mason & Dixon 151 | The God of Small Things 152 | Memoirs of a Geisha 153 | Great Apes 154 | The Late-Night News 155 | Enduring Love 156 | Troubling Love 157 | Underworld 158 | Jack Maggs 159 | The Life of Insects 160 | Our Lady of Assassins 161 | American Pastoral 162 | The Untouchable 163 | Silk 164 | Cocaine Nights 165 | Hallucinating Foucault 166 | Fugitive Pieces 167 | The Ghost Road 168 | Deep River 169 | Forever a Stranger 170 | Infinite Jest 171 | The Clay Machine-Gun 172 | Waiting for the Dark, Waiting for the Light 173 | Alias Grace 174 | The Unconsoled 175 | Morvern Callar 176 | The Information 177 | The Twins 178 | The Moor’s Last Sigh 179 | Sabbath’s Theater 180 | The Rings of Saturn 181 | The Reader 182 | A Fine Balance 183 | Love’s Work 184 | The Holder of the World 185 | The End of the Story 186 | Remembering Babylon 187 | Mr. Vertigo 188 | The Adventures and Misadventures of Magroll 189 | The Folding Star 190 | Whatever 191 | Before Night Falls 192 | Land 193 | The Master of Petersburg 194 | The Wind-Up Bird Chronicle 195 | Uncle Petros and Goldbach’s Conjecture 196 | Pereira Declares: A Testimony 197 | The Triple Mirror of the Self 198 | City Sister Silver 199 | All the Pretty Horses 200 | How Late It Was, How Late 201 | Captain Corelli’s Mandolin 202 | Felicia’s Journey 203 | Disappearance 204 | The Invention of Curried Sausage 205 | The Shipping News 206 | The Dumas Club 207 | Trainspotting 208 | Birdsong 209 | Looking for the Possible Dance 210 | Operation Shylock 211 | Memoirs of Rain 212 | Complicity 213 | On Love 214 | What a Carve Up! 215 | A Suitable Boy 216 | The Stone Diaries 217 | The Virgin Suicides 218 | The House of Doctor Dee 219 | Astradeni 220 | The Robber Bride 221 | Faceless Killers 222 | The Emigrants 223 | The Laws 224 | The Secret History 225 | Life is a Caravanserai 226 | The Discovery of Heaven 227 | The Daughter 228 | A Heart So White 229 | Possessing the Secret of Joy 230 | Indigo 231 | The Crow Road 232 | Written on the Body 233 | Jazz 234 | The English Patient 235 | The Shadow Lines 236 | Smilla’s Sense of Snow 237 | The Butcher Boy 238 | Black Water 239 | The Heather Blazing 240 | Asphodel 241 | Black Dogs 242 | Hideous Kinky 243 | Arcadia 244 | The Great Indian Novel 245 | Wild Swans 246 | American Psycho 247 | Time’s Arrow 248 | Mao II 249 | Typical 250 | Inland 251 | Regeneration 252 | Obabakoak 253 | Downriver 254 | Gimmick! 255 | Señor Vivo and the Coca Lord 256 | Wise Children 257 | Paradise of the Blind 258 | Get Shorty 259 | Amongst Women 260 | Vineland 261 | Vertigo 262 | Stone Junction 263 | The Last World 264 | The Music of Chance 265 | The First Garden 266 | The Things They Carried 267 | A Home at the End of the World 268 | Like Life 269 | Possession 270 | Kitchen 271 | The Buddha of Suburbia 272 | The Midnight Examiner 273 | A Disaffection 274 | Sexing the Cherry 275 | Moon Palace 276 | Black Box 277 | Billy Bathgate 278 | Remains of the Day 279 | All Souls 280 | The Melancholy of Resistance 281 | The Temple of My Familiar 282 | Of Love and Shadows 283 | The Trick is to Keep Breathing 284 | The History of the Siege of Lisbon 285 | Like Water for Chocolate 286 | A Prayer for Owen Meany 287 | The Ballad for Georg Henig 288 | London Fields 289 | The Book of Evidence 290 | Cat’s Eye 291 | Foucault’s Pendulum 292 | The Beautiful Room is Empty 293 | Wittgenstein’s Mistress 294 | Memory of Fire 295 | The Satanic Verses 296 | The Swimming-Pool Library 297 | Oscar and Lucinda 298 | Libra 299 | The Player of Games 300 | The Beautiful Mrs. Seidenman 301 | Nervous Conditions 302 | Ancestral Voices 303 | The Long Dark Teatime of the Soul 304 | Dirk Gently’s Holistic Detective Agency 305 | The Radiant Way 306 | Annie John 307 | The Afternoon of a Writer 308 | The Black Dahlia 309 | Simon and the Oaks 310 | The Passion 311 | The Pigeon 312 | Blood Meridian 313 | The Child in Time 314 | Cigarettes 315 | The Bonfire of the Vanities 316 | The New York Trilogy 317 | World’s End 318 | Half of Man is Woman 319 | Enigma of Arrival 320 | The Taebek Mountains 321 | Love Medicine 322 | Beloved 323 | The Young Man 324 | Anagrams 325 | Matigari 326 | Marya 327 | Watchmen 328 | The Old Devils 329 | Lost Language of Cranes 330 | An Artist of the Floating World 331 | Extinction 332 | Democracy 333 | Foe 334 | The Drowned and the Saved 335 | Reasons to Live 336 | The Parable of the Blind 337 | Larva: Midsummer Night’s Babel 338 | Love in the Time of Cholera 339 | Oranges Are Not the Only Fruit 340 | Professor Martens’ Departure 341 | The Cider House Rules 342 | A Maggot 343 | Less Than Zero 344 | Contact 345 | The Witness 346 | The Handmaid’s Tale 347 | Fado Alexandrino 348 | Perfume 349 | The Christmas Oratorio 350 | Old Masters 351 | White Noise 352 | Queer 353 | Hawksmoor 354 | Legend 355 | Dictionary of the Khazars 356 | Baltasar and Blimunda 357 | The Bus Conductor Hines 358 | The Book of Diquiet 359 | The Year of the Death of Ricardo Reis 360 | The Lover 361 | Empire of the Sun 362 | The Wasp Factory 363 | Nights at the Circus 364 | The Unbearable Lightness of Being 365 | Blood and Guts in High School 366 | Neuromancer 367 | Flaubert’s Parrot 368 | Money: A Suicide Note 369 | Couples, Passerby 370 | Shame 371 | Worstward Ho 372 | Fools of Fortune 373 | The War at the End of the World 374 | La Brava 375 | Leaden Wings 376 | Waterland 377 | The House with the Blind Glass Windows 378 | The Life and Times of Michael K 379 | The Diary of Jane Somers 380 | The Piano Teacher 381 | The Sorrow of Belgium 382 | If Not Now, When? 383 | Smell of Sadness 384 | A Boy’s Own Story 385 | The Color Purple 386 | Wittgenstein’s Nephew 387 | Clear Light of Day 388 | A Pale View of Hills 389 | Schindler’s Ark 390 | Southern Seas 391 | The House of the Spirits 392 | The Newton Letter 393 | Fool’s Gold 394 | On the Black Hill 395 | Concrete 396 | A Dry White Season 397 | The Names 398 | Rabbit is Rich 399 | Lanark: A Life in Four Books 400 | So Long a Letter 401 | The Comfort of Strangers 402 | July’s People 403 | Summer in Baden-Baden 404 | Broken April 405 | Waiting for the Barbarians 406 | The Back Room 407 | Midnight’s Children 408 | Rites of Passage 409 | Rituals 410 | Confederacy of Dunces 411 | Requiem for a Dream 412 | City Primeval 413 | The Beggar Maid 414 | The Name of the Rose 415 | The Book of Laughter and Forgetting 416 | Smiley’s People 417 | Shikasta 418 | The Wars 419 | A Bend in the River 420 | Burger’s Daughter 421 | The Safety Net 422 | Quartet in Autumn 423 | If On a Winter’s Night a Traveler 424 | The Engineer of Human Souls 425 | The Hitchhiker’s Guide to the Galaxy 426 | The Cement Garden 427 | Almost Transparent Blue 428 | The World According to Garp 429 | Kiss of the Spider Woman 430 | Life: A User’s Manual 431 | The Sea, The Sea 432 | The Singapore Grip 433 | Yes 434 | Blaming 435 | The Virgin in the Garden 436 | In the Heart of the Country 437 | The Passion of New Eve 438 | Delta of Venus 439 | The Shining 440 | Dispatches 441 | Petals of Blood 442 | Song of Solomon 443 | The Hour of the Star 444 | Woman at Point Zero 445 | The Left-Handed Woman 446 | Ratner’s Star 447 | The Year of the Hare 448 | The Public Burning 449 | The Commandant 450 | Interview With the Vampire 451 | Cutter and Bone 452 | The Port 453 | Amateurs 454 | Patterns of Childhood 455 | Autumn of the Patriarch 456 | W, or the Memory of Childhood 457 | The Diviners 458 | A Dance to the Music of Time 459 | The Dispossessed 460 | Grimus 461 | The Dead Father 462 | Fateless 463 | Willard and His Bowling Trophies 464 | High Rise 465 | Humboldt’s Gift 466 | Dead Babies 467 | Correction 468 | Ragtime 469 | The Optimistrist’s Daughter 470 | The Fan Man 471 | The Twilight Years 472 | Dusklands 473 | The Lost Honor of Katharina Blum 474 | Tinker Tailor Soldier Spy 475 | Breakfast of Champions 476 | Fear of Flying 477 | A Question of Power 478 | Lives of Girls & Women 479 | The Siege of Krishnapur 480 | The Castle of Crossed Destinies 481 | Crash 482 | The Honorary Consul 483 | Cataract 484 | Gravity’s Rainbow 485 | The Black Prince 486 | Sula 487 | Invisible Cities 488 | The Breast 489 | A World for Julius 490 | The Summer Book 491 | G 492 | Play It As It Lays 493 | Surfacing 494 | Fifth Business 495 | House Mother Normal 496 | Here’s to You, Jesusa 497 | In A Free State 498 | Seasons of Migrations to the North 499 | The Book of Daniel 500 | Heartbreak Tango 501 | Fear and Loathing in Las Vegas 502 | Moscow Stations 503 | Group Portrait With Lady 504 | The Case Worker 505 | The Wild Boys 506 | Rabbit Redux 507 | The Sea of Fertility 508 | The Driver’s Seat 509 | The Ogre 510 | The Bluest Eye 511 | Jacob the Liar 512 | Goalie’s Anxiety at the Penalty Kick 513 | I Know Why the Caged Bird Sings 514 | Mercier et Camier 515 | Troubles 516 | Jahrestage 517 | The Atrocity Exhibition 518 | Tent of Miracles 519 | Pricksongs and Descants 520 | Blind Man With a Pistol 521 | Slaughterhouse-five 522 | The French Lieutenant’s Woman 523 | The Green Man 524 | Portnoy’s Complaint 525 | The Godfather 526 | Ada 527 | Them 528 | The Cathedral 529 | A Void/Avoid 530 | Eva Trout 531 | Myra Breckinridge 532 | Day of the Dolphin 533 | The Nice and the Good 534 | Belle du Seigneur 535 | Cancer Ward 536 | The Manor 537 | The First Circle 538 | 2001: A Space Odyssey 539 | Z 540 | Do Androids Dream of Electric Sheep? 541 | Miramar 542 | Dark as the Grave Wherein My Friend is Laid 543 | The German Lesson 544 | In Watermelon Sugar 545 | A Kestrel for a Knave 546 | The Quest for Christa T. 547 | Chocky 548 | Marks of Identity 549 | The Electric Kool-Aid Acid Test 550 | The Cubs and Other Stories 551 | One Hundred Years of Solitude 552 | To Each His Own 553 | The Master and Margarita 554 | Silence 555 | Pilgrimage 556 | Death and the Dervish 557 | The Joke 558 | No Laughing Matter 559 | The Third Policeman 560 | A Man Asleep 561 | Garden, Ashes 562 | The Birds Fall Down 563 | Trawl 564 | Closely Watched Trains 565 | In Cold Blood 566 | Back to Oegstgeest 567 | The Magus 568 | The Vice-Consul 569 | Wide Sargasso Sea 570 | The Three Trapped Tigers 571 | Giles Goat-Boy 572 | The Crying of Lot 49 573 | Things 574 | The River Between 575 | August is a Wicked Month 576 | God Bless You, Mr. Rosewater 577 | Everything That Rises Must Converge 578 | The Passion According to G.H. 579 | Sometimes a Great Notion 580 | Come Back, Dr. Caligari 581 | Albert Angelo 582 | Arrow of God 583 | Dog Years 584 | The Ravishing of Lol V. Stein 585 | The Third Wedding 586 | Herzog 587 | V. 588 | Cat’s Cradle 589 | The Time of the Hero -Mario Vargas Llosa 590 | The Graduate 591 | The Death of Artemio Cruz 592 | Manon des Sources 593 | The Spy Who Came in from the Cold 594 | The Girls of Slender Means 595 | Inside Mr. Enderby 596 | The Bell Jar 597 | Time of Silence 598 | One Day in the Life of Ivan Denisovich 599 | The Collector 600 | One Flew Over the Cuckoo’s Nest 601 | A Clockwork Orange 602 | Memoirs of a Peasant Boy 603 | Pale Fire 604 | The Drowned World 605 | No One Writes to the Colonel 606 | The Golden Notebook 607 | Labyrinths 608 | Girl With Green Eyes 609 | The Garden of the Finzi-Continis 610 | Stranger in a Strange Land 611 | Franny and Zooey 612 | A Severed Head 613 | The Shipyard 614 | Faces in the Water 615 | God’s Bits of Wood 616 | Solaris 617 | Bebo’s Girl 618 | Cat and Mouse 619 | The Prime of Miss Jean Brodie 620 | Halftime 621 | Catch-22 622 | The Magician of Lublin 623 | The Violent Bear it Away 624 | How It Is 625 | Our Ancestors 626 | The Country Girls 627 | To Kill a Mockingbird 628 | Rabbit, Run 629 | Promise at Dawn 630 | Cider With Rosie 631 | Billy Liar 632 | Down Second Avenue 633 | Naked Lunch 634 | The Tin Drum 635 | Absolute Beginners 636 | Henderson the Rain King 637 | Deep Rivers 638 | Memento Mori 639 | Billiards at Half-Past Nine 640 | The Guide 641 | Breakfast at Tiffany’s 642 | The Leopard 643 | Pluck the Bud and Destroy the Offspring 644 | A Town Like Alice 645 | Gabriela, Clove and Cinnamon 646 | The Bitter Glass 647 | Things Fall Apart 648 | Saturday Night and Sunday Morning 649 | Mrs. ‘Arris Goes to Paris 650 | The Birds 651 | Borstal Boy 652 | The End of the Road 653 | The Once and Future King 654 | The Bell 655 | Jealousy 656 | Voss 657 | The Deadbeats 658 | The Midwich Cuckoos 659 | The Manila Rope 660 | Blue Noon 661 | Homo Faber 662 | On the Road 663 | Pnin 664 | The Glass Bees 665 | Doctor Zhivago 666 | The Wonderful “O” 667 | Justine 668 | Giovanni’s Room 669 | The Lonely Londoners 670 | The Roots of Heaven 671 | Seize the Day 672 | The Floating Opera 673 | The Lord of the Rings 674 | The Devil to Pay in the Backlands 675 | The Talented Mr. Ripley 676 | Lolita 677 | The Tree of Man 678 | A World of Love 679 | The Trusting and the Maimed 680 | The Quiet American 681 | The Burning Plain 682 | The Last Temptation of Christ 683 | The Recognitions 684 | The Ragazzi 685 | Bonjour Tristesse 686 | The Unknown Soldier 687 | I’m Not Stiller 688 | The Sound of Waves 689 | Self Condemned 690 | Death in Rome 691 | The Story of O 692 | A Ghost at Noon 693 | The Mandarins 694 | Lord of the Flies 695 | Under the Net 696 | The Go-Between 697 | The Long Goodbye 698 | The Unnamable 699 | A Day in Spring 700 | Watt 701 | The Dark Child 702 | Lucky Jim 703 | Junkie 704 | The Adventures of Augie March 705 | The Hothouse 706 | Go Tell It on the Mountain 707 | The Lost Steps 708 | Casino Royale 709 | The Judge and His Hangman 710 | Invisible Man 711 | The Old Man and the Sea 712 | Wise Blood 713 | A Thousand Cranes 714 | The Killer Inside Me 715 | Excellent Women 716 | Memoirs of Hadrian 717 | Malone Dies 718 | The Day of the Triffids 719 | Foundation 720 | The Opposing Shore 721 | The Hive 722 | The Catcher in the Rye 723 | The Rebel 724 | Molloy 725 | The End of the Affair 726 | The Abbot C 727 | The Labyrinth of Solitude 728 | The Third Man 729 | The 13 Clocks 730 | Gormenghast 731 | The Grass is Singing 732 | Barabbas 733 | I, Robot 734 | The Guiltless 735 | The Moon and the Bonfires 736 | The Garden Where the Brass Band Played 737 | Love in a Cold Climate 738 | The Case of Comrade Tulayev 739 | The Heat of the Day 740 | Kingdom of This World 741 | The Man With the Golden Arm 742 | Nineteen Eighty-Four 743 | All About H. Hatterr 744 | Disobedience 745 | Death Sentence 746 | The Heart of the Matter 747 | Cry, the Beloved Country 748 | Doctor Faustus 749 | The Victim 750 | Exercises in Style 751 | If This Is a Man 752 | The Way for the Gas, Ladies and Gentlemen 753 | Under the Volcano 754 | In The Heart of the Seas 755 | The Path to the Nest of Spiders 756 | The Plague 757 | Back 758 | Titus Groan 759 | Ashes and Diamonds 760 | The Bridge on the Drina 761 | Journey to the Alcarria 762 | Brideshead Revisited 763 | Froth on the Daydream 764 | Animal Farm 765 | Midaq Alley 766 | Cannery Row 767 | The Pursuit of Love 768 | Loving 769 | Arcanum 17 770 | Christ Stopped at Eboli 771 | The Razor’s Edge 772 | Transit 773 | House in the Uplands 774 | Ficciones 775 | Dangling Man 776 | Zorba the Greek 777 | The Little Prince 778 | Caught 779 | The Death of Virgil 780 | The Glass Bead Game 781 | Andrea 782 | Embers 783 | The Tin Flute 784 | Go Down, Moses 785 | Bosnian Chronicle 786 | The Outsider 787 | In Sicily 788 | The Poor Mouth 789 | The Living and the Dead 790 | Hangover Square 791 | Between the Acts 792 | The Hamlet 793 | Pippi Longstocking 794 | Farewell My Lovely 795 | For Whom the Bell Tolls 796 | Native Son 797 | The Power and the Glory 798 | The Tartar Steppe 799 | Joseph and His Brothers 800 | Party Going 801 | The Grapes of Wrath 802 | Chess Story 803 | Finnegans Wake 804 | At Swim-Two-Birds 805 | Coming Up for Air 806 | Goodbye to Berlin 807 | The Harvesters 808 | Tropic of Capricorn 809 | Good Morning, Midnight 810 | Broad and Aliens is the World 811 | The Big Sleep 812 | The Man Who Loved Children 813 | After the Death of Don Juan 814 | Miss Pettigrew Lives for a Day 815 | Nausea 816 | Rebecca 817 | Cause for Alarm 818 | Brighton Rock 819 | U.S. 820 | Murphy 821 | Of Mice and Men 822 | Their Eyes Were Watching God 823 | The Hobbit 824 | On the Edge of Reason 825 | The Years 826 | In Parenthesis 827 | The Revenge for Love 828 | Out of Africa 829 | Alamut 830 | To Have and Have Not 831 | Summer Will Show 832 | Eyeless in Gaza 833 | The Thinking Reed 834 | Gone With the Wind 835 | Keep the Aspidistra Flying 836 | Wild Harbour 837 | Absalom, Absalom! 838 | The Blind Owl 839 | At the Mountains of Madness 840 | Ferdydurke 841 | Nightwood 842 | Independent People 843 | Auto-da-Fé 844 | Rickshaw Boy 845 | The Last of Mr. Norris 846 | They Shoot Horses, Don’t They? 847 | The House in Paris 848 | England Made Me 849 | Burmese Days 850 | The Nine Tailors 851 | War with the Newts 852 | Threepenny Novel 853 | Novel With Cocaine 854 | The Postman Always Rings Twice 855 | Tropic of Cancer 856 | A Handful of Dust 857 | Untouchable 858 | Tender is the Night 859 | Thank You, Jeeves 860 | Call it Sleep 861 | Miss Lonelyhearts 862 | Murder Must Advertise 863 | The Bells of Basel 864 | The Autobiography of Alice Toklas 865 | On the Heights of Despair 866 | Testament of Youth 867 | A Day Off 868 | The Man Without Qualities 869 | A Scots Quair (Sunset Song) 870 | Journey to the End of the Night 871 | The Street of Crocodiles 872 | Brave New World 873 | Cold Comfort Farm 874 | To the North 875 | The Thin Man 876 | The Radetzky March 877 | The Waves 878 | The Glass Key 879 | Man’s Fate 880 | Cakes and Ale 881 | Cheese 882 | The Apes of God 883 | Her Privates We 884 | Vipers’ Tangle 885 | Vile Bodies 886 | The Maltese Falcon 887 | Hebdomeros 888 | The Forbidden Realm 889 | Passing 890 | A Farewell to Arms 891 | The Return of Philip Latinowicz 892 | Red Harvest 893 | Living 894 | The Time of Indifference 895 | All Quiet on the Western Front 896 | Berlin Alexanderplatz 897 | Insatiability 898 | The Last September 899 | Monica 900 | Harriet Hume 901 | The Sound and the Fury 902 | Les Enfants Terribles 903 | Look Homeward, Angel 904 | Story of the Eye 905 | Orlando 906 | Lady Chatterley’s Lover 907 | I Thought of Daisy 908 | The Well of Loneliness 909 | The Childermass 910 | Quartet 911 | Decline and Fall 912 | Quicksand 913 | Parade’s End 914 | Retreat Without Song 915 | Nadja 916 | Steppenwolf 917 | Remembrance of Things Past 918 | To The Lighthouse 919 | Tarka the Otter 920 | Amerika 921 | Some Prefer Nettles 922 | The Sun Also Rises 923 | Blindness 924 | The Castle 925 | The Good Soldier Švejk 926 | The Plumed Serpent 927 | One, None and a Hundred Thousand 928 | The Murder of Roger Ackroyd 929 | The Making of Americans 930 | The Case of Sergeant Grischa 931 | Manhattan Transfer 932 | Mrs. Dalloway 933 | The Great Gatsby 934 | The Counterfeiters 935 | The Trial 936 | Alberta and Jacob 937 | The Artamonov Business 938 | The Professor’s House 939 | Under Satan’s Sun 940 | Billy Budd, Foretopman 941 | The Green Hat 942 | The Magic Mountain 943 | We 944 | Chaka the Zulu 945 | A Passage to India 946 | The Devil in the Flesh 947 | Zeno’s Conscience 948 | Cane 949 | Antic Hay 950 | Amok 951 | The Garden Party 952 | The New World 953 | The Enormous Room 954 | Jacob’s Room 955 | Siddhartha 956 | The Glimpses of the Moon 957 | Life and Death of Harriett Frean 958 | The Last Days of Humanity 959 | Aaron’s Rod 960 | Babbitt 961 | Kristin Lavransdatter 962 | Ulysses 963 | The Fox 964 | Crome Yellow 965 | The Forest of the Hanged 966 | The Age of Innocence 967 | Main Street 968 | Claudine’s House 969 | Women in Love 970 | Night and Day 971 | Tarr 972 | Life of Christ 973 | The Return of the Soldier 974 | The Shadow Line 975 | Summer 976 | Growth of the Soil 977 | Bunner Sisters 978 | The Storm of Steel 979 | A Portrait of the Artist as a Young Man 980 | Under Fire 981 | Rashomon 982 | The Good Soldier 983 | Home and the World 984 | The Voyage Out 985 | Pallieter 986 | Of Human Bondage 987 | The Underdogs 988 | The Rainbow 989 | The Thirty-Nine Steps 990 | Kokoro 991 | Locus Solus 992 | Rosshalde 993 | Tarzan of the Apes 994 | The Ragged Trousered Philanthropists 995 | Sons and Lovers 996 | Death in Venice 997 | The Charwoman’s Daughter 998 | Ethan Frome 999 | Platero and I 1000 | Fantômas 1001 | Howards End 1002 | Impressions of Africa 1003 | Three Lives 1004 | Martin Eden 1005 | Strait is the Gate 1006 | Tono-Bungay 1007 | The Inferno 1008 | A Room With a View 1009 | The Notebooks of Malte Laurids Brigge 1010 | The Iron Heel 1011 | The Old Wives’ Tale 1012 | The House on the Borderland 1013 | Mother 1014 | The Secret Agent 1015 | The Jungle 1016 | Young Törless 1017 | The Forsyte Sage 1018 | The House of Mirth 1019 | Professor Unrat 1020 | Where Angels Fear to Tread 1021 | Nostromo 1022 | Hadrian the Seventh 1023 | The Golden Bowl 1024 | The Ambassadors 1025 | The Riddle of the Sands 1026 | The Way of All Flesh 1027 | The Immoralist 1028 | Memoirs of my Nervous Illness 1029 | The Wings of the Dove 1030 | The Call of the Wild 1031 | Heart of Darkness 1032 | The Hound of the Baskervilles 1033 | Buddenbrooks 1034 | Kim 1035 | Sister Carrie 1036 | Lord Jim 1037 | None but the Brave 1038 | Some Experiences of an Irish R.M. 1039 | The Stechlin 1040 | The Awakening 1041 | See last entry in 1900s. 1042 | The Turn of the Screw 1043 | The War of the Worlds 1044 | Sandokan: The Tigers of Mompracem 1045 | The Invisible Man 1046 | What Maisie Knew 1047 | Eclipse of the Crescent Moon 1048 | Fruits of the Earth 1049 | Dracula 1050 | Quo Vadis 1051 | Dom Casmurro 1052 | The Island of Dr. Moreau 1053 | As a Man Grows Older 1054 | The Time Machine 1055 | Effi Briest 1056 | Jude the Obscure 1057 | Pharoah 1058 | The Real Charlotte 1059 | Compassion 1060 | The Yellow Wallpaper 1061 | Born in Exile 1062 | Diary of a Nobody 1063 | The Adventures of Sherlock Holmes 1064 | News from Nowhere 1065 | New Grub Street 1066 | Gösta Berling’s Saga 1067 | Tess of the D’Urbervilles 1068 | The Viceroys 1069 | The Picture of Dorian Gray 1070 | The Kreutzer Sonata 1071 | La Bête Humaine 1072 | By the Open Sea 1073 | Hunger 1074 | The Master of Ballantrae 1075 | Pierre and Jean 1076 | Down There 1077 | Fortunata and Jacinta 1078 | The People of Hemsö 1079 | The Woodlanders 1080 | Thais 1081 | She 1082 | The Strange Case of Dr. Jekyll and Mr. Hyde 1083 | The Mayor of Casterbridge 1084 | Kidnapped 1085 | Eline Vere 1086 | King Solomon’s Mines 1087 | The Child of Pleasure 1088 | Germinal 1089 | Under the Yoke 1090 | The Adventures of Huckleberry Finn 1091 | Bel-Ami 1092 | Marius the Epicurean 1093 | The Manors of Ulloa 1094 | Against the Grain 1095 | The Death of Ivan Ilyich 1096 | The Quest 1097 | A Woman’s Life 1098 | Treasure Island 1099 | The House by the Medlar Tree 1100 | The Portrait of a Lady 1101 | Bouvard and Pécuchet 1102 | Ben-Hur 1103 | The Regent’s Wife 1104 | Nana 1105 | The Brothers Karamazov 1106 | The Red Room 1107 | Return of the Native 1108 | Anna Karenina 1109 | Drunkard 1110 | The Posthumous Memoirs of Bras Cubas 1111 | Virgin Soil 1112 | Daniel Deronda 1113 | The Hand of Ethelberta 1114 | The Temptation of Saint Anthony 1115 | Far from the Madding Crowd 1116 | The Enchanted Wanderer 1117 | Martin Fierro 1118 | Around the World in Eighty Days 1119 | In a Glass Darkly 1120 | The Devils 1121 | The Crime of Father Amado 1122 | Erewhon 1123 | Pepita Jimenez 1124 | Spring Torrents 1125 | Middlemarch 1126 | Through the Looking Glass, and What Alice Found There 1127 | King Lear of the Steppes 1128 | He Knew He Was Right 1129 | War and Peace 1130 | Sentimental Education 1131 | Phineas Finn 1132 | Maldoror 1133 | The Idiot 1134 | The Moonstone 1135 | Little Women 1136 | Thérèse Raquin 1137 | The Last Chronicle of Barset 1138 | Journey to the Centre of the Earth 1139 | Crime and Punishment 1140 | Alice’s Adventures in Wonderland 1141 | Our Mutual Friend 1142 | Uncle Silas 1143 | Notes from the Underground 1144 | The Water-Babies 1145 | Les Misérables 1146 | Fathers and Sons 1147 | Silas Marner 1148 | Great Expectations 1149 | On the Eve 1150 | Castle Richmond 1151 | The Mill on the Floss 1152 | The Woman in White 1153 | The Marble Faun 1154 | Max Havelaar 1155 | A Tale of Two Cities 1156 | Oblomovka 1157 | Adam Bede 1158 | Madame Bovary 1159 | Indian Summer 1160 | North and South 1161 | Hard Times 1162 | Walden 1163 | Green Henry 1164 | Bleak House 1165 | Villette 1166 | Cranford 1167 | Uncle Tom’s Cabin; or, Life Among the Lonely 1168 | The Blithedale Romance 1169 | The House of the Seven Gables 1170 | Moby-Dick 1171 | The Scarlet Letter 1172 | David Copperfield 1173 | Shirley 1174 | Mary Barton 1175 | The Tenant of Wildfell Hall 1176 | Wuthering Heights 1177 | Agnes Grey 1178 | The Devil’s Pool 1179 | Jane Eyre 1180 | Facundo 1181 | Vanity Fair 1182 | The Count of Monte-Cristo 1183 | La Reine Margot 1184 | The Three Musketeers 1185 | The Purloined Letter 1186 | A Hero of Our Times 1187 | Martin Chuzzlewit 1188 | Camera Obscura 1189 | The Pit and the Pendulum 1190 | Lost Illusions 1191 | A Christmas Carol 1192 | The Lion of Flanders 1193 | Dead Souls 1194 | The Charterhouse of Parma 1195 | The Fall of the House of Usher 1196 | The Life and Adventures of Nicholas Nickleby 1197 | Oliver Twist 1198 | Eugene Onegin 1199 | The Nose 1200 | Le Père Goriot 1201 | Eugénie Grandet 1202 | The Hunchback of Notre Dame 1203 | The Red and the Black 1204 | The Life of a Good-for-Nothing 1205 | The Betrothed 1206 | Last of the Mohicans 1207 | The Life and Opinions of the Tomcat Murr 1208 | The Private Memoirs and Confessions of a Justified Sinner 1209 | The Albigenses 1210 | Melmoth the Wanderer 1211 | The Monastery 1212 | Ivanhoe 1213 | Frankenstein 1214 | Northanger Abbey 1215 | Persuasion 1216 | Ormond 1217 | Michael Kohlhaas 1218 | Rob Roy 1219 | Emma 1220 | Henry of Ofterdingen 1221 | Mansfield Park 1222 | Pride and Prejudice 1223 | The Absentee 1224 | Sense and Sensibility 1225 | Elective Affinities 1226 | Castle Rackrent 1227 | Hyperion 1228 | The Nun 1229 | Camilla 1230 | The Monk 1231 | Wilhelm Meister’s Apprenticeship 1232 | The Mysteries of Udolpho 1233 | A Dream of Red Mansions 1234 | The Interesting Narrative 1235 | The Adventures of Caleb Williams 1236 | Justine 1237 | Anton Reiser 1238 | Vathek 1239 | The 120 Days of Sodom 1240 | Cecilia 1241 | Confessions 1242 | Dangerous Liaisons 1243 | Reveries of a Solitary Walker 1244 | Evelina 1245 | The Sorrows of Young Werther 1246 | Humphrey Clinker 1247 | The Man of Feeling 1248 | A Sentimental Journey 1249 | Tristram Shandy 1250 | The Vicar of Wakefield 1251 | The Castle of Otranto 1252 | Émile; or, On Education 1253 | Rameau’s Nephew 1254 | Julie; or, the New Eloise 1255 | Rasselas 1256 | Candide 1257 | The Female Quixote 1258 | Amelia 1259 | Peregrine Pickle 1260 | Fanny Hill 1261 | Tom Jones 1262 | Roderick Random 1263 | Clarissa 1264 | Pamela 1265 | Jacques the Fatalist 1266 | Memoirs of Martinus Scriblerus 1267 | Joseph Andrews 1268 | A Modest Proposal 1269 | Gulliver’s Travels 1270 | The Adventurous Simplicissimus 1271 | Roxana 1272 | The Conquest of New Spain 1273 | Moll Flanders 1274 | See Pre-1700s 1275 | Love in Excess 1276 | Robinson Crusoe 1277 | See Pre-1700s 1278 | A Tale of a Tub 1279 | The Travels of Persiles and Sigismunda 1280 | Thomas of Reading 1281 | Oroonoko 1282 | Monkey: A Journey to the West 1283 | The Princess of Clèves 1284 | The Lusiad 1285 | The Pilgrim’s Progress 1286 | Don Quixote 1287 | The Life of Lazarillo de Tormes 1288 | The Unfortunate Traveller 1289 | Amadis of Gaul 1290 | Euphues: The Anatomy of Wit 1291 | La Celestina 1292 | Gargantua and Pantagruel 1293 | Tirant lo Blanc 1294 | The Thousand and One Nights 1295 | The Golden Ass 1296 | The Water Margin 1297 | Aithiopika 1298 | Romance of the Three Kingdoms 1299 | Chaireas and Kallirhoe 1300 | The Tale of Genji 1301 | Metamorphoses 1302 | The Tale of the Bamboo Cutter 1303 | Aesop’s Fables 1304 | -------------------------------------------------------------------------------- /Fuse.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | s.name = 'Fuse' 3 | s.version = '1.4.0' 4 | s.summary = 'Fuzzy searching.' 5 | s.description = <<-DESC 6 | A lightweight fuzzy-search library, with zero dependencies 7 | DESC 8 | 9 | s.homepage = 'https://github.com/krisk/fuse-swift' 10 | s.license = { :type => 'MIT', :file => 'LICENSE' } 11 | s.author = { 'Kiro Risk' => 'kirollos@gmail.com' } 12 | s.source = { :git => 'https://github.com/krisk/fuse-swift.git', :tag => s.version.to_s } 13 | s.social_media_url = 'https://twitter.com/kirorisk' 14 | 15 | s.ios.deployment_target = '8.0' 16 | s.osx.deployment_target = '10.13' 17 | s.source_files = 'Fuse/Classes/**/*' 18 | s.swift_version = '5.0' 19 | end 20 | -------------------------------------------------------------------------------- /Fuse/Assets/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krisk/fuse-swift/26ba868691b2d8b7bf2b1322951eb591be70ccca/Fuse/Assets/.gitkeep -------------------------------------------------------------------------------- /Fuse/Classes/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/krisk/fuse-swift/26ba868691b2d8b7bf2b1322951eb591be70ccca/Fuse/Classes/.gitkeep -------------------------------------------------------------------------------- /Fuse/Classes/Fuse.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Fuse.swift 3 | // Pods 4 | // 5 | // Created by Kirollos Risk on 5/2/17. 6 | // 7 | // 8 | 9 | import Foundation 10 | 11 | public struct FuseProperty { 12 | let name: String 13 | let weight: Double 14 | 15 | public init (name: String) { 16 | self.init(name: name, weight: 1) 17 | } 18 | 19 | public init (name: String, weight: Double) { 20 | self.name = name 21 | self.weight = weight 22 | } 23 | } 24 | 25 | public protocol Fuseable { 26 | var properties: [FuseProperty] { get } 27 | } 28 | 29 | public class Fuse { 30 | private var location: Int 31 | private var distance: Int 32 | private var threshold: Double 33 | private var maxPatternLength: Int 34 | private var isCaseSensitive: Bool 35 | private var tokenize: Bool 36 | 37 | public typealias Pattern = (text: String, len: Int, mask: Int, alphabet: [Character: Int]) 38 | 39 | public typealias SearchResult = (index: Int, score: Double, ranges: [CountableClosedRange]) 40 | 41 | public typealias FusableSearchResult = ( 42 | index: Int, 43 | score: Double, 44 | results: [( 45 | key: String, 46 | score: Double, 47 | ranges: [CountableClosedRange] 48 | )] 49 | ) 50 | 51 | fileprivate lazy var searchQueue: DispatchQueue = { [unowned self] in 52 | let label = "fuse.search.queue" 53 | return DispatchQueue(label: label, attributes: .concurrent) 54 | }() 55 | 56 | /// Creates a new instance of `Fuse` 57 | /// 58 | /// - Parameters: 59 | /// - location: Approximately where in the text is the pattern expected to be found. Defaults to `0` 60 | /// - distance: Determines how close the match must be to the fuzzy `location` (specified above). An exact letter match which is `distance` characters away from the fuzzy location would score as a complete mismatch. A distance of `0` requires the match be at the exact `location` specified, a `distance` of `1000` would require a perfect match to be within `800` characters of the fuzzy location to be found using a 0.8 threshold. Defaults to `100` 61 | /// - threshold: At what point does the match algorithm give up. A threshold of `0.0` requires a perfect match (of both letters and location), a threshold of `1.0` would match anything. Defaults to `0.6` 62 | /// - maxPatternLength: The maximum valid pattern length. The longer the pattern, the more intensive the search operation will be. If the pattern exceeds the `maxPatternLength`, the `search` operation will return `nil`. Why is this important? [Read this](https://en.wikipedia.org/wiki/Word_(computer_architecture)#Word_size_choice). Defaults to `32` 63 | /// - isCaseSensitive: Indicates whether comparisons should be case sensitive. Defaults to `false` 64 | /// - tokenize: When true, the search algorithm will search individual words **and** the full string, computing the final score as a function of both. Note that when `tokenize` is `true`, the `threshold`, `distance`, and `location` are inconsequential for individual tokens. 65 | public init (location: Int = 0, distance: Int = 100, threshold: Double = 0.6, maxPatternLength: Int = 32, isCaseSensitive: Bool = false, tokenize: Bool = false) { 66 | self.location = location 67 | self.distance = distance 68 | self.threshold = threshold 69 | self.maxPatternLength = maxPatternLength 70 | self.isCaseSensitive = isCaseSensitive 71 | self.tokenize = tokenize 72 | } 73 | 74 | /// Creates a pattern tuple. 75 | /// 76 | /// - Parameter aString: A string from which to create the pattern tuple 77 | /// - Returns: A tuple containing pattern metadata 78 | public func createPattern (from aString: String) -> Pattern? { 79 | let pattern = self.isCaseSensitive ? aString : aString.lowercased() 80 | let len = pattern.count 81 | 82 | if len == 0 { 83 | return nil 84 | } 85 | 86 | return ( 87 | text: pattern, 88 | len: len, 89 | mask: 1 << (len - 1), 90 | alphabet: FuseUtilities.calculatePatternAlphabet(pattern) 91 | ) 92 | } 93 | 94 | /// Searches for a pattern in a given string. 95 | /// 96 | /// let fuse = Fuse() 97 | /// let pattern = fuse(from: "some text") 98 | /// fuse(pattern, in: "some string") 99 | /// 100 | /// - Parameters: 101 | /// - pattern: The pattern to search for. This is created by calling `createPattern` 102 | /// - aString: The string in which to search for the pattern 103 | /// - Returns: A tuple containing a `score` between `0.0` (exact match) and `1` (not a match), and `ranges` of the matched characters. If no match is found will return nil. 104 | public func search(_ pattern: Pattern?, in aString: String) -> (score: Double, ranges: [CountableClosedRange])? { 105 | guard let pattern = pattern else { 106 | return nil 107 | } 108 | 109 | //If tokenize is set we will split the pattern into individual words and take the average which should result in more accurate matches 110 | if tokenize { 111 | //Split this pattern by the space character 112 | let wordPatterns = pattern.text.split(separator: " ").compactMap { createPattern(from: String($0)) } 113 | 114 | //Get the result for testing the full pattern string. If 2 strings have equal individual word matches this will boost the full string that matches best overall to the top 115 | let fullPatternResult = _search(pattern, in: aString) 116 | 117 | //Reduce all the word pattern matches and the full pattern match into a totals tuple 118 | let results = wordPatterns.reduce(into: fullPatternResult) { (totalResult, pattern) in 119 | let result = _search(pattern, in: aString) 120 | totalResult = (totalResult.score + result.score, totalResult.ranges + result.ranges) 121 | } 122 | 123 | //Average the total score by dividing the summed scores by the number of word searches + the full string search. Also remove any range duplicates since we are searching full string and words individually. 124 | let averagedResult = (score: results.score / Double(wordPatterns.count + 1), ranges: Array>(Set>(results.ranges))) 125 | 126 | //If the averaged score is 1 then there were no matches so return nil. Otherwise return the average result 127 | return averagedResult.score == 1 ? nil : averagedResult 128 | 129 | } else { 130 | let result = _search(pattern, in: aString) 131 | 132 | //If the averaged score is 1 then there were no matches so return nil. Otherwise return the average result 133 | return result.score == 1 ? nil : result 134 | 135 | } 136 | } 137 | 138 | //// Searches for a pattern in a given string. 139 | /// 140 | /// _search(pattern, in: "some string") 141 | /// 142 | /// - Parameters: 143 | /// - pattern: The pattern to search for. This is created by calling `createPattern` 144 | /// - aString: The string in which to search for the pattern 145 | /// - Returns: A tuple containing a `score` between `0.0` (exact match) and `1` (not a match), and `ranges` of the matched characters. If no match is found will return a tuple with score of 1 and empty array of ranges. 146 | private func _search(_ pattern: Pattern, in aString: String) -> (score: Double, ranges: [CountableClosedRange]) { 147 | 148 | var text = aString 149 | 150 | if !self.isCaseSensitive { 151 | text = text.lowercased() 152 | } 153 | 154 | let textLength = text.count 155 | 156 | // Exact match 157 | if (pattern.text == text) { 158 | return (0, [0...textLength - 1]) 159 | } 160 | 161 | let location = self.location 162 | let distance = self.distance 163 | var threshold = self.threshold 164 | 165 | var bestLocation: Int? = { 166 | if let index = text.index(of: pattern.text, startingFrom: location) { 167 | return text.distance(from: text.startIndex, to: index) 168 | } 169 | return nil 170 | }() 171 | 172 | // A mask of the matches. We'll use to determine all the ranges of the matches 173 | var matchMaskArr = [Int](repeating: 0, count: textLength) 174 | 175 | // Get all exact matches, here for speed up 176 | var index = text.index(of: pattern.text, startingFrom: bestLocation) 177 | while (index != nil) { 178 | let i = text.distance(from: text.startIndex, to: index!) 179 | let score = FuseUtilities.calculateScore(pattern.len, 180 | e: 0, 181 | x: i, 182 | loc: location, 183 | distance: distance) 184 | threshold = min(threshold, score) 185 | bestLocation = i + pattern.len 186 | index = text.index(of: pattern.text, startingFrom: bestLocation) 187 | 188 | var idx = 0 189 | while (idx < pattern.len) { 190 | matchMaskArr[i + idx] = 1 191 | idx += 1 192 | } 193 | } 194 | 195 | // Reset the best location 196 | bestLocation = nil 197 | 198 | var score = 1.0 199 | var binMax: Int = pattern.len + textLength 200 | var lastBitArr = [Int]() 201 | 202 | let textCount = text.count 203 | 204 | // Magic begins now 205 | for i in 0.. finish { 231 | continue 232 | } 233 | 234 | var currentLocationIndex: String.Index? = nil 235 | 236 | for j in (start...finish).reversed() { 237 | let currentLocation = j - 1 238 | 239 | // Need to check for `nil` case, since `patternAlphabet` is a sparse hash 240 | let charMatch: Int = { 241 | if currentLocation < textCount { 242 | currentLocationIndex = currentLocationIndex.map{text.index(before: $0)} ?? text.index(text.startIndex, offsetBy: currentLocation) 243 | let char = text[currentLocationIndex!] 244 | if let result = pattern.alphabet[char] { 245 | return result 246 | } 247 | } 248 | return 0 249 | }() 250 | 251 | // A match is found 252 | if charMatch != 0 { 253 | matchMaskArr[currentLocation] = 1 254 | } 255 | 256 | // First pass: exact match 257 | bitArr[j] = ((bitArr[j + 1] << 1) | 1) & charMatch 258 | 259 | // Subsequent passes: fuzzy match 260 | if i > 0 { 261 | bitArr[j] |= (((lastBitArr[j + 1] | lastBitArr[j]) << 1) | 1) | lastBitArr[j + 1] 262 | } 263 | 264 | if (bitArr[j] & pattern.mask) != 0 { 265 | score = FuseUtilities.calculateScore(pattern.len, e: i, x: location, loc: currentLocation, distance: distance) 266 | 267 | // This match will almost certainly be better than any existing match. But check anyway. 268 | if score <= threshold { 269 | // Indeed it is 270 | threshold = score 271 | bestLocation = currentLocation 272 | 273 | guard let bestLocation = bestLocation else { 274 | break 275 | } 276 | 277 | if bestLocation > location { 278 | // When passing `bestLocation`, don't exceed our current distance from the expected `location`. 279 | start = max(1, 2 * location - bestLocation) 280 | } else { 281 | // Already passed `location`. No point in continuing. 282 | break 283 | } 284 | } 285 | } 286 | } 287 | 288 | // No hope for a better match at greater error levels 289 | if FuseUtilities.calculateScore(pattern.len, e: i + 1, x: location, loc: location, distance: distance) > threshold { 290 | break 291 | } 292 | 293 | lastBitArr = bitArr 294 | } 295 | 296 | return (score, FuseUtilities.findRanges(matchMaskArr)) 297 | } 298 | } 299 | 300 | extension Fuse { 301 | /// Searches for a text pattern in a given string. 302 | /// 303 | /// let fuse = Fuse() 304 | /// fuse.search("some text", in: "some string") 305 | /// 306 | /// **Note**: if the same text needs to be searched across many strings, consider creating the pattern once via `createPattern`, and then use the other `search` function. This will improve performance, as the pattern object would only be created once, and re-used across every search call: 307 | /// 308 | /// let fuse = Fuse() 309 | /// let pattern = fuse.createPattern(from: "some text") 310 | /// fuse.search(pattern, in: "some string") 311 | /// fuse.search(pattern, in: "another string") 312 | /// fuse.search(pattern, in: "yet another string") 313 | /// 314 | /// - Parameters: 315 | /// - text: the text string to search for. 316 | /// - aString: The string in which to search for the pattern 317 | /// - Returns: A tuple containing a `score` between `0.0` (exact match) and `1` (not a match), and `ranges` of the matched characters. 318 | public func search(_ text: String, in aString: String) -> (score: Double, ranges: [CountableClosedRange])? { 319 | return self.search(self.createPattern(from: text), in: aString) 320 | } 321 | 322 | /// Searches for a text pattern in an array of srings 323 | /// 324 | /// - Parameters: 325 | /// - text: The pattern string to search for 326 | /// - aList: The list of string in which to search 327 | /// - Returns: A tuple containing the `item` in which the match is found, the `score`, and the `ranges` of the matched characters 328 | public func search(_ text: String, in aList: [String]) -> [SearchResult] { 329 | let pattern = self.createPattern(from: text) 330 | 331 | var items = [SearchResult]() 332 | 333 | for (index, item) in aList.enumerated() { 334 | if let result = self.search(pattern, in: item) { 335 | items.append((index, result.score, result.ranges)) 336 | } 337 | } 338 | 339 | return items.sorted { $0.score < $1.score } 340 | } 341 | 342 | /// Asynchronously searches for a text pattern in an array of srings. 343 | /// 344 | /// - Parameters: 345 | /// - text: The pattern string to search for 346 | /// - aList: The list of string in which to search 347 | /// - chunkSize: The size of a single chunk of the array. For example, if the array has `1000` items, it may be useful to split the work into 10 chunks of 100. This should ideally speed up the search logic. Defaults to `100`. 348 | /// - completion: The handler which is executed upon completion 349 | public func search(_ text: String, in aList: [String], chunkSize: Int = 100, completion: @escaping ([SearchResult]) -> Void) { 350 | let pattern = self.createPattern(from: text) 351 | 352 | var items = [SearchResult]() 353 | 354 | // Serialize writes to `items`, for thread safety. 355 | // This label is non-unique but that should be fine as we don't expect 356 | // to need to debug work items running on this queue. 357 | let itemsQueue = DispatchQueue(label: "fuse.items.queue") 358 | 359 | let group = DispatchGroup() 360 | let count = aList.count 361 | 362 | stride(from: 0, to: count, by: chunkSize).forEach { offset in 363 | let chunk = Array(aList[offset.. [FusableSearchResult] { 426 | let pattern = self.createPattern(from: text) 427 | 428 | var collectionResult = [FusableSearchResult]() 429 | 430 | for (index, item) in aList.enumerated() { 431 | var scores = [Double]() 432 | var totalScore = 0.0 433 | 434 | var propertyResults = [(key: String, score: Double, ranges: [CountableClosedRange])]() 435 | 436 | item.properties.forEach { property in 437 | let value = property.name 438 | 439 | if let result = self.search(pattern, in: value) { 440 | let weight = property.weight == 1 ? 1 : 1 - property.weight 441 | let score = (result.score == 0 && weight == 1 ? 0.001 : result.score) * weight 442 | totalScore += score 443 | 444 | scores.append(score) 445 | 446 | propertyResults.append((key: property.name, score: score, ranges: result.ranges)) 447 | } 448 | } 449 | 450 | if scores.count == 0 { 451 | continue 452 | } 453 | 454 | collectionResult.append(( 455 | index: index, 456 | score: totalScore / Double(scores.count), 457 | results: propertyResults 458 | )) 459 | 460 | } 461 | 462 | return collectionResult.sorted { $0.score < $1.score } 463 | } 464 | 465 | /// Asynchronously searches for a text pattern in an array of `Fuseable` objects. 466 | /// 467 | /// Each `FuseSearchable` object contains a `properties` accessor which returns `FuseProperty` array. Each `FuseProperty` is a tuple containing a `key` (the value of the property which should be included in the search), and a `weight` (how much "weight" to assign to the score) 468 | /// 469 | /// ## Example 470 | /// 471 | /// Ensure the object conforms to `Fuseable`: 472 | /// 473 | /// struct Book: Fuseable { 474 | /// let title: String 475 | /// let author: String 476 | /// 477 | /// var properties: [FuseProperty] { 478 | /// return [ 479 | /// FuseProperty(name: title, weight: 0.3), 480 | /// FuseProperty(name: author, weight: 0.7), 481 | /// ] 482 | /// } 483 | /// } 484 | /// 485 | /// Searching: 486 | /// 487 | /// let books: [Book] = [ 488 | /// Book(author: "John X", title: "Old Man's War fiction"), 489 | /// Book(author: "P.D. Mans", title: "Right Ho Jeeves") 490 | /// ] 491 | /// 492 | /// let fuse = Fuse() 493 | /// fuse.search("Man", in: books, completion: { results in 494 | /// print(results) 495 | /// }) 496 | /// 497 | /// - Parameters: 498 | /// - text: The pattern string to search for 499 | /// - aList: The list of `Fuseable` objects in which to search 500 | /// - chunkSize: The size of a single chunk of the array. For example, if the array has `1000` items, it may be useful to split the work into 10 chunks of 100. This should ideally speed up the search logic. Defaults to `100`. 501 | /// - completion: The handler which is executed upon completion 502 | public func search(_ text: String, in aList: [Fuseable], chunkSize: Int = 100, completion: @escaping ([FusableSearchResult]) -> Void) { 503 | let pattern = self.createPattern(from: text) 504 | 505 | let group = DispatchGroup() 506 | let count = aList.count 507 | 508 | var collectionResult = [FusableSearchResult]() 509 | 510 | // Serialize writes to `collectionResult`, for thread safety. 511 | // This label is non-unique but that should be fine as we don't expect 512 | // to need to debug work items running on this queue. 513 | let collectionResultQueue = DispatchQueue(label: "fuse.result.queue") 514 | 515 | stride(from: 0, to: count, by: chunkSize).forEach { offset in 516 | let chunk = Array(aList[offset..])]() 526 | 527 | item.properties.forEach { property in 528 | 529 | let value = property.name 530 | 531 | if let result = self.search(pattern, in: value) { 532 | let weight = property.weight == 1 ? 1 : 1 - property.weight 533 | let score = result.score * weight 534 | totalScore += score 535 | 536 | scores.append(score) 537 | 538 | propertyResults.append((key: property.name, score: score, ranges: result.ranges)) 539 | } 540 | } 541 | 542 | if scores.count == 0 { 543 | continue 544 | } 545 | 546 | chunkResult.append(( 547 | index: offset + index, 548 | score: totalScore / Double(scores.count), 549 | results: propertyResults 550 | )) 551 | } 552 | 553 | collectionResultQueue.async { 554 | collectionResult.append(contentsOf: chunkResult) 555 | group.leave() 556 | } 557 | } 558 | } 559 | 560 | group.notify(queue: self.searchQueue) { 561 | // This read does not need to be protected by the queue given that 562 | // there's no longer concurrent access at this point. 563 | let sorted = collectionResult.sorted { $0.score < $1.score } 564 | DispatchQueue.main.async { 565 | completion(sorted) 566 | } 567 | } 568 | } 569 | } 570 | 571 | #if swift(>=4.2) 572 | #else 573 | extension CountableClosedRange: Hashable where Element: Hashable { 574 | public var hashValue: Int { return String(describing: self).hashValue } 575 | } 576 | #endif 577 | -------------------------------------------------------------------------------- /Fuse/Classes/FuseUtilities.swift: -------------------------------------------------------------------------------- 1 | // 2 | // FuseUtilities.swift 3 | // Pods 4 | // 5 | // Created by Kirollos Risk on 5/2/17. 6 | // 7 | // 8 | 9 | import Foundation 10 | 11 | class FuseUtilities { 12 | /// Computes the score for a match with `e` errors and `x` location. 13 | /// 14 | /// - Parameter pattern: Pattern being sought. 15 | /// - Parameter e: Number of errors in match. 16 | /// - Parameter x: Location of match. 17 | /// - Parameter loc: Expected location of match. 18 | /// - Parameter scoreTextLength: Coerced version of text's length. 19 | /// - Returns: Overall score for match (0.0 = good, 1.0 = bad). 20 | static func calculateScore(_ pattern: String, e: Int, x: Int, loc: Int, distance: Int) -> Double { 21 | return calculateScore(pattern.count, e: e, x: x, loc: loc, distance: distance) 22 | } 23 | 24 | /// Computes the score for a match with `e` errors and `x` location. 25 | /// 26 | /// - Parameter patternLength: Length of pattern being sought. 27 | /// - Parameter e: Number of errors in match. 28 | /// - Parameter x: Location of match. 29 | /// - Parameter loc: Expected location of match. 30 | /// - Parameter scoreTextLength: Coerced version of text's length. 31 | /// - Returns: Overall score for match (0.0 = good, 1.0 = bad). 32 | static func calculateScore(_ patternLength: Int, e: Int, x: Int, loc: Int, distance: Int) -> Double { 33 | let accuracy = Double(e) / Double(patternLength) 34 | let proximity = abs(x - loc) 35 | if (distance == 0) { 36 | return Double(proximity != 0 ? 1 : accuracy) 37 | } 38 | return Double(accuracy) + (Double(proximity) / Double(distance)) 39 | } 40 | 41 | /// Initializes the alphabet for the Bitap algorithm 42 | /// 43 | /// - Parameter pattern: The text to encode. 44 | /// - Returns: Hash of character locations. 45 | static func calculatePatternAlphabet(_ pattern: String) -> [Character: Int] { 46 | let len = pattern.count 47 | var mask = [Character: Int]() 48 | for (i, c) in pattern.enumerated() { 49 | mask[c] = (mask[c] ?? 0) | (1 << (len - i - 1)) 50 | } 51 | return mask 52 | } 53 | 54 | /// Returns an array of `CountableClosedRange`, where each range represents a consecutive list of `1`s. 55 | /// 56 | /// let arr = [0, 1, 1, 0, 1, 1, 1 ] 57 | /// let ranges = findRanges(arr) 58 | /// // [{startIndex 1, endIndex 2}, {startIndex 4, endIndex 6} 59 | /// 60 | /// - Parameter mask: A string representing the value to search for. 61 | /// 62 | /// - Returns: `CountableClosedRange` array. 63 | static func findRanges(_ mask: [Int]) -> [CountableClosedRange] { 64 | var ranges = [CountableClosedRange]() 65 | var start: Int = -1 66 | for (n, bit) in mask.enumerated() { 67 | if start == -1 && bit == 1 { 68 | start = n 69 | } else if start != -1 && bit == 0 { 70 | ranges.append(CountableClosedRange(start..(start.. Character? { 17 | if index >= self.count { 18 | return nil 19 | } 20 | return self[self.index(self.startIndex, offsetBy: index)] 21 | } 22 | 23 | /// Searches and returns the index within the string of the first occurrence of `searchStr`. 24 | /// 25 | /// - Parameter aString: A string representing the value to search for. 26 | /// - Parameter position: The index at which to start the searching forwards in the string. It can be any integer. The default value is 0, so the whole string is searched. If `position < 0` the entire string is searched. If `position >= str.length`, the string is not searched and `nil` is returned. Unless `searchStr` is an empty string, then str.length is returned. 27 | /// 28 | /// - Returns: The index within the calling String object of the first occurrence of `searchStr`, starting the search at `position`. Returns `nil` if the value is not found. 29 | func index(of aString: String, startingFrom position: Int? = 0) -> String.Index? { 30 | guard let position = position else { 31 | return nil 32 | } 33 | 34 | if self.count < position { 35 | return nil 36 | } 37 | 38 | let start: String.Index = self.index(self.startIndex, offsetBy: position) 39 | let range: Range = Range.init(uncheckedBounds: (lower: start, upper: self.endIndex)) 40 | return self.range(of: aString, options: .literal, range: range, locale: nil)?.lowerBound 41 | } 42 | 43 | /// Searches and returns the index within the string of the last occurrence of the `searchStr`. 44 | /// 45 | /// - Parameter searchStr: A string representing the value to search for. If `searchStr` is an empty string, then `position` is returned. 46 | /// - Parameter position: The index at which to start searching backwards in the string. It can be any integer. The default value is str.length - 1, so the whole string is searched. If `position >= str.length`, the whole string is searched. If `position < 0`, the behavior will be the same as if it would be 0. 47 | /// 48 | /// - Returns: The index of last occurrence of `searchStr`, searching backwards from `position`. Returns `nil` if the value is not found. 49 | func lastIndexOf(_ searchStr: String, position: Int? = 0) -> String.Index? { 50 | guard let position = position else { 51 | return nil 52 | } 53 | 54 | let len = self.count 55 | let start = min(max(position, 0), len) 56 | let searchLen = searchStr.count 57 | let r: Range = Range.init(uncheckedBounds: (lower: self.startIndex, upper: self.index(self.startIndex, offsetBy: min(start + searchLen, len)))) 58 | if let range = self.range(of: searchStr, options: [.backwards, .literal], range: r) { 59 | return range.lowerBound 60 | } else { 61 | return nil 62 | } 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2017 Kirollos Risk 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /Package.swift: -------------------------------------------------------------------------------- 1 | // swift-tools-version:5.0 2 | // The swift-tools-version declares the minimum version of Swift required to build this package. 3 | 4 | import PackageDescription 5 | 6 | let package = Package( 7 | name: "Fuse", 8 | platforms: [ 9 | .iOS(.v8), 10 | .macOS(.v10_13) 11 | ], 12 | products: [ 13 | .library(name: "Fuse", targets: ["Fuse"]), 14 | ], 15 | targets: [ 16 | .target(name: "Fuse", path: "Fuse") 17 | ], 18 | swiftLanguageVersions: [ 19 | .v5 20 | ] 21 | ) 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Fuse 2 | 3 | [![CI Status](http://img.shields.io/travis/krisk/fuse-swift.svg?style=flat)](https://travis-ci.org/krisk/fuse-swift) 4 | [![Version](https://img.shields.io/cocoapods/v/Fuse.svg?style=flat)](http://cocoapods.org/pods/Fuse) 5 | [![License](https://img.shields.io/cocoapods/l/Fuse.svg?style=flat)](http://cocoapods.org/pods/Fuse) 6 | [![Platform](https://img.shields.io/cocoapods/p/Fuse.svg?style=flat)](http://cocoapods.org/pods/Fuse) 7 | [![Donate](https://img.shields.io/badge/Donate-PayPal-red.svg)](https://www.paypal.me/kirorisk) 8 | [![Donate](https://img.shields.io/badge/patreon-donate-red.svg)](https://www.patreon.com/fusejs) 9 | 10 | ## What is Fuse? 11 | 12 | Fuse is a super lightweight library which provides a simple way to do fuzzy searching. 13 | 14 | ![Demo](https://i.postimg.cc/MZNZPD1F/bitap-search-demo.gif) 15 | 16 | ## Usage 17 | 18 | #### Example 1 19 | 20 | ```swift 21 | let fuse = Fuse() 22 | let result = fuse.search("od mn war", in: "Old Man's War") 23 | 24 | print(result?.score) // 0.44444444444444442 25 | print(result?.ranges) // [CountableClosedRange(0...0), CountableClosedRange(2...6), CountableClosedRange(9...12)] 26 | ``` 27 | 28 | #### Example 2 29 | 30 | Search for a text pattern in an array of srings. 31 | 32 | ```swift 33 | let books = ["The Silmarillion", "The Lock Artist", "The Lost Symbol"] 34 | let fuse = Fuse() 35 | 36 | // Improve performance by creating the pattern once 37 | let pattern = fuse.createPattern(from: "Te silm") 38 | 39 | // Search for the pattern in every book 40 | books.forEach { 41 | let result = fuse.search(pattern, in: $0) 42 | print(result?.score) 43 | print(result?.ranges) 44 | } 45 | ``` 46 | 47 | #### Example 3 48 | 49 | ```swift 50 | class Book: Fuseable { 51 | dynamic var name: String 52 | dynamic var author: String 53 | 54 | var properties: [FuseProperty] { 55 | return [ 56 | FuseProperty(name: "title", weight: 0.3), 57 | FuseProperty(name: "author", weight: 0.7), 58 | ] 59 | } 60 | } 61 | 62 | let books: [Book] = [ 63 | Book(author: "John X", title: "Old Man's War fiction"), 64 | Book(author: "P.D. Mans", title: "Right Ho Jeeves") 65 | ] 66 | 67 | let fuse = Fuse() 68 | let results = fuse.search("man", in: books) 69 | 70 | results.forEach { item in 71 | print("index: " + item.index) 72 | print("score: " + item.score) 73 | print("results: " + item.results) 74 | print("---------------") 75 | } 76 | 77 | // Output: 78 | // 79 | // index: 1 80 | // score: 0.015 81 | // results: [(key: "author", score: 0.015000000000000003, ranges: [CountableClosedRange(5...7)])] 82 | // --------------- 83 | // index: 0 84 | // score: 0.028 85 | // results: [(key: "title", score: 0.027999999999999997, ranges: [CountableClosedRange(4...6)])] 86 | ``` 87 | 88 | #### Example 4 89 | 90 | ```swift 91 | let fuse = Fuse() 92 | fuse.search("Man", in: books, completion: { results in 93 | print(results) 94 | }) 95 | ``` 96 | 97 | ### Options 98 | 99 | `Fuse` takes the following options: 100 | 101 | - `location`: Approximately where in the text is the pattern expected to be found. Defaults to `0` 102 | - `distance`: Determines how close the match must be to the fuzzy `location` (specified above). An exact letter match which is `distance` characters away from the fuzzy location would score as a complete mismatch. A distance of `0` requires the match be at the exact `location` specified, a `distance` of `1000` would require a perfect match to be within `800` characters of the fuzzy location to be found using a 0.8 threshold. Defaults to `100` 103 | - `threshold`: At what point does the match algorithm give up. A threshold of `0.0` requires a perfect match (of both letters and location), a threshold of `1.0` would match anything. Defaults to `0.6` 104 | - `maxPatternLength`: The maximum valid pattern length. The longer the pattern, the more intensive the search operation will be. If the pattern exceeds the `maxPatternLength`, the `search` operation will return `nil`. Why is this important? [Read this](https://en.wikipedia.org/wiki/Word_(computer_architecture)#Word_size_choice). Defaults to `32` 105 | - `isCaseSensitive`: Indicates whether comparisons should be case sensitive. Defaults to `false` 106 | 107 | ## Example Project 108 | 109 | To run the example project, clone the repo, and run `pod install` from the Example directory first. 110 | 111 | ## Requirements 112 | 113 | ## Installation 114 | 115 | Fuse is available through [CocoaPods](http://cocoapods.org). To install 116 | it, simply add the following line to your Podfile: 117 | 118 | ```ruby 119 | pod "Fuse" 120 | ``` 121 | 122 | ## License 123 | 124 | Fuse is available under the MIT license. See the LICENSE file for more info. 125 | -------------------------------------------------------------------------------- /_Pods.xcodeproj: -------------------------------------------------------------------------------- 1 | Example/Pods/Pods.xcodeproj --------------------------------------------------------------------------------