├── .gitignore ├── Cartfile.private ├── Cartfile.resolved ├── LICENSE ├── Monocle.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ └── contents.xcworkspacedata └── xcshareddata │ └── xcschemes │ ├── Monocle-Mac.xcscheme │ └── Monocle-iOS.xcscheme ├── Monocle ├── Info.plist ├── Lens.swift └── Monocle.h ├── README.md └── Specs ├── Info.plist └── LensSpec.swift /.gitignore: -------------------------------------------------------------------------------- 1 | Carthage/ 2 | -------------------------------------------------------------------------------- /Cartfile.private: -------------------------------------------------------------------------------- 1 | github "Quick/Nimble" ~> 4.1.0 2 | github "Quick/Quick" ~> 0.9.3 3 | -------------------------------------------------------------------------------- /Cartfile.resolved: -------------------------------------------------------------------------------- 1 | github "Quick/Nimble" "v4.1.0" 2 | github "Quick/Quick" "v0.9.3" 3 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Robert Böhnke 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Monocle.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 544A7A9E1A8E1CD70056DE25 /* Monocle.h in Headers */ = {isa = PBXBuildFile; fileRef = 544A7A9D1A8E1CD70056DE25 /* Monocle.h */; settings = {ATTRIBUTES = (Public, ); }; }; 11 | 544A7AA41A8E1CD70056DE25 /* Monocle.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 544A7A981A8E1CD70056DE25 /* Monocle.framework */; }; 12 | 544A7AC41A8E1D4F0056DE25 /* Monocle.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 544A7AB91A8E1D4E0056DE25 /* Monocle.framework */; }; 13 | 544A7AD31A8E1DAD0056DE25 /* Monocle.h in Headers */ = {isa = PBXBuildFile; fileRef = 544A7A9D1A8E1CD70056DE25 /* Monocle.h */; settings = {ATTRIBUTES = (Public, ); }; }; 14 | 549FBC901A8E27910002D8D6 /* Nimble.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 549FBC8E1A8E27850002D8D6 /* Nimble.framework */; }; 15 | 549FBC911A8E27910002D8D6 /* Quick.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 549FBC8F1A8E27850002D8D6 /* Quick.framework */; }; 16 | 549FBC921A8E279B0002D8D6 /* Nimble.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 549FBC8B1A8E27850002D8D6 /* Nimble.framework */; }; 17 | 549FBC931A8E279B0002D8D6 /* Quick.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 549FBC8C1A8E27850002D8D6 /* Quick.framework */; }; 18 | 549FBC951A8E27D90002D8D6 /* Nimble.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = 549FBC8E1A8E27850002D8D6 /* Nimble.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 19 | 549FBC961A8E27DA0002D8D6 /* Quick.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = 549FBC8F1A8E27850002D8D6 /* Quick.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 20 | 549FBC991A8E27FC0002D8D6 /* Nimble.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = 549FBC8B1A8E27850002D8D6 /* Nimble.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 21 | 549FBC9A1A8E27FC0002D8D6 /* Quick.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = 549FBC8C1A8E27850002D8D6 /* Quick.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 22 | 549FBC9C1A8E295F0002D8D6 /* Lens.swift in Sources */ = {isa = PBXBuildFile; fileRef = 549FBC9B1A8E295E0002D8D6 /* Lens.swift */; }; 23 | 549FBC9D1A8E2A3C0002D8D6 /* Lens.swift in Sources */ = {isa = PBXBuildFile; fileRef = 549FBC9B1A8E295E0002D8D6 /* Lens.swift */; }; 24 | 79FC75651C26EC0700E4BB29 /* LensSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = 544A7AAA1A8E1CD70056DE25 /* LensSpec.swift */; }; 25 | 79FC75661C26EC0800E4BB29 /* LensSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = 544A7AAA1A8E1CD70056DE25 /* LensSpec.swift */; }; 26 | /* End PBXBuildFile section */ 27 | 28 | /* Begin PBXContainerItemProxy section */ 29 | 544A7AA51A8E1CD70056DE25 /* PBXContainerItemProxy */ = { 30 | isa = PBXContainerItemProxy; 31 | containerPortal = 544A7A8F1A8E1CD70056DE25 /* Project object */; 32 | proxyType = 1; 33 | remoteGlobalIDString = 544A7A971A8E1CD70056DE25; 34 | remoteInfo = Monocle; 35 | }; 36 | 544A7AC51A8E1D4F0056DE25 /* PBXContainerItemProxy */ = { 37 | isa = PBXContainerItemProxy; 38 | containerPortal = 544A7A8F1A8E1CD70056DE25 /* Project object */; 39 | proxyType = 1; 40 | remoteGlobalIDString = 544A7AB81A8E1D4E0056DE25; 41 | remoteInfo = "Monocle-iOS"; 42 | }; 43 | /* End PBXContainerItemProxy section */ 44 | 45 | /* Begin PBXCopyFilesBuildPhase section */ 46 | 549FBC941A8E27A50002D8D6 /* Copy Frameworks */ = { 47 | isa = PBXCopyFilesBuildPhase; 48 | buildActionMask = 2147483647; 49 | dstPath = ""; 50 | dstSubfolderSpec = 10; 51 | files = ( 52 | 549FBC951A8E27D90002D8D6 /* Nimble.framework in Copy Frameworks */, 53 | 549FBC961A8E27DA0002D8D6 /* Quick.framework in Copy Frameworks */, 54 | ); 55 | name = "Copy Frameworks"; 56 | runOnlyForDeploymentPostprocessing = 0; 57 | }; 58 | 549FBC981A8E27E90002D8D6 /* Copy Frameworks */ = { 59 | isa = PBXCopyFilesBuildPhase; 60 | buildActionMask = 2147483647; 61 | dstPath = ""; 62 | dstSubfolderSpec = 10; 63 | files = ( 64 | 549FBC991A8E27FC0002D8D6 /* Nimble.framework in Copy Frameworks */, 65 | 549FBC9A1A8E27FC0002D8D6 /* Quick.framework in Copy Frameworks */, 66 | ); 67 | name = "Copy Frameworks"; 68 | runOnlyForDeploymentPostprocessing = 0; 69 | }; 70 | /* End PBXCopyFilesBuildPhase section */ 71 | 72 | /* Begin PBXFileReference section */ 73 | 544A7A981A8E1CD70056DE25 /* Monocle.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Monocle.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 74 | 544A7A9C1A8E1CD70056DE25 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 75 | 544A7A9D1A8E1CD70056DE25 /* Monocle.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Monocle.h; sourceTree = ""; }; 76 | 544A7AA31A8E1CD70056DE25 /* Specs-Mac.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "Specs-Mac.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; 77 | 544A7AA91A8E1CD70056DE25 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 78 | 544A7AAA1A8E1CD70056DE25 /* LensSpec.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LensSpec.swift; sourceTree = ""; }; 79 | 544A7AB91A8E1D4E0056DE25 /* Monocle.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Monocle.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 80 | 544A7AC31A8E1D4E0056DE25 /* Specs-iOS.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "Specs-iOS.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; 81 | 549FBC8B1A8E27850002D8D6 /* Nimble.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = Nimble.framework; sourceTree = ""; }; 82 | 549FBC8C1A8E27850002D8D6 /* Quick.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = Quick.framework; sourceTree = ""; }; 83 | 549FBC8E1A8E27850002D8D6 /* Nimble.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = Nimble.framework; sourceTree = ""; }; 84 | 549FBC8F1A8E27850002D8D6 /* Quick.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = Quick.framework; sourceTree = ""; }; 85 | 549FBC9B1A8E295E0002D8D6 /* Lens.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Lens.swift; sourceTree = ""; }; 86 | /* End PBXFileReference section */ 87 | 88 | /* Begin PBXFrameworksBuildPhase section */ 89 | 544A7A941A8E1CD70056DE25 /* Frameworks */ = { 90 | isa = PBXFrameworksBuildPhase; 91 | buildActionMask = 2147483647; 92 | files = ( 93 | ); 94 | runOnlyForDeploymentPostprocessing = 0; 95 | }; 96 | 544A7AA01A8E1CD70056DE25 /* Frameworks */ = { 97 | isa = PBXFrameworksBuildPhase; 98 | buildActionMask = 2147483647; 99 | files = ( 100 | 544A7AA41A8E1CD70056DE25 /* Monocle.framework in Frameworks */, 101 | 549FBC901A8E27910002D8D6 /* Nimble.framework in Frameworks */, 102 | 549FBC911A8E27910002D8D6 /* Quick.framework in Frameworks */, 103 | ); 104 | runOnlyForDeploymentPostprocessing = 0; 105 | }; 106 | 544A7AB51A8E1D4E0056DE25 /* Frameworks */ = { 107 | isa = PBXFrameworksBuildPhase; 108 | buildActionMask = 2147483647; 109 | files = ( 110 | ); 111 | runOnlyForDeploymentPostprocessing = 0; 112 | }; 113 | 544A7AC01A8E1D4E0056DE25 /* Frameworks */ = { 114 | isa = PBXFrameworksBuildPhase; 115 | buildActionMask = 2147483647; 116 | files = ( 117 | 544A7AC41A8E1D4F0056DE25 /* Monocle.framework in Frameworks */, 118 | 549FBC921A8E279B0002D8D6 /* Nimble.framework in Frameworks */, 119 | 549FBC931A8E279B0002D8D6 /* Quick.framework in Frameworks */, 120 | ); 121 | runOnlyForDeploymentPostprocessing = 0; 122 | }; 123 | /* End PBXFrameworksBuildPhase section */ 124 | 125 | /* Begin PBXGroup section */ 126 | 544A7A8E1A8E1CD70056DE25 = { 127 | isa = PBXGroup; 128 | children = ( 129 | 544A7A9A1A8E1CD70056DE25 /* Monocle */, 130 | 544A7AA71A8E1CD70056DE25 /* Specs */, 131 | 549FBC891A8E27850002D8D6 /* Frameworks */, 132 | 544A7A991A8E1CD70056DE25 /* Products */, 133 | ); 134 | sourceTree = ""; 135 | }; 136 | 544A7A991A8E1CD70056DE25 /* Products */ = { 137 | isa = PBXGroup; 138 | children = ( 139 | 544A7A981A8E1CD70056DE25 /* Monocle.framework */, 140 | 544A7AA31A8E1CD70056DE25 /* Specs-Mac.xctest */, 141 | 544A7AB91A8E1D4E0056DE25 /* Monocle.framework */, 142 | 544A7AC31A8E1D4E0056DE25 /* Specs-iOS.xctest */, 143 | ); 144 | name = Products; 145 | sourceTree = ""; 146 | }; 147 | 544A7A9A1A8E1CD70056DE25 /* Monocle */ = { 148 | isa = PBXGroup; 149 | children = ( 150 | 544A7A9D1A8E1CD70056DE25 /* Monocle.h */, 151 | 549FBC9B1A8E295E0002D8D6 /* Lens.swift */, 152 | 544A7A9B1A8E1CD70056DE25 /* Supporting Files */, 153 | ); 154 | path = Monocle; 155 | sourceTree = ""; 156 | }; 157 | 544A7A9B1A8E1CD70056DE25 /* Supporting Files */ = { 158 | isa = PBXGroup; 159 | children = ( 160 | 544A7A9C1A8E1CD70056DE25 /* Info.plist */, 161 | ); 162 | name = "Supporting Files"; 163 | sourceTree = ""; 164 | }; 165 | 544A7AA71A8E1CD70056DE25 /* Specs */ = { 166 | isa = PBXGroup; 167 | children = ( 168 | 544A7AAA1A8E1CD70056DE25 /* LensSpec.swift */, 169 | 544A7AA81A8E1CD70056DE25 /* Supporting Files */, 170 | ); 171 | path = Specs; 172 | sourceTree = ""; 173 | }; 174 | 544A7AA81A8E1CD70056DE25 /* Supporting Files */ = { 175 | isa = PBXGroup; 176 | children = ( 177 | 544A7AA91A8E1CD70056DE25 /* Info.plist */, 178 | ); 179 | name = "Supporting Files"; 180 | sourceTree = ""; 181 | }; 182 | 549FBC891A8E27850002D8D6 /* Frameworks */ = { 183 | isa = PBXGroup; 184 | children = ( 185 | 549FBC8A1A8E27850002D8D6 /* iOS */, 186 | 549FBC8D1A8E27850002D8D6 /* Mac */, 187 | ); 188 | name = Frameworks; 189 | path = Carthage/Build; 190 | sourceTree = ""; 191 | }; 192 | 549FBC8A1A8E27850002D8D6 /* iOS */ = { 193 | isa = PBXGroup; 194 | children = ( 195 | 549FBC8B1A8E27850002D8D6 /* Nimble.framework */, 196 | 549FBC8C1A8E27850002D8D6 /* Quick.framework */, 197 | ); 198 | path = iOS; 199 | sourceTree = ""; 200 | }; 201 | 549FBC8D1A8E27850002D8D6 /* Mac */ = { 202 | isa = PBXGroup; 203 | children = ( 204 | 549FBC8E1A8E27850002D8D6 /* Nimble.framework */, 205 | 549FBC8F1A8E27850002D8D6 /* Quick.framework */, 206 | ); 207 | path = Mac; 208 | sourceTree = ""; 209 | }; 210 | /* End PBXGroup section */ 211 | 212 | /* Begin PBXHeadersBuildPhase section */ 213 | 544A7A951A8E1CD70056DE25 /* Headers */ = { 214 | isa = PBXHeadersBuildPhase; 215 | buildActionMask = 2147483647; 216 | files = ( 217 | 544A7A9E1A8E1CD70056DE25 /* Monocle.h in Headers */, 218 | ); 219 | runOnlyForDeploymentPostprocessing = 0; 220 | }; 221 | 544A7AB61A8E1D4E0056DE25 /* Headers */ = { 222 | isa = PBXHeadersBuildPhase; 223 | buildActionMask = 2147483647; 224 | files = ( 225 | 544A7AD31A8E1DAD0056DE25 /* Monocle.h in Headers */, 226 | ); 227 | runOnlyForDeploymentPostprocessing = 0; 228 | }; 229 | /* End PBXHeadersBuildPhase section */ 230 | 231 | /* Begin PBXNativeTarget section */ 232 | 544A7A971A8E1CD70056DE25 /* Monocle-Mac */ = { 233 | isa = PBXNativeTarget; 234 | buildConfigurationList = 544A7AAE1A8E1CD70056DE25 /* Build configuration list for PBXNativeTarget "Monocle-Mac" */; 235 | buildPhases = ( 236 | 544A7A931A8E1CD70056DE25 /* Sources */, 237 | 544A7A941A8E1CD70056DE25 /* Frameworks */, 238 | 544A7A951A8E1CD70056DE25 /* Headers */, 239 | 544A7A961A8E1CD70056DE25 /* Resources */, 240 | ); 241 | buildRules = ( 242 | ); 243 | dependencies = ( 244 | ); 245 | name = "Monocle-Mac"; 246 | productName = Monocle; 247 | productReference = 544A7A981A8E1CD70056DE25 /* Monocle.framework */; 248 | productType = "com.apple.product-type.framework"; 249 | }; 250 | 544A7AA21A8E1CD70056DE25 /* Specs-Mac */ = { 251 | isa = PBXNativeTarget; 252 | buildConfigurationList = 544A7AB11A8E1CD70056DE25 /* Build configuration list for PBXNativeTarget "Specs-Mac" */; 253 | buildPhases = ( 254 | 544A7A9F1A8E1CD70056DE25 /* Sources */, 255 | 544A7AA01A8E1CD70056DE25 /* Frameworks */, 256 | 549FBC941A8E27A50002D8D6 /* Copy Frameworks */, 257 | 544A7AA11A8E1CD70056DE25 /* Resources */, 258 | ); 259 | buildRules = ( 260 | ); 261 | dependencies = ( 262 | 544A7AA61A8E1CD70056DE25 /* PBXTargetDependency */, 263 | ); 264 | name = "Specs-Mac"; 265 | productName = Specs; 266 | productReference = 544A7AA31A8E1CD70056DE25 /* Specs-Mac.xctest */; 267 | productType = "com.apple.product-type.bundle.unit-test"; 268 | }; 269 | 544A7AB81A8E1D4E0056DE25 /* Monocle-iOS */ = { 270 | isa = PBXNativeTarget; 271 | buildConfigurationList = 544A7ACC1A8E1D4F0056DE25 /* Build configuration list for PBXNativeTarget "Monocle-iOS" */; 272 | buildPhases = ( 273 | 544A7AB41A8E1D4E0056DE25 /* Sources */, 274 | 544A7AB51A8E1D4E0056DE25 /* Frameworks */, 275 | 544A7AB61A8E1D4E0056DE25 /* Headers */, 276 | 544A7AB71A8E1D4E0056DE25 /* Resources */, 277 | ); 278 | buildRules = ( 279 | ); 280 | dependencies = ( 281 | ); 282 | name = "Monocle-iOS"; 283 | productName = "Monocle-iOS"; 284 | productReference = 544A7AB91A8E1D4E0056DE25 /* Monocle.framework */; 285 | productType = "com.apple.product-type.framework"; 286 | }; 287 | 544A7AC21A8E1D4E0056DE25 /* Specs-iOS */ = { 288 | isa = PBXNativeTarget; 289 | buildConfigurationList = 544A7ACF1A8E1D4F0056DE25 /* Build configuration list for PBXNativeTarget "Specs-iOS" */; 290 | buildPhases = ( 291 | 544A7ABF1A8E1D4E0056DE25 /* Sources */, 292 | 544A7AC01A8E1D4E0056DE25 /* Frameworks */, 293 | 549FBC981A8E27E90002D8D6 /* Copy Frameworks */, 294 | 544A7AC11A8E1D4E0056DE25 /* Resources */, 295 | ); 296 | buildRules = ( 297 | ); 298 | dependencies = ( 299 | 544A7AC61A8E1D4F0056DE25 /* PBXTargetDependency */, 300 | ); 301 | name = "Specs-iOS"; 302 | productName = "Monocle-iOSTests"; 303 | productReference = 544A7AC31A8E1D4E0056DE25 /* Specs-iOS.xctest */; 304 | productType = "com.apple.product-type.bundle.unit-test"; 305 | }; 306 | /* End PBXNativeTarget section */ 307 | 308 | /* Begin PBXProject section */ 309 | 544A7A8F1A8E1CD70056DE25 /* Project object */ = { 310 | isa = PBXProject; 311 | attributes = { 312 | LastSwiftUpdateCheck = 0720; 313 | LastUpgradeCheck = 0810; 314 | ORGANIZATIONNAME = "Robert Böhnke"; 315 | TargetAttributes = { 316 | 544A7A971A8E1CD70056DE25 = { 317 | CreatedOnToolsVersion = 6.1; 318 | LastSwiftMigration = 0810; 319 | }; 320 | 544A7AA21A8E1CD70056DE25 = { 321 | CreatedOnToolsVersion = 6.1; 322 | LastSwiftMigration = 0810; 323 | }; 324 | 544A7AB81A8E1D4E0056DE25 = { 325 | CreatedOnToolsVersion = 6.1; 326 | LastSwiftMigration = 0810; 327 | }; 328 | 544A7AC21A8E1D4E0056DE25 = { 329 | CreatedOnToolsVersion = 6.1; 330 | LastSwiftMigration = 0810; 331 | }; 332 | }; 333 | }; 334 | buildConfigurationList = 544A7A921A8E1CD70056DE25 /* Build configuration list for PBXProject "Monocle" */; 335 | compatibilityVersion = "Xcode 3.2"; 336 | developmentRegion = English; 337 | hasScannedForEncodings = 0; 338 | knownRegions = ( 339 | en, 340 | ); 341 | mainGroup = 544A7A8E1A8E1CD70056DE25; 342 | productRefGroup = 544A7A991A8E1CD70056DE25 /* Products */; 343 | projectDirPath = ""; 344 | projectRoot = ""; 345 | targets = ( 346 | 544A7AB81A8E1D4E0056DE25 /* Monocle-iOS */, 347 | 544A7AC21A8E1D4E0056DE25 /* Specs-iOS */, 348 | 544A7A971A8E1CD70056DE25 /* Monocle-Mac */, 349 | 544A7AA21A8E1CD70056DE25 /* Specs-Mac */, 350 | ); 351 | }; 352 | /* End PBXProject section */ 353 | 354 | /* Begin PBXResourcesBuildPhase section */ 355 | 544A7A961A8E1CD70056DE25 /* Resources */ = { 356 | isa = PBXResourcesBuildPhase; 357 | buildActionMask = 2147483647; 358 | files = ( 359 | ); 360 | runOnlyForDeploymentPostprocessing = 0; 361 | }; 362 | 544A7AA11A8E1CD70056DE25 /* Resources */ = { 363 | isa = PBXResourcesBuildPhase; 364 | buildActionMask = 2147483647; 365 | files = ( 366 | ); 367 | runOnlyForDeploymentPostprocessing = 0; 368 | }; 369 | 544A7AB71A8E1D4E0056DE25 /* Resources */ = { 370 | isa = PBXResourcesBuildPhase; 371 | buildActionMask = 2147483647; 372 | files = ( 373 | ); 374 | runOnlyForDeploymentPostprocessing = 0; 375 | }; 376 | 544A7AC11A8E1D4E0056DE25 /* Resources */ = { 377 | isa = PBXResourcesBuildPhase; 378 | buildActionMask = 2147483647; 379 | files = ( 380 | ); 381 | runOnlyForDeploymentPostprocessing = 0; 382 | }; 383 | /* End PBXResourcesBuildPhase section */ 384 | 385 | /* Begin PBXSourcesBuildPhase section */ 386 | 544A7A931A8E1CD70056DE25 /* Sources */ = { 387 | isa = PBXSourcesBuildPhase; 388 | buildActionMask = 2147483647; 389 | files = ( 390 | 549FBC9D1A8E2A3C0002D8D6 /* Lens.swift in Sources */, 391 | ); 392 | runOnlyForDeploymentPostprocessing = 0; 393 | }; 394 | 544A7A9F1A8E1CD70056DE25 /* Sources */ = { 395 | isa = PBXSourcesBuildPhase; 396 | buildActionMask = 2147483647; 397 | files = ( 398 | 79FC75661C26EC0800E4BB29 /* LensSpec.swift in Sources */, 399 | ); 400 | runOnlyForDeploymentPostprocessing = 0; 401 | }; 402 | 544A7AB41A8E1D4E0056DE25 /* Sources */ = { 403 | isa = PBXSourcesBuildPhase; 404 | buildActionMask = 2147483647; 405 | files = ( 406 | 549FBC9C1A8E295F0002D8D6 /* Lens.swift in Sources */, 407 | ); 408 | runOnlyForDeploymentPostprocessing = 0; 409 | }; 410 | 544A7ABF1A8E1D4E0056DE25 /* Sources */ = { 411 | isa = PBXSourcesBuildPhase; 412 | buildActionMask = 2147483647; 413 | files = ( 414 | 79FC75651C26EC0700E4BB29 /* LensSpec.swift in Sources */, 415 | ); 416 | runOnlyForDeploymentPostprocessing = 0; 417 | }; 418 | /* End PBXSourcesBuildPhase section */ 419 | 420 | /* Begin PBXTargetDependency section */ 421 | 544A7AA61A8E1CD70056DE25 /* PBXTargetDependency */ = { 422 | isa = PBXTargetDependency; 423 | target = 544A7A971A8E1CD70056DE25 /* Monocle-Mac */; 424 | targetProxy = 544A7AA51A8E1CD70056DE25 /* PBXContainerItemProxy */; 425 | }; 426 | 544A7AC61A8E1D4F0056DE25 /* PBXTargetDependency */ = { 427 | isa = PBXTargetDependency; 428 | target = 544A7AB81A8E1D4E0056DE25 /* Monocle-iOS */; 429 | targetProxy = 544A7AC51A8E1D4F0056DE25 /* PBXContainerItemProxy */; 430 | }; 431 | /* End PBXTargetDependency section */ 432 | 433 | /* Begin XCBuildConfiguration section */ 434 | 544A7AAC1A8E1CD70056DE25 /* Debug */ = { 435 | isa = XCBuildConfiguration; 436 | buildSettings = { 437 | ALWAYS_SEARCH_USER_PATHS = NO; 438 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 439 | CLANG_CXX_LIBRARY = "libc++"; 440 | CLANG_ENABLE_MODULES = YES; 441 | CLANG_ENABLE_OBJC_ARC = YES; 442 | CLANG_WARN_BOOL_CONVERSION = YES; 443 | CLANG_WARN_CONSTANT_CONVERSION = YES; 444 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 445 | CLANG_WARN_EMPTY_BODY = YES; 446 | CLANG_WARN_ENUM_CONVERSION = YES; 447 | CLANG_WARN_INFINITE_RECURSION = YES; 448 | CLANG_WARN_INT_CONVERSION = YES; 449 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 450 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 451 | CLANG_WARN_UNREACHABLE_CODE = YES; 452 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 453 | COPY_PHASE_STRIP = NO; 454 | CURRENT_PROJECT_VERSION = 1; 455 | ENABLE_STRICT_OBJC_MSGSEND = YES; 456 | ENABLE_TESTABILITY = YES; 457 | GCC_C_LANGUAGE_STANDARD = gnu99; 458 | GCC_DYNAMIC_NO_PIC = NO; 459 | GCC_NO_COMMON_BLOCKS = YES; 460 | GCC_OPTIMIZATION_LEVEL = 0; 461 | GCC_PREPROCESSOR_DEFINITIONS = ( 462 | "DEBUG=1", 463 | "$(inherited)", 464 | ); 465 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 466 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 467 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 468 | GCC_WARN_UNDECLARED_SELECTOR = YES; 469 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 470 | GCC_WARN_UNUSED_FUNCTION = YES; 471 | GCC_WARN_UNUSED_VARIABLE = YES; 472 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 473 | MACOSX_DEPLOYMENT_TARGET = 10.9; 474 | MTL_ENABLE_DEBUG_INFO = YES; 475 | ONLY_ACTIVE_ARCH = YES; 476 | SDKROOT = macosx; 477 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 478 | VERSIONING_SYSTEM = "apple-generic"; 479 | VERSION_INFO_PREFIX = ""; 480 | }; 481 | name = Debug; 482 | }; 483 | 544A7AAD1A8E1CD70056DE25 /* Release */ = { 484 | isa = XCBuildConfiguration; 485 | buildSettings = { 486 | ALWAYS_SEARCH_USER_PATHS = NO; 487 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 488 | CLANG_CXX_LIBRARY = "libc++"; 489 | CLANG_ENABLE_MODULES = YES; 490 | CLANG_ENABLE_OBJC_ARC = YES; 491 | CLANG_WARN_BOOL_CONVERSION = YES; 492 | CLANG_WARN_CONSTANT_CONVERSION = YES; 493 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 494 | CLANG_WARN_EMPTY_BODY = YES; 495 | CLANG_WARN_ENUM_CONVERSION = YES; 496 | CLANG_WARN_INFINITE_RECURSION = YES; 497 | CLANG_WARN_INT_CONVERSION = YES; 498 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 499 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 500 | CLANG_WARN_UNREACHABLE_CODE = YES; 501 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 502 | COPY_PHASE_STRIP = YES; 503 | CURRENT_PROJECT_VERSION = 1; 504 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 505 | ENABLE_NS_ASSERTIONS = NO; 506 | ENABLE_STRICT_OBJC_MSGSEND = YES; 507 | GCC_C_LANGUAGE_STANDARD = gnu99; 508 | GCC_NO_COMMON_BLOCKS = YES; 509 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 510 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 511 | GCC_WARN_UNDECLARED_SELECTOR = YES; 512 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 513 | GCC_WARN_UNUSED_FUNCTION = YES; 514 | GCC_WARN_UNUSED_VARIABLE = YES; 515 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 516 | MACOSX_DEPLOYMENT_TARGET = 10.9; 517 | MTL_ENABLE_DEBUG_INFO = NO; 518 | SDKROOT = macosx; 519 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 520 | VERSIONING_SYSTEM = "apple-generic"; 521 | VERSION_INFO_PREFIX = ""; 522 | }; 523 | name = Release; 524 | }; 525 | 544A7AAF1A8E1CD70056DE25 /* Debug */ = { 526 | isa = XCBuildConfiguration; 527 | buildSettings = { 528 | COMBINE_HIDPI_IMAGES = YES; 529 | DEFINES_MODULE = YES; 530 | DYLIB_COMPATIBILITY_VERSION = 1; 531 | DYLIB_CURRENT_VERSION = 1; 532 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 533 | FRAMEWORK_VERSION = A; 534 | INFOPLIST_FILE = Monocle/Info.plist; 535 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 536 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks"; 537 | PRODUCT_BUNDLE_IDENTIFIER = "com.robertboehnke.$(PRODUCT_NAME:rfc1034identifier)"; 538 | PRODUCT_NAME = Monocle; 539 | SKIP_INSTALL = YES; 540 | SWIFT_VERSION = 2.3; 541 | }; 542 | name = Debug; 543 | }; 544 | 544A7AB01A8E1CD70056DE25 /* Release */ = { 545 | isa = XCBuildConfiguration; 546 | buildSettings = { 547 | COMBINE_HIDPI_IMAGES = YES; 548 | DEFINES_MODULE = YES; 549 | DYLIB_COMPATIBILITY_VERSION = 1; 550 | DYLIB_CURRENT_VERSION = 1; 551 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 552 | FRAMEWORK_VERSION = A; 553 | INFOPLIST_FILE = Monocle/Info.plist; 554 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 555 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks"; 556 | PRODUCT_BUNDLE_IDENTIFIER = "com.robertboehnke.$(PRODUCT_NAME:rfc1034identifier)"; 557 | PRODUCT_NAME = Monocle; 558 | SKIP_INSTALL = YES; 559 | SWIFT_VERSION = 2.3; 560 | }; 561 | name = Release; 562 | }; 563 | 544A7AB21A8E1CD70056DE25 /* Debug */ = { 564 | isa = XCBuildConfiguration; 565 | buildSettings = { 566 | COMBINE_HIDPI_IMAGES = YES; 567 | FRAMEWORK_SEARCH_PATHS = ( 568 | "$(DEVELOPER_FRAMEWORKS_DIR)", 569 | "$(inherited)", 570 | "$(PROJECT_DIR)/Carthage/Build/Mac", 571 | ); 572 | GCC_PREPROCESSOR_DEFINITIONS = ( 573 | "DEBUG=1", 574 | "$(inherited)", 575 | ); 576 | INFOPLIST_FILE = Specs/Info.plist; 577 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; 578 | PRODUCT_BUNDLE_IDENTIFIER = "com.robertboehnke.$(PRODUCT_NAME:rfc1034identifier)"; 579 | PRODUCT_NAME = "$(TARGET_NAME)"; 580 | SWIFT_VERSION = 2.3; 581 | }; 582 | name = Debug; 583 | }; 584 | 544A7AB31A8E1CD70056DE25 /* Release */ = { 585 | isa = XCBuildConfiguration; 586 | buildSettings = { 587 | COMBINE_HIDPI_IMAGES = YES; 588 | FRAMEWORK_SEARCH_PATHS = ( 589 | "$(DEVELOPER_FRAMEWORKS_DIR)", 590 | "$(inherited)", 591 | "$(PROJECT_DIR)/Carthage/Build/Mac", 592 | ); 593 | INFOPLIST_FILE = Specs/Info.plist; 594 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; 595 | PRODUCT_BUNDLE_IDENTIFIER = "com.robertboehnke.$(PRODUCT_NAME:rfc1034identifier)"; 596 | PRODUCT_NAME = "$(TARGET_NAME)"; 597 | SWIFT_VERSION = 2.3; 598 | }; 599 | name = Release; 600 | }; 601 | 544A7ACD1A8E1D4F0056DE25 /* Debug */ = { 602 | isa = XCBuildConfiguration; 603 | buildSettings = { 604 | CLANG_ENABLE_MODULES = YES; 605 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; 606 | DEFINES_MODULE = YES; 607 | DYLIB_COMPATIBILITY_VERSION = 1; 608 | DYLIB_CURRENT_VERSION = 1; 609 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 610 | GCC_PREPROCESSOR_DEFINITIONS = ( 611 | "DEBUG=1", 612 | "$(inherited)", 613 | ); 614 | INFOPLIST_FILE = Monocle/Info.plist; 615 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 616 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 617 | PRODUCT_BUNDLE_IDENTIFIER = "com.robertboehnke.$(PRODUCT_NAME:rfc1034identifier)"; 618 | PRODUCT_NAME = Monocle; 619 | SDKROOT = iphoneos; 620 | SKIP_INSTALL = YES; 621 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 622 | SWIFT_VERSION = 2.3; 623 | TARGETED_DEVICE_FAMILY = "1,2"; 624 | }; 625 | name = Debug; 626 | }; 627 | 544A7ACE1A8E1D4F0056DE25 /* Release */ = { 628 | isa = XCBuildConfiguration; 629 | buildSettings = { 630 | CLANG_ENABLE_MODULES = YES; 631 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; 632 | DEFINES_MODULE = YES; 633 | DYLIB_COMPATIBILITY_VERSION = 1; 634 | DYLIB_CURRENT_VERSION = 1; 635 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 636 | INFOPLIST_FILE = Monocle/Info.plist; 637 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 638 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 639 | PRODUCT_BUNDLE_IDENTIFIER = "com.robertboehnke.$(PRODUCT_NAME:rfc1034identifier)"; 640 | PRODUCT_NAME = Monocle; 641 | SDKROOT = iphoneos; 642 | SKIP_INSTALL = YES; 643 | SWIFT_VERSION = 2.3; 644 | TARGETED_DEVICE_FAMILY = "1,2"; 645 | VALIDATE_PRODUCT = YES; 646 | }; 647 | name = Release; 648 | }; 649 | 544A7AD01A8E1D4F0056DE25 /* Debug */ = { 650 | isa = XCBuildConfiguration; 651 | buildSettings = { 652 | FRAMEWORK_SEARCH_PATHS = ( 653 | "$(inherited)", 654 | "$(PROJECT_DIR)/Carthage/Build/iOS", 655 | ); 656 | GCC_PREPROCESSOR_DEFINITIONS = ( 657 | "DEBUG=1", 658 | "$(inherited)", 659 | ); 660 | INFOPLIST_FILE = Specs/Info.plist; 661 | IPHONEOS_DEPLOYMENT_TARGET = 8.1; 662 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 663 | PRODUCT_BUNDLE_IDENTIFIER = "com.robertboehnke.$(PRODUCT_NAME:rfc1034identifier)"; 664 | PRODUCT_NAME = "$(TARGET_NAME)"; 665 | SDKROOT = iphoneos; 666 | SWIFT_VERSION = 2.3; 667 | }; 668 | name = Debug; 669 | }; 670 | 544A7AD11A8E1D4F0056DE25 /* Release */ = { 671 | isa = XCBuildConfiguration; 672 | buildSettings = { 673 | FRAMEWORK_SEARCH_PATHS = ( 674 | "$(inherited)", 675 | "$(PROJECT_DIR)/Carthage/Build/iOS", 676 | ); 677 | INFOPLIST_FILE = Specs/Info.plist; 678 | IPHONEOS_DEPLOYMENT_TARGET = 8.1; 679 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 680 | PRODUCT_BUNDLE_IDENTIFIER = "com.robertboehnke.$(PRODUCT_NAME:rfc1034identifier)"; 681 | PRODUCT_NAME = "$(TARGET_NAME)"; 682 | SDKROOT = iphoneos; 683 | SWIFT_VERSION = 2.3; 684 | VALIDATE_PRODUCT = YES; 685 | }; 686 | name = Release; 687 | }; 688 | /* End XCBuildConfiguration section */ 689 | 690 | /* Begin XCConfigurationList section */ 691 | 544A7A921A8E1CD70056DE25 /* Build configuration list for PBXProject "Monocle" */ = { 692 | isa = XCConfigurationList; 693 | buildConfigurations = ( 694 | 544A7AAC1A8E1CD70056DE25 /* Debug */, 695 | 544A7AAD1A8E1CD70056DE25 /* Release */, 696 | ); 697 | defaultConfigurationIsVisible = 0; 698 | defaultConfigurationName = Release; 699 | }; 700 | 544A7AAE1A8E1CD70056DE25 /* Build configuration list for PBXNativeTarget "Monocle-Mac" */ = { 701 | isa = XCConfigurationList; 702 | buildConfigurations = ( 703 | 544A7AAF1A8E1CD70056DE25 /* Debug */, 704 | 544A7AB01A8E1CD70056DE25 /* Release */, 705 | ); 706 | defaultConfigurationIsVisible = 0; 707 | defaultConfigurationName = Release; 708 | }; 709 | 544A7AB11A8E1CD70056DE25 /* Build configuration list for PBXNativeTarget "Specs-Mac" */ = { 710 | isa = XCConfigurationList; 711 | buildConfigurations = ( 712 | 544A7AB21A8E1CD70056DE25 /* Debug */, 713 | 544A7AB31A8E1CD70056DE25 /* Release */, 714 | ); 715 | defaultConfigurationIsVisible = 0; 716 | defaultConfigurationName = Release; 717 | }; 718 | 544A7ACC1A8E1D4F0056DE25 /* Build configuration list for PBXNativeTarget "Monocle-iOS" */ = { 719 | isa = XCConfigurationList; 720 | buildConfigurations = ( 721 | 544A7ACD1A8E1D4F0056DE25 /* Debug */, 722 | 544A7ACE1A8E1D4F0056DE25 /* Release */, 723 | ); 724 | defaultConfigurationIsVisible = 0; 725 | defaultConfigurationName = Release; 726 | }; 727 | 544A7ACF1A8E1D4F0056DE25 /* Build configuration list for PBXNativeTarget "Specs-iOS" */ = { 728 | isa = XCConfigurationList; 729 | buildConfigurations = ( 730 | 544A7AD01A8E1D4F0056DE25 /* Debug */, 731 | 544A7AD11A8E1D4F0056DE25 /* Release */, 732 | ); 733 | defaultConfigurationIsVisible = 0; 734 | defaultConfigurationName = Release; 735 | }; 736 | /* End XCConfigurationList section */ 737 | }; 738 | rootObject = 544A7A8F1A8E1CD70056DE25 /* Project object */; 739 | } 740 | -------------------------------------------------------------------------------- /Monocle.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Monocle.xcodeproj/xcshareddata/xcschemes/Monocle-Mac.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 29 | 35 | 36 | 37 | 38 | 39 | 44 | 45 | 47 | 53 | 54 | 55 | 56 | 57 | 63 | 64 | 65 | 66 | 67 | 68 | 78 | 79 | 85 | 86 | 87 | 88 | 89 | 90 | 96 | 97 | 103 | 104 | 105 | 106 | 108 | 109 | 112 | 113 | 114 | -------------------------------------------------------------------------------- /Monocle.xcodeproj/xcshareddata/xcschemes/Monocle-iOS.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 29 | 35 | 36 | 37 | 38 | 39 | 44 | 45 | 47 | 53 | 54 | 55 | 56 | 57 | 63 | 64 | 65 | 66 | 67 | 68 | 78 | 79 | 85 | 86 | 87 | 88 | 89 | 90 | 96 | 97 | 103 | 104 | 105 | 106 | 108 | 109 | 112 | 113 | 114 | -------------------------------------------------------------------------------- /Monocle/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.0.1 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | $(CURRENT_PROJECT_VERSION) 23 | NSHumanReadableCopyright 24 | Copyright © 2015 Robert Böhnke. All rights reserved. 25 | NSPrincipalClass 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /Monocle/Lens.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Lens.swift 3 | // Monocle 4 | // 5 | // Created by Robert Böhnke on 1/17/15. 6 | // Copyright (c) 2015 Robert Böhnke. All rights reserved. 7 | // 8 | 9 | public struct Lens { 10 | private let get: A -> B 11 | private let set: (A, B) -> A 12 | 13 | public init(get: A -> B, set: (A, B) -> A) { 14 | self.get = get 15 | self.set = set 16 | } 17 | 18 | public init(get: A -> B, set: (inout A, B) -> ()) { 19 | self.get = get 20 | self.set = { (a, b) in 21 | var a = a 22 | set(&a, b) 23 | return a 24 | } 25 | } 26 | } 27 | 28 | // MARK: - Basics 29 | 30 | public func get(lens: Lens, _ a: A) -> B { 31 | return lens.get(a) 32 | } 33 | 34 | public func get(lens: Lens) -> (A) -> B { 35 | return {(a: A) -> B in 36 | return lens.get(a) 37 | } 38 | } 39 | 40 | public func get(lens: Lens, _ a: A?) -> B? { 41 | return a.map(lens.get) 42 | } 43 | 44 | public func get(lens: Lens) -> (A?) -> B? { 45 | return {(a: A?) -> B? in 46 | return a.map(lens.get) 47 | } 48 | } 49 | 50 | public func set(lens: Lens, _ a: A, _ b: B) -> A { 51 | return lens.set(a, b) 52 | } 53 | 54 | public func set(lens: Lens, _ a: A) -> (B) -> A { 55 | return {(b: B) -> A in 56 | return lens.set(a, b) 57 | } 58 | } 59 | 60 | public func mod(lens: Lens, _ a: A, _ f: B -> B) -> A { 61 | return set(lens, a, f(get(lens, a))) 62 | } 63 | 64 | // MARK: - Compose 65 | 66 | public func compose(left: Lens, _ right: Lens) -> Lens { 67 | let get: A -> C = { a in 68 | return right.get(left.get(a)) 69 | } 70 | 71 | let set: (A, C) -> A = { a, c in 72 | return left.set(a, right.set(left.get(a), c)) 73 | } 74 | 75 | return Lens(get: get, set: set) 76 | } 77 | 78 | infix operator >>> { 79 | associativity right 80 | precedence 170 81 | } 82 | 83 | public func >>> (lhs: Lens, rhs: Lens) -> Lens { 84 | return compose(lhs, rhs) 85 | } 86 | 87 | infix operator <<< { 88 | associativity right 89 | precedence 170 90 | } 91 | 92 | public func <<< (lhs: Lens, rhs: Lens) -> Lens { 93 | return compose(rhs, lhs) 94 | } 95 | 96 | // MARK: - Lift 97 | 98 | public func lift(lens: Lens) -> Lens<[A], [B]> { 99 | let get: [A] -> [B] = { xs in 100 | return xs.map(lens.get) 101 | } 102 | 103 | let set: ([A], [B]) -> [A] = { xs, ys in 104 | return zip(xs, ys).map(lens.set) 105 | } 106 | 107 | return Lens(get: get, set: set) 108 | } 109 | 110 | // MARK: - Split 111 | 112 | public func split(left: Lens, _ right: Lens) -> Lens<(A, C), (B, D)> { 113 | let get: (A, C) -> (B, D) = { (a, c) in 114 | return (left.get(a), right.get(c)) 115 | } 116 | 117 | let set: ((A, C), (B, D)) -> (A, C) = { (fst, snd) in 118 | return (left.set(fst.0, snd.0), right.set(fst.1, snd.1)) 119 | } 120 | 121 | return Lens(get: get, set: set) 122 | } 123 | 124 | infix operator *** { 125 | associativity left 126 | precedence 150 127 | } 128 | 129 | public func *** (lhs: Lens, rhs: Lens) -> Lens<(A, C), (B, D)> { 130 | return split(lhs, rhs) 131 | } 132 | 133 | // MARK: - Fanout 134 | 135 | public func fanout(left: Lens, _ right: Lens) -> Lens { 136 | let get: A -> (B, C) = { a in 137 | return (left.get(a), right.get(a)) 138 | } 139 | 140 | let set: (A, (B, C)) -> A = { (a, input) in 141 | return right.set(left.set(a, input.0), input.1) 142 | } 143 | 144 | return Lens(get: get, set: set) 145 | } 146 | 147 | infix operator &&& { 148 | associativity left 149 | precedence 120 150 | } 151 | 152 | public func &&& (lhs: Lens, rhs: Lens) -> Lens { 153 | return fanout(lhs, rhs) 154 | } 155 | -------------------------------------------------------------------------------- /Monocle/Monocle.h: -------------------------------------------------------------------------------- 1 | // 2 | // Monocle.h 3 | // Monocle 4 | // 5 | // Created by Robert Böhnke on 13/02/15. 6 | // Copyright (c) 2015 Robert Böhnke. All rights reserved. 7 | // 8 | 9 | //! Project version number for Monocle. 10 | extern double MonocleVersionNumber; 11 | 12 | //! Project version string for Monocle. 13 | extern const unsigned char MonocleVersionString[]; 14 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Monoೃcle 2 | 3 | A [lens] as a µFramework. 4 | 5 | [lens]: http://chris.eidhof.nl/posts/lenses-in-swift.html 6 | -------------------------------------------------------------------------------- /Specs/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 | -------------------------------------------------------------------------------- /Specs/LensSpec.swift: -------------------------------------------------------------------------------- 1 | // 2 | // LensSpec.swift 3 | // Pistachio 4 | // 5 | // Created by Robert Böhnke on 1/17/15. 6 | // Copyright (c) 2015 Robert Böhnke. All rights reserved. 7 | // 8 | 9 | import Monocle 10 | 11 | import Quick 12 | import Nimble 13 | 14 | struct Inner: Equatable { 15 | var count: Int 16 | } 17 | 18 | func == (lhs: Inner, rhs: Inner) -> Bool { 19 | return lhs.count == rhs.count 20 | } 21 | 22 | struct Outer: Equatable { 23 | var count: Int 24 | 25 | var inner: Inner 26 | 27 | init(count: Int = 0, inner: Inner = Inner(count: 0)) { 28 | self.count = count 29 | self.inner = inner 30 | } 31 | } 32 | 33 | func == (lhs: Outer, rhs: Outer) -> Bool { 34 | return lhs.count == rhs.count && lhs.inner == rhs.inner 35 | } 36 | 37 | struct OuterLenses { 38 | static let count = Lens(get: { $0.count }, set: { (inout outer: Outer, count) in 39 | outer.count = count 40 | }) 41 | 42 | static let inner = Lens(get: { $0.inner }, set: { (inout outer: Outer, inner) in 43 | outer.inner = inner 44 | }) 45 | } 46 | 47 | struct InnerLenses { 48 | static let count = Lens(get: { $0.count }, set: { (inout inner: Inner, count) in 49 | inner.count = count 50 | }) 51 | } 52 | 53 | class LensSpec: QuickSpec { 54 | override func spec() { 55 | describe("A Lens") { 56 | let example: Outer = Outer(count: 2) 57 | 58 | let count = OuterLenses.count 59 | 60 | it("should get values") { 61 | expect(get(count, example)!).to(equal(2)) 62 | } 63 | 64 | it("should set values") { 65 | expect(set(count, example, 4)).to(equal(Outer(count: 4))) 66 | } 67 | 68 | it("should modify values") { 69 | expect(mod(count, example, { $0 + 2 })).to(equal(Outer(count: 4))) 70 | } 71 | } 72 | 73 | describe("A composed Lens") { 74 | let example = Outer(count: 0, inner: Inner(count: 2)) 75 | 76 | let innerCount = OuterLenses.inner >>> InnerLenses.count 77 | 78 | it("should get values") { 79 | expect(get(innerCount, example)!).to(equal(2)) 80 | } 81 | 82 | it("should set values") { 83 | expect(set(innerCount, example, 4)).to(equal(Outer(count: 0, inner: Inner(count: 4)))) 84 | } 85 | 86 | it("should modify values") { 87 | expect(mod(innerCount, example, { $0 + 2 })).to(equal(Outer(count: 0, inner: Inner(count: 4)))) 88 | } 89 | } 90 | 91 | describe("Lifted lenses") { 92 | context("for arrays") { 93 | let inner = [ 94 | Inner(count: 1), 95 | Inner(count: 2), 96 | Inner(count: 3), 97 | Inner(count: 4) 98 | ] 99 | 100 | let lifted = lift(InnerLenses.count) 101 | 102 | it("should get values") { 103 | let result = get(lifted, inner) 104 | 105 | expect(result).to(equal([ 1, 2, 3, 4 ])) 106 | } 107 | 108 | it("should set values") { 109 | let result = set(lifted, inner, [ 2, 4, 6, 8 ]) 110 | 111 | expect(result).to(equal([ 112 | Inner(count: 2), 113 | Inner(count: 4), 114 | Inner(count: 6), 115 | Inner(count: 8) 116 | ])) 117 | } 118 | 119 | it("should reduce the resulting array size accordingly") { 120 | // Does this make sense? 121 | let result = set(lifted, inner, [ 42 ]) 122 | 123 | expect(result).to(equal([ 124 | Inner(count: 42) 125 | ])) 126 | } 127 | } 128 | } 129 | 130 | describe("Split lenses") { 131 | let outer = Outer(count: 2, inner: Inner(count: 4)) 132 | let inner = Inner(count: 9) 133 | 134 | let both = OuterLenses.count *** InnerLenses.count 135 | 136 | it("should get values") { 137 | let result = get(both, (outer, inner)) 138 | 139 | expect(result.0).to(equal(2)) 140 | expect(result.1).to(equal(9)) 141 | } 142 | 143 | it("should set values") { 144 | let result = set(both, (outer, inner), (12, 34)) 145 | 146 | expect(result.0.count).to(equal(12)) 147 | expect(result.0.inner.count).to(equal(4)) 148 | expect(result.1.count).to(equal(34)) 149 | } 150 | } 151 | 152 | describe("Fanned out lenses") { 153 | let example = Outer(count: 0, inner: Inner(count: 2)) 154 | 155 | let both = OuterLenses.count &&& (OuterLenses.inner >>> InnerLenses.count) 156 | 157 | it("should get values") { 158 | let result = get(both, example) 159 | 160 | expect(result.0).to(equal(0)) 161 | expect(result.1).to(equal(2)) 162 | } 163 | 164 | it("should set values") { 165 | let result = set(both, example, (12, 34)) 166 | 167 | expect(result.count).to(equal(12)) 168 | expect(result.inner.count).to(equal(34)) 169 | } 170 | } 171 | } 172 | } 173 | --------------------------------------------------------------------------------