diff --git a/Example/PNImagePickerViewController.xcodeproj/project.pbxproj b/Example/PNImagePickerViewController.xcodeproj/project.pbxproj index 2a3f3e5..62a383d 100644 --- a/Example/PNImagePickerViewController.xcodeproj/project.pbxproj +++ b/Example/PNImagePickerViewController.xcodeproj/project.pbxproj @@ -20,7 +20,10 @@ 6003F5B2195388D20070C39A /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6003F591195388D20070C39A /* UIKit.framework */; }; 6003F5BA195388D20070C39A /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 6003F5B8195388D20070C39A /* InfoPlist.strings */; }; 6003F5BC195388D20070C39A /* Tests.m in Sources */ = {isa = PBXBuildFile; fileRef = 6003F5BB195388D20070C39A /* Tests.m */; }; + 681785911C69DCB50032DAAC /* PNImagePickerViewController.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 681785901C69DCB50032DAAC /* PNImagePickerViewController.framework */; }; + 7D97D76088572AF45812187E /* Pods_PNImagePickerViewController_Tests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4328521B225C017B57B0EA26 /* Pods_PNImagePickerViewController_Tests.framework */; }; 873B8AEB1B1F5CCA007FD442 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 873B8AEA1B1F5CCA007FD442 /* Main.storyboard */; }; + D6C71C75B8F5800EC9990F14 /* Pods_PNImagePickerViewController_Example.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 685260EDF68D7C851442C12E /* Pods_PNImagePickerViewController_Example.framework */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -34,7 +37,9 @@ /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ - 2A510C8BD6FA22FF4BF841CC /* README.md */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = file; name = README.md; path = ../README.md; sourceTree = ""; }; + 12535CEF396FF4D6369EA5C0 /* Pods-PNImagePickerViewController_Tests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-PNImagePickerViewController_Tests.release.xcconfig"; path = "Pods/Target Support Files/Pods-PNImagePickerViewController_Tests/Pods-PNImagePickerViewController_Tests.release.xcconfig"; sourceTree = ""; }; + 2A510C8BD6FA22FF4BF841CC /* README.md */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = net.daringfireball.markdown; name = README.md; path = ../README.md; sourceTree = ""; }; + 4328521B225C017B57B0EA26 /* Pods_PNImagePickerViewController_Tests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_PNImagePickerViewController_Tests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 6003F58A195388D20070C39A /* PNImagePickerViewController_Example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = PNImagePickerViewController_Example.app; sourceTree = BUILT_PRODUCTS_DIR; }; 6003F58D195388D20070C39A /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 6003F58F195388D20070C39A /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; @@ -54,8 +59,13 @@ 6003F5B9195388D20070C39A /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; 6003F5BB195388D20070C39A /* Tests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = Tests.m; sourceTree = ""; }; 606FC2411953D9B200FFA9A0 /* Tests-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Tests-Prefix.pch"; sourceTree = ""; }; + 681785901C69DCB50032DAAC /* PNImagePickerViewController.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = PNImagePickerViewController.framework; path = "Pods/../build/Debug-iphoneos/PNImagePickerViewController.framework"; sourceTree = ""; }; + 685260EDF68D7C851442C12E /* Pods_PNImagePickerViewController_Example.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_PNImagePickerViewController_Example.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 86D18E23BB421419B8132D08 /* Pods-PNImagePickerViewController_Example.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-PNImagePickerViewController_Example.debug.xcconfig"; path = "Pods/Target Support Files/Pods-PNImagePickerViewController_Example/Pods-PNImagePickerViewController_Example.debug.xcconfig"; sourceTree = ""; }; 873B8AEA1B1F5CCA007FD442 /* Main.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = Main.storyboard; sourceTree = ""; }; - 930DB7C275684056258BA5EF /* PNImagePickerViewController.podspec */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = file; name = PNImagePickerViewController.podspec; path = ../PNImagePickerViewController.podspec; sourceTree = ""; }; + 930DB7C275684056258BA5EF /* PNImagePickerViewController.podspec */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = PNImagePickerViewController.podspec; path = ../PNImagePickerViewController.podspec; sourceTree = ""; }; + 98D3978B62130F866F704B9C /* Pods-PNImagePickerViewController_Example.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-PNImagePickerViewController_Example.release.xcconfig"; path = "Pods/Target Support Files/Pods-PNImagePickerViewController_Example/Pods-PNImagePickerViewController_Example.release.xcconfig"; sourceTree = ""; }; + 9DECFF91FBC10CAD6C7AEE1E /* Pods-PNImagePickerViewController_Tests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-PNImagePickerViewController_Tests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-PNImagePickerViewController_Tests/Pods-PNImagePickerViewController_Tests.debug.xcconfig"; sourceTree = ""; }; AD447568A76DA895F7B37A24 /* LICENSE */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = LICENSE; path = ../LICENSE; sourceTree = ""; }; /* End PBXFileReference section */ @@ -64,9 +74,11 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 681785911C69DCB50032DAAC /* PNImagePickerViewController.framework in Frameworks */, 6003F590195388D20070C39A /* CoreGraphics.framework in Frameworks */, 6003F592195388D20070C39A /* UIKit.framework in Frameworks */, 6003F58E195388D20070C39A /* Foundation.framework in Frameworks */, + D6C71C75B8F5800EC9990F14 /* Pods_PNImagePickerViewController_Example.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -77,6 +89,7 @@ 6003F5B0195388D20070C39A /* XCTest.framework in Frameworks */, 6003F5B2195388D20070C39A /* UIKit.framework in Frameworks */, 6003F5B1195388D20070C39A /* Foundation.framework in Frameworks */, + 7D97D76088572AF45812187E /* Pods_PNImagePickerViewController_Tests.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -91,6 +104,7 @@ 6003F5B5195388D20070C39A /* Tests */, 6003F58C195388D20070C39A /* Frameworks */, 6003F58B195388D20070C39A /* Products */, + 9BA892B7D07729CC69D18118 /* Pods */, ); sourceTree = ""; }; @@ -106,10 +120,13 @@ 6003F58C195388D20070C39A /* Frameworks */ = { isa = PBXGroup; children = ( + 681785901C69DCB50032DAAC /* PNImagePickerViewController.framework */, 6003F58D195388D20070C39A /* Foundation.framework */, 6003F58F195388D20070C39A /* CoreGraphics.framework */, 6003F591195388D20070C39A /* UIKit.framework */, 6003F5AF195388D20070C39A /* XCTest.framework */, + 685260EDF68D7C851442C12E /* Pods_PNImagePickerViewController_Example.framework */, + 4328521B225C017B57B0EA26 /* Pods_PNImagePickerViewController_Tests.framework */, ); name = Frameworks; sourceTree = ""; @@ -169,6 +186,17 @@ name = "Podspec Metadata"; sourceTree = ""; }; + 9BA892B7D07729CC69D18118 /* Pods */ = { + isa = PBXGroup; + children = ( + 86D18E23BB421419B8132D08 /* Pods-PNImagePickerViewController_Example.debug.xcconfig */, + 98D3978B62130F866F704B9C /* Pods-PNImagePickerViewController_Example.release.xcconfig */, + 9DECFF91FBC10CAD6C7AEE1E /* Pods-PNImagePickerViewController_Tests.debug.xcconfig */, + 12535CEF396FF4D6369EA5C0 /* Pods-PNImagePickerViewController_Tests.release.xcconfig */, + ); + name = Pods; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ @@ -176,9 +204,12 @@ isa = PBXNativeTarget; buildConfigurationList = 6003F5BF195388D20070C39A /* Build configuration list for PBXNativeTarget "PNImagePickerViewController_Example" */; buildPhases = ( + F8D96CF8CF3D374B5AAE33C4 /* Check Pods Manifest.lock */, 6003F586195388D20070C39A /* Sources */, 6003F587195388D20070C39A /* Frameworks */, 6003F588195388D20070C39A /* Resources */, + B94FCDE98F285449578D9F34 /* Embed Pods Frameworks */, + 56476F9757949999164002B1 /* Copy Pods Resources */, ); buildRules = ( ); @@ -193,9 +224,12 @@ isa = PBXNativeTarget; buildConfigurationList = 6003F5C2195388D20070C39A /* Build configuration list for PBXNativeTarget "PNImagePickerViewController_Tests" */; buildPhases = ( + 2FD43162D7B4455C62B23FFC /* Check Pods Manifest.lock */, 6003F5AA195388D20070C39A /* Sources */, 6003F5AB195388D20070C39A /* Frameworks */, 6003F5AC195388D20070C39A /* Resources */, + 6C7D9A9333266674130B4B6D /* Embed Pods Frameworks */, + B6A2E7AB4CD0217BA75EC551 /* Copy Pods Resources */, ); buildRules = ( ); @@ -222,7 +256,7 @@ }; }; }; - buildConfigurationList = 6003F585195388D10070C39A /* Build configuration list for PBXProject "PROJECT" */; + buildConfigurationList = 6003F585195388D10070C39A /* Build configuration list for PBXProject "PNImagePickerViewController" */; compatibilityVersion = "Xcode 3.2"; developmentRegion = English; hasScannedForEncodings = 0; @@ -262,6 +296,99 @@ }; /* End PBXResourcesBuildPhase section */ +/* Begin PBXShellScriptBuildPhase section */ + 2FD43162D7B4455C62B23FFC /* Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Check Pods Manifest.lock"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [[ $? != 0 ]] ; then\n cat << EOM\nerror: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\nEOM\n exit 1\nfi\n"; + showEnvVarsInLog = 0; + }; + 56476F9757949999164002B1 /* Copy Pods Resources */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Copy Pods Resources"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-PNImagePickerViewController_Example/Pods-PNImagePickerViewController_Example-resources.sh\"\n"; + showEnvVarsInLog = 0; + }; + 6C7D9A9333266674130B4B6D /* Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Embed Pods Frameworks"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-PNImagePickerViewController_Tests/Pods-PNImagePickerViewController_Tests-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; + B6A2E7AB4CD0217BA75EC551 /* Copy Pods Resources */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Copy Pods Resources"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-PNImagePickerViewController_Tests/Pods-PNImagePickerViewController_Tests-resources.sh\"\n"; + showEnvVarsInLog = 0; + }; + B94FCDE98F285449578D9F34 /* Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Embed Pods Frameworks"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-PNImagePickerViewController_Example/Pods-PNImagePickerViewController_Example-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; + F8D96CF8CF3D374B5AAE33C4 /* Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Check Pods Manifest.lock"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [[ $? != 0 ]] ; then\n cat << EOM\nerror: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\nEOM\n exit 1\nfi\n"; + showEnvVarsInLog = 0; + }; +/* End PBXShellScriptBuildPhase section */ + /* Begin PBXSourcesBuildPhase section */ 6003F586195388D20070C39A /* Sources */ = { isa = PBXSourcesBuildPhase; @@ -344,7 +471,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 7.1; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; TARGETED_DEVICE_FAMILY = "1,2"; @@ -377,7 +504,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 7.1; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; SDKROOT = iphoneos; TARGETED_DEVICE_FAMILY = "1,2"; VALIDATE_PRODUCT = YES; @@ -386,9 +513,14 @@ }; 6003F5C0195388D20070C39A /* Debug */ = { isa = XCBuildConfiguration; + baseConfigurationReference = 86D18E23BB421419B8132D08 /* Pods-PNImagePickerViewController_Example.debug.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/build/Debug-iphoneos", + ); GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "PNImagePickerViewController/PNImagePickerViewController-Prefix.pch"; INFOPLIST_FILE = "PNImagePickerViewController/PNImagePickerViewController-Info.plist"; @@ -401,9 +533,14 @@ }; 6003F5C1195388D20070C39A /* Release */ = { isa = XCBuildConfiguration; + baseConfigurationReference = 98D3978B62130F866F704B9C /* Pods-PNImagePickerViewController_Example.release.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/build/Debug-iphoneos", + ); GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "PNImagePickerViewController/PNImagePickerViewController-Prefix.pch"; INFOPLIST_FILE = "PNImagePickerViewController/PNImagePickerViewController-Info.plist"; @@ -416,6 +553,7 @@ }; 6003F5C3195388D20070C39A /* Debug */ = { isa = XCBuildConfiguration; + baseConfigurationReference = 9DECFF91FBC10CAD6C7AEE1E /* Pods-PNImagePickerViewController_Tests.debug.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; FRAMEWORK_SEARCH_PATHS = ( @@ -439,6 +577,7 @@ }; 6003F5C4195388D20070C39A /* Release */ = { isa = XCBuildConfiguration; + baseConfigurationReference = 12535CEF396FF4D6369EA5C0 /* Pods-PNImagePickerViewController_Tests.release.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; FRAMEWORK_SEARCH_PATHS = ( @@ -459,7 +598,7 @@ /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ - 6003F585195388D10070C39A /* Build configuration list for PBXProject "PROJECT" */ = { + 6003F585195388D10070C39A /* Build configuration list for PBXProject "PNImagePickerViewController" */ = { isa = XCConfigurationList; buildConfigurations = ( 6003F5BD195388D20070C39A /* Debug */, diff --git a/Example/PNImagePickerViewController.xcworkspace/contents.xcworkspacedata b/Example/PNImagePickerViewController.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..13df54e --- /dev/null +++ b/Example/PNImagePickerViewController.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,10 @@ + + + + + + + diff --git a/Example/PNImagePickerViewController/Images.xcassets/AppIcon.appiconset/Contents.json b/Example/PNImagePickerViewController/Images.xcassets/AppIcon.appiconset/Contents.json index f697f61..eeea76c 100644 --- a/Example/PNImagePickerViewController/Images.xcassets/AppIcon.appiconset/Contents.json +++ b/Example/PNImagePickerViewController/Images.xcassets/AppIcon.appiconset/Contents.json @@ -5,16 +5,31 @@ "size" : "29x29", "scale" : "2x" }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x" + }, { "idiom" : "iphone", "size" : "40x40", "scale" : "2x" }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "3x" + }, { "idiom" : "iphone", "size" : "60x60", "scale" : "2x" }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "3x" + }, { "idiom" : "ipad", "size" : "29x29", @@ -44,10 +59,15 @@ "idiom" : "ipad", "size" : "76x76", "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "83.5x83.5", + "scale" : "2x" } ], "info" : { "version" : 1, "author" : "xcode" } -} +} \ No newline at end of file diff --git a/Example/PNImagePickerViewController/Images.xcassets/LaunchImage.launchimage/Contents.json b/Example/PNImagePickerViewController/Images.xcassets/LaunchImage.launchimage/Contents.json index 4458b40..6a4b539 100644 --- a/Example/PNImagePickerViewController/Images.xcassets/LaunchImage.launchimage/Contents.json +++ b/Example/PNImagePickerViewController/Images.xcassets/LaunchImage.launchimage/Contents.json @@ -1,46 +1,157 @@ { "images" : [ { - "orientation" : "portrait", - "idiom" : "iphone", "extent" : "full-screen", + "idiom" : "iphone", + "filename" : "Default.png", + "orientation" : "portrait", + "scale" : "1x" + }, + { + "extent" : "full-screen", + "idiom" : "iphone", + "filename" : "Default@2x.png", "minimum-system-version" : "7.0", + "orientation" : "portrait", "scale" : "2x" }, { - "orientation" : "portrait", + "extent" : "full-screen", "idiom" : "iphone", "subtype" : "retina4", - "extent" : "full-screen", - "minimum-system-version" : "7.0", + "filename" : "Default-568h@2x.png", + "orientation" : "portrait", "scale" : "2x" }, { + "extent" : "full-screen", + "idiom" : "iphone", + "subtype" : "retina4", + "filename" : "Default-568h@2x.png", + "minimum-system-version" : "7.0", "orientation" : "portrait", - "idiom" : "ipad", - "extent" : "full-screen", - "minimum-system-version" : "7.0", - "scale" : "1x" - }, - { - "orientation" : "landscape", - "idiom" : "ipad", - "extent" : "full-screen", - "minimum-system-version" : "7.0", - "scale" : "1x" - }, - { - "orientation" : "portrait", - "idiom" : "ipad", - "extent" : "full-screen", - "minimum-system-version" : "7.0", "scale" : "2x" }, { - "orientation" : "landscape", - "idiom" : "ipad", "extent" : "full-screen", + "idiom" : "iphone", + "filename" : "Default@2x.png", + "orientation" : "portrait", + "scale" : "2x" + }, + { + "extent" : "to-status-bar", + "idiom" : "ipad", + "filename" : "Default~ipad.png", + "orientation" : "portrait", + "scale" : "1x" + }, + { + "extent" : "to-status-bar", + "idiom" : "ipad", + "filename" : "Default~ipad@2x.png", + "orientation" : "portrait", + "scale" : "2x" + }, + { + "extent" : "to-status-bar", + "idiom" : "ipad", + "filename" : "Default~ipad~landscape.png", + "orientation" : "landscape", + "scale" : "1x" + }, + { + "extent" : "to-status-bar", + "idiom" : "ipad", + "filename" : "Default~ipad~landscape@2x.png", + "orientation" : "landscape", + "scale" : "2x" + }, + { + "extent" : "full-screen", + "idiom" : "ipad", + "filename" : "Default~ipad~nostatusbar.png", "minimum-system-version" : "7.0", + "orientation" : "portrait", + "scale" : "1x" + }, + { + "extent" : "full-screen", + "idiom" : "ipad", + "filename" : "Default~ipad~nostatusbar.png", + "orientation" : "portrait", + "scale" : "1x" + }, + { + "extent" : "full-screen", + "idiom" : "ipad", + "filename" : "Default~ipad~nostatusbar@2x.png", + "minimum-system-version" : "7.0", + "orientation" : "portrait", + "scale" : "2x" + }, + { + "extent" : "full-screen", + "idiom" : "ipad", + "filename" : "Default~ipad~nostatusbar@2x.png", + "orientation" : "portrait", + "scale" : "2x" + }, + { + "extent" : "full-screen", + "idiom" : "ipad", + "filename" : "Default~ipad~landscape~nostatusbar.png", + "minimum-system-version" : "7.0", + "orientation" : "landscape", + "scale" : "1x" + }, + { + "extent" : "full-screen", + "idiom" : "ipad", + "filename" : "Default~ipad~landscape~nostatusbar.png", + "orientation" : "landscape", + "scale" : "1x" + }, + { + "extent" : "full-screen", + "idiom" : "ipad", + "filename" : "Default~ipad~landscape~nostatusbar@2x.png", + "minimum-system-version" : "7.0", + "orientation" : "landscape", + "scale" : "2x" + }, + { + "extent" : "full-screen", + "idiom" : "ipad", + "filename" : "Default~ipad~landscape~nostatusbar@2x.png", + "orientation" : "landscape", + "scale" : "2x" + }, + { + "extent" : "full-screen", + "idiom" : "iphone", + "subtype" : "736h", + "filename" : "Default-Portrait-736h@3x.png", + "minimum-system-version" : "8.0", + "orientation" : "portrait", + "scale" : "3x" + }, + { + "extent" : "full-screen", + "idiom" : "iphone", + "subtype" : "736h", + "filename" : "Default-Landscape-736h@3x.png", + "minimum-system-version" : "8.0", + "orientation" : "landscape", + "scale" : "3x" + }, + { + "extent" : "full-screen", + "idiom" : "iphone", + "subtype" : "667h", + "filename" : "Default-667h@2x.png", + "minimum-system-version" : "8.0", + "orientation" : "portrait", "scale" : "2x" } ], @@ -48,4 +159,4 @@ "version" : 1, "author" : "xcode" } -} +} \ No newline at end of file diff --git a/Example/PNImagePickerViewController/Images.xcassets/LaunchImage.launchimage/Default-568h@2x.png b/Example/PNImagePickerViewController/Images.xcassets/LaunchImage.launchimage/Default-568h@2x.png new file mode 100644 index 0000000..eba951c Binary files /dev/null and b/Example/PNImagePickerViewController/Images.xcassets/LaunchImage.launchimage/Default-568h@2x.png differ diff --git a/Example/PNImagePickerViewController/Images.xcassets/LaunchImage.launchimage/Default-667h@2x.png b/Example/PNImagePickerViewController/Images.xcassets/LaunchImage.launchimage/Default-667h@2x.png new file mode 100644 index 0000000..7c5f3bd Binary files /dev/null and b/Example/PNImagePickerViewController/Images.xcassets/LaunchImage.launchimage/Default-667h@2x.png differ diff --git a/Example/PNImagePickerViewController/Images.xcassets/LaunchImage.launchimage/Default-Landscape-736h@3x.png b/Example/PNImagePickerViewController/Images.xcassets/LaunchImage.launchimage/Default-Landscape-736h@3x.png new file mode 100644 index 0000000..bc0e221 Binary files /dev/null and b/Example/PNImagePickerViewController/Images.xcassets/LaunchImage.launchimage/Default-Landscape-736h@3x.png differ diff --git a/Example/PNImagePickerViewController/Images.xcassets/LaunchImage.launchimage/Default-Portrait-736h@3x.png b/Example/PNImagePickerViewController/Images.xcassets/LaunchImage.launchimage/Default-Portrait-736h@3x.png new file mode 100644 index 0000000..e6eefb6 Binary files /dev/null and b/Example/PNImagePickerViewController/Images.xcassets/LaunchImage.launchimage/Default-Portrait-736h@3x.png differ diff --git a/Example/PNImagePickerViewController/Images.xcassets/LaunchImage.launchimage/Default.png b/Example/PNImagePickerViewController/Images.xcassets/LaunchImage.launchimage/Default.png new file mode 100644 index 0000000..31c51d2 Binary files /dev/null and b/Example/PNImagePickerViewController/Images.xcassets/LaunchImage.launchimage/Default.png differ diff --git a/Example/PNImagePickerViewController/Images.xcassets/LaunchImage.launchimage/Default@2x.png b/Example/PNImagePickerViewController/Images.xcassets/LaunchImage.launchimage/Default@2x.png new file mode 100644 index 0000000..aeb50bf Binary files /dev/null and b/Example/PNImagePickerViewController/Images.xcassets/LaunchImage.launchimage/Default@2x.png differ diff --git a/Example/PNImagePickerViewController/Images.xcassets/LaunchImage.launchimage/Default~ipad.png b/Example/PNImagePickerViewController/Images.xcassets/LaunchImage.launchimage/Default~ipad.png new file mode 100644 index 0000000..680d830 Binary files /dev/null and b/Example/PNImagePickerViewController/Images.xcassets/LaunchImage.launchimage/Default~ipad.png differ diff --git a/Example/PNImagePickerViewController/Images.xcassets/LaunchImage.launchimage/Default~ipad@2x.png b/Example/PNImagePickerViewController/Images.xcassets/LaunchImage.launchimage/Default~ipad@2x.png new file mode 100644 index 0000000..d7e5097 Binary files /dev/null and b/Example/PNImagePickerViewController/Images.xcassets/LaunchImage.launchimage/Default~ipad@2x.png differ diff --git a/Example/PNImagePickerViewController/Images.xcassets/LaunchImage.launchimage/Default~ipad~landscape.png b/Example/PNImagePickerViewController/Images.xcassets/LaunchImage.launchimage/Default~ipad~landscape.png new file mode 100644 index 0000000..c691e47 Binary files /dev/null and b/Example/PNImagePickerViewController/Images.xcassets/LaunchImage.launchimage/Default~ipad~landscape.png differ diff --git a/Example/PNImagePickerViewController/Images.xcassets/LaunchImage.launchimage/Default~ipad~landscape@2x.png b/Example/PNImagePickerViewController/Images.xcassets/LaunchImage.launchimage/Default~ipad~landscape@2x.png new file mode 100644 index 0000000..14a1feb Binary files /dev/null and b/Example/PNImagePickerViewController/Images.xcassets/LaunchImage.launchimage/Default~ipad~landscape@2x.png differ diff --git a/Example/PNImagePickerViewController/Images.xcassets/LaunchImage.launchimage/Default~ipad~landscape~nostatusbar.png b/Example/PNImagePickerViewController/Images.xcassets/LaunchImage.launchimage/Default~ipad~landscape~nostatusbar.png new file mode 100644 index 0000000..21bb4fc Binary files /dev/null and b/Example/PNImagePickerViewController/Images.xcassets/LaunchImage.launchimage/Default~ipad~landscape~nostatusbar.png differ diff --git a/Example/PNImagePickerViewController/Images.xcassets/LaunchImage.launchimage/Default~ipad~landscape~nostatusbar@2x.png b/Example/PNImagePickerViewController/Images.xcassets/LaunchImage.launchimage/Default~ipad~landscape~nostatusbar@2x.png new file mode 100644 index 0000000..148a16a Binary files /dev/null and b/Example/PNImagePickerViewController/Images.xcassets/LaunchImage.launchimage/Default~ipad~landscape~nostatusbar@2x.png differ diff --git a/Example/PNImagePickerViewController/Images.xcassets/LaunchImage.launchimage/Default~ipad~nostatusbar.png b/Example/PNImagePickerViewController/Images.xcassets/LaunchImage.launchimage/Default~ipad~nostatusbar.png new file mode 100644 index 0000000..76fae81 Binary files /dev/null and b/Example/PNImagePickerViewController/Images.xcassets/LaunchImage.launchimage/Default~ipad~nostatusbar.png differ diff --git a/Example/PNImagePickerViewController/Images.xcassets/LaunchImage.launchimage/Default~ipad~nostatusbar@2x.png b/Example/PNImagePickerViewController/Images.xcassets/LaunchImage.launchimage/Default~ipad~nostatusbar@2x.png new file mode 100644 index 0000000..00d7f97 Binary files /dev/null and b/Example/PNImagePickerViewController/Images.xcassets/LaunchImage.launchimage/Default~ipad~nostatusbar@2x.png differ diff --git a/Example/PNImagePickerViewController/PNImagePickerViewControllerViewController.m b/Example/PNImagePickerViewController/PNImagePickerViewControllerViewController.m index e7395f5..dfc0fe6 100644 --- a/Example/PNImagePickerViewController/PNImagePickerViewControllerViewController.m +++ b/Example/PNImagePickerViewController/PNImagePickerViewControllerViewController.m @@ -7,8 +7,14 @@ // #import "PNImagePickerViewControllerViewController.h" +#import "PNImagePickerViewController.h" +#import -@interface PNImagePickerViewControllerViewController () +@interface PNImagePickerViewControllerViewController () + +@property (nonatomic) BOOL didSetupConstraints; +@property (nonatomic, strong) UIButton *button; +@property (nonatomic, strong) UIImageView *imageView; @end @@ -17,9 +23,60 @@ - (void)viewDidLoad { [super viewDidLoad]; + + _button = [UIButton newAutoLayoutView]; + [_button setTitleColor:[UIColor blueColor] forState:UIControlStateNormal]; + [_button setTitle:@"Show Picker" forState:UIControlStateNormal]; + [_button addTarget:self action:@selector(showPicker) forControlEvents:UIControlEventTouchUpInside]; + [self.view addSubview:_button]; + + _imageView = [UIImageView newAutoLayoutView]; + [_imageView setBackgroundColor:[[UIColor lightGrayColor] colorWithAlphaComponent:0.6]]; + + [self.view addSubview:_imageView]; + + [self.view setNeedsUpdateConstraints]; + // Do any additional setup after loading the view, typically from a nib. } +- (void) updateViewConstraints { + if (!_didSetupConstraints) { + _didSetupConstraints = YES; + + [self.view autoPinEdgesToSuperviewEdges]; + + [_imageView autoPinEdgeToSuperviewEdge:ALEdgeTop]; + [_imageView autoPinEdgeToSuperviewEdge:ALEdgeTrailing]; + [_imageView autoPinEdgeToSuperviewEdge:ALEdgeLeading]; + [_imageView autoAlignAxisToSuperviewAxis:ALAxisVertical]; + + [_button autoPinEdge:ALEdgeTop toEdge:ALEdgeBottom ofView:_imageView withOffset:20]; + [_button autoPinEdgeToSuperviewEdge:ALEdgeBottom withInset:20]; + [_button autoAlignAxisToSuperviewAxis:ALAxisVertical]; + [_button autoSetDimension:ALDimensionHeight toSize:30]; + [_button autoPinEdgeToSuperviewEdge:ALEdgeLeading withInset:100 relation:NSLayoutRelationGreaterThanOrEqual]; + [_button autoPinEdgeToSuperviewEdge:ALEdgeTrailing withInset:100 relation:NSLayoutRelationGreaterThanOrEqual]; + + + } + [super updateViewConstraints]; +} + +- (void) showPicker { + + PNImagePickerViewController *imagePicker = [[PNImagePickerViewController alloc] init]; + imagePicker.delegate = self; + [imagePicker showImagePickerInController:self animated:YES]; + +} + +#pragma mark - PNImagePickerViewControllerDelegate + +- (void)imagePicker:(PNImagePickerViewController *)imagePicker didSelectImage:(UIImage *)image { + self.imageView.image = image; +} + - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; diff --git a/Example/Podfile b/Example/Podfile index 8dd9402..fa2cb92 100644 --- a/Example/Podfile +++ b/Example/Podfile @@ -1,11 +1,12 @@ source 'https://github.com/CocoaPods/Specs.git' use_frameworks! -target 'PNImagePickerViewController_Example', :exclusive => true do +target 'PNImagePickerViewController_Example' do pod 'PNImagePickerViewController', :path => '../' + pod 'PureLayout' end -target 'PNImagePickerViewController_Tests', :exclusive => true do +target 'PNImagePickerViewController_Tests' do pod 'PNImagePickerViewController', :path => '../' pod 'Specta' diff --git a/Example/Podfile.lock b/Example/Podfile.lock new file mode 100644 index 0000000..e1dbdcb --- /dev/null +++ b/Example/Podfile.lock @@ -0,0 +1,38 @@ +PODS: + - Expecta (1.0.5) + - Expecta+Snapshots (2.0.0): + - Expecta (~> 1.0) + - FBSnapshotTestCase/Core (~> 2.0.3) + - FBSnapshotTestCase (2.0.7): + - FBSnapshotTestCase/SwiftSupport (= 2.0.7) + - FBSnapshotTestCase/Core (2.0.7) + - FBSnapshotTestCase/SwiftSupport (2.0.7): + - FBSnapshotTestCase/Core + - PNImagePickerViewController (0.1.0): + - PureLayout + - PureLayout (3.0.1) + - Specta (1.0.5) + +DEPENDENCIES: + - Expecta + - Expecta+Snapshots + - FBSnapshotTestCase + - PNImagePickerViewController (from `../`) + - PureLayout + - Specta + +EXTERNAL SOURCES: + PNImagePickerViewController: + :path: "../" + +SPEC CHECKSUMS: + Expecta: e1c022fcd33910b6be89c291d2775b3fe27a89fe + Expecta+Snapshots: 29b38dd695bc72a0ed2bea833937d78df41943ba + FBSnapshotTestCase: 7e85180d0d141a0cf472352edda7e80d7eaeb547 + PNImagePickerViewController: 9eaf2575e70de776463e23904f9d466f98d27ad4 + PureLayout: f35f5384c9c4e4479df041dbe33ad7577b71ddfb + Specta: ac94d110b865115fe60ff2c6d7281053c6f8e8a2 + +PODFILE CHECKSUM: dfe253f9ffc18c2f381e56e26aeba9f722b4a230 + +COCOAPODS: 1.0.0.beta.3 diff --git a/Example/Pods/Expecta+Snapshots/EXPMatchers+FBSnapshotTest.h b/Example/Pods/Expecta+Snapshots/EXPMatchers+FBSnapshotTest.h new file mode 100644 index 0000000..547e1f6 --- /dev/null +++ b/Example/Pods/Expecta+Snapshots/EXPMatchers+FBSnapshotTest.h @@ -0,0 +1,22 @@ +// +// EXPMatchers+FBSnapshotTest.h +// Artsy +// +// Created by Daniel Doubrovkine on 1/14/14. +// Copyright (c) 2014 Artsy Inc. All rights reserved. +// + +#import +#import "ExpectaObject+FBSnapshotTest.h" + +@interface EXPExpectFBSnapshotTest : NSObject +@end + +/// Set the default folder for image tests to run in +extern void setGlobalReferenceImageDir(char *reference); + +EXPMatcherInterface(haveValidSnapshot, (void)); +EXPMatcherInterface(recordSnapshot, (void)); + +EXPMatcherInterface(haveValidSnapshotNamed, (NSString *snapshot)); +EXPMatcherInterface(recordSnapshotNamed, (NSString *snapshot)); diff --git a/Example/Pods/Expecta+Snapshots/EXPMatchers+FBSnapshotTest.m b/Example/Pods/Expecta+Snapshots/EXPMatchers+FBSnapshotTest.m new file mode 100644 index 0000000..8ca877f --- /dev/null +++ b/Example/Pods/Expecta+Snapshots/EXPMatchers+FBSnapshotTest.m @@ -0,0 +1,319 @@ +// +// EXPMatchers+FBSnapshotTest.h +// Artsy +// +// Created by Daniel Doubrovkine on 1/14/14. +// Copyright (c) 2014 Artsy Inc. All rights reserved. +// + +#import "EXPMatchers+FBSnapshotTest.h" +#import +#import + +@interface EXPExpectFBSnapshotTest() +@property (nonatomic, strong) NSString *referenceImagesDirectory; +@end + +@implementation EXPExpectFBSnapshotTest + ++ (id)instance +{ + static EXPExpectFBSnapshotTest *instance = nil; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + instance = [[self alloc] init]; + }); + return instance; +} + ++ (BOOL)compareSnapshotOfViewOrLayer:(id)viewOrLayer snapshot:(NSString *)snapshot testCase:(id)testCase record:(BOOL)record referenceDirectory:(NSString *)referenceDirectory error:(NSError **)error + +{ + FBSnapshotTestController *snapshotController = [[FBSnapshotTestController alloc] initWithTestClass:[testCase class]]; + snapshotController.recordMode = record; + snapshotController.referenceImagesDirectory = referenceDirectory; + snapshotController.usesDrawViewHierarchyInRect = [Expecta usesDrawViewHierarchyInRect]; + + if (! snapshotController.referenceImagesDirectory) { + [NSException raise:@"Missing value for referenceImagesDirectory" format:@"Call [[EXPExpectFBSnapshotTest instance] setReferenceImagesDirectory"]; + } + + return [snapshotController compareSnapshotOfViewOrLayer:viewOrLayer + selector:NSSelectorFromString(snapshot) + identifier:nil + tolerance:0 + error:error]; +} + ++ (NSString *)combinedError:(NSString *)message test:(NSString *)test error:(NSError *)error +{ + NSAssert(message, @"missing message"); + NSAssert(test, @"missing test name"); + + NSMutableArray *ary = [NSMutableArray array]; + + [ary addObject:[NSString stringWithFormat:@"%@ %@", message, test]]; + + for(NSString *key in error.userInfo.keyEnumerator) { + [ary addObject:[NSString stringWithFormat:@" %@: %@", key, [error.userInfo valueForKey:key]]]; + } + + return [ary componentsJoinedByString:@"\n"]; +} + +@end + +void setGlobalReferenceImageDir(char *reference) { + NSString *referenceImagesDirectory = [NSString stringWithFormat:@"%s", reference]; + [[EXPExpectFBSnapshotTest instance] setReferenceImagesDirectory:referenceImagesDirectory]; +}; + +@interface EXPExpect(ReferenceDirExtension) +- (NSString *)_getDefaultReferenceDirectory; +@end + +@implementation EXPExpect(ReferenceDirExtension) + +- (NSString *)_getDefaultReferenceDirectory +{ + NSString *globalReference = [[EXPExpectFBSnapshotTest instance] referenceImagesDirectory]; + if (globalReference) { + return globalReference; + } + + // Search the test file's path to find the first folder with the substring "tests" + // then append "/ReferenceImages" and use that + + NSString *testFileName = [NSString stringWithCString:self.fileName encoding:NSUTF8StringEncoding]; + NSArray *pathComponents = [testFileName pathComponents]; + + for (NSString *folder in pathComponents) { + if ([folder.lowercaseString rangeOfString:@"tests"].location != NSNotFound) { + + NSArray *folderPathComponents = [pathComponents subarrayWithRange:NSMakeRange(0, [pathComponents indexOfObject:folder] + 1)]; + return [NSString stringWithFormat:@"%@/ReferenceImages", [folderPathComponents componentsJoinedByString:@"/"]]; + + } + } + + [NSException raise:@"Could not infer reference image folder" format:@"You should provide a reference dir using setGlobalReferenceImageDir(FB_REFERENCE_IMAGE_DIR);"]; + return nil; +} +@end + + + +// If you're bringing in Speca via CocoaPods +// use the test path to get the test's image file URL + +#if __has_include() +#import +#import +#import + +NSString *sanitizedTestPath(); + +NSString *sanitizedTestPath(){ + id compiledExample = [[NSThread currentThread] threadDictionary][@"SPTCurrentSpec"]; // SPTSpec + NSString *name; + if ([compiledExample respondsToSelector:@selector(name)]) { + // Specta 0.3 syntax + name = [compiledExample performSelector:@selector(name)]; + } else if ([compiledExample respondsToSelector:@selector(fileName)]) { + // Specta 0.2 syntax + name = [compiledExample performSelector:@selector(fileName)]; + } + name = [[[[name componentsSeparatedByString:@" test_"] lastObject] stringByReplacingOccurrencesOfString:@"__" withString:@"_"] stringByReplacingOccurrencesOfString:@"]" withString:@""]; + return name; +} + +EXPMatcherImplementationBegin(haveValidSnapshot, (void)){ + __block NSError *error = nil; + + match(^BOOL{ + NSString *referenceImageDir = [self _getDefaultReferenceDirectory]; + NSString *name = sanitizedTestPath(); + if ([actual isKindOfClass:UIViewController.class]) { + [actual beginAppearanceTransition:YES animated:NO]; + [actual endAppearanceTransition]; + + actual = [actual view]; + } + + return [EXPExpectFBSnapshotTest compareSnapshotOfViewOrLayer:actual snapshot:name testCase:[self testCase] record:NO referenceDirectory:referenceImageDir error:&error]; + }); + + failureMessageForTo(^NSString *{ + return [EXPExpectFBSnapshotTest combinedError:@"expected a matching snapshot in" test:sanitizedTestPath() error:error]; + }); + + failureMessageForNotTo(^NSString *{ + return [EXPExpectFBSnapshotTest combinedError:@"expected to not have a matching snapshot in" test:sanitizedTestPath() error:error]; + }); +} +EXPMatcherImplementationEnd + +EXPMatcherImplementationBegin(recordSnapshot, (void)) { + __block NSError *error = nil; + + BOOL actualIsViewLayerOrViewController = ([actual isKindOfClass:UIView.class] || [actual isKindOfClass:CALayer.class] || [actual isKindOfClass:UIViewController.class]); + + prerequisite(^BOOL{ + return actualIsViewLayerOrViewController; + }); + + match(^BOOL{ + NSString *referenceImageDir = [self _getDefaultReferenceDirectory]; + + // For view controllers do the viewWill/viewDid dance, then pass view through + if ([actual isKindOfClass:UIViewController.class]) { + + [actual beginAppearanceTransition:YES animated:NO]; + [actual endAppearanceTransition]; + actual = [actual view]; + } + + [EXPExpectFBSnapshotTest compareSnapshotOfViewOrLayer:actual snapshot:sanitizedTestPath() testCase:[self testCase] record:YES referenceDirectory:referenceImageDir error:&error]; + return NO; + }); + + failureMessageForTo(^NSString *{ + if (!actualIsViewLayerOrViewController) { + return [EXPExpectFBSnapshotTest combinedError:@"Expected a View, Layer or View Controller." test:sanitizedTestPath() error:nil]; + } + if (error) { + return [EXPExpectFBSnapshotTest combinedError:@"expected to record a snapshot in" test:sanitizedTestPath() error:error]; + } else { + return [NSString stringWithFormat:@"snapshot %@ successfully recorded, replace recordSnapshot with a check", sanitizedTestPath()]; + } + }); + + failureMessageForNotTo(^NSString *{ + if (error) { + return [EXPExpectFBSnapshotTest combinedError:@"expected to record a snapshot in" test:sanitizedTestPath() error:error]; + } else { + return [NSString stringWithFormat:@"snapshot %@ successfully recorded, replace recordSnapshot with a check", sanitizedTestPath()]; + } + }); +} +EXPMatcherImplementationEnd + +#else + +// If you don't have Speca stub the functions + +EXPMatcherImplementationBegin(haveValidSnapshot, (void)){ + + prerequisite(^BOOL{ + return NO; + }); + + failureMessageForTo(^NSString *{ + return @"you need Specta installed via CocoaPods to use haveValidSnapshot, use haveValidSnapshotNamed instead"; + }); + + failureMessageForNotTo(^NSString *{ + return @"you need Specta installed via CocoaPods to use haveValidSnapshot, use haveValidSnapshotNamed instead"; + }); +} +EXPMatcherImplementationEnd + + +EXPMatcherImplementationBegin(recordSnapshot, (void)) { + + prerequisite(^BOOL{ + return NO; + }); + + failureMessageForTo(^NSString *{ + return @"you need Specta installed via CocoaPods to use recordSnapshot, use recordSnapshotNamed instead"; + }); + + failureMessageForNotTo(^NSString *{ + return @"you need Specta installed via CocoaPods to use recordSnapshot, use recordSnapshotNamed instead"; + }); +} +EXPMatcherImplementationEnd + + +#endif + + + +EXPMatcherImplementationBegin(haveValidSnapshotNamed, (NSString *snapshot)){ + BOOL snapshotIsNil = (snapshot == nil); + __block NSError *error = nil; + + prerequisite(^BOOL{ + return !(snapshotIsNil); + }); + + match(^BOOL{ + NSString *referenceImageDir = [self _getDefaultReferenceDirectory]; + if ([actual isKindOfClass:UIViewController.class]) { + [actual beginAppearanceTransition:YES animated:NO]; + [actual endAppearanceTransition]; + + actual = [actual view]; + } + return [EXPExpectFBSnapshotTest compareSnapshotOfViewOrLayer:actual snapshot:snapshot testCase:[self testCase] record:NO referenceDirectory:referenceImageDir error:&error]; + }); + + failureMessageForTo(^NSString *{ + return [EXPExpectFBSnapshotTest combinedError:@"expected a matching snapshot named" test:snapshot error:error]; + + }); + + failureMessageForNotTo(^NSString *{ + return [EXPExpectFBSnapshotTest combinedError:@"expected not to have a matching snapshot named" test:snapshot error:error]; + }); +} +EXPMatcherImplementationEnd + +EXPMatcherImplementationBegin(recordSnapshotNamed, (NSString *snapshot)) { + BOOL snapshotExists = (snapshot != nil); + BOOL actualIsViewLayerOrViewController = ([actual isKindOfClass:UIView.class] || [actual isKindOfClass:CALayer.class] || [actual isKindOfClass:UIViewController.class]); + __block NSError *error = nil; + id actualRef = actual; + + prerequisite(^BOOL{ + return actualRef && snapshotExists && actualIsViewLayerOrViewController; + }); + + match(^BOOL{ + NSString *referenceImageDir = [self _getDefaultReferenceDirectory]; + + // For view controllers do the viewWill/viewDid dance, then pass view through + if ([actual isKindOfClass:UIViewController.class]) { + [actual beginAppearanceTransition:YES animated:NO]; + [actual endAppearanceTransition]; + actual = [actual view]; + } + + [EXPExpectFBSnapshotTest compareSnapshotOfViewOrLayer:actual snapshot:snapshot testCase:[self testCase] record:YES referenceDirectory:referenceImageDir error:&error]; + return NO; + }); + + failureMessageForTo(^NSString *{ + if (!actualIsViewLayerOrViewController) { + return [EXPExpectFBSnapshotTest combinedError:@"Expected a View, Layer or View Controller." test:snapshot error:nil]; + } + if (error) { + return [EXPExpectFBSnapshotTest combinedError:@"expected to record a matching snapshot named" test:snapshot error:error]; + } else { + return [NSString stringWithFormat:@"snapshot %@ successfully recorded, replace recordSnapshot with a check", snapshot]; + } + }); + + failureMessageForNotTo(^NSString *{ + if (!actualIsViewLayerOrViewController) { + return [EXPExpectFBSnapshotTest combinedError:@"Expected a View, Layer or View Controller." test:snapshot error:nil]; + } + if (error) { + return [EXPExpectFBSnapshotTest combinedError:@"expected to record a matching snapshot named" test:snapshot error:error]; + } else { + return [NSString stringWithFormat:@"snapshot %@ successfully recorded, replace recordSnapshot with a check", snapshot]; + } + }); +} +EXPMatcherImplementationEnd diff --git a/Example/Pods/Expecta+Snapshots/ExpectaObject+FBSnapshotTest.h b/Example/Pods/Expecta+Snapshots/ExpectaObject+FBSnapshotTest.h new file mode 100644 index 0000000..a3feec3 --- /dev/null +++ b/Example/Pods/Expecta+Snapshots/ExpectaObject+FBSnapshotTest.h @@ -0,0 +1,17 @@ +// +// ExpectaObject+FBSnapshotTest.h +// Expecta+Snapshots +// +// Created by John Boiles on 8/3/15. +// Copyright (c) 2015 Expecta+Snapshots All rights reserved. +// + +#import + +@interface Expecta (FBSnapshotTest) + ++ (void)setUsesDrawViewHierarchyInRect:(BOOL)usesDrawViewHierarchyInRect; + ++ (BOOL)usesDrawViewHierarchyInRect; + +@end diff --git a/Example/Pods/Expecta+Snapshots/ExpectaObject+FBSnapshotTest.m b/Example/Pods/Expecta+Snapshots/ExpectaObject+FBSnapshotTest.m new file mode 100644 index 0000000..698447a --- /dev/null +++ b/Example/Pods/Expecta+Snapshots/ExpectaObject+FBSnapshotTest.m @@ -0,0 +1,25 @@ +// +// ExpectaObject+FBSnapshotTest.m +// Expecta+Snapshots +// +// Created by John Boiles on 8/3/15. +// Copyright (c) 2015 Expecta+Snapshots All rights reserved. +// + +#import "ExpectaObject+FBSnapshotTest.h" +#import + +static NSString const *kUsesDrawViewHierarchyInRectKey = @"ExpectaObject+FBSnapshotTest.usesDrawViewHierarchyInRect"; + +@implementation Expecta (FBSnapshotTest) + ++ (void)setUsesDrawViewHierarchyInRect:(BOOL)usesDrawViewHierarchyInRect { + objc_setAssociatedObject(self, (__bridge const void *)(kUsesDrawViewHierarchyInRectKey), @(usesDrawViewHierarchyInRect), OBJC_ASSOCIATION_RETAIN_NONATOMIC); +} + ++ (BOOL)usesDrawViewHierarchyInRect { + NSNumber *usesDrawViewHierarchyInRect = objc_getAssociatedObject(self, (__bridge const void *)(kUsesDrawViewHierarchyInRectKey)); + return usesDrawViewHierarchyInRect.boolValue; +} + +@end diff --git a/Example/Pods/Expecta+Snapshots/LICENSE.md b/Example/Pods/Expecta+Snapshots/LICENSE.md new file mode 100644 index 0000000..47c9a3d --- /dev/null +++ b/Example/Pods/Expecta+Snapshots/LICENSE.md @@ -0,0 +1,22 @@ +MIT License + +Copyright (c) 2014 Daniel Doubrovkine, Artsy Inc. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/Example/Pods/Expecta+Snapshots/README.md b/Example/Pods/Expecta+Snapshots/README.md new file mode 100644 index 0000000..07c5265 --- /dev/null +++ b/Example/Pods/Expecta+Snapshots/README.md @@ -0,0 +1,87 @@ +Expecta Matchers for FBSnapshotTestCase +======================================= + +[Expecta](https://github.com/specta/expecta) matchers for [ios-snapshot-test-case](https://github.com/facebook/ios-snapshot-test-case). + +[![Build Status](https://travis-ci.org/dblock/ios-snapshot-test-case-expecta.png)](https://travis-ci.org/dblock/ios-snapshot-test-case-expecta) + +### Usage + +Add `Expecta+Snapshots` to your Podfile, the latest `FBSnapshotTestCase` will come in as a dependency. + +``` ruby +pod 'Expecta+Snapshots' +``` + +### App setup + +Use `expect(view).to.recordSnapshotNamed(@"unique snapshot name")` to record a snapshot and `expect(view).to.haveValidSnapshotNamed(@"unique snapshot name")` to check it. + +If you project was compiled with Specta included, you have two extra methods that use the spec hierarchy to generate the snapshot name for you: `recordSnapshot()` and `haveValidSnapshot()`. You should only call these once per `it()` block. + +If you need the `usesDrawViewHierarchyInRect` property in order to correctly render UIVisualEffect, UIAppearance and Size Classes, call `[Expecta setUsesDrawViewHierarchyInRect:NO];` inside `beforeAll`. + +``` Objective-C +#define EXP_SHORTHAND +#include +#include +#include +#include "FBExampleView.h" + +SpecBegin(FBExampleView) + +describe(@"manual matching", ^{ + + it(@"matches view", ^{ + FBExampleView *view = [[FBExampleView alloc] initWithFrame:CGRectMake(0, 0, 64, 64)]; + expect(view).to.recordSnapshotNamed(@"FBExampleView"); + expect(view).to.haveValidSnapshotNamed(@"FBExampleView"); + }); + + it(@"doesn't match a view", ^{ + FBExampleView *view = [[FBExampleView alloc] initWithFrame:CGRectMake(0, 0, 64, 64)]; + expect(view).toNot.haveValidSnapshotNamed(@"FBExampleViewDoesNotExist"); + }); + +}); + +describe(@"test name derived matching", ^{ + + it(@"matches view", ^{ + FBExampleView *view = [[FBExampleView alloc] initWithFrame:CGRectMake(0, 0, 64, 64)]; + expect(view).to.recordSnapshot(); + expect(view).to.haveValidSnapshot(); + }); + + it(@"doesn't match a view", ^{ + FBExampleView *view = [[FBExampleView alloc] initWithFrame:CGRectMake(0, 0, 64, 64)]; + expect(view).toNot.haveValidSnapshot(); + }); + +}); + +SpecEnd +``` + +### Sane defaults + +`EXPMatchers+FBSnapshotTest` will automatically figure out the tests folder, and [add a reference image](https://github.com/dblock/ios-snapshot-test-case-expecta/blob/master/EXPMatchers%2BFBSnapshotTest.m#L84-L85) directory, if you'd like to override this, you should include a `beforeAll` block setting the `setGlobalReferenceImageDir` in each file containing tests. + +``` +beforeAll(^{ + setGlobalReferenceImageDir(FB_REFERENCE_IMAGE_DIR); +}); +``` + + +### Example + +A complete project can be found in [FBSnapshotTestCaseDemo](FBSnapshotTestCaseDemo). + +Notably, take a look at [FBSnapshotTestCaseDemoSpecs.m](FBSnapshotTestCaseDemo/FBSnapshotTestCaseDemoTests/FBSnapshotTestCaseDemoSpecs.m) for a complete example, which is an expanded Specta version version of [FBSnapshotTestCaseDemoTests.m](https://github.com/facebook/ios-snapshot-test-case/blob/master/FBSnapshotTestCaseDemo/FBSnapshotTestCaseDemoTests/FBSnapshotTestCaseDemoTests.m). + +Finally you can consult the tests for [ARTiledImageView](https://github.com/dblock/ARTiledImageView/tree/master/IntegrationTests) or [NAMapKit](https://github.com/neilang/NAMapKit/tree/master/Demo/DemoTests). + +### License + +MIT, see [LICENSE](LICENSE.md) diff --git a/Example/Pods/Expecta/Expecta/EXPBlockDefinedMatcher.h b/Example/Pods/Expecta/Expecta/EXPBlockDefinedMatcher.h new file mode 100644 index 0000000..58b1282 --- /dev/null +++ b/Example/Pods/Expecta/Expecta/EXPBlockDefinedMatcher.h @@ -0,0 +1,25 @@ +// +// EXPRuntimeMatcher.h +// Expecta +// +// Created by Luke Redpath on 26/03/2012. +// Copyright (c) 2012 Peter Jihoon Kim. All rights reserved. +// + +#import +#import "EXPMatcher.h" +#import "EXPDefines.h" + +@interface EXPBlockDefinedMatcher : NSObject { + EXPBoolBlock prerequisiteBlock; + EXPBoolBlock matchBlock; + EXPStringBlock failureMessageForToBlock; + EXPStringBlock failureMessageForNotToBlock; +} + +@property(nonatomic, copy) EXPBoolBlock prerequisiteBlock; +@property(nonatomic, copy) EXPBoolBlock matchBlock; +@property(nonatomic, copy) EXPStringBlock failureMessageForToBlock; +@property(nonatomic, copy) EXPStringBlock failureMessageForNotToBlock; + +@end diff --git a/Example/Pods/Expecta/Expecta/EXPBlockDefinedMatcher.m b/Example/Pods/Expecta/Expecta/EXPBlockDefinedMatcher.m new file mode 100644 index 0000000..89bba37 --- /dev/null +++ b/Example/Pods/Expecta/Expecta/EXPBlockDefinedMatcher.m @@ -0,0 +1,60 @@ +// +// EXPRuntimeMatcher.m +// Expecta +// +// Created by Luke Redpath on 26/03/2012. +// Copyright (c) 2012 Peter Jihoon Kim. All rights reserved. +// + +#import "EXPBlockDefinedMatcher.h" + +@implementation EXPBlockDefinedMatcher + +- (void)dealloc +{ + self.prerequisiteBlock = nil; + self.matchBlock = nil; + self.failureMessageForToBlock = nil; + self.failureMessageForNotToBlock = nil; + + [super dealloc]; +} + +@synthesize prerequisiteBlock; +@synthesize matchBlock; +@synthesize failureMessageForToBlock; +@synthesize failureMessageForNotToBlock; + +- (BOOL)meetsPrerequesiteFor:(id)actual +{ + if (self.prerequisiteBlock) { + return self.prerequisiteBlock(); + } + return YES; +} + +- (BOOL)matches:(id)actual +{ + if (self.matchBlock) { + return self.matchBlock(); + } + return YES; +} + +- (NSString *)failureMessageForTo:(id)actual +{ + if (self.failureMessageForToBlock) { + return self.failureMessageForToBlock(); + } + return nil; +} + +- (NSString *)failureMessageForNotTo:(id)actual +{ + if (self.failureMessageForNotToBlock) { + return self.failureMessageForNotToBlock(); + } + return nil; +} + +@end diff --git a/Example/Pods/Expecta/Expecta/EXPDefines.h b/Example/Pods/Expecta/Expecta/EXPDefines.h new file mode 100644 index 0000000..52af721 --- /dev/null +++ b/Example/Pods/Expecta/Expecta/EXPDefines.h @@ -0,0 +1,17 @@ +// +// EXPDefines.h +// Expecta +// +// Created by Luke Redpath on 26/03/2012. +// Copyright (c) 2012 Peter Jihoon Kim. All rights reserved. +// + +#ifndef Expecta_EXPDefines_h +#define Expecta_EXPDefines_h + +typedef void (^EXPBasicBlock)(); +typedef id (^EXPIdBlock)(); +typedef BOOL (^EXPBoolBlock)(); +typedef NSString *(^EXPStringBlock)(); + +#endif diff --git a/Example/Pods/Expecta/Expecta/EXPDoubleTuple.h b/Example/Pods/Expecta/Expecta/EXPDoubleTuple.h new file mode 100644 index 0000000..4bd231c --- /dev/null +++ b/Example/Pods/Expecta/Expecta/EXPDoubleTuple.h @@ -0,0 +1,13 @@ +#import + +@interface EXPDoubleTuple : NSObject { + double *_values; + size_t _size; +} + +@property (nonatomic, assign) double *values; +@property (nonatomic, assign) size_t size; + +- (instancetype)initWithDoubleValues:(double *)values size:(size_t)size NS_DESIGNATED_INITIALIZER; + +@end diff --git a/Example/Pods/Expecta/Expecta/EXPDoubleTuple.m b/Example/Pods/Expecta/Expecta/EXPDoubleTuple.m new file mode 100644 index 0000000..9ebef50 --- /dev/null +++ b/Example/Pods/Expecta/Expecta/EXPDoubleTuple.m @@ -0,0 +1,45 @@ +#import "EXPDoubleTuple.h" + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wobjc-designated-initializers" +@implementation EXPDoubleTuple +#pragma clang diagnostic pop + +@synthesize values = _values, size = _size; + +- (instancetype)initWithDoubleValues:(double *)values size:(size_t)size { + if ((self = [super init])) { + self.values = malloc(sizeof(double) * size); + memcpy(self.values, values, sizeof(double) * size); + self.size = size; + } + return self; +} + +- (void)dealloc { + free(self.values); + [super dealloc]; +} + +- (BOOL)isEqual:(id)object { + if (![object isKindOfClass:[EXPDoubleTuple class]]) return NO; + EXPDoubleTuple *other = (EXPDoubleTuple *)object; + if (self.size == other.size) { + for (int i = 0; i < self.size; ++i) { + if (self.values[i] != other.values[i]) return NO; + } + return YES; + } + return NO; +} + +- (NSString *)description { + if (self.size == 2) { + return [NSString stringWithFormat:@"Double tuple: {%f, %f}", self.values[0], self.values[1]]; + } else if (self.size == 4) { + return [NSString stringWithFormat:@"Double tuple: {%f, %f, %f, %f}", self.values[0], self.values[1], self.values[2], self.values[3]]; + } + return [NSString stringWithFormat:@"Double tuple of unexpected size %zd, sadly", self.size]; +} + +@end diff --git a/Example/Pods/Expecta/Expecta/EXPExpect.h b/Example/Pods/Expecta/Expecta/EXPExpect.h new file mode 100644 index 0000000..985c120 --- /dev/null +++ b/Example/Pods/Expecta/Expecta/EXPExpect.h @@ -0,0 +1,45 @@ +#import +#import "EXPMatcher.h" +#import "EXPDefines.h" + +@interface EXPExpect : NSObject { + EXPIdBlock _actualBlock; + id _testCase; + int _lineNumber; + char *_fileName; + BOOL _negative; + BOOL _asynchronous; + NSTimeInterval _timeout; +} + +@property(nonatomic, copy) EXPIdBlock actualBlock; +@property(nonatomic, readonly) id actual; +@property(nonatomic, assign) id testCase; +@property(nonatomic) int lineNumber; +@property(nonatomic) const char *fileName; +@property(nonatomic) BOOL negative; +@property(nonatomic) BOOL asynchronous; +@property(nonatomic) NSTimeInterval timeout; + +@property(nonatomic, readonly) EXPExpect *to; +@property(nonatomic, readonly) EXPExpect *toNot; +@property(nonatomic, readonly) EXPExpect *notTo; +@property(nonatomic, readonly) EXPExpect *will; +@property(nonatomic, readonly) EXPExpect *willNot; +@property(nonatomic, readonly) EXPExpect *(^after)(NSTimeInterval timeInterval); + +- (instancetype)initWithActualBlock:(id)actualBlock testCase:(id)testCase lineNumber:(int)lineNumber fileName:(const char *)fileName NS_DESIGNATED_INITIALIZER; ++ (EXPExpect *)expectWithActualBlock:(id)actualBlock testCase:(id)testCase lineNumber:(int)lineNumber fileName:(const char *)fileName; + +- (void)applyMatcher:(id)matcher; +- (void)applyMatcher:(id)matcher to:(NSObject **)actual; + +@end + +@interface EXPDynamicPredicateMatcher : NSObject { + EXPExpect *_expectation; + SEL _selector; +} +- (instancetype)initWithExpectation:(EXPExpect *)expectation selector:(SEL)selector NS_DESIGNATED_INITIALIZER; +@property (nonatomic, readonly, copy) void (^dispatch)(void); +@end diff --git a/Example/Pods/Expecta/Expecta/EXPExpect.m b/Example/Pods/Expecta/Expecta/EXPExpect.m new file mode 100644 index 0000000..230e137 --- /dev/null +++ b/Example/Pods/Expecta/Expecta/EXPExpect.m @@ -0,0 +1,221 @@ +#import "EXPExpect.h" +#import "NSObject+Expecta.h" +#import "Expecta.h" +#import "EXPUnsupportedObject.h" +#import "EXPMatcher.h" +#import "EXPBlockDefinedMatcher.h" +#import + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wobjc-designated-initializers" +@implementation EXPExpect +#pragma clang diagnostic pop + +@dynamic + actual, + to, + toNot, + notTo, + will, + willNot, + after; + +@synthesize + actualBlock=_actualBlock, + testCase=_testCase, + negative=_negative, + asynchronous=_asynchronous, + timeout=_timeout, + lineNumber=_lineNumber, + fileName=_fileName; + +- (instancetype)initWithActualBlock:(id)actualBlock testCase:(id)testCase lineNumber:(int)lineNumber fileName:(const char *)fileName { + self = [super init]; + if(self) { + self.actualBlock = actualBlock; + self.testCase = testCase; + self.negative = NO; + self.asynchronous = NO; + self.timeout = [Expecta asynchronousTestTimeout]; + self.lineNumber = lineNumber; + self.fileName = fileName; + } + return self; +} + +- (void)dealloc +{ + [_actualBlock release]; + _actualBlock = nil; + [super dealloc]; +} + ++ (EXPExpect *)expectWithActualBlock:(id)actualBlock testCase:(id)testCase lineNumber:(int)lineNumber fileName:(const char *)fileName { + return [[[EXPExpect alloc] initWithActualBlock:actualBlock testCase:(id)testCase lineNumber:lineNumber fileName:fileName] autorelease]; +} + +#pragma mark - + +- (EXPExpect *)to { + return self; +} + +- (EXPExpect *)toNot { + self.negative = !self.negative; + return self; +} + +- (EXPExpect *)notTo { + return [self toNot]; +} + +- (EXPExpect *)will { + self.asynchronous = YES; + return self; +} + +- (EXPExpect *)willNot { + return self.will.toNot; +} + +- (EXPExpect *(^)(NSTimeInterval))after +{ + EXPExpect * (^block)(NSTimeInterval) = [^EXPExpect *(NSTimeInterval timeout) { + self.asynchronous = YES; + self.timeout = timeout; + return self; + } copy]; + + return [block autorelease]; +} + +#pragma mark - + +- (id)actual { + if(self.actualBlock) { + return self.actualBlock(); + } + return nil; +} + +- (void)applyMatcher:(id)matcher +{ + id actual = [self actual]; + [self applyMatcher:matcher to:&actual]; +} + +- (void)applyMatcher:(id)matcher to:(NSObject **)actual { + if([*actual isKindOfClass:[EXPUnsupportedObject class]]) { + EXPFail(self.testCase, self.lineNumber, self.fileName, + [NSString stringWithFormat:@"expecting a %@ is not supported", ((EXPUnsupportedObject *)*actual).type]); + } else { + BOOL failed = NO; + if([matcher respondsToSelector:@selector(meetsPrerequesiteFor:)] && + ![matcher meetsPrerequesiteFor:*actual]) { + failed = YES; + } else { + BOOL matchResult = NO; + if(self.asynchronous) { + NSTimeInterval timeOut = self.timeout; + NSDate *expiryDate = [NSDate dateWithTimeIntervalSinceNow:timeOut]; + while(1) { + matchResult = [matcher matches:*actual]; + failed = self.negative ? matchResult : !matchResult; + if(!failed || ([(NSDate *)[NSDate date] compare:expiryDate] == NSOrderedDescending)) { + break; + } + [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.01]]; + OSMemoryBarrier(); + *actual = self.actual; + } + } else { + matchResult = [matcher matches:*actual]; + } + failed = self.negative ? matchResult : !matchResult; + } + if(failed) { + NSString *message = nil; + + if(self.negative) { + if ([matcher respondsToSelector:@selector(failureMessageForNotTo:)]) { + message = [matcher failureMessageForNotTo:*actual]; + } + } else { + if ([matcher respondsToSelector:@selector(failureMessageForTo:)]) { + message = [matcher failureMessageForTo:*actual]; + } + } + if (message == nil) { + message = @"Match Failed."; + } + + EXPFail(self.testCase, self.lineNumber, self.fileName, message); + } + } + self.negative = NO; +} + +#pragma mark - Dynamic predicate dispatch + +- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector +{ + if ([self.actual respondsToSelector:aSelector]) { + return [self.actual methodSignatureForSelector:aSelector]; + } + return [super methodSignatureForSelector:aSelector]; +} + +- (void)forwardInvocation:(NSInvocation *)anInvocation +{ + if ([self.actual respondsToSelector:anInvocation.selector]) { + EXPDynamicPredicateMatcher *matcher = [[EXPDynamicPredicateMatcher alloc] initWithExpectation:self selector:anInvocation.selector]; + [anInvocation setSelector:@selector(dispatch)]; + [anInvocation invokeWithTarget:matcher]; + [matcher release]; + } + else { + [super forwardInvocation:anInvocation]; + } +} + +@end + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wobjc-designated-initializers" +@implementation EXPDynamicPredicateMatcher +#pragma clang diagnostic pop + +- (instancetype)initWithExpectation:(EXPExpect *)expectation selector:(SEL)selector +{ + if ((self = [super init])) { + _expectation = expectation; + _selector = selector; + } + return self; +} + +- (BOOL)matches:(id)actual +{ + return (BOOL)[actual performSelector:_selector]; +} + +- (NSString *)failureMessageForTo:(id)actual +{ + return [NSString stringWithFormat:@"expected %@ to be true", NSStringFromSelector(_selector)]; +} + +- (NSString *)failureMessageForNotTo:(id)actual +{ + return [NSString stringWithFormat:@"expected %@ to be false", NSStringFromSelector(_selector)]; +} + +- (void (^)(void))dispatch +{ + __block id blockExpectation = _expectation; + + return [[^{ + [blockExpectation applyMatcher:self]; + } copy] autorelease]; +} + +@end diff --git a/Example/Pods/Expecta/Expecta/EXPFloatTuple.h b/Example/Pods/Expecta/Expecta/EXPFloatTuple.h new file mode 100644 index 0000000..ea8ee81 --- /dev/null +++ b/Example/Pods/Expecta/Expecta/EXPFloatTuple.h @@ -0,0 +1,13 @@ +#import + +@interface EXPFloatTuple : NSObject { + float *_values; + size_t _size; +} + +@property (nonatomic, assign) float *values; +@property (nonatomic, assign) size_t size; + +- (instancetype)initWithFloatValues:(float *)values size:(size_t)size NS_DESIGNATED_INITIALIZER; + +@end diff --git a/Example/Pods/Expecta/Expecta/EXPFloatTuple.m b/Example/Pods/Expecta/Expecta/EXPFloatTuple.m new file mode 100644 index 0000000..b7ccf08 --- /dev/null +++ b/Example/Pods/Expecta/Expecta/EXPFloatTuple.m @@ -0,0 +1,55 @@ +#import "EXPFloatTuple.h" + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wobjc-designated-initializers" +@implementation EXPFloatTuple +#pragma clang diagnostic pop + +@synthesize values = _values, size = _size; + +- (instancetype)initWithFloatValues:(float *)values size:(size_t)size { + if ((self = [super init])) { + self.values = malloc(sizeof(float) * size); + memcpy(self.values, values, sizeof(float) * size); + self.size = size; + } + return self; +} + +- (void)dealloc { + free(self.values); + [super dealloc]; +} + +- (BOOL)isEqual:(id)object { + if (![object isKindOfClass:[EXPFloatTuple class]]) return NO; + EXPFloatTuple *other = (EXPFloatTuple *)object; + if (self.size == other.size) { + for (int i = 0; i < self.size; ++i) { + if (self.values[i] != other.values[i]) return NO; + } + return YES; + } + return NO; +} + +- (NSUInteger)hash +{ + NSUInteger prime = 31; + NSUInteger hash = 0; + for (int i=0; i + +@protocol EXPMatcher + +- (BOOL)matches:(id)actual; + +@optional +- (BOOL)meetsPrerequesiteFor:(id)actual; +- (NSString *)failureMessageForTo:(id)actual; +- (NSString *)failureMessageForNotTo:(id)actual; + +@end diff --git a/Example/Pods/Expecta/Expecta/EXPUnsupportedObject.h b/Example/Pods/Expecta/Expecta/EXPUnsupportedObject.h new file mode 100644 index 0000000..3ad0561 --- /dev/null +++ b/Example/Pods/Expecta/Expecta/EXPUnsupportedObject.h @@ -0,0 +1,11 @@ +#import + +@interface EXPUnsupportedObject : NSObject { + NSString *_type; +} + +@property (nonatomic, retain) NSString *type; + +- (instancetype)initWithType:(NSString *)type NS_DESIGNATED_INITIALIZER; + +@end diff --git a/Example/Pods/Expecta/Expecta/EXPUnsupportedObject.m b/Example/Pods/Expecta/Expecta/EXPUnsupportedObject.m new file mode 100644 index 0000000..3d062e3 --- /dev/null +++ b/Example/Pods/Expecta/Expecta/EXPUnsupportedObject.m @@ -0,0 +1,23 @@ +#import "EXPUnsupportedObject.h" + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wobjc-designated-initializers" +@implementation EXPUnsupportedObject +#pragma clang diagnostic pop + +@synthesize type=_type; + +- (instancetype)initWithType:(NSString *)type { + self = [super init]; + if(self) { + self.type = type; + } + return self; +} + +- (void)dealloc { + self.type = nil; + [super dealloc]; +} + +@end diff --git a/Example/Pods/Expecta/Expecta/Expecta.h b/Example/Pods/Expecta/Expecta/Expecta.h new file mode 100644 index 0000000..066e988 --- /dev/null +++ b/Example/Pods/Expecta/Expecta/Expecta.h @@ -0,0 +1,15 @@ +#import + +//! Project version number for Expecta. +FOUNDATION_EXPORT double ExpectaVersionNumber; + +//! Project version string for Expecta. +FOUNDATION_EXPORT const unsigned char ExpectaVersionString[]; + +#import +#import +#import + +// Enable shorthand by default +#define expect(...) EXP_expect((__VA_ARGS__)) +#define failure(...) EXP_failure((__VA_ARGS__)) diff --git a/Example/Pods/Expecta/Expecta/ExpectaObject.h b/Example/Pods/Expecta/Expecta/ExpectaObject.h new file mode 100644 index 0000000..e4277a9 --- /dev/null +++ b/Example/Pods/Expecta/Expecta/ExpectaObject.h @@ -0,0 +1,18 @@ +#import + +#define EXPObjectify(value) _EXPObjectify(@encode(__typeof__((value))), (value)) +#define EXP_expect(actual) _EXP_expect(self, __LINE__, __FILE__, ^id{ __typeof__((actual)) strongActual = (actual); return EXPObjectify(strongActual); }) +#define EXPMatcherInterface(matcherName, matcherArguments) _EXPMatcherInterface(matcherName, matcherArguments) +#define EXPMatcherImplementationBegin(matcherName, matcherArguments) _EXPMatcherImplementationBegin(matcherName, matcherArguments) +#define EXPMatcherImplementationEnd _EXPMatcherImplementationEnd +#define EXPMatcherAliasImplementation(newMatcherName, oldMatcherName, matcherArguments) _EXPMatcherAliasImplementation(newMatcherName, oldMatcherName, matcherArguments) + +#define EXP_failure(message) EXPFail(self, __LINE__, __FILE__, message) + + +@interface Expecta : NSObject + ++ (NSTimeInterval)asynchronousTestTimeout; ++ (void)setAsynchronousTestTimeout:(NSTimeInterval)timeout; + +@end diff --git a/Example/Pods/Expecta/Expecta/ExpectaObject.m b/Example/Pods/Expecta/Expecta/ExpectaObject.m new file mode 100644 index 0000000..b51e00a --- /dev/null +++ b/Example/Pods/Expecta/Expecta/ExpectaObject.m @@ -0,0 +1,15 @@ +#import "ExpectaObject.h" + +@implementation Expecta + +static NSTimeInterval _asynchronousTestTimeout = 1.0; + ++ (NSTimeInterval)asynchronousTestTimeout { + return _asynchronousTestTimeout; +} + ++ (void)setAsynchronousTestTimeout:(NSTimeInterval)timeout { + _asynchronousTestTimeout = timeout; +} + +@end \ No newline at end of file diff --git a/Example/Pods/Expecta/Expecta/ExpectaSupport.h b/Example/Pods/Expecta/Expecta/ExpectaSupport.h new file mode 100644 index 0000000..28fc5e0 --- /dev/null +++ b/Example/Pods/Expecta/Expecta/ExpectaSupport.h @@ -0,0 +1,74 @@ +#import "EXPExpect.h" +#import "EXPBlockDefinedMatcher.h" + +#ifdef __cplusplus +extern "C" { +#endif + +id _EXPObjectify(const char *type, ...); +EXPExpect *_EXP_expect(id testCase, int lineNumber, const char *fileName, EXPIdBlock actualBlock); + +void EXPFail(id testCase, int lineNumber, const char *fileName, NSString *message); +NSString *EXPDescribeObject(id obj); + +void EXP_prerequisite(EXPBoolBlock block); +void EXP_match(EXPBoolBlock block); +void EXP_failureMessageForTo(EXPStringBlock block); +void EXP_failureMessageForNotTo(EXPStringBlock block); + +#if __has_feature(objc_arc) +#define _EXP_release(x) +#define _EXP_autorelease(x) (x) + +#else +#define _EXP_release(x) [x release] +#define _EXP_autorelease(x) [x autorelease] +#endif + +// workaround for the categories bug: http://developer.apple.com/library/mac/#qa/qa1490/_index.html +#define EXPFixCategoriesBug(name) \ +__attribute__((constructor)) static void EXPFixCategoriesBug##name() {} + +#define _EXPMatcherInterface(matcherName, matcherArguments) \ +@interface EXPExpect (matcherName##Matcher) \ +@property (nonatomic, readonly) void(^ matcherName) matcherArguments; \ +@end + +#define _EXPMatcherImplementationBegin(matcherName, matcherArguments) \ +EXPFixCategoriesBug(EXPMatcher##matcherName##Matcher); \ +@implementation EXPExpect (matcherName##Matcher) \ +@dynamic matcherName;\ +- (void(^) matcherArguments) matcherName { \ + EXPBlockDefinedMatcher *matcher = [[EXPBlockDefinedMatcher alloc] init]; \ + [[[NSThread currentThread] threadDictionary] setObject:matcher forKey:@"EXP_currentMatcher"]; \ + __block id actual = self.actual; \ + __block void (^prerequisite)(EXPBoolBlock block) = ^(EXPBoolBlock block) { EXP_prerequisite(block); }; \ + __block void (^match)(EXPBoolBlock block) = ^(EXPBoolBlock block) { EXP_match(block); }; \ + __block void (^failureMessageForTo)(EXPStringBlock block) = ^(EXPStringBlock block) { EXP_failureMessageForTo(block); }; \ + __block void (^failureMessageForNotTo)(EXPStringBlock block) = ^(EXPStringBlock block) { EXP_failureMessageForNotTo(block); }; \ + prerequisite(nil); match(nil); failureMessageForTo(nil); failureMessageForNotTo(nil); \ + void (^matcherBlock) matcherArguments = [^ matcherArguments { \ + { + +#define _EXPMatcherImplementationEnd \ + } \ + [self applyMatcher:matcher to:&actual]; \ + [[[NSThread currentThread] threadDictionary] removeObjectForKey:@"EXP_currentMatcher"]; \ + } copy]; \ + _EXP_release(matcher); \ + return _EXP_autorelease(matcherBlock); \ +} \ +@end + +#define _EXPMatcherAliasImplementation(newMatcherName, oldMatcherName, matcherArguments) \ +EXPFixCategoriesBug(EXPMatcher##newMatcherName##Matcher); \ +@implementation EXPExpect (newMatcherName##Matcher) \ +@dynamic newMatcherName;\ +- (void(^) matcherArguments) newMatcherName { \ + return [self oldMatcherName]; \ +}\ +@end + +#ifdef __cplusplus +} +#endif diff --git a/Example/Pods/Expecta/Expecta/ExpectaSupport.m b/Example/Pods/Expecta/Expecta/ExpectaSupport.m new file mode 100644 index 0000000..8abe415 --- /dev/null +++ b/Example/Pods/Expecta/Expecta/ExpectaSupport.m @@ -0,0 +1,176 @@ +#import "ExpectaSupport.h" +#import "NSValue+Expecta.h" +#import "NSObject+Expecta.h" +#import "EXPUnsupportedObject.h" +#import "EXPFloatTuple.h" +#import "EXPDoubleTuple.h" +#import "EXPDefines.h" +#import + +@interface NSObject (ExpectaXCTestRecordFailure) + +// suppress warning +- (void)recordFailureWithDescription:(NSString *)description inFile:(NSString *)filename atLine:(NSUInteger)lineNumber expected:(BOOL)expected; + +@end + +id _EXPObjectify(const char *type, ...) { + va_list v; + va_start(v, type); + id obj = nil; + if(strcmp(type, @encode(char)) == 0) { + char actual = (char)va_arg(v, int); + obj = @(actual); + } else if(strcmp(type, @encode(_Bool)) == 0) { + _Static_assert(sizeof(_Bool) <= sizeof(int), "Expected _Bool to be subject to vararg type promotion"); + _Bool actual = (_Bool)va_arg(v, int); + obj = @(actual); + } else if(strcmp(type, @encode(double)) == 0) { + double actual = (double)va_arg(v, double); + obj = @(actual); + } else if(strcmp(type, @encode(float)) == 0) { + float actual = (float)va_arg(v, double); + obj = @(actual); + } else if(strcmp(type, @encode(int)) == 0) { + int actual = (int)va_arg(v, int); + obj = @(actual); + } else if(strcmp(type, @encode(long)) == 0) { + long actual = (long)va_arg(v, long); + obj = @(actual); + } else if(strcmp(type, @encode(long long)) == 0) { + long long actual = (long long)va_arg(v, long long); + obj = @(actual); + } else if(strcmp(type, @encode(short)) == 0) { + short actual = (short)va_arg(v, int); + obj = @(actual); + } else if(strcmp(type, @encode(unsigned char)) == 0) { + unsigned char actual = (unsigned char)va_arg(v, unsigned int); + obj = @(actual); + } else if(strcmp(type, @encode(unsigned int)) == 0) { + unsigned int actual = (int)va_arg(v, unsigned int); + obj = @(actual); + } else if(strcmp(type, @encode(unsigned long)) == 0) { + unsigned long actual = (unsigned long)va_arg(v, unsigned long); + obj = @(actual); + } else if(strcmp(type, @encode(unsigned long long)) == 0) { + unsigned long long actual = (unsigned long long)va_arg(v, unsigned long long); + obj = @(actual); + } else if(strcmp(type, @encode(unsigned short)) == 0) { + unsigned short actual = (unsigned short)va_arg(v, unsigned int); + obj = @(actual); + } else if(strstr(type, @encode(EXPBasicBlock)) != NULL) { + // @encode(EXPBasicBlock) returns @? as of clang 4.1. + // This condition must occur before the test for id/class type, + // otherwise blocks will be treated as vanilla objects. + id actual = va_arg(v, EXPBasicBlock); + obj = [[actual copy] autorelease]; + } else if((strstr(type, @encode(id)) != NULL) || (strstr(type, @encode(Class)) != 0)) { + id actual = va_arg(v, id); + obj = actual; + } else if(strcmp(type, @encode(__typeof__(nil))) == 0) { + obj = nil; + } else if(strstr(type, "ff}{") != NULL) { //TODO: of course this only works for a 2x2 e.g. CGRect + obj = [[[EXPFloatTuple alloc] initWithFloatValues:(float *)va_arg(v, float[4]) size:4] autorelease]; + } else if(strstr(type, "=ff}") != NULL) { + obj = [[[EXPFloatTuple alloc] initWithFloatValues:(float *)va_arg(v, float[2]) size:2] autorelease]; + } else if(strstr(type, "=ffff}") != NULL) { + obj = [[[EXPFloatTuple alloc] initWithFloatValues:(float *)va_arg(v, float[4]) size:4] autorelease]; + } else if(strstr(type, "dd}{") != NULL) { //TODO: same here + obj = [[[EXPDoubleTuple alloc] initWithDoubleValues:(double *)va_arg(v, double[4]) size:4] autorelease]; + } else if(strstr(type, "=dd}") != NULL) { + obj = [[[EXPDoubleTuple alloc] initWithDoubleValues:(double *)va_arg(v, double[2]) size:2] autorelease]; + } else if(strstr(type, "=dddd}") != NULL) { + obj = [[[EXPDoubleTuple alloc] initWithDoubleValues:(double *)va_arg(v, double[4]) size:4] autorelease]; + } else if(type[0] == '{') { + EXPUnsupportedObject *actual = [[[EXPUnsupportedObject alloc] initWithType:@"struct"] autorelease]; + obj = actual; + } else if(type[0] == '(') { + EXPUnsupportedObject *actual = [[[EXPUnsupportedObject alloc] initWithType:@"union"] autorelease]; + obj = actual; + } else { + void *actual = va_arg(v, void *); + obj = (actual == NULL ? nil :[NSValue valueWithPointer:actual]); + } + if([obj isKindOfClass:[NSValue class]] && ![obj isKindOfClass:[NSNumber class]]) { + [(NSValue *)obj set_EXP_objCType:type]; + } + va_end(v); + return obj; +} + +EXPExpect *_EXP_expect(id testCase, int lineNumber, const char *fileName, EXPIdBlock actualBlock) { + return [EXPExpect expectWithActualBlock:actualBlock testCase:testCase lineNumber:lineNumber fileName:fileName]; +} + +void EXPFail(id testCase, int lineNumber, const char *fileName, NSString *message) { + NSLog(@"%s:%d %@", fileName, lineNumber, message); + NSString *reason = [NSString stringWithFormat:@"%s:%d %@", fileName, lineNumber, message]; + NSException *exception = [NSException exceptionWithName:@"Expecta Error" reason:reason userInfo:nil]; + + if(testCase && [testCase respondsToSelector:@selector(recordFailureWithDescription:inFile:atLine:expected:)]){ + [testCase recordFailureWithDescription:message + inFile:@(fileName) + atLine:lineNumber + expected:NO]; + } else { + [exception raise]; + } +} + +NSString *EXPDescribeObject(id obj) { + if(obj == nil) { + return @"nil/null"; + } else if([obj isKindOfClass:[NSValue class]] && ![obj isKindOfClass:[NSNumber class]]) { + const char *type = [(NSValue *)obj _EXP_objCType]; + if(type) { + if(strcmp(type, @encode(SEL)) == 0) { + return [NSString stringWithFormat:@"@selector(%@)", NSStringFromSelector([obj pointerValue])]; + } else if(strcmp(type, @encode(Class)) == 0) { + return NSStringFromClass([obj pointerValue]); + } + } + } + NSString *description = [obj description]; + if([obj isKindOfClass:[NSArray class]]) { + NSMutableArray *arr = [NSMutableArray arrayWithCapacity:[obj count]]; + for(id o in obj) { + [arr addObject:EXPDescribeObject(o)]; + } + description = [NSString stringWithFormat:@"(%@)", [arr componentsJoinedByString:@", "]]; + } else if([obj isKindOfClass:[NSSet class]] || [obj isKindOfClass:[NSOrderedSet class]]) { + NSMutableArray *arr = [NSMutableArray arrayWithCapacity:[obj count]]; + for(id o in obj) { + [arr addObject:EXPDescribeObject(o)]; + } + description = [NSString stringWithFormat:@"{(%@)}", [arr componentsJoinedByString:@", "]]; + } else if([obj isKindOfClass:[NSDictionary class]]) { + NSMutableArray *arr = [NSMutableArray arrayWithCapacity:[obj count]]; + for(id k in obj) { + id v = obj[k]; + [arr addObject:[NSString stringWithFormat:@"%@ = %@;",EXPDescribeObject(k), EXPDescribeObject(v)]]; + } + description = [NSString stringWithFormat:@"{%@}", [arr componentsJoinedByString:@" "]]; + } else if([obj isKindOfClass:[NSAttributedString class]]) { + description = [obj string]; + } else { + description = [description stringByReplacingOccurrencesOfString:@"\n" withString:@"\\n"]; + } + return description; +} + +void EXP_prerequisite(EXPBoolBlock block) { + [[[NSThread currentThread] threadDictionary][@"EXP_currentMatcher"] setPrerequisiteBlock:block]; +} + +void EXP_match(EXPBoolBlock block) { + [[[NSThread currentThread] threadDictionary][@"EXP_currentMatcher"] setMatchBlock:block]; +} + +void EXP_failureMessageForTo(EXPStringBlock block) { + [[[NSThread currentThread] threadDictionary][@"EXP_currentMatcher"] setFailureMessageForToBlock:block]; +} + +void EXP_failureMessageForNotTo(EXPStringBlock block) { + [[[NSThread currentThread] threadDictionary][@"EXP_currentMatcher"] setFailureMessageForNotToBlock:block]; +} + diff --git a/Example/Pods/Expecta/Expecta/Matchers/EXPMatcherHelpers.h b/Example/Pods/Expecta/Expecta/Matchers/EXPMatcherHelpers.h new file mode 100644 index 0000000..5780ff6 --- /dev/null +++ b/Example/Pods/Expecta/Expecta/Matchers/EXPMatcherHelpers.h @@ -0,0 +1,4 @@ +#import + +BOOL EXPIsValuePointer(NSValue *value); +BOOL EXPIsNumberFloat(NSNumber *number); diff --git a/Example/Pods/Expecta/Expecta/Matchers/EXPMatcherHelpers.m b/Example/Pods/Expecta/Expecta/Matchers/EXPMatcherHelpers.m new file mode 100644 index 0000000..cec0343 --- /dev/null +++ b/Example/Pods/Expecta/Expecta/Matchers/EXPMatcherHelpers.m @@ -0,0 +1,9 @@ +#import "EXPMatcherHelpers.h" + +BOOL EXPIsValuePointer(NSValue *value) { + return [value objCType][0] == @encode(void *)[0]; +} + +BOOL EXPIsNumberFloat(NSNumber *number) { + return strcmp([number objCType], @encode(float)) == 0; +} diff --git a/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+beCloseTo.h b/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+beCloseTo.h new file mode 100644 index 0000000..f683d6b --- /dev/null +++ b/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+beCloseTo.h @@ -0,0 +1,7 @@ +#import "Expecta.h" + +EXPMatcherInterface(_beCloseToWithin, (id expected, id within)); +EXPMatcherInterface(beCloseToWithin, (id expected, id within)); + +#define beCloseTo(expected) _beCloseToWithin(EXPObjectify((expected)), nil) +#define beCloseToWithin(expected, range) _beCloseToWithin(EXPObjectify((expected)), EXPObjectify((range))) diff --git a/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+beCloseTo.m b/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+beCloseTo.m new file mode 100644 index 0000000..c55431a --- /dev/null +++ b/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+beCloseTo.m @@ -0,0 +1,49 @@ +#import "EXPMatchers+beCloseTo.h" +#import "EXPMatcherHelpers.h" + +EXPMatcherImplementationBegin(_beCloseToWithin, (id expected, id within)) { + prerequisite(^BOOL{ + return [actual isKindOfClass:[NSNumber class]] && + [expected isKindOfClass:[NSNumber class]] && + ([within isKindOfClass:[NSNumber class]] || (within == nil)); + }); + + match(^BOOL{ + double actualValue = [actual doubleValue]; + double expectedValue = [expected doubleValue]; + + if (within != nil) { + double withinValue = [within doubleValue]; + double lowerBound = expectedValue - withinValue; + double upperBound = expectedValue + withinValue; + return (actualValue >= lowerBound) && (actualValue <= upperBound); + } else { + double diff = fabs(actualValue - expectedValue); + actualValue = fabs(actualValue); + expectedValue = fabs(expectedValue); + double largest = (expectedValue > actualValue) ? expectedValue : actualValue; + return (diff <= largest * FLT_EPSILON); + } + }); + + failureMessageForTo(^NSString *{ + if (within) { + return [NSString stringWithFormat:@"expected %@ to be close to %@ within %@", + EXPDescribeObject(actual), EXPDescribeObject(expected), EXPDescribeObject(within)]; + } else { + return [NSString stringWithFormat:@"expected %@ to be close to %@", + EXPDescribeObject(actual), EXPDescribeObject(expected)]; + } + }); + + failureMessageForNotTo(^NSString *{ + if (within) { + return [NSString stringWithFormat:@"expected %@ not to be close to %@ within %@", + EXPDescribeObject(actual), EXPDescribeObject(expected), EXPDescribeObject(within)]; + } else { + return [NSString stringWithFormat:@"expected %@ not to be close to %@", + EXPDescribeObject(actual), EXPDescribeObject(expected)]; + } + }); +} +EXPMatcherImplementationEnd \ No newline at end of file diff --git a/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+beFalsy.h b/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+beFalsy.h new file mode 100644 index 0000000..89c8e00 --- /dev/null +++ b/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+beFalsy.h @@ -0,0 +1,3 @@ +#import "Expecta.h" + +EXPMatcherInterface(beFalsy, (void)); diff --git a/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+beFalsy.m b/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+beFalsy.m new file mode 100644 index 0000000..382cab8 --- /dev/null +++ b/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+beFalsy.m @@ -0,0 +1,24 @@ +#import "EXPMatchers+beFalsy.h" +#import "EXPMatcherHelpers.h" + +EXPMatcherImplementationBegin(beFalsy, (void)) { + match(^BOOL{ + if([actual isKindOfClass:[NSNumber class]]) { + return ![(NSNumber *)actual boolValue]; + } else if([actual isKindOfClass:[NSValue class]]) { + if(EXPIsValuePointer((NSValue *)actual)) { + return ![(NSValue *)actual pointerValue]; + } + } + return !actual; + }); + + failureMessageForTo(^NSString *{ + return [NSString stringWithFormat:@"expected: a falsy value, got: %@, which is truthy", EXPDescribeObject(actual)]; + }); + + failureMessageForNotTo(^NSString *{ + return [NSString stringWithFormat:@"expected: a non-falsy value, got: %@, which is falsy", EXPDescribeObject(actual)]; + }); +} +EXPMatcherImplementationEnd diff --git a/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+beGreaterThan.h b/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+beGreaterThan.h new file mode 100644 index 0000000..a2f9fba --- /dev/null +++ b/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+beGreaterThan.h @@ -0,0 +1,6 @@ +#import "Expecta.h" + +EXPMatcherInterface(_beGreaterThan, (id expected)); +EXPMatcherInterface(beGreaterThan, (id expected)); + +#define beGreaterThan(expected) _beGreaterThan(EXPObjectify((expected))) diff --git a/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+beGreaterThan.m b/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+beGreaterThan.m new file mode 100644 index 0000000..d725387 --- /dev/null +++ b/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+beGreaterThan.m @@ -0,0 +1,20 @@ +#import "EXPMatchers+beGreaterThan.h" +#import "EXPMatcherHelpers.h" + +EXPMatcherImplementationBegin(_beGreaterThan, (id expected)) { + match(^BOOL{ + if ([actual respondsToSelector:@selector(compare:)]) { + return [actual compare:expected] == NSOrderedDescending; + } + return NO; + }); + + failureMessageForTo(^NSString *{ + return [NSString stringWithFormat:@"expected: %@ to be greater than %@", EXPDescribeObject(actual), EXPDescribeObject(expected)]; + }); + + failureMessageForNotTo(^NSString *{ + return [NSString stringWithFormat:@"expected: %@ not to be greater than %@", EXPDescribeObject(actual), EXPDescribeObject(expected)]; + }); +} +EXPMatcherImplementationEnd \ No newline at end of file diff --git a/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+beGreaterThanOrEqualTo.h b/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+beGreaterThanOrEqualTo.h new file mode 100644 index 0000000..3e91c64 --- /dev/null +++ b/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+beGreaterThanOrEqualTo.h @@ -0,0 +1,6 @@ +#import "Expecta.h" + +EXPMatcherInterface(_beGreaterThanOrEqualTo, (id expected)); +EXPMatcherInterface(beGreaterThanOrEqualTo, (id expected)); + +#define beGreaterThanOrEqualTo(expected) _beGreaterThanOrEqualTo(EXPObjectify((expected))) diff --git a/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+beGreaterThanOrEqualTo.m b/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+beGreaterThanOrEqualTo.m new file mode 100644 index 0000000..3276344 --- /dev/null +++ b/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+beGreaterThanOrEqualTo.m @@ -0,0 +1,20 @@ +#import "EXPMatchers+beGreaterThanOrEqualTo.h" +#import "EXPMatcherHelpers.h" + +EXPMatcherImplementationBegin(_beGreaterThanOrEqualTo, (id expected)) { + match(^BOOL{ + if ([actual respondsToSelector:@selector(compare:)]) { + return [actual compare:expected] != NSOrderedAscending; + } + return NO; + }); + + failureMessageForTo(^NSString *{ + return [NSString stringWithFormat:@"expected: %@ to be greater than or equal to %@", EXPDescribeObject(actual), EXPDescribeObject(expected)]; + }); + + failureMessageForNotTo(^NSString *{ + return [NSString stringWithFormat:@"expected: %@ not to be greater than or equal to %@", EXPDescribeObject(actual), EXPDescribeObject(expected)]; + }); +} +EXPMatcherImplementationEnd \ No newline at end of file diff --git a/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+beIdenticalTo.h b/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+beIdenticalTo.h new file mode 100644 index 0000000..d13619f --- /dev/null +++ b/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+beIdenticalTo.h @@ -0,0 +1,10 @@ +#import "Expecta.h" + +EXPMatcherInterface(_beIdenticalTo, (void *expected)); +EXPMatcherInterface(beIdenticalTo, (void *expected)); // to aid code completion + +#if __has_feature(objc_arc) +#define beIdenticalTo(expected) _beIdenticalTo((__bridge void*)expected) +#else +#define beIdenticalTo(expected) _beIdenticalTo(expected) +#endif diff --git a/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+beIdenticalTo.m b/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+beIdenticalTo.m new file mode 100644 index 0000000..b62b0fe --- /dev/null +++ b/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+beIdenticalTo.m @@ -0,0 +1,24 @@ +#import "EXPMatchers+equal.h" +#import "EXPMatcherHelpers.h" + +EXPMatcherImplementationBegin(_beIdenticalTo, (void *expected)) { + match(^BOOL{ + if(actual == expected) { + return YES; + } else if([actual isKindOfClass:[NSValue class]] && EXPIsValuePointer((NSValue *)actual)) { + if([(NSValue *)actual pointerValue] == expected) { + return YES; + } + } + return NO; + }); + + failureMessageForTo(^NSString *{ + return [NSString stringWithFormat:@"expected: <%p>, got: <%p>", expected, actual]; + }); + + failureMessageForNotTo(^NSString *{ + return [NSString stringWithFormat:@"expected: not <%p>, got: <%p>", expected, actual]; + }); +} +EXPMatcherImplementationEnd diff --git a/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+beInTheRangeOf.h b/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+beInTheRangeOf.h new file mode 100644 index 0000000..8ea990e --- /dev/null +++ b/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+beInTheRangeOf.h @@ -0,0 +1,6 @@ +#import "Expecta.h" + +EXPMatcherInterface(_beInTheRangeOf, (id expectedLowerBound, id expectedUpperBound)); +EXPMatcherInterface(beInTheRangeOf, (id expectedLowerBound, id expectedUpperBound)); + +#define beInTheRangeOf(expectedLowerBound, expectedUpperBound) _beInTheRangeOf(EXPObjectify((expectedLowerBound)), EXPObjectify((expectedUpperBound))) diff --git a/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+beInTheRangeOf.m b/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+beInTheRangeOf.m new file mode 100644 index 0000000..1631f24 --- /dev/null +++ b/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+beInTheRangeOf.m @@ -0,0 +1,30 @@ +#import "EXPMatchers+beInTheRangeOf.h" +#import "EXPMatcherHelpers.h" + +EXPMatcherImplementationBegin(_beInTheRangeOf, (id expectedLowerBound, id expectedUpperBound)) { + match(^BOOL{ + if ([actual respondsToSelector:@selector(compare:)]) { + NSComparisonResult compareLowerBound = [expectedLowerBound compare: actual]; + NSComparisonResult compareUpperBound = [expectedUpperBound compare: actual]; + if (compareLowerBound == NSOrderedSame) { + return YES; + } + if (compareUpperBound == NSOrderedSame) { + return YES; + } + if ((compareLowerBound == NSOrderedAscending) && (compareUpperBound == NSOrderedDescending)) { + return YES; + } + } + return NO; + }); + + failureMessageForTo(^NSString *{ + return [NSString stringWithFormat:@"expected: %@ to be in the range [%@, %@] (inclusive)", EXPDescribeObject(actual), EXPDescribeObject(expectedLowerBound), EXPDescribeObject(expectedUpperBound)]; + }); + + failureMessageForNotTo(^NSString *{ + return [NSString stringWithFormat:@"expected: %@ not to be in the range [%@, %@] (inclusive)", EXPDescribeObject(actual), EXPDescribeObject(expectedLowerBound), EXPDescribeObject(expectedUpperBound)]; + }); +} +EXPMatcherImplementationEnd \ No newline at end of file diff --git a/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+beInstanceOf.h b/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+beInstanceOf.h new file mode 100644 index 0000000..a8e8175 --- /dev/null +++ b/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+beInstanceOf.h @@ -0,0 +1,6 @@ +#import "Expecta.h" + +EXPMatcherInterface(beInstanceOf, (Class expected)); +EXPMatcherInterface(beAnInstanceOf, (Class expected)); +EXPMatcherInterface(beMemberOf, (Class expected)); +EXPMatcherInterface(beAMemberOf, (Class expected)); diff --git a/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+beInstanceOf.m b/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+beInstanceOf.m new file mode 100644 index 0000000..9535e1e --- /dev/null +++ b/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+beInstanceOf.m @@ -0,0 +1,31 @@ +#import "EXPMatchers+beInstanceOf.h" + +EXPMatcherImplementationBegin(beInstanceOf, (Class expected)) { + BOOL actualIsNil = (actual == nil); + BOOL expectedIsNil = (expected == nil); + + prerequisite(^BOOL{ + return !(actualIsNil || expectedIsNil); + }); + + match(^BOOL{ + return [actual isMemberOfClass:expected]; + }); + + failureMessageForTo(^NSString *{ + if(actualIsNil) return @"the actual value is nil/null"; + if(expectedIsNil) return @"the expected value is nil/null"; + return [NSString stringWithFormat:@"expected: an instance of %@, got: an instance of %@", [expected class], [actual class]]; + }); + + failureMessageForNotTo(^NSString *{ + if(actualIsNil) return @"the actual value is nil/null"; + if(expectedIsNil) return @"the expected value is nil/null"; + return [NSString stringWithFormat:@"expected: not an instance of %@, got: an instance of %@", [expected class], [actual class]]; + }); +} +EXPMatcherImplementationEnd + +EXPMatcherAliasImplementation(beAnInstanceOf, beInstanceOf, (Class expected)); +EXPMatcherAliasImplementation(beMemberOf, beInstanceOf, (Class expected)); +EXPMatcherAliasImplementation(beAMemberOf, beInstanceOf, (Class expected)); diff --git a/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+beKindOf.h b/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+beKindOf.h new file mode 100644 index 0000000..b8623e0 --- /dev/null +++ b/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+beKindOf.h @@ -0,0 +1,4 @@ +#import "Expecta.h" + +EXPMatcherInterface(beKindOf, (Class expected)); +EXPMatcherInterface(beAKindOf, (Class expected)); diff --git a/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+beKindOf.m b/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+beKindOf.m new file mode 100644 index 0000000..f13ffb5 --- /dev/null +++ b/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+beKindOf.m @@ -0,0 +1,29 @@ +#import "EXPMatchers+beKindOf.h" + +EXPMatcherImplementationBegin(beKindOf, (Class expected)) { + BOOL actualIsNil = (actual == nil); + BOOL expectedIsNil = (expected == nil); + + prerequisite(^BOOL{ + return !(actualIsNil || expectedIsNil); + }); + + match(^BOOL{ + return [actual isKindOfClass:expected]; + }); + + failureMessageForTo(^NSString *{ + if(actualIsNil) return @"the actual value is nil/null"; + if(expectedIsNil) return @"the expected value is nil/null"; + return [NSString stringWithFormat:@"expected: a kind of %@, got: an instance of %@, which is not a kind of %@", [expected class], [actual class], [expected class]]; + }); + + failureMessageForNotTo(^NSString *{ + if(actualIsNil) return @"the actual value is nil/null"; + if(expectedIsNil) return @"the expected value is nil/null"; + return [NSString stringWithFormat:@"expected: not a kind of %@, got: an instance of %@, which is a kind of %@", [expected class], [actual class], [expected class]]; + }); +} +EXPMatcherImplementationEnd + +EXPMatcherAliasImplementation(beAKindOf, beKindOf, (Class expected)); diff --git a/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+beLessThan.h b/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+beLessThan.h new file mode 100644 index 0000000..5ed0a24 --- /dev/null +++ b/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+beLessThan.h @@ -0,0 +1,6 @@ +#import "Expecta.h" + +EXPMatcherInterface(_beLessThan, (id expected)); +EXPMatcherInterface(beLessThan, (id expected)); + +#define beLessThan(expected) _beLessThan(EXPObjectify((expected))) diff --git a/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+beLessThan.m b/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+beLessThan.m new file mode 100644 index 0000000..39b6883 --- /dev/null +++ b/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+beLessThan.m @@ -0,0 +1,20 @@ +#import "EXPMatchers+beLessThan.h" +#import "EXPMatcherHelpers.h" + +EXPMatcherImplementationBegin(_beLessThan, (id expected)) { + match(^BOOL{ + if ([actual respondsToSelector:@selector(compare:)]) { + return [actual compare:expected] == NSOrderedAscending; + } + return NO; + }); + + failureMessageForTo(^NSString *{ + return [NSString stringWithFormat:@"expected: %@ to be less than %@", EXPDescribeObject(actual), EXPDescribeObject(expected)]; + }); + + failureMessageForNotTo(^NSString *{ + return [NSString stringWithFormat:@"expected: %@ not to be less than %@", EXPDescribeObject(actual), EXPDescribeObject(expected)]; + }); +} +EXPMatcherImplementationEnd \ No newline at end of file diff --git a/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+beLessThanOrEqualTo.h b/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+beLessThanOrEqualTo.h new file mode 100644 index 0000000..2c31341 --- /dev/null +++ b/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+beLessThanOrEqualTo.h @@ -0,0 +1,6 @@ +#import "Expecta.h" + +EXPMatcherInterface(_beLessThanOrEqualTo, (id expected)); +EXPMatcherInterface(beLessThanOrEqualTo, (id expected)); + +#define beLessThanOrEqualTo(expected) _beLessThanOrEqualTo(EXPObjectify((expected))) diff --git a/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+beLessThanOrEqualTo.m b/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+beLessThanOrEqualTo.m new file mode 100644 index 0000000..401c194 --- /dev/null +++ b/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+beLessThanOrEqualTo.m @@ -0,0 +1,20 @@ +#import "EXPMatchers+beLessThanOrEqualTo.h" +#import "EXPMatcherHelpers.h" + +EXPMatcherImplementationBegin(_beLessThanOrEqualTo, (id expected)) { + match(^BOOL{ + if ([actual respondsToSelector:@selector(compare:)]) { + return [actual compare:expected] != NSOrderedDescending; + } + return NO; + }); + + failureMessageForTo(^NSString *{ + return [NSString stringWithFormat:@"expected: %@ to be less than or equal to %@", EXPDescribeObject(actual), EXPDescribeObject(expected)]; + }); + + failureMessageForNotTo(^NSString *{ + return [NSString stringWithFormat:@"expected: %@ not to be less than or equal to %@", EXPDescribeObject(actual), EXPDescribeObject(expected)]; + }); +} +EXPMatcherImplementationEnd \ No newline at end of file diff --git a/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+beNil.h b/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+beNil.h new file mode 100644 index 0000000..6d78162 --- /dev/null +++ b/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+beNil.h @@ -0,0 +1,4 @@ +#import "Expecta.h" + +EXPMatcherInterface(beNil, (void)); +EXPMatcherInterface(beNull, (void)); diff --git a/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+beNil.m b/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+beNil.m new file mode 100644 index 0000000..161067f --- /dev/null +++ b/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+beNil.m @@ -0,0 +1,18 @@ +#import "EXPMatchers+beNil.h" + +EXPMatcherImplementationBegin(beNil, (void)) { + match(^BOOL{ + return actual == nil; + }); + + failureMessageForTo(^NSString *{ + return [NSString stringWithFormat:@"expected: nil/null, got: %@", EXPDescribeObject(actual)]; + }); + + failureMessageForNotTo(^NSString *{ + return [NSString stringWithFormat:@"expected: not nil/null, got: %@", EXPDescribeObject(actual)]; + }); +} +EXPMatcherImplementationEnd + +EXPMatcherAliasImplementation(beNull, beNil, (void)); diff --git a/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+beSubclassOf.h b/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+beSubclassOf.h new file mode 100644 index 0000000..65401c5 --- /dev/null +++ b/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+beSubclassOf.h @@ -0,0 +1,4 @@ +#import "Expecta.h" + +EXPMatcherInterface(beSubclassOf, (Class expected)); +EXPMatcherInterface(beASubclassOf, (Class expected)); diff --git a/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+beSubclassOf.m b/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+beSubclassOf.m new file mode 100644 index 0000000..d4976d5 --- /dev/null +++ b/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+beSubclassOf.m @@ -0,0 +1,29 @@ +#import "EXPMatchers+beSubclassOf.h" +#import "NSValue+Expecta.h" +#import + +EXPMatcherImplementationBegin(beSubclassOf, (Class expected)) { + __block BOOL actualIsClass = YES; + + prerequisite(^BOOL { + actualIsClass = class_isMetaClass(object_getClass(actual)); + return actualIsClass; + }); + + match(^BOOL{ + return [actual isSubclassOfClass:expected]; + }); + + failureMessageForTo(^NSString *{ + if(!actualIsClass) return @"the actual value is not a Class"; + return [NSString stringWithFormat:@"expected: a subclass of %@, got: a class %@, which is not a subclass of %@", [expected class], actual, [expected class]]; + }); + + failureMessageForNotTo(^NSString *{ + if(!actualIsClass) return @"the actual value is not a Class"; + return [NSString stringWithFormat:@"expected: not a subclass of %@, got: a class %@, which is a subclass of %@", [expected class], actual, [expected class]]; + }); +} +EXPMatcherImplementationEnd + +EXPMatcherAliasImplementation(beASubclassOf, beSubclassOf, (Class expected)); diff --git a/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+beSupersetOf.h b/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+beSupersetOf.h new file mode 100644 index 0000000..f9a47ba --- /dev/null +++ b/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+beSupersetOf.h @@ -0,0 +1,4 @@ +#import "Expecta.h" + +EXPMatcherInterface(beSupersetOf, (id subset)); + diff --git a/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+beSupersetOf.m b/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+beSupersetOf.m new file mode 100644 index 0000000..f4d05c0 --- /dev/null +++ b/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+beSupersetOf.m @@ -0,0 +1,62 @@ +#import "EXPMatchers+contain.h" + +EXPMatcherImplementationBegin(beSupersetOf, (id subset)) { + BOOL actualIsCompatible = [actual isKindOfClass:[NSDictionary class]] || [actual respondsToSelector:@selector(containsObject:)]; + BOOL subsetIsNil = (subset == nil); + + // For some instances the isKindOfClass: method returns false, even though + // they are both actually dictionaries. e.g. Comparing a NSCFDictionary and a + // NSDictionary. + // Or in cases when you compare NSMutableArray (which implementation is __NSArrayM:NSMutableArray:NSArray) + // and NSArray (which implementation is __NSArrayI:NSArray) + BOOL bothAreIdenticalCollectionClasses = ([actual isKindOfClass:[NSDictionary class]] && [subset isKindOfClass:[NSDictionary class]]) || + ([actual isKindOfClass:[NSArray class]] && [subset isKindOfClass:[NSArray class]]) || + ([actual isKindOfClass:[NSSet class]] && [subset isKindOfClass:[NSSet class]]) || + ([actual isKindOfClass:[NSOrderedSet class]] && [subset isKindOfClass:[NSOrderedSet class]]); + + BOOL classMatches = bothAreIdenticalCollectionClasses || [subset isKindOfClass:[actual class]]; + + prerequisite(^BOOL{ + return actualIsCompatible && !subsetIsNil && classMatches; + }); + + match(^BOOL{ + if(!actualIsCompatible) return NO; + + if([actual isKindOfClass:[NSDictionary class]]) { + for (id key in subset) { + id actualValue = [actual valueForKey:key]; + id subsetValue = [subset valueForKey:key]; + + if (![subsetValue isEqual:actualValue]) return NO; + } + } else { + for (id object in subset) { + if (![actual containsObject:object]) return NO; + } + } + + return YES; + }); + + failureMessageForTo(^NSString *{ + if(!actualIsCompatible) return [NSString stringWithFormat:@"%@ is not an instance of NSDictionary and does not implement -containsObject:", EXPDescribeObject(actual)]; + + if(subsetIsNil) return @"the expected value is nil/null"; + + if(!classMatches) return [NSString stringWithFormat:@"%@ does not match the class of %@", EXPDescribeObject(subset), EXPDescribeObject(actual)]; + + return [NSString stringWithFormat:@"expected %@ to be a superset of %@", EXPDescribeObject(actual), EXPDescribeObject(subset)]; + }); + + failureMessageForNotTo(^NSString *{ + if(!actualIsCompatible) return [NSString stringWithFormat:@"%@ is not an instance of NSDictionary and does not implement -containsObject:", EXPDescribeObject(actual)]; + + if(subsetIsNil) return @"the expected value is nil/null"; + + if(!classMatches) return [NSString stringWithFormat:@"%@ does not match the class of %@", EXPDescribeObject(subset), EXPDescribeObject(actual)]; + + return [NSString stringWithFormat:@"expected %@ not to be a superset of %@", EXPDescribeObject(actual), EXPDescribeObject(subset)]; + }); +} +EXPMatcherImplementationEnd diff --git a/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+beTruthy.h b/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+beTruthy.h new file mode 100644 index 0000000..1e4e78f --- /dev/null +++ b/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+beTruthy.h @@ -0,0 +1,3 @@ +#import "Expecta.h" + +EXPMatcherInterface(beTruthy, (void)); diff --git a/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+beTruthy.m b/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+beTruthy.m new file mode 100644 index 0000000..02fa6e7 --- /dev/null +++ b/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+beTruthy.m @@ -0,0 +1,24 @@ +#import "EXPMatchers+beTruthy.h" +#import "EXPMatcherHelpers.h" + +EXPMatcherImplementationBegin(beTruthy, (void)) { + match(^BOOL{ + if([actual isKindOfClass:[NSNumber class]]) { + return !![(NSNumber *)actual boolValue]; + } else if([actual isKindOfClass:[NSValue class]]) { + if(EXPIsValuePointer((NSValue *)actual)) { + return !![(NSValue *)actual pointerValue]; + } + } + return !!actual; + }); + + failureMessageForTo(^NSString *{ + return [NSString stringWithFormat:@"expected: a truthy value, got: %@, which is falsy", EXPDescribeObject(actual)]; + }); + + failureMessageForNotTo(^NSString *{ + return [NSString stringWithFormat:@"expected: a non-truthy value, got: %@, which is truthy", EXPDescribeObject(actual)]; + }); +} +EXPMatcherImplementationEnd diff --git a/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+beginWith.h b/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+beginWith.h new file mode 100644 index 0000000..07ddd6c --- /dev/null +++ b/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+beginWith.h @@ -0,0 +1,4 @@ +#import "Expecta.h" + +EXPMatcherInterface(beginWith, (id expected)); +EXPMatcherInterface(startWith, (id expected)); diff --git a/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+beginWith.m b/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+beginWith.m new file mode 100644 index 0000000..a7c9e59 --- /dev/null +++ b/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+beginWith.m @@ -0,0 +1,51 @@ +#import "EXPMatchers+beginWith.h" + +EXPMatcherImplementationBegin(beginWith, (id expected)) { + BOOL actualIsNil = (actual == nil); + BOOL expectedIsNil = (expected == nil); + //This condition allows the comparison of an immutable string or ordered collection to the mutable type of the same + BOOL actualAndExpectedAreCompatible = (([actual isKindOfClass:[NSString class]] && [expected isKindOfClass:[NSString class]]) + || ([actual isKindOfClass:[NSArray class]] && [expected isKindOfClass:[NSArray class]]) + || ([actual isKindOfClass:[NSOrderedSet class]] && [expected isKindOfClass:[NSOrderedSet class]])); + + prerequisite(^BOOL { + return actualAndExpectedAreCompatible; + }); + + match(^BOOL { + if ([actual isKindOfClass:[NSString class]]) { + return [actual hasPrefix:expected]; + } else if ([actual isKindOfClass:[NSArray class]]) { + if ([expected count] > [actual count] || [expected count] == 0) { + return NO; + } + NSArray *subArray = [actual subarrayWithRange:NSMakeRange(0, [expected count])]; + return [subArray isEqualToArray:expected]; + } else { + if ([expected count] > [actual count] || [expected count] == 0) { + return NO; + } + + NSOrderedSet *subset = [NSOrderedSet orderedSetWithOrderedSet:actual range:NSMakeRange(0, [expected count]) copyItems:NO]; + return [subset isEqualToOrderedSet:expected]; + } + }); + + failureMessageForTo(^NSString *{ + if (actualIsNil) return @"the object is nil/null"; + if (expectedIsNil) return @"the expected value is nil/null"; + if (!actualAndExpectedAreCompatible) return [NSString stringWithFormat:@"%@ and %@ are not instances of one of %@, %@, or %@", EXPDescribeObject(actual), EXPDescribeObject(expected), [NSString class], [NSArray class], [NSOrderedSet class]]; + return [NSString stringWithFormat:@"expected: %@ to begin with %@", EXPDescribeObject(actual), EXPDescribeObject(expected)]; + }); + + failureMessageForNotTo(^NSString *{ + if (actualIsNil) return @"the object is nil/null"; + if (expectedIsNil) return @"the expected value is nil/null"; + if (!actualAndExpectedAreCompatible) return [NSString stringWithFormat:@"%@ and %@ are not instances of one of %@, %@, or %@", EXPDescribeObject(actual), EXPDescribeObject(expected), [NSString class], [NSArray class], [NSOrderedSet class]]; + + return [NSString stringWithFormat:@"expected: %@ not to begin with %@", EXPDescribeObject(actual), EXPDescribeObject(expected)]; + }); +} +EXPMatcherImplementationEnd + +EXPMatcherAliasImplementation(startWith, beginWith, (id expected)); diff --git a/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+conformTo.h b/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+conformTo.h new file mode 100644 index 0000000..efc7b98 --- /dev/null +++ b/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+conformTo.h @@ -0,0 +1,3 @@ +#import "Expecta.h" + +EXPMatcherInterface(conformTo, (Protocol *expected)); diff --git a/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+conformTo.m b/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+conformTo.m new file mode 100644 index 0000000..b88014d --- /dev/null +++ b/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+conformTo.m @@ -0,0 +1,33 @@ +#import "EXPMatchers+conformTo.h" +#import "NSValue+Expecta.h" +#import + +EXPMatcherImplementationBegin(conformTo, (Protocol *expected)) { + BOOL actualIsNil = (actual == nil); + BOOL expectedIsNil = (expected == nil); + + prerequisite(^BOOL{ + return !(actualIsNil || expectedIsNil); + }); + + match(^BOOL{ + return [actual conformsToProtocol:expected]; + }); + + failureMessageForTo(^NSString *{ + if(actualIsNil) return @"the object is nil/null"; + if(expectedIsNil) return @"the protocol is nil/null"; + + NSString *name = NSStringFromProtocol(expected); + return [NSString stringWithFormat:@"expected: %@ to conform to %@", actual, name]; + }); + + failureMessageForNotTo(^NSString *{ + if(actualIsNil) return @"the object is nil/null"; + if(expectedIsNil) return @"the protocol is nil/null"; + + NSString *name = NSStringFromProtocol(expected); + return [NSString stringWithFormat:@"expected: %@ not to conform to %@", actual, name]; + }); +} +EXPMatcherImplementationEnd diff --git a/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+contain.h b/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+contain.h new file mode 100644 index 0000000..5803146 --- /dev/null +++ b/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+contain.h @@ -0,0 +1,5 @@ +#import "Expecta.h" + +EXPMatcherInterface(_contain, (id expected)); +EXPMatcherInterface(contain, (id expected)); // to aid code completion +#define contain(expected) _contain(EXPObjectify((expected))) diff --git a/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+contain.m b/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+contain.m new file mode 100644 index 0000000..b8a6f86 --- /dev/null +++ b/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+contain.m @@ -0,0 +1,38 @@ +#import "EXPMatchers+contain.h" + +EXPMatcherImplementationBegin(_contain, (id expected)) { + BOOL actualIsCompatible = [actual isKindOfClass:[NSString class]] || [actual conformsToProtocol:@protocol(NSFastEnumeration)]; + BOOL expectedIsNil = (expected == nil); + + prerequisite(^BOOL{ + return actualIsCompatible && !expectedIsNil; + }); + + match(^BOOL{ + if(actualIsCompatible) { + if([actual isKindOfClass:[NSString class]]) { + return [(NSString *)actual rangeOfString:[expected description]].location != NSNotFound; + } else { + for (id object in actual) { + if ([object isEqual:expected]) { + return YES; + } + } + } + } + return NO; + }); + + failureMessageForTo(^NSString *{ + if(!actualIsCompatible) return [NSString stringWithFormat:@"%@ is not an instance of NSString or NSFastEnumeration", EXPDescribeObject(actual)]; + if(expectedIsNil) return @"the expected value is nil/null"; + return [NSString stringWithFormat:@"expected %@ to contain %@", EXPDescribeObject(actual), EXPDescribeObject(expected)]; + }); + + failureMessageForNotTo(^NSString *{ + if(!actualIsCompatible) return [NSString stringWithFormat:@"%@ is not an instance of NSString or NSFastEnumeration", EXPDescribeObject(actual)]; + if(expectedIsNil) return @"the expected value is nil/null"; + return [NSString stringWithFormat:@"expected %@ not to contain %@", EXPDescribeObject(actual), EXPDescribeObject(expected)]; + }); +} +EXPMatcherImplementationEnd diff --git a/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+endWith.h b/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+endWith.h new file mode 100644 index 0000000..228cea9 --- /dev/null +++ b/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+endWith.h @@ -0,0 +1,3 @@ +#import "Expecta.h" + +EXPMatcherInterface(endWith, (id expected)); diff --git a/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+endWith.m b/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+endWith.m new file mode 100644 index 0000000..f34bd90 --- /dev/null +++ b/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+endWith.m @@ -0,0 +1,49 @@ +#import "EXPMatchers+endWith.h" + +EXPMatcherImplementationBegin(endWith, (id expected)) { + BOOL actualIsNil = (actual == nil); + BOOL expectedIsNil = (expected == nil); + //This condition allows the comparison of an immutable string or ordered collection to the mutable type of the same + BOOL actualAndExpectedAreCompatible = (([actual isKindOfClass:[NSString class]] && [expected isKindOfClass:[NSString class]]) + || ([actual isKindOfClass:[NSArray class]] && [expected isKindOfClass:[NSArray class]]) + || ([actual isKindOfClass:[NSOrderedSet class]] && [expected isKindOfClass:[NSOrderedSet class]])); + + prerequisite(^BOOL { + return actualAndExpectedAreCompatible; + }); + + match(^BOOL { + if ([actual isKindOfClass:[NSString class]]) { + return [actual hasSuffix:expected]; + } else if ([actual isKindOfClass:[NSArray class]]) { + if ([expected count] > [actual count] || [expected count] == 0) { + return NO; + } + NSArray *subArray = [actual subarrayWithRange:NSMakeRange([actual count] - [expected count], [expected count])]; + return [subArray isEqualToArray:expected]; + } else { + if ([expected count] > [actual count] || [expected count] == 0) { + return NO; + } + + NSOrderedSet *subset = [NSOrderedSet orderedSetWithOrderedSet:actual range:NSMakeRange([actual count] - [expected count], [expected count]) copyItems:NO]; + return [subset isEqualToOrderedSet:expected]; + } + }); + + failureMessageForTo(^NSString *{ + if (actualIsNil) return @"the object is nil/null"; + if (expectedIsNil) return @"the expected value is nil/null"; + if (!actualAndExpectedAreCompatible) return [NSString stringWithFormat:@"%@ and %@ are not instances of one of %@, %@, or %@", EXPDescribeObject(actual), EXPDescribeObject(expected), [NSString class], [NSArray class], [NSOrderedSet class]]; + return [NSString stringWithFormat:@"expected: %@ to end with %@", EXPDescribeObject(actual), EXPDescribeObject(expected)]; + }); + + failureMessageForNotTo(^NSString *{ + if (actualIsNil) return @"the object is nil/null"; + if (expectedIsNil) return @"the expected value is nil/null"; + if (!actualAndExpectedAreCompatible) return [NSString stringWithFormat:@"%@ and %@ are not instances of one of %@, %@, or %@", EXPDescribeObject(actual), EXPDescribeObject(expected), [NSString class], [NSArray class], [NSOrderedSet class]]; + + return [NSString stringWithFormat:@"expected: %@ not to end with %@", EXPDescribeObject(actual), EXPDescribeObject(expected)]; + }); +} +EXPMatcherImplementationEnd diff --git a/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+equal.h b/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+equal.h new file mode 100644 index 0000000..b4047c0 --- /dev/null +++ b/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+equal.h @@ -0,0 +1,5 @@ +#import "Expecta.h" + +EXPMatcherInterface(_equal, (id expected)); +EXPMatcherInterface(equal, (id expected)); // to aid code completion +#define equal(...) _equal(EXPObjectify((__VA_ARGS__))) diff --git a/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+equal.m b/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+equal.m new file mode 100644 index 0000000..0dc4d33 --- /dev/null +++ b/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+equal.m @@ -0,0 +1,38 @@ +#import "EXPMatchers+equal.h" +#import "EXPMatcherHelpers.h" + +EXPMatcherImplementationBegin(_equal, (id expected)) { + match(^BOOL{ + if((actual == expected) || [actual isEqual:expected]) { + return YES; + } else if([actual isKindOfClass:[NSNumber class]] && [expected isKindOfClass:[NSNumber class]]) { + if([actual isKindOfClass:[NSDecimalNumber class]] || [expected isKindOfClass:[NSDecimalNumber class]]) { + NSDecimalNumber *actualDecimalNumber = [NSDecimalNumber decimalNumberWithDecimal:[(NSNumber *) actual decimalValue]]; + NSDecimalNumber *expectedDecimalNumber = [NSDecimalNumber decimalNumberWithDecimal:[(NSNumber *) expected decimalValue]]; + return [actualDecimalNumber isEqualToNumber:expectedDecimalNumber]; + } + else { + if(EXPIsNumberFloat((NSNumber *)actual) || EXPIsNumberFloat((NSNumber *)expected)) { + return [(NSNumber *)actual floatValue] == [(NSNumber *)expected floatValue]; + } + } + } + return NO; + }); + + failureMessageForTo(^NSString *{ + NSString *expectedDescription = EXPDescribeObject(expected); + NSString *actualDescription = EXPDescribeObject(actual); + + if (![expectedDescription isEqualToString:actualDescription]) { + return [NSString stringWithFormat:@"expected: %@, got: %@", EXPDescribeObject(expected), EXPDescribeObject(actual)]; + } else { + return [NSString stringWithFormat:@"expected (%@): %@, got (%@): %@", NSStringFromClass([expected class]), EXPDescribeObject(expected), NSStringFromClass([actual class]), EXPDescribeObject(actual)]; + } + }); + + failureMessageForNotTo(^NSString *{ + return [NSString stringWithFormat:@"expected: not %@, got: %@", EXPDescribeObject(expected), EXPDescribeObject(actual)]; + }); +} +EXPMatcherImplementationEnd diff --git a/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+haveCountOf.h b/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+haveCountOf.h new file mode 100644 index 0000000..2e9aef5 --- /dev/null +++ b/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+haveCountOf.h @@ -0,0 +1,10 @@ +#import "Expecta.h" + +EXPMatcherInterface(haveCountOf, (NSUInteger expected)); +EXPMatcherInterface(haveCount, (NSUInteger expected)); +EXPMatcherInterface(haveACountOf, (NSUInteger expected)); +EXPMatcherInterface(haveLength, (NSUInteger expected)); +EXPMatcherInterface(haveLengthOf, (NSUInteger expected)); +EXPMatcherInterface(haveALengthOf, (NSUInteger expected)); + +#define beEmpty() haveCountOf(0) diff --git a/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+haveCountOf.m b/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+haveCountOf.m new file mode 100644 index 0000000..ecc4831 --- /dev/null +++ b/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+haveCountOf.m @@ -0,0 +1,42 @@ +#import "EXPMatchers+haveCountOf.h" + +EXPMatcherImplementationBegin(haveCountOf, (NSUInteger expected)) { + BOOL actualIsStringy = [actual isKindOfClass:[NSString class]] || [actual isKindOfClass:[NSAttributedString class]]; + BOOL actualIsCompatible = actualIsStringy || [actual respondsToSelector:@selector(count)]; + + prerequisite(^BOOL{ + return actualIsCompatible; + }); + + NSUInteger (^count)(id) = ^(id actual) { + if(actualIsStringy) { + return [actual length]; + } else { + return [actual count]; + } + }; + + match(^BOOL{ + if(actualIsCompatible) { + return count(actual) == expected; + } + return NO; + }); + + failureMessageForTo(^NSString *{ + if(!actualIsCompatible) return [NSString stringWithFormat:@"%@ is not an instance of NSString, NSAttributedString, NSArray, NSSet, NSOrderedSet, or NSDictionary", EXPDescribeObject(actual)]; + return [NSString stringWithFormat:@"expected %@ to have a count of %zi but got %zi", EXPDescribeObject(actual), expected, count(actual)]; + }); + + failureMessageForNotTo(^NSString *{ + if(!actualIsCompatible) return [NSString stringWithFormat:@"%@ is not an instance of NSString, NSAttributedString, NSArray, NSSet, NSOrderedSet, or NSDictionary", EXPDescribeObject(actual)]; + return [NSString stringWithFormat:@"expected %@ not to have a count of %zi", EXPDescribeObject(actual), expected]; + }); +} +EXPMatcherImplementationEnd + +EXPMatcherAliasImplementation(haveCount, haveCountOf, (NSUInteger expected)); +EXPMatcherAliasImplementation(haveACountOf, haveCountOf, (NSUInteger expected)); +EXPMatcherAliasImplementation(haveLength, haveCountOf, (NSUInteger expected)); +EXPMatcherAliasImplementation(haveLengthOf, haveCountOf, (NSUInteger expected)); +EXPMatcherAliasImplementation(haveALengthOf, haveCountOf, (NSUInteger expected)); diff --git a/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+match.h b/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+match.h new file mode 100644 index 0000000..4f0e8e4 --- /dev/null +++ b/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+match.h @@ -0,0 +1,3 @@ +#import "Expecta.h" + +EXPMatcherInterface(match, (NSString *expected)); diff --git a/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+match.m b/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+match.m new file mode 100644 index 0000000..a217467 --- /dev/null +++ b/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+match.m @@ -0,0 +1,38 @@ +#import "EXPMatchers+match.h" +#import "EXPMatcherHelpers.h" + +EXPMatcherImplementationBegin(match, (NSString *expected)) { + BOOL actualIsNil = (actual == nil); + BOOL expectedIsNil = (expected == nil); + + __block NSRegularExpression *regex = nil; + __block NSError *regexError = nil; + + prerequisite (^BOOL { + BOOL nilInput = (actualIsNil || expectedIsNil); + if (!nilInput) { + regex = [NSRegularExpression regularExpressionWithPattern:expected options:0 error:®exError]; + } + return !nilInput && regex; + }); + + match(^BOOL { + NSRange range = [regex rangeOfFirstMatchInString:actual options:0 range:NSMakeRange(0, [actual length])]; + return !NSEqualRanges(range, NSMakeRange(NSNotFound, 0)); + }); + + failureMessageForTo(^NSString *{ + if (actualIsNil) return @"the object is nil/null"; + if (expectedIsNil) return @"the expression is nil/null"; + if (regexError) return [NSString stringWithFormat:@"unable to create regular expression from given parameter: %@", [regexError localizedDescription]]; + return [NSString stringWithFormat:@"expected: %@ to match to %@", EXPDescribeObject(actual), expected]; + }); + + failureMessageForNotTo(^NSString *{ + if (actualIsNil) return @"the object is nil/null"; + if (expectedIsNil) return @"the expression is nil/null"; + if (regexError) return [NSString stringWithFormat:@"unable to create regular expression from given parameter: %@", [regexError localizedDescription]]; + return [NSString stringWithFormat:@"expected: %@ not to match to %@", EXPDescribeObject(actual), expected]; + }); +} +EXPMatcherImplementationEnd diff --git a/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+postNotification.h b/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+postNotification.h new file mode 100644 index 0000000..cdba4a3 --- /dev/null +++ b/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+postNotification.h @@ -0,0 +1,4 @@ +#import "Expecta.h" + +EXPMatcherInterface(postNotification, (id expectedNotification)); +EXPMatcherInterface(notify, (id expectedNotification)); diff --git a/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+postNotification.m b/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+postNotification.m new file mode 100644 index 0000000..6e517c4 --- /dev/null +++ b/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+postNotification.m @@ -0,0 +1,88 @@ +#import "EXPMatchers+postNotification.h" + +@implementation NSNotification (EXPEquality) + +- (BOOL)exp_isFunctionallyEqualTo:(NSNotification *)otherNotification +{ + if (![otherNotification isKindOfClass:[NSNotification class]]) return NO; + + BOOL namesMatch = [otherNotification.name isEqualToString:self.name]; + + BOOL objectsMatch = YES; + if (otherNotification.object || self.object) { + objectsMatch = [otherNotification.object isEqual:self.object]; + } + + BOOL userInfoMatches = YES; + if (otherNotification.userInfo || self.userInfo) { + userInfoMatches = [otherNotification.userInfo isEqual:self.userInfo]; + } + + return (namesMatch && objectsMatch && userInfoMatches); +} + +@end + +EXPMatcherImplementationBegin(postNotification, (id expected)){ + BOOL actualIsNil = (actual == nil); + BOOL expectedIsNil = (expected == nil); + BOOL isNotification = [expected isKindOfClass:[NSNotification class]]; + BOOL isName = [expected isKindOfClass:[NSString class]]; + + __block NSString *expectedName; + __block BOOL expectedNotificationOccurred = NO; + __block id observer; + + prerequisite(^BOOL{ + expectedNotificationOccurred = NO; + if (actualIsNil || expectedIsNil) return NO; + if (isNotification) { + expectedName = [expected name]; + }else if(isName) { + expectedName = expected; + }else{ + return NO; + } + + observer = [[NSNotificationCenter defaultCenter] addObserverForName:expectedName object:nil queue:nil usingBlock:^(NSNotification *note){ + if (isNotification) { + expectedNotificationOccurred |= [expected exp_isFunctionallyEqualTo:note]; + }else{ + expectedNotificationOccurred = YES; + } + }]; + ((EXPBasicBlock)actual)(); + return YES; + }); + + match(^BOOL{ + if(expectedNotificationOccurred) { + [[NSNotificationCenter defaultCenter] removeObserver:observer]; + } + return expectedNotificationOccurred; + }); + + failureMessageForTo(^NSString *{ + if (observer) { + [[NSNotificationCenter defaultCenter] removeObserver:observer]; + } + if(actualIsNil) return @"the actual value is nil/null"; + if(expectedIsNil) return @"the expected value is nil/null"; + if(!(isNotification || isName)) return @"the actual value is not a notification or string"; + return [NSString stringWithFormat:@"expected: %@, got: none",expectedName]; + }); + + failureMessageForNotTo(^NSString *{ + if (observer) { + [[NSNotificationCenter defaultCenter] removeObserver:observer]; + } + if(actualIsNil) return @"the actual value is nil/null"; + if(expectedIsNil) return @"the expected value is nil/null"; + if(!(isNotification || isName)) return @"the actual value is not a notification or string"; + return [NSString stringWithFormat:@"expected: none, got: %@", expectedName]; + }); +} + +EXPMatcherImplementationEnd + +EXPMatcherAliasImplementation(notify, postNotification, (id expectedNotification)) diff --git a/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+raise.h b/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+raise.h new file mode 100644 index 0000000..1f7fae0 --- /dev/null +++ b/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+raise.h @@ -0,0 +1,4 @@ +#import "Expecta.h" + +EXPMatcherInterface(raise, (NSString *expectedExceptionName)); +#define raiseAny() raise(nil) diff --git a/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+raise.m b/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+raise.m new file mode 100644 index 0000000..26f3c55 --- /dev/null +++ b/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+raise.m @@ -0,0 +1,30 @@ +#import "EXPMatchers+raise.h" +#import "EXPDefines.h" + +EXPMatcherImplementationBegin(raise, (NSString *expectedExceptionName)) { + __block NSException *exceptionCaught = nil; + + match(^BOOL{ + BOOL expectedExceptionCaught = NO; + @try { + ((EXPBasicBlock)actual)(); + } @catch(NSException *e) { + exceptionCaught = e; + expectedExceptionCaught = (expectedExceptionName == nil) || [[exceptionCaught name] isEqualToString:expectedExceptionName]; + } + return expectedExceptionCaught; + }); + + failureMessageForTo(^NSString *{ + return [NSString stringWithFormat:@"expected: %@, got: %@", + expectedExceptionName ? expectedExceptionName : @"any exception", + exceptionCaught ? [exceptionCaught name] : @"no exception"]; + }); + + failureMessageForNotTo(^NSString *{ + return [NSString stringWithFormat:@"expected: %@, got: %@", + expectedExceptionName ? [NSString stringWithFormat:@"not %@", expectedExceptionName] : @"no exception", + exceptionCaught ? [exceptionCaught name] : @"no exception"]; + }); +} +EXPMatcherImplementationEnd diff --git a/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+raiseWithReason.h b/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+raiseWithReason.h new file mode 100644 index 0000000..2cf5a5d --- /dev/null +++ b/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+raiseWithReason.h @@ -0,0 +1,3 @@ +#import "Expecta.h" + +EXPMatcherInterface(raiseWithReason, (NSString *expectedExceptionName, NSString *expectedReason)); diff --git a/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+raiseWithReason.m b/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+raiseWithReason.m new file mode 100644 index 0000000..3943d38 --- /dev/null +++ b/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+raiseWithReason.m @@ -0,0 +1,35 @@ +#import "EXPMatchers+raiseWithReason.h" +#import "EXPDefines.h" + +EXPMatcherImplementationBegin(raiseWithReason, (NSString *expectedExceptionName, NSString *expectedReason)) { + __block NSException *exceptionCaught = nil; + + match(^BOOL{ + BOOL expectedExceptionCaught = NO; + @try { + ((EXPBasicBlock)actual)(); + } @catch(NSException *e) { + exceptionCaught = e; + expectedExceptionCaught = (((expectedExceptionName == nil) || [[exceptionCaught name] isEqualToString:expectedExceptionName]) && + ((expectedReason == nil) || ([[exceptionCaught reason] isEqualToString:expectedReason]))); + } + return expectedExceptionCaught; + }); + + failureMessageForTo(^NSString *{ + return [NSString stringWithFormat:@"expected: %@ (%@), got: %@ (%@)", + expectedExceptionName ?: @"any exception", + expectedReason ?: @"any reason", + exceptionCaught ? [exceptionCaught name] : @"no exception", + exceptionCaught ? [exceptionCaught reason] : @""]; + }); + + failureMessageForNotTo(^NSString *{ + return [NSString stringWithFormat:@"expected: %@ (%@), got: %@ (%@)", + expectedExceptionName ? [NSString stringWithFormat:@"not %@", expectedExceptionName] : @"no exception", + expectedReason ? [NSString stringWithFormat:@"not '%@'", expectedReason] : @"no reason", + exceptionCaught ? [exceptionCaught name] : @"no exception", + exceptionCaught ? [exceptionCaught reason] : @"no reason"]; + }); +} +EXPMatcherImplementationEnd diff --git a/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+respondTo.h b/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+respondTo.h new file mode 100644 index 0000000..279131d --- /dev/null +++ b/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+respondTo.h @@ -0,0 +1,3 @@ +#import "Expecta.h" + +EXPMatcherInterface(respondTo, (SEL expected)); diff --git a/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+respondTo.m b/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+respondTo.m new file mode 100644 index 0000000..d294113 --- /dev/null +++ b/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers+respondTo.m @@ -0,0 +1,28 @@ +#import "EXPMatchers+respondTo.h" +#import "EXPMatcherHelpers.h" + +EXPMatcherImplementationBegin(respondTo, (SEL expected)) { + BOOL actualIsNil = (actual == nil); + BOOL expectedIsNull = (expected == NULL); + + prerequisite (^BOOL { + return !(actualIsNil || expectedIsNull); + }); + + match(^BOOL { + return [actual respondsToSelector:expected]; + }); + + failureMessageForTo(^NSString *{ + if (actualIsNil) return @"the object is nil/null"; + if (expectedIsNull) return @"the selector is null"; + return [NSString stringWithFormat:@"expected: %@ to respond to %@", EXPDescribeObject(actual), NSStringFromSelector(expected)]; + }); + + failureMessageForNotTo(^NSString *{ + if (actualIsNil) return @"the object is nil/null"; + if (expectedIsNull) return @"the selector is null"; + return [NSString stringWithFormat:@"expected: %@ not to respond to %@", EXPDescribeObject(actual), NSStringFromSelector(expected)]; + }); +} +EXPMatcherImplementationEnd diff --git a/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers.h b/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers.h new file mode 100644 index 0000000..ed6ef85 --- /dev/null +++ b/Example/Pods/Expecta/Expecta/Matchers/EXPMatchers.h @@ -0,0 +1,25 @@ +#import "EXPMatchers+beNil.h" +#import "EXPMatchers+equal.h" +#import "EXPMatchers+beInstanceOf.h" +#import "EXPMatchers+beKindOf.h" +#import "EXPMatchers+beSubclassOf.h" +#import "EXPMatchers+conformTo.h" +#import "EXPMatchers+beTruthy.h" +#import "EXPMatchers+beFalsy.h" +#import "EXPMatchers+contain.h" +#import "EXPMatchers+beSupersetOf.h" +#import "EXPMatchers+haveCountOf.h" +#import "EXPMatchers+beIdenticalTo.h" +#import "EXPMatchers+beGreaterThan.h" +#import "EXPMatchers+beGreaterThanOrEqualTo.h" +#import "EXPMatchers+beLessThan.h" +#import "EXPMatchers+beLessThanOrEqualTo.h" +#import "EXPMatchers+beInTheRangeOf.h" +#import "EXPMatchers+beCloseTo.h" +#import "EXPMatchers+raise.h" +#import "EXPMatchers+raiseWithReason.h" +#import "EXPMatchers+respondTo.h" +#import "EXPMatchers+postNotification.h" +#import "EXPMatchers+beginWith.h" +#import "EXPMatchers+endWith.h" +#import "EXPMatchers+match.h" diff --git a/Example/Pods/Expecta/Expecta/NSObject+Expecta.h b/Example/Pods/Expecta/Expecta/NSObject+Expecta.h new file mode 100644 index 0000000..5920e31 --- /dev/null +++ b/Example/Pods/Expecta/Expecta/NSObject+Expecta.h @@ -0,0 +1,10 @@ +#import + +@interface NSObject (Expecta) + +- (void)recordFailureWithDescription:(NSString *)description + inFile:(NSString *)filename + atLine:(NSUInteger)lineNumber + expected:(BOOL)expected; + +@end diff --git a/Example/Pods/Expecta/Expecta/NSValue+Expecta.h b/Example/Pods/Expecta/Expecta/NSValue+Expecta.h new file mode 100644 index 0000000..e8ff6a4 --- /dev/null +++ b/Example/Pods/Expecta/Expecta/NSValue+Expecta.h @@ -0,0 +1,7 @@ +#import + +@interface NSValue (Expecta) + +@property (nonatomic) const char *_EXP_objCType; + +@end diff --git a/Example/Pods/Expecta/Expecta/NSValue+Expecta.m b/Example/Pods/Expecta/Expecta/NSValue+Expecta.m new file mode 100644 index 0000000..f660996 --- /dev/null +++ b/Example/Pods/Expecta/Expecta/NSValue+Expecta.m @@ -0,0 +1,21 @@ +#import "NSValue+Expecta.h" +#import +#import "Expecta.h" + +EXPFixCategoriesBug(NSValue_Expecta); + +@implementation NSValue (Expecta) + +static char _EXP_typeKey; + +- (const char *)_EXP_objCType { + return [(NSString *)objc_getAssociatedObject(self, &_EXP_typeKey) cStringUsingEncoding:NSASCIIStringEncoding]; +} + +- (void)set_EXP_objCType:(const char *)_EXP_objCType { + objc_setAssociatedObject(self, &_EXP_typeKey, + @(_EXP_objCType), + OBJC_ASSOCIATION_COPY_NONATOMIC); +} + +@end diff --git a/Example/Pods/Expecta/LICENSE b/Example/Pods/Expecta/LICENSE new file mode 100644 index 0000000..a036c85 --- /dev/null +++ b/Example/Pods/Expecta/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2011-2015 Specta Team - https://github.com/specta + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/Example/Pods/Expecta/README.md b/Example/Pods/Expecta/README.md new file mode 100644 index 0000000..1933707 --- /dev/null +++ b/Example/Pods/Expecta/README.md @@ -0,0 +1,293 @@ +#Expecta + +[![Build Status](http://img.shields.io/travis/specta/expecta/master.svg?style=flat)](https://travis-ci.org/specta/expecta) +[![Pod Version](http://img.shields.io/cocoapods/v/Expecta.svg?style=flat)](http://cocoadocs.org/docsets/Expecta/) +[![Pod Platform](http://img.shields.io/cocoapods/p/Expecta.svg?style=flat)](http://cocoadocs.org/docsets/Expecta/) +[![Pod License](http://img.shields.io/cocoapods/l/Expecta.svg?style=flat)](https://www.apache.org/licenses/LICENSE-2.0.html) + +A matcher framework for Objective-C and Cocoa. + +## Introduction + +The main advantage of using Expecta over other matcher frameworks is that you do not have to specify the data types. Also, the syntax of Expecta matchers is much more readable and does not suffer from parenthesitis. + +```objective-c +expect(@"foo").to.equal(@"foo"); // `to` is a syntactic sugar and can be safely omitted. +expect(foo).notTo.equal(1); +expect([bar isBar]).to.equal(YES); +expect(baz).to.equal(3.14159); +``` + +Expecta is framework-agnostic: it works well with XCTest and XCTest-compatible test frameworks such as [Specta](http://github.com/petejkim/specta/). + + +## Installation + +You can setup Expecta using [Carthage](https://github.com/Carthage/Carthage), [CocoaPods](http://github.com/CocoaPods/CocoaPods) or [completely manually](#setting-up-manually). + +### Carthage + +1. Add Expecta to your project's `Cartfile.private`: + + ```ruby + github "specta/expecta" "master" + ``` + +2. Run `carthage update` in your project directory. +3. Drag the appropriate **Expecta.framework** for your platform (located in `Carthage/Build/`) into your application’s Xcode project, and add it to your test target(s). + +### CocoaPods + +1. Add Expecta to your project's `Podfile`: + + ```ruby + target :MyApp do + # Your app's dependencies + end + + target :MyAppTests do + pod 'Expecta', '~> 1.0.0' + end + ``` + +2. Run `pod update` or `pod install` in your project directory. + +### Setting Up Manually + +1. Clone Expecta from Github. +2. Run `rake` in your project directory to build the frameworks and libraries. +3. Add a Cocoa or Cocoa Touch Unit Testing Bundle target to your Xcode project if you don't already have one. +4. For **OS X projects**, copy and add `Expecta.framework` in the `Products/osx` folder to your project's test target. + + For **iOS projects**, copy and add `Expecta.framework` in the `Products/ios` folder to your project's test target. + + You can also use `libExpecta.a` if you prefer to link Expecta as a static library — iOS 7.x and below require this. + +6. Add `-ObjC` and `-all_load` to the **Other Linker Flags** build setting for the test target in your Xcode project. +7. You can now use Expecta in your test classes by adding the following import: + + ```objective-c + @import Expecta; // If you're using Expecta.framework + + // OR + + #import // If you're using the static library, or the framework + ``` + +## Built-in Matchers + +> `expect(x).to.equal(y);` compares objects or primitives x and y and passes if they are identical (==) or equivalent isEqual:). + +> `expect(x).to.beIdenticalTo(y);` compares objects x and y and passes if they are identical and have the same memory address. + +> `expect(x).to.beNil();` passes if x is nil. + +> `expect(x).to.beTruthy();` passes if x evaluates to true (non-zero). + +> `expect(x).to.beFalsy();` passes if x evaluates to false (zero). + +> `expect(x).to.contain(y);` passes if an instance of NSArray or NSString x contains y. + +> `expect(x).to.beSupersetOf(y);` passes if an instance of NSArray, NSSet, NSDictionary or NSOrderedSet x contains all elements of y. + +> `expect(x).to.haveCountOf(y);` passes if an instance of NSArray, NSSet, NSDictionary or NSString x has a count or length of y. + +> `expect(x).to.beEmpty();` passes if an instance of NSArray, NSSet, NSDictionary or NSString x has a count or length of . + +> `expect(x).to.beInstanceOf([Foo class]);` passes if x is an instance of a class Foo. + +> `expect(x).to.beKindOf([Foo class]);` passes if x is an instance of a class Foo or if x is an instance of any class that inherits from the class Foo. + +> `expect([Foo class]).to.beSubclassOf([Bar class]);` passes if the class Foo is a subclass of the class Bar or if it is identical to the class Bar. Use beKindOf() for class clusters. + +> `expect(x).to.beLessThan(y);` passes if `x` is less than `y`. + +> `expect(x).to.beLessThanOrEqualTo(y);` passes if `x` is less than or equal to `y`. + +> `expect(x).to.beGreaterThan(y);` passes if `x` is greater than `y`. + +> `expect(x).to.beGreaterThanOrEqualTo(y);` passes if `x` is greater than or equal to `y`. + +> `expect(x).to.beInTheRangeOf(y,z);` passes if `x` is in the range of `y` and `z`. + +> `expect(x).to.beCloseTo(y);` passes if `x` is close to `y`. + +> `expect(x).to.beCloseToWithin(y, z);` passes if `x` is close to `y` within `z`. + +> `expect(^{ /* code */ }).to.raise(@"ExceptionName");` passes if a given block of code raises an exception named `ExceptionName`. + +> `expect(^{ /* code */ }).to.raiseAny();` passes if a given block of code raises any exception. + +> `expect(x).to.conformTo(y);` passes if `x` conforms to the protocol `y`. + +> `expect(x).to.respondTo(y);` passes if `x` responds to the selector `y`. + +> `expect(^{ /* code */ }).to.notify(@"NotificationName");` passes if a given block of code generates an NSNotification amed `NotificationName`. + +> `expect(^{ /* code */ }).to.notify(notification);` passes if a given block of code generates an NSNotification equal to the passed `notification`. + +> `expect(x).to.beginWith(y);` passes if an instance of NSString, NSArray, or NSOrderedSet `x` begins with `y`. Also liased by `startWith` + +> `expect(x).to.endWith(y);` passes if an instance of NSString, NSArray, or NSOrderedSet `x` ends with `y`. + +> `expect(x).to.match(y);` passes if an instance of NSString `x` matches regular expression (given as NSString) `y` one or more times. + +## Inverting Matchers + +Every matcher's criteria can be inverted by prepending `.notTo` or `.toNot`: + +>`expect(x).notTo.equal(y);` compares objects or primitives x and y and passes if they are *not* equivalent. + +## Asynchronous Testing + +Every matcher can be made to perform asynchronous testing by prepending `.will`, `.willNot` or `after(...)`: + +>`expect(x).will.beNil();` passes if x becomes nil before the default timeout. +> +>`expect(x).willNot.beNil();` passes if x becomes non-nil before the default timeout. +> +>`expect(x).after(3).to.beNil();` passes if x becoms nil after 3.0 seconds. +> +>`expect(x).after(2.5).notTo.equal(42);` passes if x doesn't equal 42 after 2.5 seconds. + +The default timeout is 1.0 second and is used for all matchers if not otherwise specified. This setting can be changed by calling `[Expecta setAsynchronousTestTimeout:x]`, where `x` is the desired timeout in seconds. + +```objective-c +describe(@"Foo", ^{ + beforeAll(^{ + // All asynchronous matching using `will` and `willNot` + // will have a timeout of 2.0 seconds + [Expecta setAsynchronousTestTimeout:2]; + }); + + it(@"will not be nil", ^{ + // Test case where default timeout is used + expect(foo).willNot.beNil(); + }); + + it(@"should equal 42 after 3 seconds", ^{ + // Signle case where timeout differs from the default + expect(foo).after(3).to.equal(42); + }); +}); +``` + +## Forced Failing + +You can fail a test by using the `failure` attribute. This can be used to test branching. + +> `failure(@"This should not happen");` outright fails a test. + + +## Writing New Matchers + +Writing a new matcher is easy with special macros provided by Expecta. Take a look at how `.beKindOf()` matcher is defined: + +`EXPMatchers+beKindOf.h` + +```objective-c +#import "Expecta.h" + +EXPMatcherInterface(beKindOf, (Class expected)); +// 1st argument is the name of the matcher function +// 2nd argument is the list of arguments that may be passed in the function +// call. +// Multiple arguments are fine. (e.g. (int foo, float bar)) + +#define beAKindOf beKindOf +``` + +`EXPMatchers+beKindOf.m` + +```objective-c +#import "EXPMatchers+beKindOf.h" + +EXPMatcherImplementationBegin(beKindOf, (Class expected)) { + BOOL actualIsNil = (actual == nil); + BOOL expectedIsNil = (expected == nil); + + prerequisite(^BOOL { + return !(actualIsNil || expectedIsNil); + // Return `NO` if matcher should fail whether or not the result is inverted + // using `.Not`. + }); + + match(^BOOL { + return [actual isKindOfClass:expected]; + // Return `YES` if the matcher should pass, `NO` if it should not. + // The actual value/object is passed as `actual`. + // Please note that primitive values will be wrapped in NSNumber/NSValue. + }); + + failureMessageForTo(^NSString * { + if (actualIsNil) + return @"the actual value is nil/null"; + if (expectedIsNil) + return @"the expected value is nil/null"; + return [NSString + stringWithFormat:@"expected: a kind of %@, " + "got: an instance of %@, which is not a kind of %@", + [expected class], [actual class], [expected class]]; + // Return the message to be displayed when the match function returns `YES`. + }); + + failureMessageForNotTo(^NSString * { + if (actualIsNil) + return @"the actual value is nil/null"; + if (expectedIsNil) + return @"the expected value is nil/null"; + return [NSString + stringWithFormat:@"expected: not a kind of %@, " + "got: an instance of %@, which is a kind of %@", + [expected class], [actual class], [expected class]]; + // Return the message to be displayed when the match function returns `NO`. + }); +} +EXPMatcherImplementationEnd +``` + +## Dynamic Predicate Matchers + +It is possible to add predicate matchers by simply defining the matcher interface, with the matcher implementation being handled at runtime by delegating to the predicate method on your object. + +For instance, if you have the following class: + +```objc +@interface LightSwitch : NSObject +@property (nonatomic, assign, getter=isTurnedOn) BOOL turnedOn; +@end + +@implementation LightSwitch +@synthesize turnedOn; +@end +``` + +The normal way to write an assertion that the switch is turned on would be: + +```objc +expect([lightSwitch isTurnedOn]).to.beTruthy(); +``` + +However, if we define a custom predicate matcher: + +```objc +EXPMatcherInterface(isTurnedOn, (void)); +``` + +(Note: we haven't defined the matcher implementation, just it's interface) + +You can now write your assertion as follows: + +```objc +expect(lightSwitch).isTurnedOn(); +``` + +## Contribution Guidelines + +* Please use only spaces and indent 2 spaces at a time. +* Please prefix instance variable names with a single underscore (`_`). +* Please prefix custom classes and functions defined in the global scope with `EXP`. + +## License + +Copyright (c) 2012-2015 [Specta Team](https://github.com/specta?tab=members). This software is licensed under the [MIT License](http://github.com/specta/specta/raw/master/LICENSE). diff --git a/Example/Pods/FBSnapshotTestCase/FBSnapshotTestCase.modulemap b/Example/Pods/FBSnapshotTestCase/FBSnapshotTestCase.modulemap new file mode 100644 index 0000000..733e78b --- /dev/null +++ b/Example/Pods/FBSnapshotTestCase/FBSnapshotTestCase.modulemap @@ -0,0 +1,15 @@ +framework module FBSnapshotTestCase { + umbrella header "FBSnapshotTestCase.h" + + export * + module * { export * } + + header "FBSnapshotTestCase.h" + header "FBSnapshotTestCasePlatform.h" + header "FBSnapshotTestController.h" + + private header "UIImage+Compare.h" + private header "UIImage+Diff.h" + private header "UIImage+Snapshot.h" +} + diff --git a/Example/Pods/FBSnapshotTestCase/FBSnapshotTestCase/Categories/UIImage+Compare.h b/Example/Pods/FBSnapshotTestCase/FBSnapshotTestCase/Categories/UIImage+Compare.h new file mode 100644 index 0000000..9091d62 --- /dev/null +++ b/Example/Pods/FBSnapshotTestCase/FBSnapshotTestCase/Categories/UIImage+Compare.h @@ -0,0 +1,37 @@ +// +// Created by Gabriel Handford on 3/1/09. +// Copyright 2009-2013. All rights reserved. +// Created by John Boiles on 10/20/11. +// Copyright (c) 2011. All rights reserved +// Modified by Felix Schulze on 2/11/13. +// Copyright 2013. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without +// restriction, including without limitation the rights to use, +// copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following +// conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. +// + +#import + +@interface UIImage (Compare) + +- (BOOL)fb_compareWithImage:(UIImage *)image tolerance:(CGFloat)tolerance; + +@end diff --git a/Example/Pods/FBSnapshotTestCase/FBSnapshotTestCase/Categories/UIImage+Compare.m b/Example/Pods/FBSnapshotTestCase/FBSnapshotTestCase/Categories/UIImage+Compare.m new file mode 100644 index 0000000..c997f57 --- /dev/null +++ b/Example/Pods/FBSnapshotTestCase/FBSnapshotTestCase/Categories/UIImage+Compare.m @@ -0,0 +1,134 @@ +// +// Created by Gabriel Handford on 3/1/09. +// Copyright 2009-2013. All rights reserved. +// Created by John Boiles on 10/20/11. +// Copyright (c) 2011. All rights reserved +// Modified by Felix Schulze on 2/11/13. +// Copyright 2013. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without +// restriction, including without limitation the rights to use, +// copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following +// conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. +// + +#import + +// This makes debugging much more fun +typedef union { + uint32_t raw; + unsigned char bytes[4]; + struct { + char red; + char green; + char blue; + char alpha; + } __attribute__ ((packed)) pixels; +} FBComparePixel; + +@implementation UIImage (Compare) + +- (BOOL)fb_compareWithImage:(UIImage *)image tolerance:(CGFloat)tolerance +{ + NSAssert(CGSizeEqualToSize(self.size, image.size), @"Images must be same size."); + + CGSize referenceImageSize = CGSizeMake(CGImageGetWidth(self.CGImage), CGImageGetHeight(self.CGImage)); + CGSize imageSize = CGSizeMake(CGImageGetWidth(image.CGImage), CGImageGetHeight(image.CGImage)); + + // The images have the equal size, so we could use the smallest amount of bytes because of byte padding + size_t minBytesPerRow = MIN(CGImageGetBytesPerRow(self.CGImage), CGImageGetBytesPerRow(image.CGImage)); + size_t referenceImageSizeBytes = referenceImageSize.height * minBytesPerRow; + void *referenceImagePixels = calloc(1, referenceImageSizeBytes); + void *imagePixels = calloc(1, referenceImageSizeBytes); + + if (!referenceImagePixels || !imagePixels) { + free(referenceImagePixels); + free(imagePixels); + return NO; + } + + CGContextRef referenceImageContext = CGBitmapContextCreate(referenceImagePixels, + referenceImageSize.width, + referenceImageSize.height, + CGImageGetBitsPerComponent(self.CGImage), + minBytesPerRow, + CGImageGetColorSpace(self.CGImage), + (CGBitmapInfo)kCGImageAlphaPremultipliedLast + ); + CGContextRef imageContext = CGBitmapContextCreate(imagePixels, + imageSize.width, + imageSize.height, + CGImageGetBitsPerComponent(image.CGImage), + minBytesPerRow, + CGImageGetColorSpace(image.CGImage), + (CGBitmapInfo)kCGImageAlphaPremultipliedLast + ); + + if (!referenceImageContext || !imageContext) { + CGContextRelease(referenceImageContext); + CGContextRelease(imageContext); + free(referenceImagePixels); + free(imagePixels); + return NO; + } + + CGContextDrawImage(referenceImageContext, CGRectMake(0, 0, referenceImageSize.width, referenceImageSize.height), self.CGImage); + CGContextDrawImage(imageContext, CGRectMake(0, 0, imageSize.width, imageSize.height), image.CGImage); + + CGContextRelease(referenceImageContext); + CGContextRelease(imageContext); + + BOOL imageEqual = YES; + + // Do a fast compare if we can + if (tolerance == 0) { + imageEqual = (memcmp(referenceImagePixels, imagePixels, referenceImageSizeBytes) == 0); + } else { + // Go through each pixel in turn and see if it is different + const NSInteger pixelCount = referenceImageSize.width * referenceImageSize.height; + + FBComparePixel *p1 = referenceImagePixels; + FBComparePixel *p2 = imagePixels; + + NSInteger numDiffPixels = 0; + for (int n = 0; n < pixelCount; ++n) { + // If this pixel is different, increment the pixel diff count and see + // if we have hit our limit. + if (p1->raw != p2->raw) { + numDiffPixels ++; + + CGFloat percent = (CGFloat)numDiffPixels / pixelCount; + if (percent > tolerance) { + imageEqual = NO; + break; + } + } + + p1++; + p2++; + } + } + + free(referenceImagePixels); + free(imagePixels); + + return imageEqual; +} + +@end diff --git a/Example/Pods/FBSnapshotTestCase/FBSnapshotTestCase/Categories/UIImage+Diff.h b/Example/Pods/FBSnapshotTestCase/FBSnapshotTestCase/Categories/UIImage+Diff.h new file mode 100644 index 0000000..a0863f3 --- /dev/null +++ b/Example/Pods/FBSnapshotTestCase/FBSnapshotTestCase/Categories/UIImage+Diff.h @@ -0,0 +1,37 @@ +// +// Created by Gabriel Handford on 3/1/09. +// Copyright 2009-2013. All rights reserved. +// Created by John Boiles on 10/20/11. +// Copyright (c) 2011. All rights reserved +// Modified by Felix Schulze on 2/11/13. +// Copyright 2013. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without +// restriction, including without limitation the rights to use, +// copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following +// conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. +// + +#import + +@interface UIImage (Diff) + +- (UIImage *)fb_diffWithImage:(UIImage *)image; + +@end diff --git a/Example/Pods/FBSnapshotTestCase/FBSnapshotTestCase/Categories/UIImage+Diff.m b/Example/Pods/FBSnapshotTestCase/FBSnapshotTestCase/Categories/UIImage+Diff.m new file mode 100644 index 0000000..ebb72fe --- /dev/null +++ b/Example/Pods/FBSnapshotTestCase/FBSnapshotTestCase/Categories/UIImage+Diff.m @@ -0,0 +1,56 @@ +// +// Created by Gabriel Handford on 3/1/09. +// Copyright 2009-2013. All rights reserved. +// Created by John Boiles on 10/20/11. +// Copyright (c) 2011. All rights reserved +// Modified by Felix Schulze on 2/11/13. +// Copyright 2013. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without +// restriction, including without limitation the rights to use, +// copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following +// conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. +// + +#import + +@implementation UIImage (Diff) + +- (UIImage *)fb_diffWithImage:(UIImage *)image +{ + if (!image) { + return nil; + } + CGSize imageSize = CGSizeMake(MAX(self.size.width, image.size.width), MAX(self.size.height, image.size.height)); + UIGraphicsBeginImageContextWithOptions(imageSize, YES, 0); + CGContextRef context = UIGraphicsGetCurrentContext(); + [self drawInRect:CGRectMake(0, 0, self.size.width, self.size.height)]; + CGContextSetAlpha(context, 0.5); + CGContextBeginTransparencyLayer(context, NULL); + [image drawInRect:CGRectMake(0, 0, image.size.width, image.size.height)]; + CGContextSetBlendMode(context, kCGBlendModeDifference); + CGContextSetFillColorWithColor(context,[UIColor whiteColor].CGColor); + CGContextFillRect(context, CGRectMake(0, 0, self.size.width, self.size.height)); + CGContextEndTransparencyLayer(context); + UIImage *returnImage = UIGraphicsGetImageFromCurrentImageContext(); + UIGraphicsEndImageContext(); + return returnImage; +} + +@end diff --git a/Example/Pods/FBSnapshotTestCase/FBSnapshotTestCase/Categories/UIImage+Snapshot.h b/Example/Pods/FBSnapshotTestCase/FBSnapshotTestCase/Categories/UIImage+Snapshot.h new file mode 100644 index 0000000..b0d5b26 --- /dev/null +++ b/Example/Pods/FBSnapshotTestCase/FBSnapshotTestCase/Categories/UIImage+Snapshot.h @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + */ + +#import + +@interface UIImage (Snapshot) + +/// Uses renderInContext: to get a snapshot of the layer. ++ (UIImage *)fb_imageForLayer:(CALayer *)layer; + +/// Uses renderInContext: to get a snapshot of the view layer. ++ (UIImage *)fb_imageForViewLayer:(UIView *)view; + +/// Uses drawViewHierarchyInRect: to get a snapshot of the view and adds the view into a window if needed. ++ (UIImage *)fb_imageForView:(UIView *)view; + +@end diff --git a/Example/Pods/FBSnapshotTestCase/FBSnapshotTestCase/Categories/UIImage+Snapshot.m b/Example/Pods/FBSnapshotTestCase/FBSnapshotTestCase/Categories/UIImage+Snapshot.m new file mode 100644 index 0000000..c792077 --- /dev/null +++ b/Example/Pods/FBSnapshotTestCase/FBSnapshotTestCase/Categories/UIImage+Snapshot.m @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + */ + +#import + +@implementation UIImage (Snapshot) + ++ (UIImage *)fb_imageForLayer:(CALayer *)layer +{ + CGRect bounds = layer.bounds; + NSAssert1(CGRectGetWidth(bounds), @"Zero width for layer %@", layer); + NSAssert1(CGRectGetHeight(bounds), @"Zero height for layer %@", layer); + + UIGraphicsBeginImageContextWithOptions(bounds.size, NO, 0); + CGContextRef context = UIGraphicsGetCurrentContext(); + NSAssert1(context, @"Could not generate context for layer %@", layer); + CGContextSaveGState(context); + [layer layoutIfNeeded]; + [layer renderInContext:context]; + CGContextRestoreGState(context); + + UIImage *snapshot = UIGraphicsGetImageFromCurrentImageContext(); + UIGraphicsEndImageContext(); + return snapshot; +} + ++ (UIImage *)fb_imageForViewLayer:(UIView *)view +{ + [view layoutIfNeeded]; + return [self fb_imageForLayer:view.layer]; +} + ++ (UIImage *)fb_imageForView:(UIView *)view +{ + CGRect bounds = view.bounds; + NSAssert1(CGRectGetWidth(bounds), @"Zero width for view %@", view); + NSAssert1(CGRectGetHeight(bounds), @"Zero height for view %@", view); + + UIWindow *window = view.window; + if (window == nil) { + window = [[UIWindow alloc] initWithFrame:bounds]; + [window addSubview:view]; + [window makeKeyAndVisible]; + } + + UIGraphicsBeginImageContextWithOptions(bounds.size, NO, 0); + [view layoutIfNeeded]; + [view drawViewHierarchyInRect:view.bounds afterScreenUpdates:YES]; + + UIImage *snapshot = UIGraphicsGetImageFromCurrentImageContext(); + UIGraphicsEndImageContext(); + return snapshot; +} + +@end diff --git a/Example/Pods/FBSnapshotTestCase/FBSnapshotTestCase/FBSnapshotTestCase.h b/Example/Pods/FBSnapshotTestCase/FBSnapshotTestCase/FBSnapshotTestCase.h new file mode 100644 index 0000000..54e301e --- /dev/null +++ b/Example/Pods/FBSnapshotTestCase/FBSnapshotTestCase/FBSnapshotTestCase.h @@ -0,0 +1,200 @@ +/* + * Copyright (c) 2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + */ + +#import + +#import + +#import + +#import + +/* + There are three ways of setting reference image directories. + + 1. Set the preprocessor macro FB_REFERENCE_IMAGE_DIR to a double quoted + c-string with the path. + 2. Set an environment variable named FB_REFERENCE_IMAGE_DIR with the path. This + takes precedence over the preprocessor macro to allow for run-time override. + 3. Keep everything unset, which will cause the reference images to be looked up + inside the bundle holding the current test, in the + Resources/ReferenceImages_* directories. + */ +#ifndef FB_REFERENCE_IMAGE_DIR +#define FB_REFERENCE_IMAGE_DIR "" +#endif + +/** + Similar to our much-loved XCTAssert() macros. Use this to perform your test. No need to write an explanation, though. + @param view The view to snapshot + @param identifier An optional identifier, used if there are multiple snapshot tests in a given -test method. + @param suffixes An NSOrderedSet of strings for the different suffixes + @param tolerance The percentage of pixels that can differ and still count as an 'identical' view + */ +#define FBSnapshotVerifyViewWithOptions(view__, identifier__, suffixes__, tolerance__) \ + FBSnapshotVerifyViewOrLayerWithOptions(View, view__, identifier__, suffixes__, tolerance__) + +#define FBSnapshotVerifyView(view__, identifier__) \ + FBSnapshotVerifyViewWithOptions(view__, identifier__, FBSnapshotTestCaseDefaultSuffixes(), 0) + + +/** + Similar to our much-loved XCTAssert() macros. Use this to perform your test. No need to write an explanation, though. + @param layer The layer to snapshot + @param identifier An optional identifier, used is there are multiple snapshot tests in a given -test method. + @param suffixes An NSOrderedSet of strings for the different suffixes + @param tolerance The percentage of pixels that can differ and still count as an 'identical' layer + */ +#define FBSnapshotVerifyLayerWithOptions(layer__, identifier__, suffixes__, tolerance__) \ + FBSnapshotVerifyViewOrLayerWithOptions(Layer, layer__, identifier__, suffixes__, tolerance__) + +#define FBSnapshotVerifyLayer(layer__, identifier__) \ + FBSnapshotVerifyLayerWithOptions(layer__, identifier__, FBSnapshotTestCaseDefaultSuffixes(), 0) + + +#define FBSnapshotVerifyViewOrLayerWithOptions(what__, viewOrLayer__, identifier__, suffixes__, tolerance__) \ +{ \ + NSString *referenceImageDirectory = [self getReferenceImageDirectoryWithDefault:(@ FB_REFERENCE_IMAGE_DIR)]; \ + XCTAssertNotNil(referenceImageDirectory, @"Missing value for referenceImagesDirectory - Set FB_REFERENCE_IMAGE_DIR as Environment variable in your scheme.");\ + XCTAssertTrue((suffixes__.count > 0), @"Suffixes set cannot be empty %@", suffixes__); \ + \ + BOOL testSuccess__ = NO; \ + NSError *error__ = nil; \ + NSMutableArray *errors__ = [NSMutableArray array]; \ + \ + if (self.recordMode) { \ + \ + NSString *referenceImagesDirectory__ = [NSString stringWithFormat:@"%@%@", referenceImageDirectory, suffixes__.firstObject]; \ + BOOL referenceImageSaved__ = [self compareSnapshotOf ## what__ :(viewOrLayer__) referenceImagesDirectory:referenceImagesDirectory__ identifier:(identifier__) tolerance:(tolerance__) error:&error__]; \ + if (!referenceImageSaved__) { \ + [errors__ addObject:error__]; \ + } \ + } else { \ + \ + for (NSString *suffix__ in suffixes__) { \ + NSString *referenceImagesDirectory__ = [NSString stringWithFormat:@"%@%@", referenceImageDirectory, suffix__]; \ + BOOL referenceImageAvailable = [self referenceImageRecordedInDirectory:referenceImagesDirectory__ identifier:(identifier__) error:&error__]; \ + \ + if (referenceImageAvailable) { \ + BOOL comparisonSuccess__ = [self compareSnapshotOf ## what__ :(viewOrLayer__) referenceImagesDirectory:referenceImagesDirectory__ identifier:(identifier__) tolerance:(tolerance__) error:&error__]; \ + [errors__ removeAllObjects]; \ + if (comparisonSuccess__) { \ + testSuccess__ = YES; \ + break; \ + } else { \ + [errors__ addObject:error__]; \ + } \ + } else { \ + [errors__ addObject:error__]; \ + } \ + } \ + } \ + XCTAssertTrue(testSuccess__, @"Snapshot comparison failed: %@", errors__.firstObject); \ + XCTAssertFalse(self.recordMode, @"Test ran in record mode. Reference image is now saved. Disable record mode to perform an actual snapshot comparison!"); \ +} + + +/** + The base class of view snapshotting tests. If you have small UI component, it's often easier to configure it in a test + and compare an image of the view to a reference image that write lots of complex layout-code tests. + + In order to flip the tests in your subclass to record the reference images set @c recordMode to @c YES. + + @attention When recording, the reference image directory should be explicitly + set, otherwise the images may be written to somewhere inside the + simulator directory. + + For example: + @code + - (void)setUp + { + [super setUp]; + self.recordMode = YES; + } + @endcode + */ +@interface FBSnapshotTestCase : XCTestCase + +/** + When YES, the test macros will save reference images, rather than performing an actual test. + */ +@property (readwrite, nonatomic, assign) BOOL recordMode; + +/** + When @c YES appends the name of the device model and OS to the snapshot file name. + The default value is @c NO. + */ +@property (readwrite, nonatomic, assign, getter=isDeviceAgnostic) BOOL deviceAgnostic; + +/** + When YES, renders a snapshot of the complete view hierarchy as visible onscreen. + There are several things that do not work if renderInContext: is used. + - UIVisualEffect #70 + - UIAppearance #91 + - Size Classes #92 + + @attention If the view does't belong to a UIWindow, it will create one and add the view as a subview. + */ +@property (readwrite, nonatomic, assign) BOOL usesDrawViewHierarchyInRect; + +- (void)setUp NS_REQUIRES_SUPER; +- (void)tearDown NS_REQUIRES_SUPER; + +/** + Performs the comparison or records a snapshot of the layer if recordMode is YES. + @param layer The Layer to snapshot + @param referenceImagesDirectory The directory in which reference images are stored. + @param identifier An optional identifier, used if there are multiple snapshot tests in a given -test method. + @param tolerance The percentage difference to still count as identical - 0 mean pixel perfect, 1 means I don't care + @param errorPtr An error to log in an XCTAssert() macro if the method fails (missing reference image, images differ, etc). + @returns YES if the comparison (or saving of the reference image) succeeded. + */ +- (BOOL)compareSnapshotOfLayer:(CALayer *)layer + referenceImagesDirectory:(NSString *)referenceImagesDirectory + identifier:(NSString *)identifier + tolerance:(CGFloat)tolerance + error:(NSError **)errorPtr; + +/** + Performs the comparison or records a snapshot of the view if recordMode is YES. + @param view The view to snapshot + @param referenceImagesDirectory The directory in which reference images are stored. + @param identifier An optional identifier, used if there are multiple snapshot tests in a given -test method. + @param tolerance The percentage difference to still count as identical - 0 mean pixel perfect, 1 means I don't care + @param errorPtr An error to log in an XCTAssert() macro if the method fails (missing reference image, images differ, etc). + @returns YES if the comparison (or saving of the reference image) succeeded. + */ +- (BOOL)compareSnapshotOfView:(UIView *)view + referenceImagesDirectory:(NSString *)referenceImagesDirectory + identifier:(NSString *)identifier + tolerance:(CGFloat)tolerance + error:(NSError **)errorPtr; + +/** + Checks if reference image with identifier based name exists in the reference images directory. + @param referenceImagesDirectory The directory in which reference images are stored. + @param identifier An optional identifier, used if there are multiple snapshot tests in a given -test method. + @param errorPtr An error to log in an XCTAssert() macro if the method fails (missing reference image, images differ, etc). + @returns YES if reference image exists. + */ +- (BOOL)referenceImageRecordedInDirectory:(NSString *)referenceImagesDirectory + identifier:(NSString *)identifier + error:(NSError **)errorPtr; + +/** + Returns the reference image directory. + + Helper function used to implement the assert macros. + + @param dir directory to use if environment variable not specified. Ignored if null or empty. + */ +- (NSString *)getReferenceImageDirectoryWithDefault:(NSString *)dir; + +@end diff --git a/Example/Pods/FBSnapshotTestCase/FBSnapshotTestCase/FBSnapshotTestCase.m b/Example/Pods/FBSnapshotTestCase/FBSnapshotTestCase/FBSnapshotTestCase.m new file mode 100644 index 0000000..3ee351f --- /dev/null +++ b/Example/Pods/FBSnapshotTestCase/FBSnapshotTestCase/FBSnapshotTestCase.m @@ -0,0 +1,136 @@ +/* + * Copyright (c) 2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + */ + +#import +#import + +@implementation FBSnapshotTestCase +{ + FBSnapshotTestController *_snapshotController; +} + +#pragma mark - Overrides + +- (void)setUp +{ + [super setUp]; + _snapshotController = [[FBSnapshotTestController alloc] initWithTestName:NSStringFromClass([self class])]; +} + +- (void)tearDown +{ + _snapshotController = nil; + [super tearDown]; +} + +- (BOOL)recordMode +{ + return _snapshotController.recordMode; +} + +- (void)setRecordMode:(BOOL)recordMode +{ + NSAssert1(_snapshotController, @"%s cannot be called before [super setUp]", __FUNCTION__); + _snapshotController.recordMode = recordMode; +} + +- (BOOL)isDeviceAgnostic +{ + return _snapshotController.deviceAgnostic; +} + +- (void)setDeviceAgnostic:(BOOL)deviceAgnostic +{ + NSAssert1(_snapshotController, @"%s cannot be called before [super setUp]", __FUNCTION__); + _snapshotController.deviceAgnostic = deviceAgnostic; +} + +- (BOOL)usesDrawViewHierarchyInRect +{ + return _snapshotController.usesDrawViewHierarchyInRect; +} + +- (void)setUsesDrawViewHierarchyInRect:(BOOL)usesDrawViewHierarchyInRect +{ + NSAssert1(_snapshotController, @"%s cannot be called before [super setUp]", __FUNCTION__); + _snapshotController.usesDrawViewHierarchyInRect = usesDrawViewHierarchyInRect; +} + +#pragma mark - Public API + +- (BOOL)compareSnapshotOfLayer:(CALayer *)layer + referenceImagesDirectory:(NSString *)referenceImagesDirectory + identifier:(NSString *)identifier + tolerance:(CGFloat)tolerance + error:(NSError **)errorPtr +{ + return [self _compareSnapshotOfViewOrLayer:layer + referenceImagesDirectory:referenceImagesDirectory + identifier:identifier + tolerance:tolerance + error:errorPtr]; +} + +- (BOOL)compareSnapshotOfView:(UIView *)view + referenceImagesDirectory:(NSString *)referenceImagesDirectory + identifier:(NSString *)identifier + tolerance:(CGFloat)tolerance + error:(NSError **)errorPtr +{ + return [self _compareSnapshotOfViewOrLayer:view + referenceImagesDirectory:referenceImagesDirectory + identifier:identifier + tolerance:tolerance + error:errorPtr]; +} + +- (BOOL)referenceImageRecordedInDirectory:(NSString *)referenceImagesDirectory + identifier:(NSString *)identifier + error:(NSError **)errorPtr +{ + NSAssert1(_snapshotController, @"%s cannot be called before [super setUp]", __FUNCTION__); + _snapshotController.referenceImagesDirectory = referenceImagesDirectory; + UIImage *referenceImage = [_snapshotController referenceImageForSelector:self.invocation.selector + identifier:identifier + error:errorPtr]; + + return (referenceImage != nil); +} + +- (NSString *)getReferenceImageDirectoryWithDefault:(NSString *)dir +{ + NSString *envReferenceImageDirectory = [NSProcessInfo processInfo].environment[@"FB_REFERENCE_IMAGE_DIR"]; + if (envReferenceImageDirectory) { + return envReferenceImageDirectory; + } + if (dir && dir.length > 0) { + return dir; + } + return [[NSBundle bundleForClass:self.class].resourcePath stringByAppendingPathComponent:@"ReferenceImages"]; +} + + +#pragma mark - Private API + +- (BOOL)_compareSnapshotOfViewOrLayer:(id)viewOrLayer + referenceImagesDirectory:(NSString *)referenceImagesDirectory + identifier:(NSString *)identifier + tolerance:(CGFloat)tolerance + error:(NSError **)errorPtr +{ + _snapshotController.referenceImagesDirectory = referenceImagesDirectory; + return [_snapshotController compareSnapshotOfViewOrLayer:viewOrLayer + selector:self.invocation.selector + identifier:identifier + tolerance:tolerance + error:errorPtr]; +} + +@end diff --git a/Example/Pods/FBSnapshotTestCase/FBSnapshotTestCase/FBSnapshotTestCasePlatform.h b/Example/Pods/FBSnapshotTestCase/FBSnapshotTestCase/FBSnapshotTestCasePlatform.h new file mode 100644 index 0000000..e04acf2 --- /dev/null +++ b/Example/Pods/FBSnapshotTestCase/FBSnapshotTestCase/FBSnapshotTestCasePlatform.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + */ + +#import + +#ifdef __cplusplus +extern "C" { +#endif + +/** + Returns a Boolean value that indicates whether the snapshot test is running in 64Bit. + This method is a convenience for creating the suffixes set based on the architecture + that the test is running. + + @returns @c YES if the test is running in 64bit, otherwise @c NO. + */ +BOOL FBSnapshotTestCaseIs64Bit(void); + +/** + Returns a default set of strings that is used to append a suffix based on the architectures. + @warning Do not modify this function, you can create your own and use it with @c FBSnapshotVerifyViewWithOptions() + + @returns An @c NSOrderedSet object containing strings that are appended to the reference images directory. + */ +NSOrderedSet *FBSnapshotTestCaseDefaultSuffixes(void); + +/** + Returns a fully «normalized» file name. + Strips punctuation and spaces and replaces them with @c _. Also appends the device model, running OS and screen size to the file name. + + @returns An @c NSString object containing the passed @c fileName with the device model, OS and screen size appended at the end. + */ +NSString *FBDeviceAgnosticNormalizedFileName(NSString *fileName); + +#ifdef __cplusplus +} +#endif diff --git a/Example/Pods/FBSnapshotTestCase/FBSnapshotTestCase/FBSnapshotTestCasePlatform.m b/Example/Pods/FBSnapshotTestCase/FBSnapshotTestCase/FBSnapshotTestCasePlatform.m new file mode 100644 index 0000000..4f6fb01 --- /dev/null +++ b/Example/Pods/FBSnapshotTestCase/FBSnapshotTestCase/FBSnapshotTestCasePlatform.m @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + */ + +#import +#import + +BOOL FBSnapshotTestCaseIs64Bit(void) +{ +#if __LP64__ + return YES; +#else + return NO; +#endif +} + +NSOrderedSet *FBSnapshotTestCaseDefaultSuffixes(void) +{ + NSMutableOrderedSet *suffixesSet = [[NSMutableOrderedSet alloc] init]; + [suffixesSet addObject:@"_32"]; + [suffixesSet addObject:@"_64"]; + if (FBSnapshotTestCaseIs64Bit()) { + return [suffixesSet reversedOrderedSet]; + } + return [suffixesSet copy]; +} + +NSString *FBDeviceAgnosticNormalizedFileName(NSString *fileName) +{ + UIDevice *device = [UIDevice currentDevice]; + CGSize screenSize = [[UIApplication sharedApplication] keyWindow].bounds.size; + NSString *os = device.systemVersion; + + fileName = [NSString stringWithFormat:@"%@_%@%@_%.0fx%.0f", fileName, device.model, os, screenSize.width, screenSize.height]; + + NSMutableCharacterSet *invalidCharacters = [NSMutableCharacterSet new]; + [invalidCharacters formUnionWithCharacterSet:[NSCharacterSet whitespaceCharacterSet]]; + [invalidCharacters formUnionWithCharacterSet:[NSCharacterSet punctuationCharacterSet]]; + NSArray *validComponents = [fileName componentsSeparatedByCharactersInSet:invalidCharacters]; + fileName = [validComponents componentsJoinedByString:@"_"]; + + return fileName; +} \ No newline at end of file diff --git a/Example/Pods/FBSnapshotTestCase/FBSnapshotTestCase/FBSnapshotTestController.h b/Example/Pods/FBSnapshotTestCase/FBSnapshotTestCase/FBSnapshotTestController.h new file mode 100644 index 0000000..5719aba --- /dev/null +++ b/Example/Pods/FBSnapshotTestCase/FBSnapshotTestCase/FBSnapshotTestController.h @@ -0,0 +1,151 @@ +/* + * Copyright (c) 2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + */ + +#import +#import + +typedef NS_ENUM(NSInteger, FBSnapshotTestControllerErrorCode) { + FBSnapshotTestControllerErrorCodeUnknown, + FBSnapshotTestControllerErrorCodeNeedsRecord, + FBSnapshotTestControllerErrorCodePNGCreationFailed, + FBSnapshotTestControllerErrorCodeImagesDifferentSizes, + FBSnapshotTestControllerErrorCodeImagesDifferent, +}; +/** + Errors returned by the methods of FBSnapshotTestController use this domain. + */ +extern NSString *const FBSnapshotTestControllerErrorDomain; + +/** + Errors returned by the methods of FBSnapshotTestController sometimes contain this key in the `userInfo` dictionary. + */ +extern NSString *const FBReferenceImageFilePathKey; + +/** + Provides the heavy-lifting for FBSnapshotTestCase. It loads and saves images, along with performing the actual pixel- + by-pixel comparison of images. + Instances are initialized with the test class, and directories to read and write to. + */ +@interface FBSnapshotTestController : NSObject + +/** + Record snapshots. + */ +@property (readwrite, nonatomic, assign) BOOL recordMode; + +/** + When @c YES appends the name of the device model and OS to the snapshot file name. + The default value is @c NO. + */ +@property (readwrite, nonatomic, assign, getter=isDeviceAgnostic) BOOL deviceAgnostic; + +/** + Uses drawViewHierarchyInRect:afterScreenUpdates: to draw the image instead of renderInContext: + */ +@property (readwrite, nonatomic, assign) BOOL usesDrawViewHierarchyInRect; + +/** + The directory in which referfence images are stored. + */ +@property (readwrite, nonatomic, copy) NSString *referenceImagesDirectory; + +/** + @param testClass The subclass of FBSnapshotTestCase that is using this controller. + @returns An instance of FBSnapshotTestController. + */ +- (instancetype)initWithTestClass:(Class)testClass; + +/** + Designated initializer. + @param testName The name of the tests. + @returns An instance of FBSnapshotTestController. + */ +- (instancetype)initWithTestName:(NSString *)testName; + +/** + Performs the comparison of the layer. + @param layer The Layer to snapshot. + @param selector The test method being run. + @param identifier An optional identifier, used is there are muliptle snapshot tests in a given -test method. + @param error An error to log in an XCTAssert() macro if the method fails (missing reference image, images differ, etc). + @returns YES if the comparison (or saving of the reference image) succeeded. + */ +- (BOOL)compareSnapshotOfLayer:(CALayer *)layer + selector:(SEL)selector + identifier:(NSString *)identifier + error:(NSError **)errorPtr; + +/** + Performs the comparison of the view. + @param view The view to snapshot. + @param selector The test method being run. + @param identifier An optional identifier, used is there are muliptle snapshot tests in a given -test method. + @param error An error to log in an XCTAssert() macro if the method fails (missing reference image, images differ, etc). + @returns YES if the comparison (or saving of the reference image) succeeded. + */ +- (BOOL)compareSnapshotOfView:(UIView *)view + selector:(SEL)selector + identifier:(NSString *)identifier + error:(NSError **)errorPtr; + +/** + Performs the comparison of a view or layer. + @param view The view or layer to snapshot. + @param selector The test method being run. + @param identifier An optional identifier, used is there are muliptle snapshot tests in a given -test method. + @param tolerance The percentage of pixels that can differ and still be considered 'identical' + @param error An error to log in an XCTAssert() macro if the method fails (missing reference image, images differ, etc). + @returns YES if the comparison (or saving of the reference image) succeeded. + */ +- (BOOL)compareSnapshotOfViewOrLayer:(id)viewOrLayer + selector:(SEL)selector + identifier:(NSString *)identifier + tolerance:(CGFloat)tolerance + error:(NSError **)errorPtr; + +/** + Loads a reference image. + @param selector The test method being run. + @param identifier The optional identifier, used when multiple images are tested in a single -test method. + @param errorPtr An error, if this methods returns nil, the error will be something useful. + @returns An image. + */ +- (UIImage *)referenceImageForSelector:(SEL)selector + identifier:(NSString *)identifier + error:(NSError **)errorPtr; + +/** + Performs a pixel-by-pixel comparison of the two images with an allowable margin of error. + @param referenceImage The reference (correct) image. + @param image The image to test against the reference. + @param tolerance The percentage of pixels that can differ and still be considered 'identical' + @param errorPtr An error that indicates why the comparison failed if it does. + @returns YES if the comparison succeeded and the images are the same(ish). + */ +- (BOOL)compareReferenceImage:(UIImage *)referenceImage + toImage:(UIImage *)image + tolerance:(CGFloat)tolerance + error:(NSError **)errorPtr; + +/** + Saves the reference image and the test image to `failedOutputDirectory`. + @param referenceImage The reference (correct) image. + @param testImage The image to test against the reference. + @param selector The test method being run. + @param identifier The optional identifier, used when multiple images are tested in a single -test method. + @param errorPtr An error that indicates why the comparison failed if it does. + @returns YES if the save succeeded. + */ +- (BOOL)saveFailedReferenceImage:(UIImage *)referenceImage + testImage:(UIImage *)testImage + selector:(SEL)selector + identifier:(NSString *)identifier + error:(NSError **)errorPtr; +@end diff --git a/Example/Pods/FBSnapshotTestCase/FBSnapshotTestCase/FBSnapshotTestController.m b/Example/Pods/FBSnapshotTestCase/FBSnapshotTestCase/FBSnapshotTestController.m new file mode 100644 index 0000000..4cebe10 --- /dev/null +++ b/Example/Pods/FBSnapshotTestCase/FBSnapshotTestCase/FBSnapshotTestController.m @@ -0,0 +1,356 @@ +/* + * Copyright (c) 2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + */ + +#import +#import +#import +#import +#import + +#import + +NSString *const FBSnapshotTestControllerErrorDomain = @"FBSnapshotTestControllerErrorDomain"; +NSString *const FBReferenceImageFilePathKey = @"FBReferenceImageFilePathKey"; + +typedef NS_ENUM(NSUInteger, FBTestSnapshotFileNameType) { + FBTestSnapshotFileNameTypeReference, + FBTestSnapshotFileNameTypeFailedReference, + FBTestSnapshotFileNameTypeFailedTest, + FBTestSnapshotFileNameTypeFailedTestDiff, +}; + +@implementation FBSnapshotTestController +{ + NSString *_testName; + NSFileManager *_fileManager; +} + +#pragma mark - Initializers + +- (instancetype)initWithTestClass:(Class)testClass; +{ + return [self initWithTestName:NSStringFromClass(testClass)]; +} + +- (instancetype)initWithTestName:(NSString *)testName +{ + if (self = [super init]) { + _testName = [testName copy]; + _deviceAgnostic = NO; + + _fileManager = [[NSFileManager alloc] init]; + } + return self; +} + +#pragma mark - Overrides + +- (NSString *)description +{ + return [NSString stringWithFormat:@"%@ %@", [super description], _referenceImagesDirectory]; +} + +#pragma mark - Public API + +- (BOOL)compareSnapshotOfLayer:(CALayer *)layer + selector:(SEL)selector + identifier:(NSString *)identifier + error:(NSError **)errorPtr +{ + return [self compareSnapshotOfViewOrLayer:layer + selector:selector + identifier:identifier + tolerance:0 + error:errorPtr]; +} + +- (BOOL)compareSnapshotOfView:(UIView *)view + selector:(SEL)selector + identifier:(NSString *)identifier + error:(NSError **)errorPtr +{ + return [self compareSnapshotOfViewOrLayer:view + selector:selector + identifier:identifier + tolerance:0 + error:errorPtr]; +} + +- (BOOL)compareSnapshotOfViewOrLayer:(id)viewOrLayer + selector:(SEL)selector + identifier:(NSString *)identifier + tolerance:(CGFloat)tolerance + error:(NSError **)errorPtr +{ + if (self.recordMode) { + return [self _recordSnapshotOfViewOrLayer:viewOrLayer selector:selector identifier:identifier error:errorPtr]; + } else { + return [self _performPixelComparisonWithViewOrLayer:viewOrLayer selector:selector identifier:identifier tolerance:tolerance error:errorPtr]; + } +} + +- (UIImage *)referenceImageForSelector:(SEL)selector + identifier:(NSString *)identifier + error:(NSError **)errorPtr +{ + NSString *filePath = [self _referenceFilePathForSelector:selector identifier:identifier]; + UIImage *image = [UIImage imageWithContentsOfFile:filePath]; + if (nil == image && NULL != errorPtr) { + BOOL exists = [_fileManager fileExistsAtPath:filePath]; + if (!exists) { + *errorPtr = [NSError errorWithDomain:FBSnapshotTestControllerErrorDomain + code:FBSnapshotTestControllerErrorCodeNeedsRecord + userInfo:@{ + FBReferenceImageFilePathKey: filePath, + NSLocalizedDescriptionKey: @"Unable to load reference image.", + NSLocalizedFailureReasonErrorKey: @"Reference image not found. You need to run the test in record mode", + }]; + } else { + *errorPtr = [NSError errorWithDomain:FBSnapshotTestControllerErrorDomain + code:FBSnapshotTestControllerErrorCodeUnknown + userInfo:nil]; + } + } + return image; +} + +- (BOOL)compareReferenceImage:(UIImage *)referenceImage + toImage:(UIImage *)image + tolerance:(CGFloat)tolerance + error:(NSError **)errorPtr +{ + if (CGSizeEqualToSize(referenceImage.size, image.size)) { + BOOL imagesEqual = [referenceImage fb_compareWithImage:image tolerance:tolerance]; + if (NULL != errorPtr) { + *errorPtr = [NSError errorWithDomain:FBSnapshotTestControllerErrorDomain + code:FBSnapshotTestControllerErrorCodeImagesDifferent + userInfo:@{ + NSLocalizedDescriptionKey: @"Images different", + }]; + } + return imagesEqual; + } + if (NULL != errorPtr) { + *errorPtr = [NSError errorWithDomain:FBSnapshotTestControllerErrorDomain + code:FBSnapshotTestControllerErrorCodeImagesDifferentSizes + userInfo:@{ + NSLocalizedDescriptionKey: @"Images different sizes", + NSLocalizedFailureReasonErrorKey: [NSString stringWithFormat:@"referenceImage:%@, image:%@", + NSStringFromCGSize(referenceImage.size), + NSStringFromCGSize(image.size)], + }]; + } + return NO; +} + +- (BOOL)saveFailedReferenceImage:(UIImage *)referenceImage + testImage:(UIImage *)testImage + selector:(SEL)selector + identifier:(NSString *)identifier + error:(NSError **)errorPtr +{ + NSData *referencePNGData = UIImagePNGRepresentation(referenceImage); + NSData *testPNGData = UIImagePNGRepresentation(testImage); + + NSString *referencePath = [self _failedFilePathForSelector:selector + identifier:identifier + fileNameType:FBTestSnapshotFileNameTypeFailedReference]; + + NSError *creationError = nil; + BOOL didCreateDir = [_fileManager createDirectoryAtPath:[referencePath stringByDeletingLastPathComponent] + withIntermediateDirectories:YES + attributes:nil + error:&creationError]; + if (!didCreateDir) { + if (NULL != errorPtr) { + *errorPtr = creationError; + } + return NO; + } + + if (![referencePNGData writeToFile:referencePath options:NSDataWritingAtomic error:errorPtr]) { + return NO; + } + + NSString *testPath = [self _failedFilePathForSelector:selector + identifier:identifier + fileNameType:FBTestSnapshotFileNameTypeFailedTest]; + + if (![testPNGData writeToFile:testPath options:NSDataWritingAtomic error:errorPtr]) { + return NO; + } + + NSString *diffPath = [self _failedFilePathForSelector:selector + identifier:identifier + fileNameType:FBTestSnapshotFileNameTypeFailedTestDiff]; + + UIImage *diffImage = [referenceImage fb_diffWithImage:testImage]; + NSData *diffImageData = UIImagePNGRepresentation(diffImage); + + if (![diffImageData writeToFile:diffPath options:NSDataWritingAtomic error:errorPtr]) { + return NO; + } + + NSLog(@"If you have Kaleidoscope installed you can run this command to see an image diff:\n" + @"ksdiff \"%@\" \"%@\"", referencePath, testPath); + + return YES; +} + +#pragma mark - Private API + +- (NSString *)_fileNameForSelector:(SEL)selector + identifier:(NSString *)identifier + fileNameType:(FBTestSnapshotFileNameType)fileNameType +{ + NSString *fileName = nil; + switch (fileNameType) { + case FBTestSnapshotFileNameTypeFailedReference: + fileName = @"reference_"; + break; + case FBTestSnapshotFileNameTypeFailedTest: + fileName = @"failed_"; + break; + case FBTestSnapshotFileNameTypeFailedTestDiff: + fileName = @"diff_"; + break; + default: + fileName = @""; + break; + } + fileName = [fileName stringByAppendingString:NSStringFromSelector(selector)]; + if (0 < identifier.length) { + fileName = [fileName stringByAppendingFormat:@"_%@", identifier]; + } + + if (self.isDeviceAgnostic) { + fileName = FBDeviceAgnosticNormalizedFileName(fileName); + } + + if ([[UIScreen mainScreen] scale] > 1) { + fileName = [fileName stringByAppendingFormat:@"@%.fx", [[UIScreen mainScreen] scale]]; + } + fileName = [fileName stringByAppendingPathExtension:@"png"]; + return fileName; +} + +- (NSString *)_referenceFilePathForSelector:(SEL)selector + identifier:(NSString *)identifier +{ + NSString *fileName = [self _fileNameForSelector:selector + identifier:identifier + fileNameType:FBTestSnapshotFileNameTypeReference]; + NSString *filePath = [_referenceImagesDirectory stringByAppendingPathComponent:_testName]; + filePath = [filePath stringByAppendingPathComponent:fileName]; + return filePath; +} + +- (NSString *)_failedFilePathForSelector:(SEL)selector + identifier:(NSString *)identifier + fileNameType:(FBTestSnapshotFileNameType)fileNameType +{ + NSString *fileName = [self _fileNameForSelector:selector + identifier:identifier + fileNameType:fileNameType]; + NSString *folderPath = NSTemporaryDirectory(); + if (getenv("IMAGE_DIFF_DIR")) { + folderPath = @(getenv("IMAGE_DIFF_DIR")); + } + NSString *filePath = [folderPath stringByAppendingPathComponent:_testName]; + filePath = [filePath stringByAppendingPathComponent:fileName]; + return filePath; +} + +- (BOOL)_performPixelComparisonWithViewOrLayer:(id)viewOrLayer + selector:(SEL)selector + identifier:(NSString *)identifier + tolerance:(CGFloat)tolerance + error:(NSError **)errorPtr +{ + UIImage *referenceImage = [self referenceImageForSelector:selector identifier:identifier error:errorPtr]; + if (nil != referenceImage) { + UIImage *snapshot = [self _imageForViewOrLayer:viewOrLayer]; + BOOL imagesSame = [self compareReferenceImage:referenceImage toImage:snapshot tolerance:tolerance error:errorPtr]; + if (!imagesSame) { + [self saveFailedReferenceImage:referenceImage + testImage:snapshot + selector:selector + identifier:identifier + error:errorPtr]; + } + return imagesSame; + } + return NO; +} + +- (BOOL)_recordSnapshotOfViewOrLayer:(id)viewOrLayer + selector:(SEL)selector + identifier:(NSString *)identifier + error:(NSError **)errorPtr +{ + UIImage *snapshot = [self _imageForViewOrLayer:viewOrLayer]; + return [self _saveReferenceImage:snapshot selector:selector identifier:identifier error:errorPtr]; +} + +- (BOOL)_saveReferenceImage:(UIImage *)image + selector:(SEL)selector + identifier:(NSString *)identifier + error:(NSError **)errorPtr +{ + BOOL didWrite = NO; + if (nil != image) { + NSString *filePath = [self _referenceFilePathForSelector:selector identifier:identifier]; + NSData *pngData = UIImagePNGRepresentation(image); + if (nil != pngData) { + NSError *creationError = nil; + BOOL didCreateDir = [_fileManager createDirectoryAtPath:[filePath stringByDeletingLastPathComponent] + withIntermediateDirectories:YES + attributes:nil + error:&creationError]; + if (!didCreateDir) { + if (NULL != errorPtr) { + *errorPtr = creationError; + } + return NO; + } + didWrite = [pngData writeToFile:filePath options:NSDataWritingAtomic error:errorPtr]; + if (didWrite) { + NSLog(@"Reference image save at: %@", filePath); + } + } else { + if (nil != errorPtr) { + *errorPtr = [NSError errorWithDomain:FBSnapshotTestControllerErrorDomain + code:FBSnapshotTestControllerErrorCodePNGCreationFailed + userInfo:@{ + FBReferenceImageFilePathKey: filePath, + }]; + } + } + } + return didWrite; +} + +- (UIImage *)_imageForViewOrLayer:(id)viewOrLayer +{ + if ([viewOrLayer isKindOfClass:[UIView class]]) { + if (_usesDrawViewHierarchyInRect) { + return [UIImage fb_imageForView:viewOrLayer]; + } else { + return [UIImage fb_imageForViewLayer:viewOrLayer]; + } + } else if ([viewOrLayer isKindOfClass:[CALayer class]]) { + return [UIImage fb_imageForLayer:viewOrLayer]; + } else { + [NSException raise:@"Only UIView and CALayer classes can be snapshotted" format:@"%@", viewOrLayer]; + } + return nil; +} + +@end diff --git a/Example/Pods/FBSnapshotTestCase/FBSnapshotTestCase/SwiftSupport.swift b/Example/Pods/FBSnapshotTestCase/FBSnapshotTestCase/SwiftSupport.swift new file mode 100644 index 0000000..d3058fb --- /dev/null +++ b/Example/Pods/FBSnapshotTestCase/FBSnapshotTestCase/SwiftSupport.swift @@ -0,0 +1,66 @@ +/* +* Copyright (c) 2015, Facebook, Inc. +* All rights reserved. +* +* This source code is licensed under the BSD-style license found in the +* LICENSE file in the root directory of this source tree. An additional grant +* of patent rights can be found in the PATENTS file in the same directory. +* +*/ + +public extension FBSnapshotTestCase { + public func FBSnapshotVerifyView(view: UIView, identifier: String = "", suffixes: NSOrderedSet = FBSnapshotTestCaseDefaultSuffixes(), file: String = __FILE__, line: UInt = __LINE__) { + FBSnapshotVerifyViewOrLayer(view, identifier: identifier, suffixes: suffixes) + } + + public func FBSnapshotVerifyLayer(layer: CALayer, identifier: String = "", suffixes: NSOrderedSet = FBSnapshotTestCaseDefaultSuffixes(), file: String = __FILE__, line: UInt = __LINE__) { + FBSnapshotVerifyViewOrLayer(layer, identifier: identifier, suffixes: suffixes) + } + + private func FBSnapshotVerifyViewOrLayer(viewOrLayer: AnyObject, identifier: String = "", suffixes: NSOrderedSet = FBSnapshotTestCaseDefaultSuffixes(), file: String = __FILE__, line: UInt = __LINE__) { + let envReferenceImageDirectory = self.getReferenceImageDirectoryWithDefault(FB_REFERENCE_IMAGE_DIR) + var error: NSError? + var comparisonSuccess = false + + if let envReferenceImageDirectory = envReferenceImageDirectory { + for suffix in suffixes { + let referenceImagesDirectory = "\(envReferenceImageDirectory)\(suffix)" + if viewOrLayer.isKindOfClass(UIView) { + do { + try compareSnapshotOfView(viewOrLayer as! UIView, referenceImagesDirectory: referenceImagesDirectory, identifier: identifier, tolerance: 0) + comparisonSuccess = true + } catch let error1 as NSError { + error = error1 + comparisonSuccess = false + } + } else if viewOrLayer.isKindOfClass(CALayer) { + do { + try compareSnapshotOfLayer(viewOrLayer as! CALayer, referenceImagesDirectory: referenceImagesDirectory, identifier: identifier, tolerance: 0) + comparisonSuccess = true + } catch let error1 as NSError { + error = error1 + comparisonSuccess = false + } + } else { + assertionFailure("Only UIView and CALayer classes can be snapshotted") + } + + assert(recordMode == false, message: "Test ran in record mode. Reference image is now saved. Disable record mode to perform an actual snapshot comparison!", file: file, line: line) + + if comparisonSuccess || recordMode { + break + } + + assert(comparisonSuccess, message: "Snapshot comparison failed: \(error)", file: file, line: line) + } + } else { + XCTFail("Missing value for referenceImagesDirectory - Set FB_REFERENCE_IMAGE_DIR as Environment variable in your scheme.") + } + } + + func assert(assertion: Bool, message: String, file: String, line: UInt) { + if !assertion { + XCTFail(message, file: file, line: line) + } + } +} diff --git a/Example/Pods/FBSnapshotTestCase/LICENSE b/Example/Pods/FBSnapshotTestCase/LICENSE new file mode 100644 index 0000000..2dd780c --- /dev/null +++ b/Example/Pods/FBSnapshotTestCase/LICENSE @@ -0,0 +1,29 @@ +BSD License + +For the FBSnapshotTestCase software + +Copyright (c) 2013, Facebook, Inc. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + * Neither the name Facebook nor the names of its contributors may be used to + endorse or promote products derived from this software without specific + prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/Example/Pods/FBSnapshotTestCase/README.md b/Example/Pods/FBSnapshotTestCase/README.md new file mode 100644 index 0000000..bc23b83 --- /dev/null +++ b/Example/Pods/FBSnapshotTestCase/README.md @@ -0,0 +1,97 @@ +FBSnapshotTestCase +====================== + +[![Build Status](https://travis-ci.org/facebook/ios-snapshot-test-case.svg)](https://travis-ci.org/facebook/ios-snapshot-test-case) [![Cocoa Pod Version](https://cocoapod-badges.herokuapp.com/v/FBSnapshotTestCase/badge.svg)](http://cocoadocs.org/docsets/FBSnapshotTestCase/) + +What it does +------------ + +A "snapshot test case" takes a configured `UIView` or `CALayer` and uses the +`renderInContext:` method to get an image snapshot of its contents. It +compares this snapshot to a "reference image" stored in your source code +repository and fails the test if the two images don't match. + +Why? +---- + +At Facebook we write a lot of UI code. As you might imagine, each type of +feed story is rendered using a subclass of `UIView`. There are a lot of edge +cases that we want to handle correctly: + +- What if there is more text than can fit in the space available? +- What if an image doesn't match the size of an image view? +- What should the highlighted state look like? + +It's straightforward to test logic code, but less obvious how you should test +views. You can do a lot of rectangle asserts, but these are hard to understand +or visualize. Looking at an image diff shows you exactly what changed and how +it will look to users. + +We developed `FBSnapshotTestCase` to make snapshot tests easy. + +Installation with CocoaPods +--------------------------- + +1. Add the following lines to your Podfile: + + ``` + target "Tests" do + pod 'FBSnapshotTestCase' + end + ``` + + If you support iOS 7 use `FBSnapshotTestCase/Core` instead, which doesn't contain Swift support. + + Replace "Tests" with the name of your test project. + +2. There are [three ways](https://github.com/facebook/ios-snapshot-test-case/blob/master/FBSnapshotTestCase/FBSnapshotTestCase.h#L19-L29) of setting reference image directories, the recommended one is to define `FB_REFERENCE_IMAGE_DIR` in your scheme. This should point to the directory where you want reference images to be stored. At Facebook, we normally use this: + +|Name|Value| +|:---|:----| +|`FB_REFERENCE_IMAGE_DIR`|`$(SOURCE_ROOT)/$(PROJECT_NAME)Tests/ReferenceImages`| + + +![](FBSnapshotTestCaseDemo/Scheme_FB_REFERENCE_IMAGE_DIR.png) + +Creating a snapshot test +------------------------ + +1. Subclass `FBSnapshotTestCase` instead of `XCTestCase`. +2. From within your test, use `FBSnapshotVerifyView`. +3. Run the test once with `self.recordMode = YES;` in the test's `-setUp` + method. (This creates the reference images on disk.) +4. Remove the line enabling record mode and run the test. + +Features +-------- + +- Automatically names reference images on disk according to test class and + selector. +- Prints a descriptive error message to the console on failure. (Bonus: + failure message includes a one-line command to see an image diff if + you have [Kaleidoscope](http://www.kaleidoscopeapp.com) installed.) +- Supply an optional "identifier" if you want to perform multiple snapshots + in a single test method. +- Support for `CALayer` via `FBSnapshotVerifyLayer`. +- `usesDrawViewHierarchyInRect` to handle cases like `UIVisualEffect`, `UIAppearance` and Size Classes. +- `isDeviceAgnostic` to allow appending the device model (`iPhone`, `iPad`, `iPod Touch`, etc), OS version and screen size to the images (allowing to have multiple tests for the same «snapshot» for different `OS`s and devices). + +Notes +----- + +Your unit test must be an "application test", not a "logic test." (That is, it +must be run within the Simulator so that it has access to UIKit.) In Xcode 5 +and later new projects only offer application tests, but older projects will +have separate targets for the two types. + +Authors +------- + +`FBSnapshotTestCase` was written at Facebook by +[Jonathan Dann](https://facebook.com/j.p.dann) with significant contributions by +[Todd Krabach](https://facebook.com/toddkrabach). + +License +------- + +`FBSnapshotTestCase` is BSD-licensed. See `LICENSE`. diff --git a/Example/Pods/Local Podspecs/PNImagePickerViewController.podspec.json b/Example/Pods/Local Podspecs/PNImagePickerViewController.podspec.json new file mode 100644 index 0000000..7928698 --- /dev/null +++ b/Example/Pods/Local Podspecs/PNImagePickerViewController.podspec.json @@ -0,0 +1,33 @@ +{ + "name": "PNImagePickerViewController", + "version": "0.1.0", + "summary": "PNImagePickerViewController is a fork of jacobsieradzki/JSImagePickerController with iOS8+ PhotoKit support.", + "homepage": "https://github.com//PNImagePickerViewController", + "license": "MIT", + "authors": { + "Giuseppe Nucifora": "me@giuseppenucifora.com" + }, + "source": { + "git": "https://github.com//PNImagePickerViewController.git", + "tag": "0.1.0" + }, + "platforms": { + "ios": "7.0" + }, + "requires_arc": true, + "source_files": "Pod/Classes/**/*", + "resource_bundles": { + "PNImagePickerViewController": [ + "Pod/Assets/*.png" + ] + }, + "frameworks": [ + "Photos", + "PhotosUI" + ], + "dependencies": { + "PureLayout": [ + + ] + } +} diff --git a/Example/Pods/Manifest.lock b/Example/Pods/Manifest.lock new file mode 100644 index 0000000..e1dbdcb --- /dev/null +++ b/Example/Pods/Manifest.lock @@ -0,0 +1,38 @@ +PODS: + - Expecta (1.0.5) + - Expecta+Snapshots (2.0.0): + - Expecta (~> 1.0) + - FBSnapshotTestCase/Core (~> 2.0.3) + - FBSnapshotTestCase (2.0.7): + - FBSnapshotTestCase/SwiftSupport (= 2.0.7) + - FBSnapshotTestCase/Core (2.0.7) + - FBSnapshotTestCase/SwiftSupport (2.0.7): + - FBSnapshotTestCase/Core + - PNImagePickerViewController (0.1.0): + - PureLayout + - PureLayout (3.0.1) + - Specta (1.0.5) + +DEPENDENCIES: + - Expecta + - Expecta+Snapshots + - FBSnapshotTestCase + - PNImagePickerViewController (from `../`) + - PureLayout + - Specta + +EXTERNAL SOURCES: + PNImagePickerViewController: + :path: "../" + +SPEC CHECKSUMS: + Expecta: e1c022fcd33910b6be89c291d2775b3fe27a89fe + Expecta+Snapshots: 29b38dd695bc72a0ed2bea833937d78df41943ba + FBSnapshotTestCase: 7e85180d0d141a0cf472352edda7e80d7eaeb547 + PNImagePickerViewController: 9eaf2575e70de776463e23904f9d466f98d27ad4 + PureLayout: f35f5384c9c4e4479df041dbe33ad7577b71ddfb + Specta: ac94d110b865115fe60ff2c6d7281053c6f8e8a2 + +PODFILE CHECKSUM: dfe253f9ffc18c2f381e56e26aeba9f722b4a230 + +COCOAPODS: 1.0.0.beta.3 diff --git a/Example/Pods/Pods.xcodeproj/project.pbxproj b/Example/Pods/Pods.xcodeproj/project.pbxproj new file mode 100644 index 0000000..e9fa21f --- /dev/null +++ b/Example/Pods/Pods.xcodeproj/project.pbxproj @@ -0,0 +1,2233 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 0690251E14FB6236B8C0F921AC475FB6 /* PNCollectionViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = BE3F27961738F25BC58F8322179B8364 /* PNCollectionViewCell.m */; }; + 07CAFACAFAC87ABBF28D453E70832464 /* UIImage+Compare.m in Sources */ = {isa = PBXBuildFile; fileRef = 49B0983683A73B0A5B7A4FB352CBD58A /* UIImage+Compare.m */; }; + 0A5DFD94EE83E385C1C7D24986E04592 /* SwiftSupport.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03125582C7BE5CEF86A73FA369065311 /* SwiftSupport.swift */; }; + 0C1DCD965236FA97FD51175704561126 /* XCTest+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 543F7BDA4F5F79573CAA43601F700A67 /* XCTest+Private.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 0C6FF91EB1F0391ED75DC72D31D159EF /* EXPMatchers+beTruthy.m in Sources */ = {isa = PBXBuildFile; fileRef = 6F7482216BDAA86DA901E47954D81943 /* EXPMatchers+beTruthy.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + 0D16B556212D317A0D4FEB71E102E207 /* EXPMatchers+beLessThan.h in Headers */ = {isa = PBXBuildFile; fileRef = 2CD52C0184F0903B7EA8B033B01717A9 /* EXPMatchers+beLessThan.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 0EBFA5FBE4953A83B677CE2A75746761 /* EXPMatchers+beLessThan.m in Sources */ = {isa = PBXBuildFile; fileRef = 390F5EAD0FA0ACB91D06A90A974E0A45 /* EXPMatchers+beLessThan.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + 0F94F5B0ABB3252B9275B7C129EC7A26 /* EXPMatchers+equal.h in Headers */ = {isa = PBXBuildFile; fileRef = 238F2FBD86752F42D840CC54A3F5A407 /* EXPMatchers+equal.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 11C1AEB289C1EB80089349B71F09D04B /* EXPMatchers+raiseWithReason.h in Headers */ = {isa = PBXBuildFile; fileRef = 510D07686732BBA3C4B870F02EAC7A30 /* EXPMatchers+raiseWithReason.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 1303C5017F898BD7F98DB1BD1AFFAB49 /* Specta-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = AA01D298630B12AA0970C55ADF492FE2 /* Specta-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 1312A7D381C51428CF481E33E3D37901 /* EXPMatchers+beGreaterThan.m in Sources */ = {isa = PBXBuildFile; fileRef = 80156AEEDC4D129C5C54BFFED8633BF6 /* EXPMatchers+beGreaterThan.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + 131532787AD40BE1F35DF288D2E6FFD7 /* EXPMatchers+beInTheRangeOf.h in Headers */ = {isa = PBXBuildFile; fileRef = 70688D0A2ACC0A7F02D0F1235F0E8BF4 /* EXPMatchers+beInTheRangeOf.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 13E6BEF790F8746E9BA8849BFAB94E3F /* SPTCallSite.m in Sources */ = {isa = PBXBuildFile; fileRef = F2326EBC2CEBEDD1AC39E41341CE4A96 /* SPTCallSite.m */; }; + 16CB96DE4260C29B5932E729435BD2AD /* NSString+HexColor.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E902D9B8E310A8D78AFE8B074819218 /* NSString+HexColor.m */; }; + 17572374B2AE183C6347C41E8DF8E579 /* EXPMatchers+beFalsy.m in Sources */ = {isa = PBXBuildFile; fileRef = 31480E56FB4A5AF08ADA95062BFEFC89 /* EXPMatchers+beFalsy.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + 184CCD5A7C9B2FDBD13FB45D3D3B99FD /* Specta-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 703612D1CEA30E0B8C9E02D238F7196E /* Specta-dummy.m */; }; + 1993857B26D7AFE6B3C888986768FDE2 /* PureLayoutDefines.h in Headers */ = {isa = PBXBuildFile; fileRef = 6BF30C23B3BDD819BCFB41457392E2D9 /* PureLayoutDefines.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 1A1AB2EC52323C5EA28DAA99F1E1A90D /* EXPMatchers+endWith.h in Headers */ = {isa = PBXBuildFile; fileRef = 313C5B73A027A335880529469217DAC0 /* EXPMatchers+endWith.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 1AAC27517D2E1C6AC73AE3B609AF359C /* SPTTestSuite.m in Sources */ = {isa = PBXBuildFile; fileRef = 58380708EFDF326D68D6060E486CB90D /* SPTTestSuite.m */; }; + 1AB3304B6884F626BC54150AC7565E18 /* EXPMatchers+equal.m in Sources */ = {isa = PBXBuildFile; fileRef = 4016B648F56236C2BA14F6C65E94AFC0 /* EXPMatchers+equal.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + 1B0389CD88AA949B34DC7269030FEC6F /* EXPMatchers+beGreaterThanOrEqualTo.m in Sources */ = {isa = PBXBuildFile; fileRef = F65C9454F6F8DB1D7E3FFDE17F54D58C /* EXPMatchers+beGreaterThanOrEqualTo.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + 1F0DDAD8051AFDC85E1C7CE42CEFE024 /* Pods-PNImagePickerViewController_Example-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 61DF146816D923BA85792DC9693B94D4 /* Pods-PNImagePickerViewController_Example-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 201BF9C605852822CA5A65ADE282A310 /* EXPMatcherHelpers.m in Sources */ = {isa = PBXBuildFile; fileRef = 52B96B599CCF1E2C6EE96048EA5880E3 /* EXPMatcherHelpers.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + 202982C27067054C061304D6A53C9830 /* SPTSharedExampleGroups.h in Headers */ = {isa = PBXBuildFile; fileRef = 957CBE35D3FC82EDC76EDF33D58CC14A /* SPTSharedExampleGroups.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 204D694B03BFF3B244A6AB73FACFFC43 /* Expecta-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 5F9093C7E794724D47C617BE24557A5D /* Expecta-dummy.m */; }; + 20C0CFB6F8C29123D1667E2676D8B2F5 /* FBSnapshotTestCase.h in Headers */ = {isa = PBXBuildFile; fileRef = C3F02F121BD9AAA950DEC5C89D564638 /* FBSnapshotTestCase.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 2374C44ACA9EB74301CC387D2C99587D /* NSArray+PureLayout.h in Headers */ = {isa = PBXBuildFile; fileRef = F42F0DA116857769307897100F7DA2CA /* NSArray+PureLayout.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 2549CD1370AF63009DEC76693F5E9BD1 /* FBSnapshotTestCase.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 901657B874B99B4D8BAC6029F1239819 /* FBSnapshotTestCase.framework */; }; + 260BC7EED9289AF321A6F791964CE472 /* EXPMatchers+respondTo.h in Headers */ = {isa = PBXBuildFile; fileRef = 17A1FCF90A9C0E52BA56CCF8B9DCF00C /* EXPMatchers+respondTo.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 264D55B73E4BE829EFD707ADED9655EB /* XCTestCase+Specta.m in Sources */ = {isa = PBXBuildFile; fileRef = CC4EC6D3BB6C4AAB71B02968CCEB66EA /* XCTestCase+Specta.m */; }; + 274D9545D0357B667BCAA82B3FB38ECD /* UIImage+Diff.h in Headers */ = {isa = PBXBuildFile; fileRef = 6296391EB02733986480B8C3B38C1751 /* UIImage+Diff.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 278432744E184DE2FAAC997F0455021F /* Specta.h in Headers */ = {isa = PBXBuildFile; fileRef = C58ECDACD8D2FD15B5D6F0D6276B0700 /* Specta.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 2916A0606136A9DC67F2463AB230868B /* EXPMatchers+match.h in Headers */ = {isa = PBXBuildFile; fileRef = AA7B81ED73344E500125187115387A8F /* EXPMatchers+match.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 29923C8237C2521B7761DFBA1176AEF6 /* SPTExcludeGlobalBeforeAfterEach.h in Headers */ = {isa = PBXBuildFile; fileRef = 2BC4279D7351FD3A726A6EF02FC8ED19 /* SPTExcludeGlobalBeforeAfterEach.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 29F2AEAF2B01E3739BF745ADE8E9D0A4 /* Expecta+Snapshots-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = B3E4CD3EBCF888648A5FDAC1B196AF58 /* Expecta+Snapshots-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 2A7748A0699C2B1BE8ABEA9CFED631FC /* PureLayout-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 32ECF317E9844862171B030F13E92DD9 /* PureLayout-dummy.m */; }; + 2AE7AC04A02ABF5575E481C2AC56BAA4 /* SPTSpec.h in Headers */ = {isa = PBXBuildFile; fileRef = 0566C8B9ADE96B49FC01A2B3E52421BE /* SPTSpec.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 2C0A8737FDB9B9C6A6BDF437FD11334C /* EXPMatchers+beNil.m in Sources */ = {isa = PBXBuildFile; fileRef = D32A0E3BF4F5096301528945D03203B2 /* EXPMatchers+beNil.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + 2CFE2898496C1C7096DB8DA43AF19103 /* EXPMatchers+raise.m in Sources */ = {isa = PBXBuildFile; fileRef = 96722169F2EE7FD1D3A8A151F68B4997 /* EXPMatchers+raise.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + 2E14619153A453BB8DF389FB6EA147BE /* ExpectaObject.h in Headers */ = {isa = PBXBuildFile; fileRef = AF51448F8D892B8D7E10576612FBA77A /* ExpectaObject.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 2E1FAA5E50BC174E7356BEAC15993B77 /* Photos.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3858144F30FB57931C02F64C362E3B5C /* Photos.framework */; }; + 2F427490ACABC4408D57CC0592276678 /* EXPDoubleTuple.h in Headers */ = {isa = PBXBuildFile; fileRef = FB37123DB4D2486C30EA392F17BF7505 /* EXPDoubleTuple.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 2F48F56D90BA2AF519FDB5966BF7288F /* SPTExampleGroup.m in Sources */ = {isa = PBXBuildFile; fileRef = 563BDF7C8114F5105A8038CFD0803495 /* SPTExampleGroup.m */; }; + 2FF07674284F10FF5382D0AEAB764FB0 /* PNImagePickerViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = 659207AE2EF6E56A99A2880417729552 /* PNImagePickerViewController.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 346833B09DCB096D7E23EF1DF3AA37A3 /* PNImagePickerViewController.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 9BE9B9F15F1FC0C7BDDA5C9ED0AF220F /* PNImagePickerViewController.bundle */; }; + 34B6E9A30603BEBBD87BA535B7D384CA /* EXPMatchers+beInstanceOf.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BB793EEEA2972B9A2DB5CC84E5C7FC8 /* EXPMatchers+beInstanceOf.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 35D17528C41E69D04EF227502A8EC77B /* SpectaUtility.m in Sources */ = {isa = PBXBuildFile; fileRef = 749800021466D47EDC1F64E037BF45CC /* SpectaUtility.m */; }; + 372F7A9CCE59CE86316CF436F832A3FC /* EXPMatchers+beGreaterThanOrEqualTo.h in Headers */ = {isa = PBXBuildFile; fileRef = 7BD87D11D30651D5EB6E5F42D4FCDFFE /* EXPMatchers+beGreaterThanOrEqualTo.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 378AB5D15998CBD19ABD7E01BED7B391 /* SPTSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 20327CEB6D3F13297BDAB7FE6026920E /* SPTSpec.m */; }; + 37A2D0F8493469EF2495FC689440F079 /* EXPMatchers+beLessThanOrEqualTo.h in Headers */ = {isa = PBXBuildFile; fileRef = F0BE4B0FD430ED5364A83BE6EFAB44E3 /* EXPMatchers+beLessThanOrEqualTo.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 397B320B7C59C168CC5B62E18ED8DEA0 /* EXPMatchers+beSubclassOf.h in Headers */ = {isa = PBXBuildFile; fileRef = 25BC55E750A529F4D0F46F5119E3EFB0 /* EXPMatchers+beSubclassOf.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 39F3AFD4DADD9BF4AEDFAF1FEA82B2F2 /* ExpectaObject+FBSnapshotTest.h in Headers */ = {isa = PBXBuildFile; fileRef = DDE582482FAF1CEB39F0B9126CC59D6D /* ExpectaObject+FBSnapshotTest.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 3B5B7495707BF7133B9FB3F834045611 /* EXPBlockDefinedMatcher.h in Headers */ = {isa = PBXBuildFile; fileRef = AA101E016C76302C06F4575172FDC9DE /* EXPBlockDefinedMatcher.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 3C2700C7DAA15C6AF84A595865C42F4D /* EXPMatchers+contain.h in Headers */ = {isa = PBXBuildFile; fileRef = EF3299BF94C0392FCBAA98D2E58CB10E /* EXPMatchers+contain.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 3D48EE131B6577ED73A5CC481A6FE40C /* Expecta.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D4DBA040A9E2814F4869DD7B7B7E4F98 /* Expecta.framework */; }; + 3F5AFB158433D800A9AE61CB744054B0 /* SPTGlobalBeforeAfterEach.h in Headers */ = {isa = PBXBuildFile; fileRef = 4DBFEEB0166000625503662CDE93CDF3 /* SPTGlobalBeforeAfterEach.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 403292D82DA62291204BF59524BC4EDB /* EXPMatchers+haveCountOf.m in Sources */ = {isa = PBXBuildFile; fileRef = 289E592F6B702F82121F6BAC6F5CA8AA /* EXPMatchers+haveCountOf.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + 4052EB66107F09D6F856EAA1F4FC0846 /* UIImage+Snapshot.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EBE0B34BA8C3C5428B651C33628FFEC /* UIImage+Snapshot.m */; }; + 453097252D8DA15ED33554933CDDBD06 /* SPTSharedExampleGroups.m in Sources */ = {isa = PBXBuildFile; fileRef = E172DFC29EE8C2A36AEC06644DCCA25D /* SPTSharedExampleGroups.m */; }; + 46137F5CC368BF38BAF0D0AF81DD8FFE /* EXPMatchers+raise.h in Headers */ = {isa = PBXBuildFile; fileRef = AD498EF1F11DF000A23462687DB4F486 /* EXPMatchers+raise.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 471FD4F68E27AB26FA2AEBB8B245CEE4 /* NSValue+Expecta.h in Headers */ = {isa = PBXBuildFile; fileRef = 4A4547E4EE9A69F8554ABE6EB6C8F6FA /* NSValue+Expecta.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 47D16DB1D23CFE027F5BE7F7E391AB4C /* EXPMatchers+FBSnapshotTest.m in Sources */ = {isa = PBXBuildFile; fileRef = AC25E36ECB984C6D46E07D449F8E6AD3 /* EXPMatchers+FBSnapshotTest.m */; }; + 47DE038D397A1D8D169BEA7C24549EF4 /* SPTCompiledExample.h in Headers */ = {isa = PBXBuildFile; fileRef = 4AE18936EDB988BC6D3A33128764D642 /* SPTCompiledExample.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 48A3244684540E73970769D236CE8793 /* SPTExample.h in Headers */ = {isa = PBXBuildFile; fileRef = 8AAA1981FD0C38B91AE527BE960EE881 /* SPTExample.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 4AE1F0FA07542E17D534D443E55BB63E /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8F82F3F7B94F183AEC45FD4AD8E6187C /* Foundation.framework */; }; + 4B5542E72A64100965FFFA704684CED4 /* ExpectaObject+FBSnapshotTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 89B4983E65DB1A8DD67F7A9D82A5CBBE /* ExpectaObject+FBSnapshotTest.m */; }; + 4BBCBB9D8EF0B241A4A4FE4982985481 /* ExpectaSupport.m in Sources */ = {isa = PBXBuildFile; fileRef = D7B03B244D464496A92ACED43DA0DE3D /* ExpectaSupport.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + 5056E0520959CBC31CCB037B59BFC847 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 80D1D2F56444ACE235744A744B9C8D67 /* UIKit.framework */; }; + 51DDDB0FB4899757CF6A826B531B940D /* EXPUnsupportedObject.h in Headers */ = {isa = PBXBuildFile; fileRef = 10E1AB2290A940590A50E8D54F54A2F6 /* EXPUnsupportedObject.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 55BF89A8370D6D6E6971AC4F0D7B86FD /* SPTCallSite.h in Headers */ = {isa = PBXBuildFile; fileRef = A6922487AB8095FA4A248866B59E44EB /* SPTCallSite.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 5B2D4A621D3DA971A474776AF36BB073 /* EXPBlockDefinedMatcher.m in Sources */ = {isa = PBXBuildFile; fileRef = F6EB583A0E0B95BC98422547435C1DB8 /* EXPBlockDefinedMatcher.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + 5BF1E1FBAE24D8B3CA47C9FC381296DF /* SpectaDSL.h in Headers */ = {isa = PBXBuildFile; fileRef = 45EBC5857C0FBA732752E48E9359EDD8 /* SpectaDSL.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 5CF7526D330A734F7ABCDCFF3D1A9B35 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8F82F3F7B94F183AEC45FD4AD8E6187C /* Foundation.framework */; }; + 5EA7043FE10E75D02F3C3052AF8B8318 /* EXPDefines.h in Headers */ = {isa = PBXBuildFile; fileRef = B73FA83187F6E3585C08B5C189A6F033 /* EXPDefines.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 5EE6F0E14E01D6AFF2C5D0A28584D9AF /* Pods-PNImagePickerViewController_Tests-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = FE1A6C6BC96129C4BD3805467E03F49C /* Pods-PNImagePickerViewController_Tests-dummy.m */; }; + 6361270EB2EFD4CE80ABB4D9D726BDD1 /* PureLayout.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E6F5F421366F1062F96C25902DB7BFD2 /* PureLayout.framework */; }; + 65BC31095CCDFC80CBF6BBA843751F23 /* EXPMatcher.h in Headers */ = {isa = PBXBuildFile; fileRef = 44C2BCB8ADDB4424AC3426DA52A88FD0 /* EXPMatcher.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 66A27898E989A3FA5C15AA671C4536F0 /* EXPMatchers+beIdenticalTo.m in Sources */ = {isa = PBXBuildFile; fileRef = 4A483661BF65897902AB0A0CFCD975AE /* EXPMatchers+beIdenticalTo.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + 67459AD239EF669A365519E06B45DCFE /* EXPExpect.h in Headers */ = {isa = PBXBuildFile; fileRef = FF49B4C3C61836DE302F437C919A7A05 /* EXPExpect.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 6E1D978790705E137FDE439AA68DD3AA /* EXPFloatTuple.h in Headers */ = {isa = PBXBuildFile; fileRef = 593892C8C11EDE0285489E134696F878 /* EXPFloatTuple.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 6EFC63A5CED45BB39FC79D87F2C47D6B /* EXPMatchers+beGreaterThan.h in Headers */ = {isa = PBXBuildFile; fileRef = DC7DF335401532E474FB05944C1ED485 /* EXPMatchers+beGreaterThan.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 6F278423C8AE1DA47F35E374BB5B91EC /* EXPMatchers+beSupersetOf.m in Sources */ = {isa = PBXBuildFile; fileRef = 88B5C933CDFBD78AAD0546A4AF52B9D5 /* EXPMatchers+beSupersetOf.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + 70967F6B7BDAE8BCBBC039DF9984015C /* PNImagePickerViewController-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = CA9637AFF7146F0DA6D5F4D8A13DFECA /* PNImagePickerViewController-dummy.m */; }; + 70E4BCC789D8C8F1033F23E0752502A7 /* FBSnapshotTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 8B977762C348A6EDA1883600F1DCFE58 /* FBSnapshotTestCase.m */; }; + 715A1122272BB3A29A10AAE4C8C03913 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8F82F3F7B94F183AEC45FD4AD8E6187C /* Foundation.framework */; }; + 75D32A41CF8027A97FD575048AFC035C /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8F82F3F7B94F183AEC45FD4AD8E6187C /* Foundation.framework */; }; + 76CCABE79C04444450153424D7CE1DC1 /* EXPMatchers+beSupersetOf.h in Headers */ = {isa = PBXBuildFile; fileRef = C3F844297B8662ADF09537912FAC73ED /* EXPMatchers+beSupersetOf.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 76D337327C10A7555447B69AA1562647 /* EXPMatchers+beInstanceOf.m in Sources */ = {isa = PBXBuildFile; fileRef = 1509EB0EDB59BB6A235C075BDF27ACA5 /* EXPMatchers+beInstanceOf.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + 772BFB9529121111C517FBA06EA26237 /* Expecta+Snapshots-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 35F1FA87897C7070C74ECF8D2CE8DAF9 /* Expecta+Snapshots-dummy.m */; }; + 774FE3A849D9CEA65AB50972674CE4C6 /* Pods-PNImagePickerViewController_Tests-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 2BE45DFB6789AAEB03C87E14911811BD /* Pods-PNImagePickerViewController_Tests-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 7861523B9D5DFCF0F4A56E4DE3296AA2 /* FBSnapshotTestController.m in Sources */ = {isa = PBXBuildFile; fileRef = A3238F2F8580E2D38D5628A33F934CFA /* FBSnapshotTestController.m */; }; + 79558B1F97ABE4AB8942DC18BEBD4B82 /* EXPMatchers+beKindOf.h in Headers */ = {isa = PBXBuildFile; fileRef = BB4F841C6A0CF76946BB788A161240EA /* EXPMatchers+beKindOf.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 79E61152676FBAF9799E4F1DCA969CF2 /* PNImagePickerViewController-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 39EF931D9991CC7A7257528EC5239C85 /* PNImagePickerViewController-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 7B223B4E6EF14BA12DA113F7EE10B96C /* NSObject+Expecta.h in Headers */ = {isa = PBXBuildFile; fileRef = 87DC71BCE9F88907D4CA9EA6C6D4CD3A /* NSObject+Expecta.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 7C16E367C0BD248774049989B329FEE6 /* ALView+PureLayout.m in Sources */ = {isa = PBXBuildFile; fileRef = 8E64F0B58141D2A8C5B35D8B7E1D76E0 /* ALView+PureLayout.m */; }; + 805E425BBEF7A6133E32E1D30A073010 /* EXPExpect.m in Sources */ = {isa = PBXBuildFile; fileRef = 430444E6E86490E2572119A37E68341B /* EXPExpect.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + 837B593D7C1D01B4EA400247309D6AB0 /* Expecta-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 5C0D2BAE8C19CA6614F3CA94783F095D /* Expecta-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 85E31076D5530AEEB45ACF16B2B8A983 /* EXPMatchers.h in Headers */ = {isa = PBXBuildFile; fileRef = 4DFBE5937DE9B4E2ADFCD9B2EBF09325 /* EXPMatchers.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 85EB2F216487CB2E8F3FCCFBC4D69912 /* EXPMatchers+beTruthy.h in Headers */ = {isa = PBXBuildFile; fileRef = 579F45E6A47205E79C183A91C534F864 /* EXPMatchers+beTruthy.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 87FD5F0F682CDEB6A348CA448889E3EA /* EXPMatchers+beKindOf.m in Sources */ = {isa = PBXBuildFile; fileRef = C1EF7A5D7462BAA91E23F816C1B96180 /* EXPMatchers+beKindOf.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + 89A46B63E469F17791D14FC64466794A /* UIImage+Diff.m in Sources */ = {isa = PBXBuildFile; fileRef = 3251AD74FAC3B67F2A03E3F30133557D /* UIImage+Diff.m */; }; + 89BAEBD7FF6D270EECD5AA2EBAAD22E5 /* PureLayout-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = BC4E6D745DD948298DA344813F4F67D4 /* PureLayout-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 8BAA5A5F568886A0D333718CE7B2C3DB /* SPTExample.m in Sources */ = {isa = PBXBuildFile; fileRef = AADBF70B3B9D2D9143BFF2AC688B29D1 /* SPTExample.m */; }; + 8C8C1B0D83FE6A4352F15154DB16372C /* EXPMatcherHelpers.h in Headers */ = {isa = PBXBuildFile; fileRef = AA729BBF9CB238789CCA63E476AEA5CE /* EXPMatcherHelpers.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 8D1A5F519C1BBBEEE77F66B515FC3D66 /* ALView+PureLayout.h in Headers */ = {isa = PBXBuildFile; fileRef = 54493E6647B30E3C5BEEFB40F581FF54 /* ALView+PureLayout.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 918E06480F28F27361B19D19432F8538 /* EXPMatchers+endWith.m in Sources */ = {isa = PBXBuildFile; fileRef = CB278C4D8E22AB0B2386C27A5DC84F44 /* EXPMatchers+endWith.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + 931D410B9F8ACB935883DF8C59F9C93E /* EXPMatchers+postNotification.m in Sources */ = {isa = PBXBuildFile; fileRef = FAD450F231B69F75615E743CE1ED2B4C /* EXPMatchers+postNotification.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + 94C47C87E397972CE98F75929F3B706C /* ExpectaObject.m in Sources */ = {isa = PBXBuildFile; fileRef = C42C93ADD945A4372635BD32CAD3C814 /* ExpectaObject.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + 9B2E761A064459F77EA9870BEF03ACC3 /* EXPMatchers+postNotification.h in Headers */ = {isa = PBXBuildFile; fileRef = DD8F605551C2300C9C46FB3364564F6D /* EXPMatchers+postNotification.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 9BB9159FBA757600D3D4C0FF645F3911 /* EXPMatchers+beInTheRangeOf.m in Sources */ = {isa = PBXBuildFile; fileRef = 9106954FD71A00CE85BF2799C2328977 /* EXPMatchers+beInTheRangeOf.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + A1B0E811BF9898CBA7B29B546070BC5E /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8F82F3F7B94F183AEC45FD4AD8E6187C /* Foundation.framework */; }; + A3372B44BC67F60CE578D36F6BA3530A /* NSLayoutConstraint+PureLayout.h in Headers */ = {isa = PBXBuildFile; fileRef = 0B4D563AB4E127AF0A9FBC1E231C5D43 /* NSLayoutConstraint+PureLayout.h */; settings = {ATTRIBUTES = (Public, ); }; }; + A4ABC102CBD31F39E80EFEA4AB7A738E /* PureLayout.h in Headers */ = {isa = PBXBuildFile; fileRef = 3FB4A919E61BF9E7388E2A08D5F6D7EA /* PureLayout.h */; settings = {ATTRIBUTES = (Public, ); }; }; + A4AC67807A52576C168C0606BC9C783A /* SPTTestSuite.h in Headers */ = {isa = PBXBuildFile; fileRef = 416F8ABB7F7E98CB081B7F19F9EB2F92 /* SPTTestSuite.h */; settings = {ATTRIBUTES = (Public, ); }; }; + A8360AF9EB52A18F5FC74182F1FC577D /* Pods-PNImagePickerViewController_Example-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 49EDEF02628E2CD3C475A46896250265 /* Pods-PNImagePickerViewController_Example-dummy.m */; }; + AB6685722275C4592751D73600321350 /* SpectaUtility.h in Headers */ = {isa = PBXBuildFile; fileRef = 68FDF6EB112C4423747393766720207C /* SpectaUtility.h */; settings = {ATTRIBUTES = (Public, ); }; }; + AF1F46668D4591602887998C6E9C10AD /* EXPMatchers+beCloseTo.h in Headers */ = {isa = PBXBuildFile; fileRef = 19C53BEC21D8B0E161B0702E54CF7D9D /* EXPMatchers+beCloseTo.h */; settings = {ATTRIBUTES = (Public, ); }; }; + AFFC8900E52BBEC72059334132F3A8F3 /* ExpectaSupport.h in Headers */ = {isa = PBXBuildFile; fileRef = 63531BD7407ED90996601DCE8FCEFD55 /* ExpectaSupport.h */; settings = {ATTRIBUTES = (Public, ); }; }; + B0879F635160F10BB9A8820E97A6ABEA /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8F82F3F7B94F183AEC45FD4AD8E6187C /* Foundation.framework */; }; + B7489960D6579E861620D733D15BE2C1 /* NSArray+PureLayout.m in Sources */ = {isa = PBXBuildFile; fileRef = 3DDC2F0DB66FDE2D99014751F0C471C6 /* NSArray+PureLayout.m */; }; + B84431CF8C64F363A334AA7089F6C134 /* NSValue+Expecta.m in Sources */ = {isa = PBXBuildFile; fileRef = DD4E5110B5ED80C99A3F9576C46C4672 /* NSValue+Expecta.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + BA12B131F10BCE3BE6E9A02FC908FE9D /* EXPMatchers+beCloseTo.m in Sources */ = {isa = PBXBuildFile; fileRef = 10782AE189DA5C3D8516751CF9C19A5E /* EXPMatchers+beCloseTo.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + BB5DD166C1EB3ECED5BB3CFD5524E2F5 /* NSLayoutConstraint+PureLayout.m in Sources */ = {isa = PBXBuildFile; fileRef = 309AE29D56F62AA38812FCD588D97505 /* NSLayoutConstraint+PureLayout.m */; }; + BC55C8365AEFF8217F6A567607754854 /* EXPDoubleTuple.m in Sources */ = {isa = PBXBuildFile; fileRef = 815FCECEE4FF630729054295EC5482B3 /* EXPDoubleTuple.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + BD6235346E7F7116E42D25320126EA98 /* PNCollectionViewCell.h in Headers */ = {isa = PBXBuildFile; fileRef = 096309059441EB5D11744229922922D4 /* PNCollectionViewCell.h */; settings = {ATTRIBUTES = (Public, ); }; }; + BEFFE9FFE52E9A0833A7D2D8FB67EB4D /* EXPMatchers+beSubclassOf.m in Sources */ = {isa = PBXBuildFile; fileRef = ECF097833A853FF056370CCA06DA4831 /* EXPMatchers+beSubclassOf.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + C200BCDC767A422FD3C9709B1BEA37E7 /* SPTCompiledExample.m in Sources */ = {isa = PBXBuildFile; fileRef = 4F85577F3A8EFCC75870860E9CFCD164 /* SPTCompiledExample.m */; }; + C46E9249E3A217379AFDEF4E1B1D6D8E /* PhotosUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FB6EF84A0C4781A668F2F6F76CE56AC4 /* PhotosUI.framework */; }; + C6E9B0A908F410317F2DBBECA0944AAB /* FBSnapshotTestCase-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 173AC2808350B2FCFA846157AE99C71D /* FBSnapshotTestCase-dummy.m */; }; + C733E814C226F0AA7C6C7915E6FA3D90 /* SpectaTypes.h in Headers */ = {isa = PBXBuildFile; fileRef = 0E225E66B94E712DC093C6724AD11CFD /* SpectaTypes.h */; settings = {ATTRIBUTES = (Public, ); }; }; + CC6B5A8198B55F9EFB60F446F2FD9BBC /* XCTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C71086A693BC5E296E2F30B405EEC247 /* XCTest.framework */; }; + CE3F4ECBB0BC095577D66AE50C8E604C /* EXPFloatTuple.m in Sources */ = {isa = PBXBuildFile; fileRef = DEEE8F25AEEDB29355650590026262C0 /* EXPFloatTuple.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + CE91E0B7C2BF362403CB3A75E69AA061 /* UIImage+Snapshot.h in Headers */ = {isa = PBXBuildFile; fileRef = 05543C138878FE2F76FA1482DE5F50D0 /* UIImage+Snapshot.h */; settings = {ATTRIBUTES = (Private, ); }; }; + D181FA8D3863D4294F5CD912DBEDA7C2 /* XCTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C71086A693BC5E296E2F30B405EEC247 /* XCTest.framework */; }; + D1E9E55D21C92E33ACE7E911BCB96269 /* FBSnapshotTestCasePlatform.h in Headers */ = {isa = PBXBuildFile; fileRef = 3B8BA7F1B66924CA150C782F5DD71763 /* FBSnapshotTestCasePlatform.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D83677C54D2226C67886A525B0B46FBE /* EXPMatchers+beLessThanOrEqualTo.m in Sources */ = {isa = PBXBuildFile; fileRef = 3F639A935CAD81D124435F643E505794 /* EXPMatchers+beLessThanOrEqualTo.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + DA5D8E9EC82544ADAF4A5119C7C4F693 /* PNImagePickerViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B8CFE481DA04D4CD82C10A8448158D2 /* PNImagePickerViewController.m */; }; + DB30F82FB1BE083D9471B965FB500CA2 /* EXPMatchers+conformTo.m in Sources */ = {isa = PBXBuildFile; fileRef = 5723825DA3450735996AC90B937A4AEF /* EXPMatchers+conformTo.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + E0A077DFB064B79685B810CCEFB2F1EF /* EXPMatchers+respondTo.m in Sources */ = {isa = PBXBuildFile; fileRef = C764B935846E8C662CCF7906D8A555DA /* EXPMatchers+respondTo.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + E0AAF49134A0505DF00E20E7B62087E1 /* EXPMatchers+beIdenticalTo.h in Headers */ = {isa = PBXBuildFile; fileRef = 3649CB424097BF48E430598CDE474EEC /* EXPMatchers+beIdenticalTo.h */; settings = {ATTRIBUTES = (Public, ); }; }; + E0E4B1728B841A7E77AB9FF263F0502B /* XCTestCase+Specta.h in Headers */ = {isa = PBXBuildFile; fileRef = 03F0E7D7379464D80A5585C3D68EF9BF /* XCTestCase+Specta.h */; settings = {ATTRIBUTES = (Public, ); }; }; + E10811B5E4578C31FB675361C99EDED6 /* UIImage+Compare.h in Headers */ = {isa = PBXBuildFile; fileRef = 393BCCE5FB0CAEDC7193DE9EBE3A4E09 /* UIImage+Compare.h */; settings = {ATTRIBUTES = (Private, ); }; }; + E1EC4532663CA75DE5BD00CB0A56814D /* Expecta.h in Headers */ = {isa = PBXBuildFile; fileRef = 5AE13025CC5C6B218AAF479784CD9ED2 /* Expecta.h */; settings = {ATTRIBUTES = (Public, ); }; }; + E3C61206BEDBA3EBAA0A69B51DE0F3AA /* FBSnapshotTestCasePlatform.m in Sources */ = {isa = PBXBuildFile; fileRef = 47E9000729E4BF417953FB356297ADC3 /* FBSnapshotTestCasePlatform.m */; }; + E4A96998069826E71AC9408A8D53B772 /* NSString+HexColor.h in Headers */ = {isa = PBXBuildFile; fileRef = 9CE6DF46652A13B55C1A75A6C5257818 /* NSString+HexColor.h */; settings = {ATTRIBUTES = (Public, ); }; }; + E4EC16570D46F25B3BD2830D65C06AE5 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8F82F3F7B94F183AEC45FD4AD8E6187C /* Foundation.framework */; }; + E735386085CE344F6A01178CF4763852 /* EXPMatchers+beNil.h in Headers */ = {isa = PBXBuildFile; fileRef = AF42AAF54B5A41D37200E11671FFA6E8 /* EXPMatchers+beNil.h */; settings = {ATTRIBUTES = (Public, ); }; }; + EA840679AC9463E0E3D371FCC3466B0A /* EXPMatchers+FBSnapshotTest.h in Headers */ = {isa = PBXBuildFile; fileRef = 6D0C6649E2D25AE53519CD3D4CD09ADC /* EXPMatchers+FBSnapshotTest.h */; settings = {ATTRIBUTES = (Public, ); }; }; + EF6497EE123F6BC0C1B09717437C5908 /* EXPUnsupportedObject.m in Sources */ = {isa = PBXBuildFile; fileRef = 47C3908A5AAE0260FB6D95C74D65652D /* EXPUnsupportedObject.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + F0DDF02A078B917997FF025BB33BB842 /* EXPMatchers+conformTo.h in Headers */ = {isa = PBXBuildFile; fileRef = CE7DBAFD56D35A84CC36342276EA5A27 /* EXPMatchers+conformTo.h */; settings = {ATTRIBUTES = (Public, ); }; }; + F12D57414A73406831CC032A7170DBFF /* EXPMatchers+beginWith.m in Sources */ = {isa = PBXBuildFile; fileRef = FA9AA960F05653C47EB2662A7E0E3796 /* EXPMatchers+beginWith.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + F14F53742FD27FA7A2C5CF692E801898 /* PureLayout+Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 90A24E859872FBF4996DB8FF2C72D641 /* PureLayout+Internal.h */; settings = {ATTRIBUTES = (Public, ); }; }; + F16445694BAA1C8B9B1D639DD27D05EC /* SpectaDSL.m in Sources */ = {isa = PBXBuildFile; fileRef = 567FED50899A681C87568B30C6A8DDF2 /* SpectaDSL.m */; }; + F1867C99D4A92FC191093E4901E463B5 /* XCTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C71086A693BC5E296E2F30B405EEC247 /* XCTest.framework */; }; + F41209A94070904A00BDF24ACB6336B6 /* EXPMatchers+beFalsy.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AA72D353A2583EA748D45A0652D40A4 /* EXPMatchers+beFalsy.h */; settings = {ATTRIBUTES = (Public, ); }; }; + F58F9BC7759BB8A5007B8821A275AEDD /* FBSnapshotTestController.h in Headers */ = {isa = PBXBuildFile; fileRef = 76148374B1A8C1EE9BF4C8D44A477428 /* FBSnapshotTestController.h */; settings = {ATTRIBUTES = (Public, ); }; }; + F75CB2A727F678C9A848A3A11EA7979B /* EXPMatchers+haveCountOf.h in Headers */ = {isa = PBXBuildFile; fileRef = 65B4136A49BEA00E3874E067A148CFE2 /* EXPMatchers+haveCountOf.h */; settings = {ATTRIBUTES = (Public, ); }; }; + F78C02E1874FB6F2664E8C242CC13663 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8F82F3F7B94F183AEC45FD4AD8E6187C /* Foundation.framework */; }; + FA839F20BC13A260E089D374CAAB584E /* XCTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C71086A693BC5E296E2F30B405EEC247 /* XCTest.framework */; }; + FAD264330709B586D2D5B17B4A7040C3 /* SPTExampleGroup.h in Headers */ = {isa = PBXBuildFile; fileRef = B19A9279E73679D3F9F1DFAEA13E347C /* SPTExampleGroup.h */; settings = {ATTRIBUTES = (Public, ); }; }; + FC20596ABFE14A61F171A29FD03275E7 /* EXPMatchers+contain.m in Sources */ = {isa = PBXBuildFile; fileRef = 1A2536CA1A4C375065588D7CA7FFFD04 /* EXPMatchers+contain.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + FC45858927D3B6A0F922C4B697B04A38 /* EXPMatchers+match.m in Sources */ = {isa = PBXBuildFile; fileRef = 5A5036265EC2BF776D08D8ED807B8000 /* EXPMatchers+match.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + FCDC9C0B871F82CB1AEE73303F9A2927 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0BB31E11DDAAA96925A1236365EEB21F /* QuartzCore.framework */; }; + FD2D4497BC41412128C2D87C1BDE7398 /* EXPMatchers+beginWith.h in Headers */ = {isa = PBXBuildFile; fileRef = 8306A05F3FC954D6F3B4E35C4F6B2E24 /* EXPMatchers+beginWith.h */; settings = {ATTRIBUTES = (Public, ); }; }; + FE8E34356D24F6759A8B010ED2F5707B /* EXPMatchers+raiseWithReason.m in Sources */ = {isa = PBXBuildFile; fileRef = FB445B211C424686C720B085874E2EF7 /* EXPMatchers+raiseWithReason.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 02C606CD56CADA7FF7771A0F41C332B4 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = D41D8CD98F00B204E9800998ECF8427E /* Project object */; + proxyType = 1; + remoteGlobalIDString = 7FE41DC3CF812C74E34FCA5182C46DCD; + remoteInfo = PureLayout; + }; + 037C447B9E4583FED14E4E492EAB8B04 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = D41D8CD98F00B204E9800998ECF8427E /* Project object */; + proxyType = 1; + remoteGlobalIDString = 7FE41DC3CF812C74E34FCA5182C46DCD; + remoteInfo = PureLayout; + }; + 25D545AF0C131B5A33DE6AC856C932C2 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = D41D8CD98F00B204E9800998ECF8427E /* Project object */; + proxyType = 1; + remoteGlobalIDString = FE84737BD4D109801238DAB5722D7DA1; + remoteInfo = PNImagePickerViewController; + }; + 6B01D766351D59ABC09AC96D739D963F /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = D41D8CD98F00B204E9800998ECF8427E /* Project object */; + proxyType = 1; + remoteGlobalIDString = 7FE41DC3CF812C74E34FCA5182C46DCD; + remoteInfo = PureLayout; + }; + 7765DEDE45993B63B9AA156E3F974450 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = D41D8CD98F00B204E9800998ECF8427E /* Project object */; + proxyType = 1; + remoteGlobalIDString = FE84737BD4D109801238DAB5722D7DA1; + remoteInfo = PNImagePickerViewController; + }; + 77E6E93D39DA113B90AF7616159755B1 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = D41D8CD98F00B204E9800998ECF8427E /* Project object */; + proxyType = 1; + remoteGlobalIDString = 21517BCEE59047E37A446CC807587934; + remoteInfo = Specta; + }; + 82B55322802EC90372810696DA7E5480 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = D41D8CD98F00B204E9800998ECF8427E /* Project object */; + proxyType = 1; + remoteGlobalIDString = D07447EE3CEBB0BCB8D61DFCB8EA915F; + remoteInfo = FBSnapshotTestCase; + }; + 83D396FFFD51E051AD4896C4BEC7C3B5 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = D41D8CD98F00B204E9800998ECF8427E /* Project object */; + proxyType = 1; + remoteGlobalIDString = 0D888F29E05E498D0CD91A51D28599A5; + remoteInfo = Expecta; + }; + C646DF0ABBA05EB1CFA2F6A24B8A9FAA /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = D41D8CD98F00B204E9800998ECF8427E /* Project object */; + proxyType = 1; + remoteGlobalIDString = 619F0D28240534293108906FED04836F; + remoteInfo = "Expecta+Snapshots"; + }; + CCF83280732A67033B72EE54815FFD3F /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = D41D8CD98F00B204E9800998ECF8427E /* Project object */; + proxyType = 1; + remoteGlobalIDString = 0D888F29E05E498D0CD91A51D28599A5; + remoteInfo = Expecta; + }; + DCF7ED085C0C4D510878736F8920D8A6 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = D41D8CD98F00B204E9800998ECF8427E /* Project object */; + proxyType = 1; + remoteGlobalIDString = 651F3556BCECD15ACE6DA3826056C550; + remoteInfo = "PNImagePickerViewController-PNImagePickerViewController"; + }; + F9BBA6CBCE0B1A136EAFACE5185B512D /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = D41D8CD98F00B204E9800998ECF8427E /* Project object */; + proxyType = 1; + remoteGlobalIDString = D07447EE3CEBB0BCB8D61DFCB8EA915F; + remoteInfo = FBSnapshotTestCase; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXFileReference section */ + 03125582C7BE5CEF86A73FA369065311 /* SwiftSupport.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SwiftSupport.swift; path = FBSnapshotTestCase/SwiftSupport.swift; sourceTree = ""; }; + 03F0E7D7379464D80A5585C3D68EF9BF /* XCTestCase+Specta.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "XCTestCase+Specta.h"; path = "Specta/Specta/XCTestCase+Specta.h"; sourceTree = ""; }; + 05543C138878FE2F76FA1482DE5F50D0 /* UIImage+Snapshot.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "UIImage+Snapshot.h"; path = "FBSnapshotTestCase/Categories/UIImage+Snapshot.h"; sourceTree = ""; }; + 0566C8B9ADE96B49FC01A2B3E52421BE /* SPTSpec.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SPTSpec.h; path = Specta/Specta/SPTSpec.h; sourceTree = ""; }; + 096309059441EB5D11744229922922D4 /* PNCollectionViewCell.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = PNCollectionViewCell.h; sourceTree = ""; }; + 099A52678B3E80735A017D133E675C0B /* Expecta+Snapshots-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Expecta+Snapshots-prefix.pch"; sourceTree = ""; }; + 0B4D563AB4E127AF0A9FBC1E231C5D43 /* NSLayoutConstraint+PureLayout.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "NSLayoutConstraint+PureLayout.h"; path = "PureLayout/PureLayout/NSLayoutConstraint+PureLayout.h"; sourceTree = ""; }; + 0BB31E11DDAAA96925A1236365EEB21F /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS9.2.sdk/System/Library/Frameworks/QuartzCore.framework; sourceTree = DEVELOPER_DIR; }; + 0CD0F5EFF1B3472519F5B4EE821A38E4 /* PureLayout.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = PureLayout.xcconfig; sourceTree = ""; }; + 0E225E66B94E712DC093C6724AD11CFD /* SpectaTypes.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SpectaTypes.h; path = Specta/Specta/SpectaTypes.h; sourceTree = ""; }; + 10782AE189DA5C3D8516751CF9C19A5E /* EXPMatchers+beCloseTo.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "EXPMatchers+beCloseTo.m"; path = "Expecta/Matchers/EXPMatchers+beCloseTo.m"; sourceTree = ""; }; + 10E1AB2290A940590A50E8D54F54A2F6 /* EXPUnsupportedObject.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = EXPUnsupportedObject.h; path = Expecta/EXPUnsupportedObject.h; sourceTree = ""; }; + 129E1C0CEC059CE5EFEA8DDBDC6BA783 /* PureLayout-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "PureLayout-prefix.pch"; sourceTree = ""; }; + 1509EB0EDB59BB6A235C075BDF27ACA5 /* EXPMatchers+beInstanceOf.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "EXPMatchers+beInstanceOf.m"; path = "Expecta/Matchers/EXPMatchers+beInstanceOf.m"; sourceTree = ""; }; + 173AC2808350B2FCFA846157AE99C71D /* FBSnapshotTestCase-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "FBSnapshotTestCase-dummy.m"; sourceTree = ""; }; + 17A1FCF90A9C0E52BA56CCF8B9DCF00C /* EXPMatchers+respondTo.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "EXPMatchers+respondTo.h"; path = "Expecta/Matchers/EXPMatchers+respondTo.h"; sourceTree = ""; }; + 19C53BEC21D8B0E161B0702E54CF7D9D /* EXPMatchers+beCloseTo.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "EXPMatchers+beCloseTo.h"; path = "Expecta/Matchers/EXPMatchers+beCloseTo.h"; sourceTree = ""; }; + 1A2536CA1A4C375065588D7CA7FFFD04 /* EXPMatchers+contain.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "EXPMatchers+contain.m"; path = "Expecta/Matchers/EXPMatchers+contain.m"; sourceTree = ""; }; + 1AA72D353A2583EA748D45A0652D40A4 /* EXPMatchers+beFalsy.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "EXPMatchers+beFalsy.h"; path = "Expecta/Matchers/EXPMatchers+beFalsy.h"; sourceTree = ""; }; + 1EBA70DC0FA8837D95B73DCC11AA764D /* Pods-PNImagePickerViewController_Tests-acknowledgements.markdown */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; path = "Pods-PNImagePickerViewController_Tests-acknowledgements.markdown"; sourceTree = ""; }; + 20327CEB6D3F13297BDAB7FE6026920E /* SPTSpec.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SPTSpec.m; path = Specta/Specta/SPTSpec.m; sourceTree = ""; }; + 214647B96EB8D7B1FA18DD92A6EA3917 /* Expecta.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = Expecta.xcconfig; sourceTree = ""; }; + 238F2FBD86752F42D840CC54A3F5A407 /* EXPMatchers+equal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "EXPMatchers+equal.h"; path = "Expecta/Matchers/EXPMatchers+equal.h"; sourceTree = ""; }; + 25BC55E750A529F4D0F46F5119E3EFB0 /* EXPMatchers+beSubclassOf.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "EXPMatchers+beSubclassOf.h"; path = "Expecta/Matchers/EXPMatchers+beSubclassOf.h"; sourceTree = ""; }; + 289E592F6B702F82121F6BAC6F5CA8AA /* EXPMatchers+haveCountOf.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "EXPMatchers+haveCountOf.m"; path = "Expecta/Matchers/EXPMatchers+haveCountOf.m"; sourceTree = ""; }; + 2BC4279D7351FD3A726A6EF02FC8ED19 /* SPTExcludeGlobalBeforeAfterEach.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SPTExcludeGlobalBeforeAfterEach.h; path = Specta/Specta/SPTExcludeGlobalBeforeAfterEach.h; sourceTree = ""; }; + 2BD49C93526619102F2D474766196B38 /* Pods-PNImagePickerViewController_Example.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-PNImagePickerViewController_Example.release.xcconfig"; sourceTree = ""; }; + 2BE45DFB6789AAEB03C87E14911811BD /* Pods-PNImagePickerViewController_Tests-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Pods-PNImagePickerViewController_Tests-umbrella.h"; sourceTree = ""; }; + 2C6E94DA05F91DF35F74319DC6F0DF33 /* Specta.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = Specta.xcconfig; sourceTree = ""; }; + 2CC7838A86697C8CC0F9C91603830498 /* Pods-PNImagePickerViewController_Example-acknowledgements.markdown */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; path = "Pods-PNImagePickerViewController_Example-acknowledgements.markdown"; sourceTree = ""; }; + 2CD52C0184F0903B7EA8B033B01717A9 /* EXPMatchers+beLessThan.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "EXPMatchers+beLessThan.h"; path = "Expecta/Matchers/EXPMatchers+beLessThan.h"; sourceTree = ""; }; + 305597218253482DD97EA53544065F82 /* Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 309AE29D56F62AA38812FCD588D97505 /* NSLayoutConstraint+PureLayout.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "NSLayoutConstraint+PureLayout.m"; path = "PureLayout/PureLayout/NSLayoutConstraint+PureLayout.m"; sourceTree = ""; }; + 313C5B73A027A335880529469217DAC0 /* EXPMatchers+endWith.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "EXPMatchers+endWith.h"; path = "Expecta/Matchers/EXPMatchers+endWith.h"; sourceTree = ""; }; + 31480E56FB4A5AF08ADA95062BFEFC89 /* EXPMatchers+beFalsy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "EXPMatchers+beFalsy.m"; path = "Expecta/Matchers/EXPMatchers+beFalsy.m"; sourceTree = ""; }; + 3251AD74FAC3B67F2A03E3F30133557D /* UIImage+Diff.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "UIImage+Diff.m"; path = "FBSnapshotTestCase/Categories/UIImage+Diff.m"; sourceTree = ""; }; + 32ECF317E9844862171B030F13E92DD9 /* PureLayout-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "PureLayout-dummy.m"; sourceTree = ""; }; + 35F1FA87897C7070C74ECF8D2CE8DAF9 /* Expecta+Snapshots-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Expecta+Snapshots-dummy.m"; sourceTree = ""; }; + 3649CB424097BF48E430598CDE474EEC /* EXPMatchers+beIdenticalTo.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "EXPMatchers+beIdenticalTo.h"; path = "Expecta/Matchers/EXPMatchers+beIdenticalTo.h"; sourceTree = ""; }; + 3858144F30FB57931C02F64C362E3B5C /* Photos.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Photos.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS9.2.sdk/System/Library/Frameworks/Photos.framework; sourceTree = DEVELOPER_DIR; }; + 3891C8C7F92D4B56E91DBC75F4091968 /* Pods-PNImagePickerViewController_Example-frameworks.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-PNImagePickerViewController_Example-frameworks.sh"; sourceTree = ""; }; + 390F5EAD0FA0ACB91D06A90A974E0A45 /* EXPMatchers+beLessThan.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "EXPMatchers+beLessThan.m"; path = "Expecta/Matchers/EXPMatchers+beLessThan.m"; sourceTree = ""; }; + 393BCCE5FB0CAEDC7193DE9EBE3A4E09 /* UIImage+Compare.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "UIImage+Compare.h"; path = "FBSnapshotTestCase/Categories/UIImage+Compare.h"; sourceTree = ""; }; + 39EF931D9991CC7A7257528EC5239C85 /* PNImagePickerViewController-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "PNImagePickerViewController-umbrella.h"; sourceTree = ""; }; + 3B5DC91278AF0B7B1C84CA0D25C7FC08 /* FBSnapshotTestCase.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = FBSnapshotTestCase.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 3B8BA7F1B66924CA150C782F5DD71763 /* FBSnapshotTestCasePlatform.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FBSnapshotTestCasePlatform.h; path = FBSnapshotTestCase/FBSnapshotTestCasePlatform.h; sourceTree = ""; }; + 3DDC2F0DB66FDE2D99014751F0C471C6 /* NSArray+PureLayout.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "NSArray+PureLayout.m"; path = "PureLayout/PureLayout/NSArray+PureLayout.m"; sourceTree = ""; }; + 3E76906C21A6360E59BAB98FB678511A /* PNImagePickerViewController.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = PNImagePickerViewController.xcconfig; sourceTree = ""; }; + 3F639A935CAD81D124435F643E505794 /* EXPMatchers+beLessThanOrEqualTo.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "EXPMatchers+beLessThanOrEqualTo.m"; path = "Expecta/Matchers/EXPMatchers+beLessThanOrEqualTo.m"; sourceTree = ""; }; + 3FB4A919E61BF9E7388E2A08D5F6D7EA /* PureLayout.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = PureLayout.h; path = PureLayout/PureLayout/PureLayout.h; sourceTree = ""; }; + 4016B648F56236C2BA14F6C65E94AFC0 /* EXPMatchers+equal.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "EXPMatchers+equal.m"; path = "Expecta/Matchers/EXPMatchers+equal.m"; sourceTree = ""; }; + 416F8ABB7F7E98CB081B7F19F9EB2F92 /* SPTTestSuite.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SPTTestSuite.h; path = Specta/Specta/SPTTestSuite.h; sourceTree = ""; }; + 430444E6E86490E2572119A37E68341B /* EXPExpect.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = EXPExpect.m; path = Expecta/EXPExpect.m; sourceTree = ""; }; + 43E396376F0A58FC93901CB23B161BC3 /* Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 44C2BCB8ADDB4424AC3426DA52A88FD0 /* EXPMatcher.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = EXPMatcher.h; path = Expecta/EXPMatcher.h; sourceTree = ""; }; + 45EBC5857C0FBA732752E48E9359EDD8 /* SpectaDSL.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SpectaDSL.h; path = Specta/Specta/SpectaDSL.h; sourceTree = ""; }; + 47C3908A5AAE0260FB6D95C74D65652D /* EXPUnsupportedObject.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = EXPUnsupportedObject.m; path = Expecta/EXPUnsupportedObject.m; sourceTree = ""; }; + 47E9000729E4BF417953FB356297ADC3 /* FBSnapshotTestCasePlatform.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FBSnapshotTestCasePlatform.m; path = FBSnapshotTestCase/FBSnapshotTestCasePlatform.m; sourceTree = ""; }; + 49B0983683A73B0A5B7A4FB352CBD58A /* UIImage+Compare.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "UIImage+Compare.m"; path = "FBSnapshotTestCase/Categories/UIImage+Compare.m"; sourceTree = ""; }; + 49EDEF02628E2CD3C475A46896250265 /* Pods-PNImagePickerViewController_Example-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Pods-PNImagePickerViewController_Example-dummy.m"; sourceTree = ""; }; + 4A4547E4EE9A69F8554ABE6EB6C8F6FA /* NSValue+Expecta.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "NSValue+Expecta.h"; path = "Expecta/NSValue+Expecta.h"; sourceTree = ""; }; + 4A483661BF65897902AB0A0CFCD975AE /* EXPMatchers+beIdenticalTo.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "EXPMatchers+beIdenticalTo.m"; path = "Expecta/Matchers/EXPMatchers+beIdenticalTo.m"; sourceTree = ""; }; + 4AE18936EDB988BC6D3A33128764D642 /* SPTCompiledExample.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SPTCompiledExample.h; path = Specta/Specta/SPTCompiledExample.h; sourceTree = ""; }; + 4B8CFE481DA04D4CD82C10A8448158D2 /* PNImagePickerViewController.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = PNImagePickerViewController.m; sourceTree = ""; }; + 4BB793EEEA2972B9A2DB5CC84E5C7FC8 /* EXPMatchers+beInstanceOf.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "EXPMatchers+beInstanceOf.h"; path = "Expecta/Matchers/EXPMatchers+beInstanceOf.h"; sourceTree = ""; }; + 4C2BA4F2B7217FDC234E2325261A2BF9 /* Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 4DBFEEB0166000625503662CDE93CDF3 /* SPTGlobalBeforeAfterEach.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SPTGlobalBeforeAfterEach.h; path = Specta/Specta/SPTGlobalBeforeAfterEach.h; sourceTree = ""; }; + 4DFBE5937DE9B4E2ADFCD9B2EBF09325 /* EXPMatchers.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = EXPMatchers.h; path = Expecta/Matchers/EXPMatchers.h; sourceTree = ""; }; + 4E902D9B8E310A8D78AFE8B074819218 /* NSString+HexColor.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "NSString+HexColor.m"; sourceTree = ""; }; + 4F719753BD46AC4A79F8FAE6B7A60BD9 /* FBSnapshotTestCase.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = FBSnapshotTestCase.xcconfig; sourceTree = ""; }; + 4F85577F3A8EFCC75870860E9CFCD164 /* SPTCompiledExample.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SPTCompiledExample.m; path = Specta/Specta/SPTCompiledExample.m; sourceTree = ""; }; + 510D07686732BBA3C4B870F02EAC7A30 /* EXPMatchers+raiseWithReason.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "EXPMatchers+raiseWithReason.h"; path = "Expecta/Matchers/EXPMatchers+raiseWithReason.h"; sourceTree = ""; }; + 52B96B599CCF1E2C6EE96048EA5880E3 /* EXPMatcherHelpers.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = EXPMatcherHelpers.m; path = Expecta/Matchers/EXPMatcherHelpers.m; sourceTree = ""; }; + 53C8060B20388BDEA288843D2FAA8749 /* FBSnapshotTestCase.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = "sourcecode.module-map"; path = FBSnapshotTestCase.modulemap; sourceTree = ""; }; + 543F7BDA4F5F79573CAA43601F700A67 /* XCTest+Private.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "XCTest+Private.h"; path = "Specta/Specta/XCTest+Private.h"; sourceTree = ""; }; + 54493E6647B30E3C5BEEFB40F581FF54 /* ALView+PureLayout.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "ALView+PureLayout.h"; path = "PureLayout/PureLayout/ALView+PureLayout.h"; sourceTree = ""; }; + 561534F9468BFFFCD27420D9028EAF1D /* Expecta+Snapshots.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Expecta+Snapshots.xcconfig"; sourceTree = ""; }; + 563BDF7C8114F5105A8038CFD0803495 /* SPTExampleGroup.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SPTExampleGroup.m; path = Specta/Specta/SPTExampleGroup.m; sourceTree = ""; }; + 567FED50899A681C87568B30C6A8DDF2 /* SpectaDSL.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SpectaDSL.m; path = Specta/Specta/SpectaDSL.m; sourceTree = ""; }; + 5723825DA3450735996AC90B937A4AEF /* EXPMatchers+conformTo.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "EXPMatchers+conformTo.m"; path = "Expecta/Matchers/EXPMatchers+conformTo.m"; sourceTree = ""; }; + 579F45E6A47205E79C183A91C534F864 /* EXPMatchers+beTruthy.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "EXPMatchers+beTruthy.h"; path = "Expecta/Matchers/EXPMatchers+beTruthy.h"; sourceTree = ""; }; + 57D04540F7B5B7AB05AC9DE49BC0B44A /* Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 58380708EFDF326D68D6060E486CB90D /* SPTTestSuite.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SPTTestSuite.m; path = Specta/Specta/SPTTestSuite.m; sourceTree = ""; }; + 5892291CEFA7A94FA402E6AA6A47B34D /* Expecta-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Expecta-prefix.pch"; sourceTree = ""; }; + 593892C8C11EDE0285489E134696F878 /* EXPFloatTuple.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = EXPFloatTuple.h; path = Expecta/EXPFloatTuple.h; sourceTree = ""; }; + 5A5036265EC2BF776D08D8ED807B8000 /* EXPMatchers+match.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "EXPMatchers+match.m"; path = "Expecta/Matchers/EXPMatchers+match.m"; sourceTree = ""; }; + 5AE13025CC5C6B218AAF479784CD9ED2 /* Expecta.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = Expecta.h; path = Expecta/Expecta.h; sourceTree = ""; }; + 5C0D2BAE8C19CA6614F3CA94783F095D /* Expecta-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Expecta-umbrella.h"; sourceTree = ""; }; + 5D2E7B136F89A8D5E8D9B527B8F5A555 /* Expecta.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Expecta.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 5F9093C7E794724D47C617BE24557A5D /* Expecta-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Expecta-dummy.m"; sourceTree = ""; }; + 61DF146816D923BA85792DC9693B94D4 /* Pods-PNImagePickerViewController_Example-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Pods-PNImagePickerViewController_Example-umbrella.h"; sourceTree = ""; }; + 6296391EB02733986480B8C3B38C1751 /* UIImage+Diff.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "UIImage+Diff.h"; path = "FBSnapshotTestCase/Categories/UIImage+Diff.h"; sourceTree = ""; }; + 63531BD7407ED90996601DCE8FCEFD55 /* ExpectaSupport.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ExpectaSupport.h; path = Expecta/ExpectaSupport.h; sourceTree = ""; }; + 659207AE2EF6E56A99A2880417729552 /* PNImagePickerViewController.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = PNImagePickerViewController.h; sourceTree = ""; }; + 65B4136A49BEA00E3874E067A148CFE2 /* EXPMatchers+haveCountOf.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "EXPMatchers+haveCountOf.h"; path = "Expecta/Matchers/EXPMatchers+haveCountOf.h"; sourceTree = ""; }; + 68FDF6EB112C4423747393766720207C /* SpectaUtility.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SpectaUtility.h; path = Specta/Specta/SpectaUtility.h; sourceTree = ""; }; + 6BF30C23B3BDD819BCFB41457392E2D9 /* PureLayoutDefines.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = PureLayoutDefines.h; path = PureLayout/PureLayout/PureLayoutDefines.h; sourceTree = ""; }; + 6D0C6649E2D25AE53519CD3D4CD09ADC /* EXPMatchers+FBSnapshotTest.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "EXPMatchers+FBSnapshotTest.h"; sourceTree = ""; }; + 6F7482216BDAA86DA901E47954D81943 /* EXPMatchers+beTruthy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "EXPMatchers+beTruthy.m"; path = "Expecta/Matchers/EXPMatchers+beTruthy.m"; sourceTree = ""; }; + 703612D1CEA30E0B8C9E02D238F7196E /* Specta-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Specta-dummy.m"; sourceTree = ""; }; + 70688D0A2ACC0A7F02D0F1235F0E8BF4 /* EXPMatchers+beInTheRangeOf.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "EXPMatchers+beInTheRangeOf.h"; path = "Expecta/Matchers/EXPMatchers+beInTheRangeOf.h"; sourceTree = ""; }; + 72F2DDEC55FD77846852BF0BF7CA2EB1 /* PNImagePickerViewController-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "PNImagePickerViewController-prefix.pch"; sourceTree = ""; }; + 749800021466D47EDC1F64E037BF45CC /* SpectaUtility.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SpectaUtility.m; path = Specta/Specta/SpectaUtility.m; sourceTree = ""; }; + 752FC542E7B313CF2DF46F9CE019D1DC /* Pods-PNImagePickerViewController_Example-resources.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-PNImagePickerViewController_Example-resources.sh"; sourceTree = ""; }; + 76148374B1A8C1EE9BF4C8D44A477428 /* FBSnapshotTestController.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FBSnapshotTestController.h; path = FBSnapshotTestCase/FBSnapshotTestController.h; sourceTree = ""; }; + 7BD87D11D30651D5EB6E5F42D4FCDFFE /* EXPMatchers+beGreaterThanOrEqualTo.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "EXPMatchers+beGreaterThanOrEqualTo.h"; path = "Expecta/Matchers/EXPMatchers+beGreaterThanOrEqualTo.h"; sourceTree = ""; }; + 80156AEEDC4D129C5C54BFFED8633BF6 /* EXPMatchers+beGreaterThan.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "EXPMatchers+beGreaterThan.m"; path = "Expecta/Matchers/EXPMatchers+beGreaterThan.m"; sourceTree = ""; }; + 80D1D2F56444ACE235744A744B9C8D67 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS9.2.sdk/System/Library/Frameworks/UIKit.framework; sourceTree = DEVELOPER_DIR; }; + 815FCECEE4FF630729054295EC5482B3 /* EXPDoubleTuple.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = EXPDoubleTuple.m; path = Expecta/EXPDoubleTuple.m; sourceTree = ""; }; + 8306A05F3FC954D6F3B4E35C4F6B2E24 /* EXPMatchers+beginWith.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "EXPMatchers+beginWith.h"; path = "Expecta/Matchers/EXPMatchers+beginWith.h"; sourceTree = ""; }; + 87DC71BCE9F88907D4CA9EA6C6D4CD3A /* NSObject+Expecta.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "NSObject+Expecta.h"; path = "Expecta/NSObject+Expecta.h"; sourceTree = ""; }; + 88B5C933CDFBD78AAD0546A4AF52B9D5 /* EXPMatchers+beSupersetOf.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "EXPMatchers+beSupersetOf.m"; path = "Expecta/Matchers/EXPMatchers+beSupersetOf.m"; sourceTree = ""; }; + 88BD5BA29761B79241CFE6925C3ABA4B /* Pods-PNImagePickerViewController_Tests.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = "sourcecode.module-map"; path = "Pods-PNImagePickerViewController_Tests.modulemap"; sourceTree = ""; }; + 89B4983E65DB1A8DD67F7A9D82A5CBBE /* ExpectaObject+FBSnapshotTest.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "ExpectaObject+FBSnapshotTest.m"; sourceTree = ""; }; + 8AAA1981FD0C38B91AE527BE960EE881 /* SPTExample.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SPTExample.h; path = Specta/Specta/SPTExample.h; sourceTree = ""; }; + 8B977762C348A6EDA1883600F1DCFE58 /* FBSnapshotTestCase.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FBSnapshotTestCase.m; path = FBSnapshotTestCase/FBSnapshotTestCase.m; sourceTree = ""; }; + 8CADF593C95BE01C0B91DBC2C8884939 /* Specta.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = "sourcecode.module-map"; path = Specta.modulemap; sourceTree = ""; }; + 8E64F0B58141D2A8C5B35D8B7E1D76E0 /* ALView+PureLayout.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "ALView+PureLayout.m"; path = "PureLayout/PureLayout/ALView+PureLayout.m"; sourceTree = ""; }; + 8EBE0B34BA8C3C5428B651C33628FFEC /* UIImage+Snapshot.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "UIImage+Snapshot.m"; path = "FBSnapshotTestCase/Categories/UIImage+Snapshot.m"; sourceTree = ""; }; + 8F82F3F7B94F183AEC45FD4AD8E6187C /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS9.2.sdk/System/Library/Frameworks/Foundation.framework; sourceTree = DEVELOPER_DIR; }; + 901657B874B99B4D8BAC6029F1239819 /* FBSnapshotTestCase.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = FBSnapshotTestCase.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 90A24E859872FBF4996DB8FF2C72D641 /* PureLayout+Internal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "PureLayout+Internal.h"; path = "PureLayout/PureLayout/PureLayout+Internal.h"; sourceTree = ""; }; + 9106954FD71A00CE85BF2799C2328977 /* EXPMatchers+beInTheRangeOf.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "EXPMatchers+beInTheRangeOf.m"; path = "Expecta/Matchers/EXPMatchers+beInTheRangeOf.m"; sourceTree = ""; }; + 91F059E3298F34C1DD6BD93980CD997D /* FBSnapshotTestCase-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "FBSnapshotTestCase-prefix.pch"; sourceTree = ""; }; + 93BEE7CACAD612FBBE99E8998D378EA4 /* Pods-PNImagePickerViewController_Example.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-PNImagePickerViewController_Example.debug.xcconfig"; sourceTree = ""; }; + 957CBE35D3FC82EDC76EDF33D58CC14A /* SPTSharedExampleGroups.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SPTSharedExampleGroups.h; path = Specta/Specta/SPTSharedExampleGroups.h; sourceTree = ""; }; + 96722169F2EE7FD1D3A8A151F68B4997 /* EXPMatchers+raise.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "EXPMatchers+raise.m"; path = "Expecta/Matchers/EXPMatchers+raise.m"; sourceTree = ""; }; + 9BE9B9F15F1FC0C7BDDA5C9ED0AF220F /* PNImagePickerViewController.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = PNImagePickerViewController.bundle; sourceTree = BUILT_PRODUCTS_DIR; }; + 9CE6DF46652A13B55C1A75A6C5257818 /* NSString+HexColor.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "NSString+HexColor.h"; sourceTree = ""; }; + 9EDA6325E8E3E42FBA74C8D748457683 /* PureLayout.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = PureLayout.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 9FB8B39DAF075037CE45C64C5EC44A54 /* Pods-PNImagePickerViewController_Tests-resources.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-PNImagePickerViewController_Tests-resources.sh"; sourceTree = ""; }; + A2B5894FEB35480FC1B773A4D38D14DF /* Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + A3238F2F8580E2D38D5628A33F934CFA /* FBSnapshotTestController.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FBSnapshotTestController.m; path = FBSnapshotTestCase/FBSnapshotTestController.m; sourceTree = ""; }; + A6922487AB8095FA4A248866B59E44EB /* SPTCallSite.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SPTCallSite.h; path = Specta/Specta/SPTCallSite.h; sourceTree = ""; }; + A823928D76472F638E2F3C697450BDB5 /* Expecta_Snapshots.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Expecta_Snapshots.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + AA01D298630B12AA0970C55ADF492FE2 /* Specta-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Specta-umbrella.h"; sourceTree = ""; }; + AA07840C0EE1A07210D7D9A95B28E2D6 /* Expecta+Snapshots.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = "sourcecode.module-map"; path = "Expecta+Snapshots.modulemap"; sourceTree = ""; }; + AA101E016C76302C06F4575172FDC9DE /* EXPBlockDefinedMatcher.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = EXPBlockDefinedMatcher.h; path = Expecta/EXPBlockDefinedMatcher.h; sourceTree = ""; }; + AA729BBF9CB238789CCA63E476AEA5CE /* EXPMatcherHelpers.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = EXPMatcherHelpers.h; path = Expecta/Matchers/EXPMatcherHelpers.h; sourceTree = ""; }; + AA7B81ED73344E500125187115387A8F /* EXPMatchers+match.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "EXPMatchers+match.h"; path = "Expecta/Matchers/EXPMatchers+match.h"; sourceTree = ""; }; + AADBF70B3B9D2D9143BFF2AC688B29D1 /* SPTExample.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SPTExample.m; path = Specta/Specta/SPTExample.m; sourceTree = ""; }; + AC25E36ECB984C6D46E07D449F8E6AD3 /* EXPMatchers+FBSnapshotTest.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "EXPMatchers+FBSnapshotTest.m"; sourceTree = ""; }; + ACEB5B1D16C37F59E5D415018626CCA1 /* Pods-PNImagePickerViewController_Tests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-PNImagePickerViewController_Tests.debug.xcconfig"; sourceTree = ""; }; + AD498EF1F11DF000A23462687DB4F486 /* EXPMatchers+raise.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "EXPMatchers+raise.h"; path = "Expecta/Matchers/EXPMatchers+raise.h"; sourceTree = ""; }; + AF42AAF54B5A41D37200E11671FFA6E8 /* EXPMatchers+beNil.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "EXPMatchers+beNil.h"; path = "Expecta/Matchers/EXPMatchers+beNil.h"; sourceTree = ""; }; + AF51448F8D892B8D7E10576612FBA77A /* ExpectaObject.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ExpectaObject.h; path = Expecta/ExpectaObject.h; sourceTree = ""; }; + AF5617EDFECDB96475E8797AE4B46329 /* Specta.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Specta.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + B14A4098A520661746E764122D3AFC5A /* Pods-PNImagePickerViewController_Example.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = "sourcecode.module-map"; path = "Pods-PNImagePickerViewController_Example.modulemap"; sourceTree = ""; }; + B19A9279E73679D3F9F1DFAEA13E347C /* SPTExampleGroup.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SPTExampleGroup.h; path = Specta/Specta/SPTExampleGroup.h; sourceTree = ""; }; + B3E4CD3EBCF888648A5FDAC1B196AF58 /* Expecta+Snapshots-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Expecta+Snapshots-umbrella.h"; sourceTree = ""; }; + B73FA83187F6E3585C08B5C189A6F033 /* EXPDefines.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = EXPDefines.h; path = Expecta/EXPDefines.h; sourceTree = ""; }; + BA6428E9F66FD5A23C0A2E06ED26CD2F /* Podfile */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = Podfile; path = ../Podfile; sourceTree = SOURCE_ROOT; xcLanguageSpecificationIdentifier = xcode.lang.ruby; }; + BB4F841C6A0CF76946BB788A161240EA /* EXPMatchers+beKindOf.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "EXPMatchers+beKindOf.h"; path = "Expecta/Matchers/EXPMatchers+beKindOf.h"; sourceTree = ""; }; + BC4E6D745DD948298DA344813F4F67D4 /* PureLayout-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "PureLayout-umbrella.h"; sourceTree = ""; }; + BE3F27961738F25BC58F8322179B8364 /* PNCollectionViewCell.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = PNCollectionViewCell.m; sourceTree = ""; }; + C12D30394F19452C8D319BD3A8525FBE /* PNImagePickerViewController.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = PNImagePickerViewController.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + C1EF7A5D7462BAA91E23F816C1B96180 /* EXPMatchers+beKindOf.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "EXPMatchers+beKindOf.m"; path = "Expecta/Matchers/EXPMatchers+beKindOf.m"; sourceTree = ""; }; + C3F02F121BD9AAA950DEC5C89D564638 /* FBSnapshotTestCase.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FBSnapshotTestCase.h; path = FBSnapshotTestCase/FBSnapshotTestCase.h; sourceTree = ""; }; + C3F40FED1E15AC795397B1F66824BC1E /* ResourceBundle-PNImagePickerViewController-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "ResourceBundle-PNImagePickerViewController-Info.plist"; sourceTree = ""; }; + C3F844297B8662ADF09537912FAC73ED /* EXPMatchers+beSupersetOf.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "EXPMatchers+beSupersetOf.h"; path = "Expecta/Matchers/EXPMatchers+beSupersetOf.h"; sourceTree = ""; }; + C42C93ADD945A4372635BD32CAD3C814 /* ExpectaObject.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = ExpectaObject.m; path = Expecta/ExpectaObject.m; sourceTree = ""; }; + C58ECDACD8D2FD15B5D6F0D6276B0700 /* Specta.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = Specta.h; path = Specta/Specta/Specta.h; sourceTree = ""; }; + C67A01B644DD8AC9FAB6D7E50DCB62FF /* Specta-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Specta-prefix.pch"; sourceTree = ""; }; + C6E39DC4C4570C3FCD7D5264E2865BAB /* Pods-PNImagePickerViewController_Tests-acknowledgements.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-PNImagePickerViewController_Tests-acknowledgements.plist"; sourceTree = ""; }; + C71086A693BC5E296E2F30B405EEC247 /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS9.2.sdk/System/Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; }; + C764B935846E8C662CCF7906D8A555DA /* EXPMatchers+respondTo.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "EXPMatchers+respondTo.m"; path = "Expecta/Matchers/EXPMatchers+respondTo.m"; sourceTree = ""; }; + CA9637AFF7146F0DA6D5F4D8A13DFECA /* PNImagePickerViewController-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "PNImagePickerViewController-dummy.m"; sourceTree = ""; }; + CB278C4D8E22AB0B2386C27A5DC84F44 /* EXPMatchers+endWith.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "EXPMatchers+endWith.m"; path = "Expecta/Matchers/EXPMatchers+endWith.m"; sourceTree = ""; }; + CC4EC6D3BB6C4AAB71B02968CCEB66EA /* XCTestCase+Specta.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "XCTestCase+Specta.m"; path = "Specta/Specta/XCTestCase+Specta.m"; sourceTree = ""; }; + CE7DBAFD56D35A84CC36342276EA5A27 /* EXPMatchers+conformTo.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "EXPMatchers+conformTo.h"; path = "Expecta/Matchers/EXPMatchers+conformTo.h"; sourceTree = ""; }; + CE96BE4D508513697B2AE8807F0073AE /* Pods-PNImagePickerViewController_Example-acknowledgements.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-PNImagePickerViewController_Example-acknowledgements.plist"; sourceTree = ""; }; + D26170D9FFE0101C1DC15C07C5AC2494 /* Pods_PNImagePickerViewController_Tests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_PNImagePickerViewController_Tests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + D32A0E3BF4F5096301528945D03203B2 /* EXPMatchers+beNil.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "EXPMatchers+beNil.m"; path = "Expecta/Matchers/EXPMatchers+beNil.m"; sourceTree = ""; }; + D379A5C7BC685C47EB0D3A2731BB215D /* PNImagePickerViewController.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = "sourcecode.module-map"; path = PNImagePickerViewController.modulemap; sourceTree = ""; }; + D45CEC3FA189AD45AE0D5D65F0096A2E /* Pods-PNImagePickerViewController_Tests-frameworks.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-PNImagePickerViewController_Tests-frameworks.sh"; sourceTree = ""; }; + D4DBA040A9E2814F4869DD7B7B7E4F98 /* Expecta.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Expecta.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + D78F728DA45B9D043472FCF4315E60C7 /* Pods-PNImagePickerViewController_Tests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-PNImagePickerViewController_Tests.release.xcconfig"; sourceTree = ""; }; + D7B03B244D464496A92ACED43DA0DE3D /* ExpectaSupport.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = ExpectaSupport.m; path = Expecta/ExpectaSupport.m; sourceTree = ""; }; + DC7DF335401532E474FB05944C1ED485 /* EXPMatchers+beGreaterThan.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "EXPMatchers+beGreaterThan.h"; path = "Expecta/Matchers/EXPMatchers+beGreaterThan.h"; sourceTree = ""; }; + DD4E5110B5ED80C99A3F9576C46C4672 /* NSValue+Expecta.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "NSValue+Expecta.m"; path = "Expecta/NSValue+Expecta.m"; sourceTree = ""; }; + DD8F605551C2300C9C46FB3364564F6D /* EXPMatchers+postNotification.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "EXPMatchers+postNotification.h"; path = "Expecta/Matchers/EXPMatchers+postNotification.h"; sourceTree = ""; }; + DDE582482FAF1CEB39F0B9126CC59D6D /* ExpectaObject+FBSnapshotTest.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "ExpectaObject+FBSnapshotTest.h"; sourceTree = ""; }; + DEEE8F25AEEDB29355650590026262C0 /* EXPFloatTuple.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = EXPFloatTuple.m; path = Expecta/EXPFloatTuple.m; sourceTree = ""; }; + E172DFC29EE8C2A36AEC06644DCCA25D /* SPTSharedExampleGroups.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SPTSharedExampleGroups.m; path = Specta/Specta/SPTSharedExampleGroups.m; sourceTree = ""; }; + E3CB665E7978D3A27C3461E4A59F8AA2 /* PureLayout.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = "sourcecode.module-map"; path = PureLayout.modulemap; sourceTree = ""; }; + E6E6D4534F1730616FF47535F95B2D36 /* Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + E6F5F421366F1062F96C25902DB7BFD2 /* PureLayout.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = PureLayout.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + E8D774152B4DC4C8DD12BEACA9AC7949 /* Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + ECF097833A853FF056370CCA06DA4831 /* EXPMatchers+beSubclassOf.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "EXPMatchers+beSubclassOf.m"; path = "Expecta/Matchers/EXPMatchers+beSubclassOf.m"; sourceTree = ""; }; + EF3299BF94C0392FCBAA98D2E58CB10E /* EXPMatchers+contain.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "EXPMatchers+contain.h"; path = "Expecta/Matchers/EXPMatchers+contain.h"; sourceTree = ""; }; + F0BE4B0FD430ED5364A83BE6EFAB44E3 /* EXPMatchers+beLessThanOrEqualTo.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "EXPMatchers+beLessThanOrEqualTo.h"; path = "Expecta/Matchers/EXPMatchers+beLessThanOrEqualTo.h"; sourceTree = ""; }; + F2326EBC2CEBEDD1AC39E41341CE4A96 /* SPTCallSite.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SPTCallSite.m; path = Specta/Specta/SPTCallSite.m; sourceTree = ""; }; + F3844FAB6104C0385AC09C2DC5801A0C /* Pods_PNImagePickerViewController_Example.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_PNImagePickerViewController_Example.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + F42F0DA116857769307897100F7DA2CA /* NSArray+PureLayout.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "NSArray+PureLayout.h"; path = "PureLayout/PureLayout/NSArray+PureLayout.h"; sourceTree = ""; }; + F65C9454F6F8DB1D7E3FFDE17F54D58C /* EXPMatchers+beGreaterThanOrEqualTo.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "EXPMatchers+beGreaterThanOrEqualTo.m"; path = "Expecta/Matchers/EXPMatchers+beGreaterThanOrEqualTo.m"; sourceTree = ""; }; + F6EB583A0E0B95BC98422547435C1DB8 /* EXPBlockDefinedMatcher.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = EXPBlockDefinedMatcher.m; path = Expecta/EXPBlockDefinedMatcher.m; sourceTree = ""; }; + F890E1326443FD6C451595F103347DE3 /* Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + FA9AA960F05653C47EB2662A7E0E3796 /* EXPMatchers+beginWith.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "EXPMatchers+beginWith.m"; path = "Expecta/Matchers/EXPMatchers+beginWith.m"; sourceTree = ""; }; + FAD450F231B69F75615E743CE1ED2B4C /* EXPMatchers+postNotification.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "EXPMatchers+postNotification.m"; path = "Expecta/Matchers/EXPMatchers+postNotification.m"; sourceTree = ""; }; + FB37123DB4D2486C30EA392F17BF7505 /* EXPDoubleTuple.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = EXPDoubleTuple.h; path = Expecta/EXPDoubleTuple.h; sourceTree = ""; }; + FB445B211C424686C720B085874E2EF7 /* EXPMatchers+raiseWithReason.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "EXPMatchers+raiseWithReason.m"; path = "Expecta/Matchers/EXPMatchers+raiseWithReason.m"; sourceTree = ""; }; + FB6EF84A0C4781A668F2F6F76CE56AC4 /* PhotosUI.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = PhotosUI.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS9.2.sdk/System/Library/Frameworks/PhotosUI.framework; sourceTree = DEVELOPER_DIR; }; + FE1A6C6BC96129C4BD3805467E03F49C /* Pods-PNImagePickerViewController_Tests-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Pods-PNImagePickerViewController_Tests-dummy.m"; sourceTree = ""; }; + FEB36DA91AA655F244A3A65C2737019B /* Expecta.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = "sourcecode.module-map"; path = Expecta.modulemap; sourceTree = ""; }; + FF49B4C3C61836DE302F437C919A7A05 /* EXPExpect.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = EXPExpect.h; path = Expecta/EXPExpect.h; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 41131740B636263BD1EEEC1AE48A5FE5 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + B0879F635160F10BB9A8820E97A6ABEA /* Foundation.framework in Frameworks */, + 2E1FAA5E50BC174E7356BEAC15993B77 /* Photos.framework in Frameworks */, + C46E9249E3A217379AFDEF4E1B1D6D8E /* PhotosUI.framework in Frameworks */, + 6361270EB2EFD4CE80ABB4D9D726BDD1 /* PureLayout.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 5FD40AFC02C709F6ED4D9F0C06326705 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + F78C02E1874FB6F2664E8C242CC13663 /* Foundation.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 77C8DC8D8019C7EDE5CC25054CEDA12D /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 914A3FA7C160948DE0A308FB745E7380 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 5CF7526D330A734F7ABCDCFF3D1A9B35 /* Foundation.framework in Frameworks */, + FCDC9C0B871F82CB1AEE73303F9A2927 /* QuartzCore.framework in Frameworks */, + 5056E0520959CBC31CCB037B59BFC847 /* UIKit.framework in Frameworks */, + FA839F20BC13A260E089D374CAAB584E /* XCTest.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + C3F694A7A9B57150F692CCC6CF809986 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 4AE1F0FA07542E17D534D443E55BB63E /* Foundation.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + C8A41C7CCA6F30278B15F814DC7A8314 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 75D32A41CF8027A97FD575048AFC035C /* Foundation.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + CAA11A0174C8A3D794A30E4E29C61B85 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + A1B0E811BF9898CBA7B29B546070BC5E /* Foundation.framework in Frameworks */, + CC6B5A8198B55F9EFB60F446F2FD9BBC /* XCTest.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + CFF5B7915B7C4A2828E27F2C89B1769C /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 3D48EE131B6577ED73A5CC481A6FE40C /* Expecta.framework in Frameworks */, + 2549CD1370AF63009DEC76693F5E9BD1 /* FBSnapshotTestCase.framework in Frameworks */, + 715A1122272BB3A29A10AAE4C8C03913 /* Foundation.framework in Frameworks */, + D181FA8D3863D4294F5CD912DBEDA7C2 /* XCTest.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + E6B836B352B13C63D3C0FA0E500C98A4 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + E4EC16570D46F25B3BD2830D65C06AE5 /* Foundation.framework in Frameworks */, + F1867C99D4A92FC191093E4901E463B5 /* XCTest.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 01B7874DB1C39E2441E993D3FF792FA3 /* Pods */ = { + isa = PBXGroup; + children = ( + 9FA8BF66C6BE1C7120E1E47AD378C8C6 /* Expecta */, + 7D81D7EEC312BCAFD21F876E09579B84 /* Expecta+Snapshots */, + D6FBCAC8CB6DB5C7D390A634584D202A /* FBSnapshotTestCase */, + 235FB682F838C6842792EF01A4DB7606 /* PureLayout */, + E2A7D3FA8FED9DAF6BC709B458B46525 /* Specta */, + ); + name = Pods; + sourceTree = ""; + }; + 0820FB7D050FF74CA4B083F2DD0331B2 /* Support Files */ = { + isa = PBXGroup; + children = ( + E8D774152B4DC4C8DD12BEACA9AC7949 /* Info.plist */, + D379A5C7BC685C47EB0D3A2731BB215D /* PNImagePickerViewController.modulemap */, + 3E76906C21A6360E59BAB98FB678511A /* PNImagePickerViewController.xcconfig */, + CA9637AFF7146F0DA6D5F4D8A13DFECA /* PNImagePickerViewController-dummy.m */, + 72F2DDEC55FD77846852BF0BF7CA2EB1 /* PNImagePickerViewController-prefix.pch */, + 39EF931D9991CC7A7257528EC5239C85 /* PNImagePickerViewController-umbrella.h */, + C3F40FED1E15AC795397B1F66824BC1E /* ResourceBundle-PNImagePickerViewController-Info.plist */, + ); + name = "Support Files"; + path = "Example/Pods/Target Support Files/PNImagePickerViewController"; + sourceTree = ""; + }; + 0E11A4D50A782231FDB626A90E455E8D /* Pods-PNImagePickerViewController_Tests */ = { + isa = PBXGroup; + children = ( + 57D04540F7B5B7AB05AC9DE49BC0B44A /* Info.plist */, + 88BD5BA29761B79241CFE6925C3ABA4B /* Pods-PNImagePickerViewController_Tests.modulemap */, + 1EBA70DC0FA8837D95B73DCC11AA764D /* Pods-PNImagePickerViewController_Tests-acknowledgements.markdown */, + C6E39DC4C4570C3FCD7D5264E2865BAB /* Pods-PNImagePickerViewController_Tests-acknowledgements.plist */, + FE1A6C6BC96129C4BD3805467E03F49C /* Pods-PNImagePickerViewController_Tests-dummy.m */, + D45CEC3FA189AD45AE0D5D65F0096A2E /* Pods-PNImagePickerViewController_Tests-frameworks.sh */, + 9FB8B39DAF075037CE45C64C5EC44A54 /* Pods-PNImagePickerViewController_Tests-resources.sh */, + 2BE45DFB6789AAEB03C87E14911811BD /* Pods-PNImagePickerViewController_Tests-umbrella.h */, + ACEB5B1D16C37F59E5D415018626CCA1 /* Pods-PNImagePickerViewController_Tests.debug.xcconfig */, + D78F728DA45B9D043472FCF4315E60C7 /* Pods-PNImagePickerViewController_Tests.release.xcconfig */, + ); + name = "Pods-PNImagePickerViewController_Tests"; + path = "Target Support Files/Pods-PNImagePickerViewController_Tests"; + sourceTree = ""; + }; + 235FB682F838C6842792EF01A4DB7606 /* PureLayout */ = { + isa = PBXGroup; + children = ( + 54493E6647B30E3C5BEEFB40F581FF54 /* ALView+PureLayout.h */, + 8E64F0B58141D2A8C5B35D8B7E1D76E0 /* ALView+PureLayout.m */, + F42F0DA116857769307897100F7DA2CA /* NSArray+PureLayout.h */, + 3DDC2F0DB66FDE2D99014751F0C471C6 /* NSArray+PureLayout.m */, + 0B4D563AB4E127AF0A9FBC1E231C5D43 /* NSLayoutConstraint+PureLayout.h */, + 309AE29D56F62AA38812FCD588D97505 /* NSLayoutConstraint+PureLayout.m */, + 3FB4A919E61BF9E7388E2A08D5F6D7EA /* PureLayout.h */, + 90A24E859872FBF4996DB8FF2C72D641 /* PureLayout+Internal.h */, + 6BF30C23B3BDD819BCFB41457392E2D9 /* PureLayoutDefines.h */, + 3EB72DEC4DAC99AC8BD863243952158A /* Support Files */, + ); + path = PureLayout; + sourceTree = ""; + }; + 31B1351B9842557D1F7BCA12FA7686F2 /* Targets Support Files */ = { + isa = PBXGroup; + children = ( + 741C4B37F1FEC3F7A4248C7481FEB5D8 /* Pods-PNImagePickerViewController_Example */, + 0E11A4D50A782231FDB626A90E455E8D /* Pods-PNImagePickerViewController_Tests */, + ); + name = "Targets Support Files"; + sourceTree = ""; + }; + 394FF4AF0BB7FD76522D0F47CE397B2B /* Pod */ = { + isa = PBXGroup; + children = ( + 6394BC67FAEF06AFF50E9B62D71269AC /* Classes */, + ); + path = Pod; + sourceTree = ""; + }; + 3D46073AFEBEAB728714C657DAC9D3F4 /* Colors */ = { + isa = PBXGroup; + children = ( + 9CE6DF46652A13B55C1A75A6C5257818 /* NSString+HexColor.h */, + 4E902D9B8E310A8D78AFE8B074819218 /* NSString+HexColor.m */, + ); + path = Colors; + sourceTree = ""; + }; + 3EB72DEC4DAC99AC8BD863243952158A /* Support Files */ = { + isa = PBXGroup; + children = ( + F890E1326443FD6C451595F103347DE3 /* Info.plist */, + E3CB665E7978D3A27C3461E4A59F8AA2 /* PureLayout.modulemap */, + 0CD0F5EFF1B3472519F5B4EE821A38E4 /* PureLayout.xcconfig */, + 32ECF317E9844862171B030F13E92DD9 /* PureLayout-dummy.m */, + 129E1C0CEC059CE5EFEA8DDBDC6BA783 /* PureLayout-prefix.pch */, + BC4E6D745DD948298DA344813F4F67D4 /* PureLayout-umbrella.h */, + ); + name = "Support Files"; + path = "../Target Support Files/PureLayout"; + sourceTree = ""; + }; + 4621F714C66A3C941F99C7EFD8ED3D70 /* iOS */ = { + isa = PBXGroup; + children = ( + 8F82F3F7B94F183AEC45FD4AD8E6187C /* Foundation.framework */, + 3858144F30FB57931C02F64C362E3B5C /* Photos.framework */, + FB6EF84A0C4781A668F2F6F76CE56AC4 /* PhotosUI.framework */, + 0BB31E11DDAAA96925A1236365EEB21F /* QuartzCore.framework */, + 80D1D2F56444ACE235744A744B9C8D67 /* UIKit.framework */, + C71086A693BC5E296E2F30B405EEC247 /* XCTest.framework */, + ); + name = iOS; + sourceTree = ""; + }; + 6394BC67FAEF06AFF50E9B62D71269AC /* Classes */ = { + isa = PBXGroup; + children = ( + 096309059441EB5D11744229922922D4 /* PNCollectionViewCell.h */, + BE3F27961738F25BC58F8322179B8364 /* PNCollectionViewCell.m */, + 659207AE2EF6E56A99A2880417729552 /* PNImagePickerViewController.h */, + 4B8CFE481DA04D4CD82C10A8448158D2 /* PNImagePickerViewController.m */, + 3D46073AFEBEAB728714C657DAC9D3F4 /* Colors */, + ); + path = Classes; + sourceTree = ""; + }; + 7310AB29AEC4B95181B6E62AA0D4BB60 /* PNImagePickerViewController */ = { + isa = PBXGroup; + children = ( + 394FF4AF0BB7FD76522D0F47CE397B2B /* Pod */, + 0820FB7D050FF74CA4B083F2DD0331B2 /* Support Files */, + ); + name = PNImagePickerViewController; + path = ../..; + sourceTree = ""; + }; + 741C4B37F1FEC3F7A4248C7481FEB5D8 /* Pods-PNImagePickerViewController_Example */ = { + isa = PBXGroup; + children = ( + 4C2BA4F2B7217FDC234E2325261A2BF9 /* Info.plist */, + B14A4098A520661746E764122D3AFC5A /* Pods-PNImagePickerViewController_Example.modulemap */, + 2CC7838A86697C8CC0F9C91603830498 /* Pods-PNImagePickerViewController_Example-acknowledgements.markdown */, + CE96BE4D508513697B2AE8807F0073AE /* Pods-PNImagePickerViewController_Example-acknowledgements.plist */, + 49EDEF02628E2CD3C475A46896250265 /* Pods-PNImagePickerViewController_Example-dummy.m */, + 3891C8C7F92D4B56E91DBC75F4091968 /* Pods-PNImagePickerViewController_Example-frameworks.sh */, + 752FC542E7B313CF2DF46F9CE019D1DC /* Pods-PNImagePickerViewController_Example-resources.sh */, + 61DF146816D923BA85792DC9693B94D4 /* Pods-PNImagePickerViewController_Example-umbrella.h */, + 93BEE7CACAD612FBBE99E8998D378EA4 /* Pods-PNImagePickerViewController_Example.debug.xcconfig */, + 2BD49C93526619102F2D474766196B38 /* Pods-PNImagePickerViewController_Example.release.xcconfig */, + ); + name = "Pods-PNImagePickerViewController_Example"; + path = "Target Support Files/Pods-PNImagePickerViewController_Example"; + sourceTree = ""; + }; + 7D81D7EEC312BCAFD21F876E09579B84 /* Expecta+Snapshots */ = { + isa = PBXGroup; + children = ( + DDE582482FAF1CEB39F0B9126CC59D6D /* ExpectaObject+FBSnapshotTest.h */, + 89B4983E65DB1A8DD67F7A9D82A5CBBE /* ExpectaObject+FBSnapshotTest.m */, + 6D0C6649E2D25AE53519CD3D4CD09ADC /* EXPMatchers+FBSnapshotTest.h */, + AC25E36ECB984C6D46E07D449F8E6AD3 /* EXPMatchers+FBSnapshotTest.m */, + 89798485B53447DE77BDD20C695E90B5 /* Support Files */, + ); + path = "Expecta+Snapshots"; + sourceTree = ""; + }; + 7DB346D0F39D3F0E887471402A8071AB = { + isa = PBXGroup; + children = ( + BA6428E9F66FD5A23C0A2E06ED26CD2F /* Podfile */, + CB2BEA235224960B8B8E37CF10D3BF61 /* Development Pods */, + D8D11877A57F64660DAA2F4F2A976132 /* Frameworks */, + 01B7874DB1C39E2441E993D3FF792FA3 /* Pods */, + 97B9907A03FDAC9EF3A5FDB0B78A27E5 /* Products */, + 31B1351B9842557D1F7BCA12FA7686F2 /* Targets Support Files */, + ); + sourceTree = ""; + }; + 83740C9D7B90CA3BE24F881C3D85F5FE /* Support Files */ = { + isa = PBXGroup; + children = ( + FEB36DA91AA655F244A3A65C2737019B /* Expecta.modulemap */, + 214647B96EB8D7B1FA18DD92A6EA3917 /* Expecta.xcconfig */, + 5F9093C7E794724D47C617BE24557A5D /* Expecta-dummy.m */, + 5892291CEFA7A94FA402E6AA6A47B34D /* Expecta-prefix.pch */, + 5C0D2BAE8C19CA6614F3CA94783F095D /* Expecta-umbrella.h */, + 305597218253482DD97EA53544065F82 /* Info.plist */, + ); + name = "Support Files"; + path = "../Target Support Files/Expecta"; + sourceTree = ""; + }; + 89798485B53447DE77BDD20C695E90B5 /* Support Files */ = { + isa = PBXGroup; + children = ( + AA07840C0EE1A07210D7D9A95B28E2D6 /* Expecta+Snapshots.modulemap */, + 561534F9468BFFFCD27420D9028EAF1D /* Expecta+Snapshots.xcconfig */, + 35F1FA87897C7070C74ECF8D2CE8DAF9 /* Expecta+Snapshots-dummy.m */, + 099A52678B3E80735A017D133E675C0B /* Expecta+Snapshots-prefix.pch */, + B3E4CD3EBCF888648A5FDAC1B196AF58 /* Expecta+Snapshots-umbrella.h */, + A2B5894FEB35480FC1B773A4D38D14DF /* Info.plist */, + ); + name = "Support Files"; + path = "../Target Support Files/Expecta+Snapshots"; + sourceTree = ""; + }; + 97B9907A03FDAC9EF3A5FDB0B78A27E5 /* Products */ = { + isa = PBXGroup; + children = ( + 5D2E7B136F89A8D5E8D9B527B8F5A555 /* Expecta.framework */, + A823928D76472F638E2F3C697450BDB5 /* Expecta_Snapshots.framework */, + 3B5DC91278AF0B7B1C84CA0D25C7FC08 /* FBSnapshotTestCase.framework */, + 9BE9B9F15F1FC0C7BDDA5C9ED0AF220F /* PNImagePickerViewController.bundle */, + C12D30394F19452C8D319BD3A8525FBE /* PNImagePickerViewController.framework */, + F3844FAB6104C0385AC09C2DC5801A0C /* Pods_PNImagePickerViewController_Example.framework */, + D26170D9FFE0101C1DC15C07C5AC2494 /* Pods_PNImagePickerViewController_Tests.framework */, + 9EDA6325E8E3E42FBA74C8D748457683 /* PureLayout.framework */, + AF5617EDFECDB96475E8797AE4B46329 /* Specta.framework */, + ); + name = Products; + sourceTree = ""; + }; + 9FA8BF66C6BE1C7120E1E47AD378C8C6 /* Expecta */ = { + isa = PBXGroup; + children = ( + AA101E016C76302C06F4575172FDC9DE /* EXPBlockDefinedMatcher.h */, + F6EB583A0E0B95BC98422547435C1DB8 /* EXPBlockDefinedMatcher.m */, + B73FA83187F6E3585C08B5C189A6F033 /* EXPDefines.h */, + FB37123DB4D2486C30EA392F17BF7505 /* EXPDoubleTuple.h */, + 815FCECEE4FF630729054295EC5482B3 /* EXPDoubleTuple.m */, + 5AE13025CC5C6B218AAF479784CD9ED2 /* Expecta.h */, + AF51448F8D892B8D7E10576612FBA77A /* ExpectaObject.h */, + C42C93ADD945A4372635BD32CAD3C814 /* ExpectaObject.m */, + 63531BD7407ED90996601DCE8FCEFD55 /* ExpectaSupport.h */, + D7B03B244D464496A92ACED43DA0DE3D /* ExpectaSupport.m */, + FF49B4C3C61836DE302F437C919A7A05 /* EXPExpect.h */, + 430444E6E86490E2572119A37E68341B /* EXPExpect.m */, + 593892C8C11EDE0285489E134696F878 /* EXPFloatTuple.h */, + DEEE8F25AEEDB29355650590026262C0 /* EXPFloatTuple.m */, + 44C2BCB8ADDB4424AC3426DA52A88FD0 /* EXPMatcher.h */, + AA729BBF9CB238789CCA63E476AEA5CE /* EXPMatcherHelpers.h */, + 52B96B599CCF1E2C6EE96048EA5880E3 /* EXPMatcherHelpers.m */, + 4DFBE5937DE9B4E2ADFCD9B2EBF09325 /* EXPMatchers.h */, + 19C53BEC21D8B0E161B0702E54CF7D9D /* EXPMatchers+beCloseTo.h */, + 10782AE189DA5C3D8516751CF9C19A5E /* EXPMatchers+beCloseTo.m */, + 1AA72D353A2583EA748D45A0652D40A4 /* EXPMatchers+beFalsy.h */, + 31480E56FB4A5AF08ADA95062BFEFC89 /* EXPMatchers+beFalsy.m */, + 8306A05F3FC954D6F3B4E35C4F6B2E24 /* EXPMatchers+beginWith.h */, + FA9AA960F05653C47EB2662A7E0E3796 /* EXPMatchers+beginWith.m */, + DC7DF335401532E474FB05944C1ED485 /* EXPMatchers+beGreaterThan.h */, + 80156AEEDC4D129C5C54BFFED8633BF6 /* EXPMatchers+beGreaterThan.m */, + 7BD87D11D30651D5EB6E5F42D4FCDFFE /* EXPMatchers+beGreaterThanOrEqualTo.h */, + F65C9454F6F8DB1D7E3FFDE17F54D58C /* EXPMatchers+beGreaterThanOrEqualTo.m */, + 3649CB424097BF48E430598CDE474EEC /* EXPMatchers+beIdenticalTo.h */, + 4A483661BF65897902AB0A0CFCD975AE /* EXPMatchers+beIdenticalTo.m */, + 4BB793EEEA2972B9A2DB5CC84E5C7FC8 /* EXPMatchers+beInstanceOf.h */, + 1509EB0EDB59BB6A235C075BDF27ACA5 /* EXPMatchers+beInstanceOf.m */, + 70688D0A2ACC0A7F02D0F1235F0E8BF4 /* EXPMatchers+beInTheRangeOf.h */, + 9106954FD71A00CE85BF2799C2328977 /* EXPMatchers+beInTheRangeOf.m */, + BB4F841C6A0CF76946BB788A161240EA /* EXPMatchers+beKindOf.h */, + C1EF7A5D7462BAA91E23F816C1B96180 /* EXPMatchers+beKindOf.m */, + 2CD52C0184F0903B7EA8B033B01717A9 /* EXPMatchers+beLessThan.h */, + 390F5EAD0FA0ACB91D06A90A974E0A45 /* EXPMatchers+beLessThan.m */, + F0BE4B0FD430ED5364A83BE6EFAB44E3 /* EXPMatchers+beLessThanOrEqualTo.h */, + 3F639A935CAD81D124435F643E505794 /* EXPMatchers+beLessThanOrEqualTo.m */, + AF42AAF54B5A41D37200E11671FFA6E8 /* EXPMatchers+beNil.h */, + D32A0E3BF4F5096301528945D03203B2 /* EXPMatchers+beNil.m */, + 25BC55E750A529F4D0F46F5119E3EFB0 /* EXPMatchers+beSubclassOf.h */, + ECF097833A853FF056370CCA06DA4831 /* EXPMatchers+beSubclassOf.m */, + C3F844297B8662ADF09537912FAC73ED /* EXPMatchers+beSupersetOf.h */, + 88B5C933CDFBD78AAD0546A4AF52B9D5 /* EXPMatchers+beSupersetOf.m */, + 579F45E6A47205E79C183A91C534F864 /* EXPMatchers+beTruthy.h */, + 6F7482216BDAA86DA901E47954D81943 /* EXPMatchers+beTruthy.m */, + CE7DBAFD56D35A84CC36342276EA5A27 /* EXPMatchers+conformTo.h */, + 5723825DA3450735996AC90B937A4AEF /* EXPMatchers+conformTo.m */, + EF3299BF94C0392FCBAA98D2E58CB10E /* EXPMatchers+contain.h */, + 1A2536CA1A4C375065588D7CA7FFFD04 /* EXPMatchers+contain.m */, + 313C5B73A027A335880529469217DAC0 /* EXPMatchers+endWith.h */, + CB278C4D8E22AB0B2386C27A5DC84F44 /* EXPMatchers+endWith.m */, + 238F2FBD86752F42D840CC54A3F5A407 /* EXPMatchers+equal.h */, + 4016B648F56236C2BA14F6C65E94AFC0 /* EXPMatchers+equal.m */, + 65B4136A49BEA00E3874E067A148CFE2 /* EXPMatchers+haveCountOf.h */, + 289E592F6B702F82121F6BAC6F5CA8AA /* EXPMatchers+haveCountOf.m */, + AA7B81ED73344E500125187115387A8F /* EXPMatchers+match.h */, + 5A5036265EC2BF776D08D8ED807B8000 /* EXPMatchers+match.m */, + DD8F605551C2300C9C46FB3364564F6D /* EXPMatchers+postNotification.h */, + FAD450F231B69F75615E743CE1ED2B4C /* EXPMatchers+postNotification.m */, + AD498EF1F11DF000A23462687DB4F486 /* EXPMatchers+raise.h */, + 96722169F2EE7FD1D3A8A151F68B4997 /* EXPMatchers+raise.m */, + 510D07686732BBA3C4B870F02EAC7A30 /* EXPMatchers+raiseWithReason.h */, + FB445B211C424686C720B085874E2EF7 /* EXPMatchers+raiseWithReason.m */, + 17A1FCF90A9C0E52BA56CCF8B9DCF00C /* EXPMatchers+respondTo.h */, + C764B935846E8C662CCF7906D8A555DA /* EXPMatchers+respondTo.m */, + 10E1AB2290A940590A50E8D54F54A2F6 /* EXPUnsupportedObject.h */, + 47C3908A5AAE0260FB6D95C74D65652D /* EXPUnsupportedObject.m */, + 87DC71BCE9F88907D4CA9EA6C6D4CD3A /* NSObject+Expecta.h */, + 4A4547E4EE9A69F8554ABE6EB6C8F6FA /* NSValue+Expecta.h */, + DD4E5110B5ED80C99A3F9576C46C4672 /* NSValue+Expecta.m */, + 83740C9D7B90CA3BE24F881C3D85F5FE /* Support Files */, + ); + path = Expecta; + sourceTree = ""; + }; + B2B52F67A43F3D9C4612A0F17F4F2B8D /* SwiftSupport */ = { + isa = PBXGroup; + children = ( + 03125582C7BE5CEF86A73FA369065311 /* SwiftSupport.swift */, + ); + name = SwiftSupport; + sourceTree = ""; + }; + CB2BEA235224960B8B8E37CF10D3BF61 /* Development Pods */ = { + isa = PBXGroup; + children = ( + 7310AB29AEC4B95181B6E62AA0D4BB60 /* PNImagePickerViewController */, + ); + name = "Development Pods"; + sourceTree = ""; + }; + D0370DE86B87E489F9AF431610178DD3 /* Support Files */ = { + isa = PBXGroup; + children = ( + 43E396376F0A58FC93901CB23B161BC3 /* Info.plist */, + 8CADF593C95BE01C0B91DBC2C8884939 /* Specta.modulemap */, + 2C6E94DA05F91DF35F74319DC6F0DF33 /* Specta.xcconfig */, + 703612D1CEA30E0B8C9E02D238F7196E /* Specta-dummy.m */, + C67A01B644DD8AC9FAB6D7E50DCB62FF /* Specta-prefix.pch */, + AA01D298630B12AA0970C55ADF492FE2 /* Specta-umbrella.h */, + ); + name = "Support Files"; + path = "../Target Support Files/Specta"; + sourceTree = ""; + }; + D6FBCAC8CB6DB5C7D390A634584D202A /* FBSnapshotTestCase */ = { + isa = PBXGroup; + children = ( + FD92B3AD787566F87818EB869C872F59 /* Core */, + FDA4458458FFF781EABF8F25A06B490E /* Support Files */, + B2B52F67A43F3D9C4612A0F17F4F2B8D /* SwiftSupport */, + ); + path = FBSnapshotTestCase; + sourceTree = ""; + }; + D8D11877A57F64660DAA2F4F2A976132 /* Frameworks */ = { + isa = PBXGroup; + children = ( + D4DBA040A9E2814F4869DD7B7B7E4F98 /* Expecta.framework */, + 901657B874B99B4D8BAC6029F1239819 /* FBSnapshotTestCase.framework */, + E6F5F421366F1062F96C25902DB7BFD2 /* PureLayout.framework */, + 4621F714C66A3C941F99C7EFD8ED3D70 /* iOS */, + ); + name = Frameworks; + sourceTree = ""; + }; + E2A7D3FA8FED9DAF6BC709B458B46525 /* Specta */ = { + isa = PBXGroup; + children = ( + C58ECDACD8D2FD15B5D6F0D6276B0700 /* Specta.h */, + 45EBC5857C0FBA732752E48E9359EDD8 /* SpectaDSL.h */, + 567FED50899A681C87568B30C6A8DDF2 /* SpectaDSL.m */, + 0E225E66B94E712DC093C6724AD11CFD /* SpectaTypes.h */, + 68FDF6EB112C4423747393766720207C /* SpectaUtility.h */, + 749800021466D47EDC1F64E037BF45CC /* SpectaUtility.m */, + A6922487AB8095FA4A248866B59E44EB /* SPTCallSite.h */, + F2326EBC2CEBEDD1AC39E41341CE4A96 /* SPTCallSite.m */, + 4AE18936EDB988BC6D3A33128764D642 /* SPTCompiledExample.h */, + 4F85577F3A8EFCC75870860E9CFCD164 /* SPTCompiledExample.m */, + 8AAA1981FD0C38B91AE527BE960EE881 /* SPTExample.h */, + AADBF70B3B9D2D9143BFF2AC688B29D1 /* SPTExample.m */, + B19A9279E73679D3F9F1DFAEA13E347C /* SPTExampleGroup.h */, + 563BDF7C8114F5105A8038CFD0803495 /* SPTExampleGroup.m */, + 2BC4279D7351FD3A726A6EF02FC8ED19 /* SPTExcludeGlobalBeforeAfterEach.h */, + 4DBFEEB0166000625503662CDE93CDF3 /* SPTGlobalBeforeAfterEach.h */, + 957CBE35D3FC82EDC76EDF33D58CC14A /* SPTSharedExampleGroups.h */, + E172DFC29EE8C2A36AEC06644DCCA25D /* SPTSharedExampleGroups.m */, + 0566C8B9ADE96B49FC01A2B3E52421BE /* SPTSpec.h */, + 20327CEB6D3F13297BDAB7FE6026920E /* SPTSpec.m */, + 416F8ABB7F7E98CB081B7F19F9EB2F92 /* SPTTestSuite.h */, + 58380708EFDF326D68D6060E486CB90D /* SPTTestSuite.m */, + 543F7BDA4F5F79573CAA43601F700A67 /* XCTest+Private.h */, + 03F0E7D7379464D80A5585C3D68EF9BF /* XCTestCase+Specta.h */, + CC4EC6D3BB6C4AAB71B02968CCEB66EA /* XCTestCase+Specta.m */, + D0370DE86B87E489F9AF431610178DD3 /* Support Files */, + ); + path = Specta; + sourceTree = ""; + }; + FD92B3AD787566F87818EB869C872F59 /* Core */ = { + isa = PBXGroup; + children = ( + C3F02F121BD9AAA950DEC5C89D564638 /* FBSnapshotTestCase.h */, + 8B977762C348A6EDA1883600F1DCFE58 /* FBSnapshotTestCase.m */, + 3B8BA7F1B66924CA150C782F5DD71763 /* FBSnapshotTestCasePlatform.h */, + 47E9000729E4BF417953FB356297ADC3 /* FBSnapshotTestCasePlatform.m */, + 76148374B1A8C1EE9BF4C8D44A477428 /* FBSnapshotTestController.h */, + A3238F2F8580E2D38D5628A33F934CFA /* FBSnapshotTestController.m */, + 393BCCE5FB0CAEDC7193DE9EBE3A4E09 /* UIImage+Compare.h */, + 49B0983683A73B0A5B7A4FB352CBD58A /* UIImage+Compare.m */, + 6296391EB02733986480B8C3B38C1751 /* UIImage+Diff.h */, + 3251AD74FAC3B67F2A03E3F30133557D /* UIImage+Diff.m */, + 05543C138878FE2F76FA1482DE5F50D0 /* UIImage+Snapshot.h */, + 8EBE0B34BA8C3C5428B651C33628FFEC /* UIImage+Snapshot.m */, + ); + name = Core; + sourceTree = ""; + }; + FDA4458458FFF781EABF8F25A06B490E /* Support Files */ = { + isa = PBXGroup; + children = ( + 53C8060B20388BDEA288843D2FAA8749 /* FBSnapshotTestCase.modulemap */, + 4F719753BD46AC4A79F8FAE6B7A60BD9 /* FBSnapshotTestCase.xcconfig */, + 173AC2808350B2FCFA846157AE99C71D /* FBSnapshotTestCase-dummy.m */, + 91F059E3298F34C1DD6BD93980CD997D /* FBSnapshotTestCase-prefix.pch */, + E6E6D4534F1730616FF47535F95B2D36 /* Info.plist */, + ); + name = "Support Files"; + path = "../Target Support Files/FBSnapshotTestCase"; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXHeadersBuildPhase section */ + 13245866A0FA9CFE52EB0E322C80A93A /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 1F0DDAD8051AFDC85E1C7CE42CEFE024 /* Pods-PNImagePickerViewController_Example-umbrella.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 27BDB612E6600F7141DAAA402A902000 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + E4A96998069826E71AC9408A8D53B772 /* NSString+HexColor.h in Headers */, + BD6235346E7F7116E42D25320126EA98 /* PNCollectionViewCell.h in Headers */, + 79E61152676FBAF9799E4F1DCA969CF2 /* PNImagePickerViewController-umbrella.h in Headers */, + 2FF07674284F10FF5382D0AEAB764FB0 /* PNImagePickerViewController.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 8FB01615761213E34DCCB4C6D1ACDF95 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 774FE3A849D9CEA65AB50972674CE4C6 /* Pods-PNImagePickerViewController_Tests-umbrella.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 966427BD32145AD621F074D1691342B8 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 3B5B7495707BF7133B9FB3F834045611 /* EXPBlockDefinedMatcher.h in Headers */, + 5EA7043FE10E75D02F3C3052AF8B8318 /* EXPDefines.h in Headers */, + 2F427490ACABC4408D57CC0592276678 /* EXPDoubleTuple.h in Headers */, + 837B593D7C1D01B4EA400247309D6AB0 /* Expecta-umbrella.h in Headers */, + E1EC4532663CA75DE5BD00CB0A56814D /* Expecta.h in Headers */, + 2E14619153A453BB8DF389FB6EA147BE /* ExpectaObject.h in Headers */, + AFFC8900E52BBEC72059334132F3A8F3 /* ExpectaSupport.h in Headers */, + 67459AD239EF669A365519E06B45DCFE /* EXPExpect.h in Headers */, + 6E1D978790705E137FDE439AA68DD3AA /* EXPFloatTuple.h in Headers */, + 65BC31095CCDFC80CBF6BBA843751F23 /* EXPMatcher.h in Headers */, + 8C8C1B0D83FE6A4352F15154DB16372C /* EXPMatcherHelpers.h in Headers */, + AF1F46668D4591602887998C6E9C10AD /* EXPMatchers+beCloseTo.h in Headers */, + F41209A94070904A00BDF24ACB6336B6 /* EXPMatchers+beFalsy.h in Headers */, + FD2D4497BC41412128C2D87C1BDE7398 /* EXPMatchers+beginWith.h in Headers */, + 6EFC63A5CED45BB39FC79D87F2C47D6B /* EXPMatchers+beGreaterThan.h in Headers */, + 372F7A9CCE59CE86316CF436F832A3FC /* EXPMatchers+beGreaterThanOrEqualTo.h in Headers */, + E0AAF49134A0505DF00E20E7B62087E1 /* EXPMatchers+beIdenticalTo.h in Headers */, + 34B6E9A30603BEBBD87BA535B7D384CA /* EXPMatchers+beInstanceOf.h in Headers */, + 131532787AD40BE1F35DF288D2E6FFD7 /* EXPMatchers+beInTheRangeOf.h in Headers */, + 79558B1F97ABE4AB8942DC18BEBD4B82 /* EXPMatchers+beKindOf.h in Headers */, + 0D16B556212D317A0D4FEB71E102E207 /* EXPMatchers+beLessThan.h in Headers */, + 37A2D0F8493469EF2495FC689440F079 /* EXPMatchers+beLessThanOrEqualTo.h in Headers */, + E735386085CE344F6A01178CF4763852 /* EXPMatchers+beNil.h in Headers */, + 397B320B7C59C168CC5B62E18ED8DEA0 /* EXPMatchers+beSubclassOf.h in Headers */, + 76CCABE79C04444450153424D7CE1DC1 /* EXPMatchers+beSupersetOf.h in Headers */, + 85EB2F216487CB2E8F3FCCFBC4D69912 /* EXPMatchers+beTruthy.h in Headers */, + F0DDF02A078B917997FF025BB33BB842 /* EXPMatchers+conformTo.h in Headers */, + 3C2700C7DAA15C6AF84A595865C42F4D /* EXPMatchers+contain.h in Headers */, + 1A1AB2EC52323C5EA28DAA99F1E1A90D /* EXPMatchers+endWith.h in Headers */, + 0F94F5B0ABB3252B9275B7C129EC7A26 /* EXPMatchers+equal.h in Headers */, + F75CB2A727F678C9A848A3A11EA7979B /* EXPMatchers+haveCountOf.h in Headers */, + 2916A0606136A9DC67F2463AB230868B /* EXPMatchers+match.h in Headers */, + 9B2E761A064459F77EA9870BEF03ACC3 /* EXPMatchers+postNotification.h in Headers */, + 46137F5CC368BF38BAF0D0AF81DD8FFE /* EXPMatchers+raise.h in Headers */, + 11C1AEB289C1EB80089349B71F09D04B /* EXPMatchers+raiseWithReason.h in Headers */, + 260BC7EED9289AF321A6F791964CE472 /* EXPMatchers+respondTo.h in Headers */, + 85E31076D5530AEEB45ACF16B2B8A983 /* EXPMatchers.h in Headers */, + 51DDDB0FB4899757CF6A826B531B940D /* EXPUnsupportedObject.h in Headers */, + 7B223B4E6EF14BA12DA113F7EE10B96C /* NSObject+Expecta.h in Headers */, + 471FD4F68E27AB26FA2AEBB8B245CEE4 /* NSValue+Expecta.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + BA0FDF67467F294ACFEF3C734E0A426A /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 29F2AEAF2B01E3739BF745ADE8E9D0A4 /* Expecta+Snapshots-umbrella.h in Headers */, + 39F3AFD4DADD9BF4AEDFAF1FEA82B2F2 /* ExpectaObject+FBSnapshotTest.h in Headers */, + EA840679AC9463E0E3D371FCC3466B0A /* EXPMatchers+FBSnapshotTest.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + BF90EF59A85943F6A27FA9DD5E78D3F5 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 1303C5017F898BD7F98DB1BD1AFFAB49 /* Specta-umbrella.h in Headers */, + 278432744E184DE2FAAC997F0455021F /* Specta.h in Headers */, + 5BF1E1FBAE24D8B3CA47C9FC381296DF /* SpectaDSL.h in Headers */, + C733E814C226F0AA7C6C7915E6FA3D90 /* SpectaTypes.h in Headers */, + AB6685722275C4592751D73600321350 /* SpectaUtility.h in Headers */, + 55BF89A8370D6D6E6971AC4F0D7B86FD /* SPTCallSite.h in Headers */, + 47DE038D397A1D8D169BEA7C24549EF4 /* SPTCompiledExample.h in Headers */, + 48A3244684540E73970769D236CE8793 /* SPTExample.h in Headers */, + FAD264330709B586D2D5B17B4A7040C3 /* SPTExampleGroup.h in Headers */, + 29923C8237C2521B7761DFBA1176AEF6 /* SPTExcludeGlobalBeforeAfterEach.h in Headers */, + 3F5AFB158433D800A9AE61CB744054B0 /* SPTGlobalBeforeAfterEach.h in Headers */, + 202982C27067054C061304D6A53C9830 /* SPTSharedExampleGroups.h in Headers */, + 2AE7AC04A02ABF5575E481C2AC56BAA4 /* SPTSpec.h in Headers */, + A4AC67807A52576C168C0606BC9C783A /* SPTTestSuite.h in Headers */, + 0C1DCD965236FA97FD51175704561126 /* XCTest+Private.h in Headers */, + E0E4B1728B841A7E77AB9FF263F0502B /* XCTestCase+Specta.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + DD3ACD9DEA6F25AD1E2CF659A4B11E53 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 8D1A5F519C1BBBEEE77F66B515FC3D66 /* ALView+PureLayout.h in Headers */, + 2374C44ACA9EB74301CC387D2C99587D /* NSArray+PureLayout.h in Headers */, + A3372B44BC67F60CE578D36F6BA3530A /* NSLayoutConstraint+PureLayout.h in Headers */, + F14F53742FD27FA7A2C5CF692E801898 /* PureLayout+Internal.h in Headers */, + 89BAEBD7FF6D270EECD5AA2EBAAD22E5 /* PureLayout-umbrella.h in Headers */, + A4ABC102CBD31F39E80EFEA4AB7A738E /* PureLayout.h in Headers */, + 1993857B26D7AFE6B3C888986768FDE2 /* PureLayoutDefines.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + F4CD5DD853B84CC2D8644CF4FED35F1E /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 20C0CFB6F8C29123D1667E2676D8B2F5 /* FBSnapshotTestCase.h in Headers */, + D1E9E55D21C92E33ACE7E911BCB96269 /* FBSnapshotTestCasePlatform.h in Headers */, + F58F9BC7759BB8A5007B8821A275AEDD /* FBSnapshotTestController.h in Headers */, + E10811B5E4578C31FB675361C99EDED6 /* UIImage+Compare.h in Headers */, + 274D9545D0357B667BCAA82B3FB38ECD /* UIImage+Diff.h in Headers */, + CE91E0B7C2BF362403CB3A75E69AA061 /* UIImage+Snapshot.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXHeadersBuildPhase section */ + +/* Begin PBXNativeTarget section */ + 0D888F29E05E498D0CD91A51D28599A5 /* Expecta */ = { + isa = PBXNativeTarget; + buildConfigurationList = DC61702A42844E4ED762A73E8893436B /* Build configuration list for PBXNativeTarget "Expecta" */; + buildPhases = ( + B239BD93C67DE976C7F3A1AD982A0A58 /* Sources */, + E6B836B352B13C63D3C0FA0E500C98A4 /* Frameworks */, + 966427BD32145AD621F074D1691342B8 /* Headers */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = Expecta; + productName = Expecta; + productReference = 5D2E7B136F89A8D5E8D9B527B8F5A555 /* Expecta.framework */; + productType = "com.apple.product-type.framework"; + }; + 21517BCEE59047E37A446CC807587934 /* Specta */ = { + isa = PBXNativeTarget; + buildConfigurationList = FE7B905FF421B939093E504FA8416FB9 /* Build configuration list for PBXNativeTarget "Specta" */; + buildPhases = ( + 1B0F6F0F0C88825E02A0941AB887630B /* Sources */, + CAA11A0174C8A3D794A30E4E29C61B85 /* Frameworks */, + BF90EF59A85943F6A27FA9DD5E78D3F5 /* Headers */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = Specta; + productName = Specta; + productReference = AF5617EDFECDB96475E8797AE4B46329 /* Specta.framework */; + productType = "com.apple.product-type.framework"; + }; + 23D340B60A4AFAC4F736A98B95130BA2 /* Pods-PNImagePickerViewController_Tests */ = { + isa = PBXNativeTarget; + buildConfigurationList = A965CE36E5BBB9F4B7E10CE04497D68D /* Build configuration list for PBXNativeTarget "Pods-PNImagePickerViewController_Tests" */; + buildPhases = ( + E59B738A7006C1A1BC0981F33DD3C8C0 /* Sources */, + C3F694A7A9B57150F692CCC6CF809986 /* Frameworks */, + 8FB01615761213E34DCCB4C6D1ACDF95 /* Headers */, + ); + buildRules = ( + ); + dependencies = ( + 3E8666E8062830CA7E6B80029BEBF570 /* PBXTargetDependency */, + 63CE6196F06F78C762EE65F715CC0C25 /* PBXTargetDependency */, + B4DAF485093F85F17C8F9D6D86DF1151 /* PBXTargetDependency */, + 6B0210962967B76806B28BA4C7E656F8 /* PBXTargetDependency */, + 89233824D34D1468C7237A7B776D6115 /* PBXTargetDependency */, + F2719D6C52BBE801E57042E39AB858C6 /* PBXTargetDependency */, + ); + name = "Pods-PNImagePickerViewController_Tests"; + productName = "Pods-PNImagePickerViewController_Tests"; + productReference = D26170D9FFE0101C1DC15C07C5AC2494 /* Pods_PNImagePickerViewController_Tests.framework */; + productType = "com.apple.product-type.framework"; + }; + 619F0D28240534293108906FED04836F /* Expecta+Snapshots */ = { + isa = PBXNativeTarget; + buildConfigurationList = D5B74CC207A82790DE2A82F49EDF170A /* Build configuration list for PBXNativeTarget "Expecta+Snapshots" */; + buildPhases = ( + 796C061AD650C052C9339513DE83940A /* Sources */, + CFF5B7915B7C4A2828E27F2C89B1769C /* Frameworks */, + BA0FDF67467F294ACFEF3C734E0A426A /* Headers */, + ); + buildRules = ( + ); + dependencies = ( + 4ACA793EC27274D41A670C74CD739365 /* PBXTargetDependency */, + CFC3C60C0541C54818441E331A7E8753 /* PBXTargetDependency */, + ); + name = "Expecta+Snapshots"; + productName = "Expecta+Snapshots"; + productReference = A823928D76472F638E2F3C697450BDB5 /* Expecta_Snapshots.framework */; + productType = "com.apple.product-type.framework"; + }; + 651F3556BCECD15ACE6DA3826056C550 /* PNImagePickerViewController-PNImagePickerViewController */ = { + isa = PBXNativeTarget; + buildConfigurationList = 76F91EF3CC28EF7FFE902CF383943B85 /* Build configuration list for PBXNativeTarget "PNImagePickerViewController-PNImagePickerViewController" */; + buildPhases = ( + 4F7BBF6DD9541399E0E16254CC057F55 /* Sources */, + 77C8DC8D8019C7EDE5CC25054CEDA12D /* Frameworks */, + E349C217F28CFD7A4A7FCA0377537BC0 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "PNImagePickerViewController-PNImagePickerViewController"; + productName = "PNImagePickerViewController-PNImagePickerViewController"; + productReference = 9BE9B9F15F1FC0C7BDDA5C9ED0AF220F /* PNImagePickerViewController.bundle */; + productType = "com.apple.product-type.bundle"; + }; + 71DE9043E58C58DEF5414CD6AB84A3DE /* Pods-PNImagePickerViewController_Example */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1F383D29DD374DAB98FA28FE6DB19F4F /* Build configuration list for PBXNativeTarget "Pods-PNImagePickerViewController_Example" */; + buildPhases = ( + DAED09FC3F32E1180B41F527BF45E706 /* Sources */, + C8A41C7CCA6F30278B15F814DC7A8314 /* Frameworks */, + 13245866A0FA9CFE52EB0E322C80A93A /* Headers */, + ); + buildRules = ( + ); + dependencies = ( + 8A9FD2D30D0F80D6677CF6162621C223 /* PBXTargetDependency */, + FF4D44CDD59FE7D4D5FBC665DB46D8D6 /* PBXTargetDependency */, + ); + name = "Pods-PNImagePickerViewController_Example"; + productName = "Pods-PNImagePickerViewController_Example"; + productReference = F3844FAB6104C0385AC09C2DC5801A0C /* Pods_PNImagePickerViewController_Example.framework */; + productType = "com.apple.product-type.framework"; + }; + 7FE41DC3CF812C74E34FCA5182C46DCD /* PureLayout */ = { + isa = PBXNativeTarget; + buildConfigurationList = 28EF1888BB5588EC5A14D296BD25A457 /* Build configuration list for PBXNativeTarget "PureLayout" */; + buildPhases = ( + 2BEC50F9C1AC55856DE563DB0714AAE1 /* Sources */, + 5FD40AFC02C709F6ED4D9F0C06326705 /* Frameworks */, + DD3ACD9DEA6F25AD1E2CF659A4B11E53 /* Headers */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = PureLayout; + productName = PureLayout; + productReference = 9EDA6325E8E3E42FBA74C8D748457683 /* PureLayout.framework */; + productType = "com.apple.product-type.framework"; + }; + D07447EE3CEBB0BCB8D61DFCB8EA915F /* FBSnapshotTestCase */ = { + isa = PBXNativeTarget; + buildConfigurationList = 7C7B4BE8DC7E24A96243E4D67565D719 /* Build configuration list for PBXNativeTarget "FBSnapshotTestCase" */; + buildPhases = ( + 050B9690E875D70369E073EC11B52256 /* Sources */, + 914A3FA7C160948DE0A308FB745E7380 /* Frameworks */, + F4CD5DD853B84CC2D8644CF4FED35F1E /* Headers */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = FBSnapshotTestCase; + productName = FBSnapshotTestCase; + productReference = 3B5DC91278AF0B7B1C84CA0D25C7FC08 /* FBSnapshotTestCase.framework */; + productType = "com.apple.product-type.framework"; + }; + FE84737BD4D109801238DAB5722D7DA1 /* PNImagePickerViewController */ = { + isa = PBXNativeTarget; + buildConfigurationList = 6D67EE9FBEA41A7642E41234789E9570 /* Build configuration list for PBXNativeTarget "PNImagePickerViewController" */; + buildPhases = ( + 3B9B29F0D9320D540483047106D73899 /* Sources */, + 41131740B636263BD1EEEC1AE48A5FE5 /* Frameworks */, + 3CB61D7EBF265A002BFDAD298AE786C4 /* Resources */, + 27BDB612E6600F7141DAAA402A902000 /* Headers */, + ); + buildRules = ( + ); + dependencies = ( + 63E8130BC0840C7A0839A25F4D03FFF8 /* PBXTargetDependency */, + 8F8779D84E871A6CCECBC6FE4E649C59 /* PBXTargetDependency */, + ); + name = PNImagePickerViewController; + productName = PNImagePickerViewController; + productReference = C12D30394F19452C8D319BD3A8525FBE /* PNImagePickerViewController.framework */; + productType = "com.apple.product-type.framework"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + D41D8CD98F00B204E9800998ECF8427E /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 0720; + LastUpgradeCheck = 0700; + }; + buildConfigurationList = 2D8E8EC45A3A1A1D94AE762CB5028504 /* Build configuration list for PBXProject "Pods" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + ); + mainGroup = 7DB346D0F39D3F0E887471402A8071AB; + productRefGroup = 97B9907A03FDAC9EF3A5FDB0B78A27E5 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 0D888F29E05E498D0CD91A51D28599A5 /* Expecta */, + 619F0D28240534293108906FED04836F /* Expecta+Snapshots */, + D07447EE3CEBB0BCB8D61DFCB8EA915F /* FBSnapshotTestCase */, + FE84737BD4D109801238DAB5722D7DA1 /* PNImagePickerViewController */, + 651F3556BCECD15ACE6DA3826056C550 /* PNImagePickerViewController-PNImagePickerViewController */, + 71DE9043E58C58DEF5414CD6AB84A3DE /* Pods-PNImagePickerViewController_Example */, + 23D340B60A4AFAC4F736A98B95130BA2 /* Pods-PNImagePickerViewController_Tests */, + 7FE41DC3CF812C74E34FCA5182C46DCD /* PureLayout */, + 21517BCEE59047E37A446CC807587934 /* Specta */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 3CB61D7EBF265A002BFDAD298AE786C4 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 346833B09DCB096D7E23EF1DF3AA37A3 /* PNImagePickerViewController.bundle in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + E349C217F28CFD7A4A7FCA0377537BC0 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 050B9690E875D70369E073EC11B52256 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + C6E9B0A908F410317F2DBBECA0944AAB /* FBSnapshotTestCase-dummy.m in Sources */, + 70E4BCC789D8C8F1033F23E0752502A7 /* FBSnapshotTestCase.m in Sources */, + E3C61206BEDBA3EBAA0A69B51DE0F3AA /* FBSnapshotTestCasePlatform.m in Sources */, + 7861523B9D5DFCF0F4A56E4DE3296AA2 /* FBSnapshotTestController.m in Sources */, + 0A5DFD94EE83E385C1C7D24986E04592 /* SwiftSupport.swift in Sources */, + 07CAFACAFAC87ABBF28D453E70832464 /* UIImage+Compare.m in Sources */, + 89A46B63E469F17791D14FC64466794A /* UIImage+Diff.m in Sources */, + 4052EB66107F09D6F856EAA1F4FC0846 /* UIImage+Snapshot.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 1B0F6F0F0C88825E02A0941AB887630B /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 184CCD5A7C9B2FDBD13FB45D3D3B99FD /* Specta-dummy.m in Sources */, + F16445694BAA1C8B9B1D639DD27D05EC /* SpectaDSL.m in Sources */, + 35D17528C41E69D04EF227502A8EC77B /* SpectaUtility.m in Sources */, + 13E6BEF790F8746E9BA8849BFAB94E3F /* SPTCallSite.m in Sources */, + C200BCDC767A422FD3C9709B1BEA37E7 /* SPTCompiledExample.m in Sources */, + 8BAA5A5F568886A0D333718CE7B2C3DB /* SPTExample.m in Sources */, + 2F48F56D90BA2AF519FDB5966BF7288F /* SPTExampleGroup.m in Sources */, + 453097252D8DA15ED33554933CDDBD06 /* SPTSharedExampleGroups.m in Sources */, + 378AB5D15998CBD19ABD7E01BED7B391 /* SPTSpec.m in Sources */, + 1AAC27517D2E1C6AC73AE3B609AF359C /* SPTTestSuite.m in Sources */, + 264D55B73E4BE829EFD707ADED9655EB /* XCTestCase+Specta.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 2BEC50F9C1AC55856DE563DB0714AAE1 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 7C16E367C0BD248774049989B329FEE6 /* ALView+PureLayout.m in Sources */, + B7489960D6579E861620D733D15BE2C1 /* NSArray+PureLayout.m in Sources */, + BB5DD166C1EB3ECED5BB3CFD5524E2F5 /* NSLayoutConstraint+PureLayout.m in Sources */, + 2A7748A0699C2B1BE8ABEA9CFED631FC /* PureLayout-dummy.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 3B9B29F0D9320D540483047106D73899 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 16CB96DE4260C29B5932E729435BD2AD /* NSString+HexColor.m in Sources */, + 0690251E14FB6236B8C0F921AC475FB6 /* PNCollectionViewCell.m in Sources */, + 70967F6B7BDAE8BCBBC039DF9984015C /* PNImagePickerViewController-dummy.m in Sources */, + DA5D8E9EC82544ADAF4A5119C7C4F693 /* PNImagePickerViewController.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 4F7BBF6DD9541399E0E16254CC057F55 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 796C061AD650C052C9339513DE83940A /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 772BFB9529121111C517FBA06EA26237 /* Expecta+Snapshots-dummy.m in Sources */, + 4B5542E72A64100965FFFA704684CED4 /* ExpectaObject+FBSnapshotTest.m in Sources */, + 47D16DB1D23CFE027F5BE7F7E391AB4C /* EXPMatchers+FBSnapshotTest.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + B239BD93C67DE976C7F3A1AD982A0A58 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 5B2D4A621D3DA971A474776AF36BB073 /* EXPBlockDefinedMatcher.m in Sources */, + BC55C8365AEFF8217F6A567607754854 /* EXPDoubleTuple.m in Sources */, + 204D694B03BFF3B244A6AB73FACFFC43 /* Expecta-dummy.m in Sources */, + 94C47C87E397972CE98F75929F3B706C /* ExpectaObject.m in Sources */, + 4BBCBB9D8EF0B241A4A4FE4982985481 /* ExpectaSupport.m in Sources */, + 805E425BBEF7A6133E32E1D30A073010 /* EXPExpect.m in Sources */, + CE3F4ECBB0BC095577D66AE50C8E604C /* EXPFloatTuple.m in Sources */, + 201BF9C605852822CA5A65ADE282A310 /* EXPMatcherHelpers.m in Sources */, + BA12B131F10BCE3BE6E9A02FC908FE9D /* EXPMatchers+beCloseTo.m in Sources */, + 17572374B2AE183C6347C41E8DF8E579 /* EXPMatchers+beFalsy.m in Sources */, + F12D57414A73406831CC032A7170DBFF /* EXPMatchers+beginWith.m in Sources */, + 1312A7D381C51428CF481E33E3D37901 /* EXPMatchers+beGreaterThan.m in Sources */, + 1B0389CD88AA949B34DC7269030FEC6F /* EXPMatchers+beGreaterThanOrEqualTo.m in Sources */, + 66A27898E989A3FA5C15AA671C4536F0 /* EXPMatchers+beIdenticalTo.m in Sources */, + 76D337327C10A7555447B69AA1562647 /* EXPMatchers+beInstanceOf.m in Sources */, + 9BB9159FBA757600D3D4C0FF645F3911 /* EXPMatchers+beInTheRangeOf.m in Sources */, + 87FD5F0F682CDEB6A348CA448889E3EA /* EXPMatchers+beKindOf.m in Sources */, + 0EBFA5FBE4953A83B677CE2A75746761 /* EXPMatchers+beLessThan.m in Sources */, + D83677C54D2226C67886A525B0B46FBE /* EXPMatchers+beLessThanOrEqualTo.m in Sources */, + 2C0A8737FDB9B9C6A6BDF437FD11334C /* EXPMatchers+beNil.m in Sources */, + BEFFE9FFE52E9A0833A7D2D8FB67EB4D /* EXPMatchers+beSubclassOf.m in Sources */, + 6F278423C8AE1DA47F35E374BB5B91EC /* EXPMatchers+beSupersetOf.m in Sources */, + 0C6FF91EB1F0391ED75DC72D31D159EF /* EXPMatchers+beTruthy.m in Sources */, + DB30F82FB1BE083D9471B965FB500CA2 /* EXPMatchers+conformTo.m in Sources */, + FC20596ABFE14A61F171A29FD03275E7 /* EXPMatchers+contain.m in Sources */, + 918E06480F28F27361B19D19432F8538 /* EXPMatchers+endWith.m in Sources */, + 1AB3304B6884F626BC54150AC7565E18 /* EXPMatchers+equal.m in Sources */, + 403292D82DA62291204BF59524BC4EDB /* EXPMatchers+haveCountOf.m in Sources */, + FC45858927D3B6A0F922C4B697B04A38 /* EXPMatchers+match.m in Sources */, + 931D410B9F8ACB935883DF8C59F9C93E /* EXPMatchers+postNotification.m in Sources */, + 2CFE2898496C1C7096DB8DA43AF19103 /* EXPMatchers+raise.m in Sources */, + FE8E34356D24F6759A8B010ED2F5707B /* EXPMatchers+raiseWithReason.m in Sources */, + E0A077DFB064B79685B810CCEFB2F1EF /* EXPMatchers+respondTo.m in Sources */, + EF6497EE123F6BC0C1B09717437C5908 /* EXPUnsupportedObject.m in Sources */, + B84431CF8C64F363A334AA7089F6C134 /* NSValue+Expecta.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + DAED09FC3F32E1180B41F527BF45E706 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + A8360AF9EB52A18F5FC74182F1FC577D /* Pods-PNImagePickerViewController_Example-dummy.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + E59B738A7006C1A1BC0981F33DD3C8C0 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 5EE6F0E14E01D6AFF2C5D0A28584D9AF /* Pods-PNImagePickerViewController_Tests-dummy.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 3E8666E8062830CA7E6B80029BEBF570 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = Expecta; + target = 0D888F29E05E498D0CD91A51D28599A5 /* Expecta */; + targetProxy = 83D396FFFD51E051AD4896C4BEC7C3B5 /* PBXContainerItemProxy */; + }; + 4ACA793EC27274D41A670C74CD739365 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = Expecta; + target = 0D888F29E05E498D0CD91A51D28599A5 /* Expecta */; + targetProxy = CCF83280732A67033B72EE54815FFD3F /* PBXContainerItemProxy */; + }; + 63CE6196F06F78C762EE65F715CC0C25 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = "Expecta+Snapshots"; + target = 619F0D28240534293108906FED04836F /* Expecta+Snapshots */; + targetProxy = C646DF0ABBA05EB1CFA2F6A24B8A9FAA /* PBXContainerItemProxy */; + }; + 63E8130BC0840C7A0839A25F4D03FFF8 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = "PNImagePickerViewController-PNImagePickerViewController"; + target = 651F3556BCECD15ACE6DA3826056C550 /* PNImagePickerViewController-PNImagePickerViewController */; + targetProxy = DCF7ED085C0C4D510878736F8920D8A6 /* PBXContainerItemProxy */; + }; + 6B0210962967B76806B28BA4C7E656F8 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = PNImagePickerViewController; + target = FE84737BD4D109801238DAB5722D7DA1 /* PNImagePickerViewController */; + targetProxy = 7765DEDE45993B63B9AA156E3F974450 /* PBXContainerItemProxy */; + }; + 89233824D34D1468C7237A7B776D6115 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = PureLayout; + target = 7FE41DC3CF812C74E34FCA5182C46DCD /* PureLayout */; + targetProxy = 6B01D766351D59ABC09AC96D739D963F /* PBXContainerItemProxy */; + }; + 8A9FD2D30D0F80D6677CF6162621C223 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = PNImagePickerViewController; + target = FE84737BD4D109801238DAB5722D7DA1 /* PNImagePickerViewController */; + targetProxy = 25D545AF0C131B5A33DE6AC856C932C2 /* PBXContainerItemProxy */; + }; + 8F8779D84E871A6CCECBC6FE4E649C59 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = PureLayout; + target = 7FE41DC3CF812C74E34FCA5182C46DCD /* PureLayout */; + targetProxy = 02C606CD56CADA7FF7771A0F41C332B4 /* PBXContainerItemProxy */; + }; + B4DAF485093F85F17C8F9D6D86DF1151 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = FBSnapshotTestCase; + target = D07447EE3CEBB0BCB8D61DFCB8EA915F /* FBSnapshotTestCase */; + targetProxy = 82B55322802EC90372810696DA7E5480 /* PBXContainerItemProxy */; + }; + CFC3C60C0541C54818441E331A7E8753 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = FBSnapshotTestCase; + target = D07447EE3CEBB0BCB8D61DFCB8EA915F /* FBSnapshotTestCase */; + targetProxy = F9BBA6CBCE0B1A136EAFACE5185B512D /* PBXContainerItemProxy */; + }; + F2719D6C52BBE801E57042E39AB858C6 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = Specta; + target = 21517BCEE59047E37A446CC807587934 /* Specta */; + targetProxy = 77E6E93D39DA113B90AF7616159755B1 /* PBXContainerItemProxy */; + }; + FF4D44CDD59FE7D4D5FBC665DB46D8D6 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = PureLayout; + target = 7FE41DC3CF812C74E34FCA5182C46DCD /* PureLayout */; + targetProxy = 037C447B9E4583FED14E4E492EAB8B04 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin XCBuildConfiguration section */ + 12AE6F83274C7A824845A8BF52BA16DF /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 4F719753BD46AC4A79F8FAE6B7A60BD9 /* FBSnapshotTestCase.xcconfig */; + buildSettings = { + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_NO_COMMON_BLOCKS = YES; + GCC_PREFIX_HEADER = "Target Support Files/FBSnapshotTestCase/FBSnapshotTestCase-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/FBSnapshotTestCase/Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MODULEMAP_FILE = "Target Support Files/FBSnapshotTestCase/FBSnapshotTestCase.modulemap"; + MTL_ENABLE_DEBUG_INFO = NO; + PRODUCT_NAME = FBSnapshotTestCase; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; + 1965B6BE6D14EE5813652BC17E8B70E0 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 3E76906C21A6360E59BAB98FB678511A /* PNImagePickerViewController.xcconfig */; + buildSettings = { + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_NO_COMMON_BLOCKS = YES; + INFOPLIST_FILE = "Target Support Files/PNImagePickerViewController/ResourceBundle-PNImagePickerViewController-Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + PRODUCT_NAME = PNImagePickerViewController; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + WRAPPER_EXTENSION = bundle; + }; + name = Release; + }; + 1BD8423F9E51E0E25A5BC39E697CBF01 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 4F719753BD46AC4A79F8FAE6B7A60BD9 /* FBSnapshotTestCase.xcconfig */; + buildSettings = { + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = dwarf; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_NO_COMMON_BLOCKS = YES; + GCC_PREFIX_HEADER = "Target Support Files/FBSnapshotTestCase/FBSnapshotTestCase-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/FBSnapshotTestCase/Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MODULEMAP_FILE = "Target Support Files/FBSnapshotTestCase/FBSnapshotTestCase.modulemap"; + MTL_ENABLE_DEBUG_INFO = YES; + PRODUCT_NAME = FBSnapshotTestCase; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + 2F914909F85A5B7FA381E7629A0FFB17 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 561534F9468BFFFCD27420D9028EAF1D /* Expecta+Snapshots.xcconfig */; + buildSettings = { + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_NO_COMMON_BLOCKS = YES; + GCC_PREFIX_HEADER = "Target Support Files/Expecta+Snapshots/Expecta+Snapshots-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/Expecta+Snapshots/Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MODULEMAP_FILE = "Target Support Files/Expecta+Snapshots/Expecta+Snapshots.modulemap"; + MTL_ENABLE_DEBUG_INFO = NO; + PRODUCT_NAME = Expecta_Snapshots; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; + 373349C30AA02CB77851CFF553DFAE5C /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 561534F9468BFFFCD27420D9028EAF1D /* Expecta+Snapshots.xcconfig */; + buildSettings = { + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = dwarf; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_NO_COMMON_BLOCKS = YES; + GCC_PREFIX_HEADER = "Target Support Files/Expecta+Snapshots/Expecta+Snapshots-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/Expecta+Snapshots/Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MODULEMAP_FILE = "Target Support Files/Expecta+Snapshots/Expecta+Snapshots.modulemap"; + MTL_ENABLE_DEBUG_INFO = YES; + PRODUCT_NAME = Expecta_Snapshots; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + 435F223D245E301D06EA7C9385806DAE /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 2C6E94DA05F91DF35F74319DC6F0DF33 /* Specta.xcconfig */; + buildSettings = { + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_NO_COMMON_BLOCKS = YES; + GCC_PREFIX_HEADER = "Target Support Files/Specta/Specta-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/Specta/Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MODULEMAP_FILE = "Target Support Files/Specta/Specta.modulemap"; + MTL_ENABLE_DEBUG_INFO = NO; + PRODUCT_NAME = Specta; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; + 48C22ED69DEDF1DF7633F4DCDC508AA7 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 93BEE7CACAD612FBBE99E8998D378EA4 /* Pods-PNImagePickerViewController_Example.debug.xcconfig */; + buildSettings = { + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = dwarf; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_NO_COMMON_BLOCKS = YES; + INFOPLIST_FILE = "Target Support Files/Pods-PNImagePickerViewController_Example/Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MACH_O_TYPE = staticlib; + MODULEMAP_FILE = "Target Support Files/Pods-PNImagePickerViewController_Example/Pods-PNImagePickerViewController_Example.modulemap"; + MTL_ENABLE_DEBUG_INFO = YES; + OTHER_LDFLAGS = ""; + OTHER_LIBTOOLFLAGS = ""; + PODS_ROOT = "$(SRCROOT)"; + PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; + PRODUCT_NAME = Pods_PNImagePickerViewController_Example; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + 7813B4E239095F012A7DD63CFA6457E3 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 0CD0F5EFF1B3472519F5B4EE821A38E4 /* PureLayout.xcconfig */; + buildSettings = { + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_NO_COMMON_BLOCKS = YES; + GCC_PREFIX_HEADER = "Target Support Files/PureLayout/PureLayout-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/PureLayout/Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MODULEMAP_FILE = "Target Support Files/PureLayout/PureLayout.modulemap"; + MTL_ENABLE_DEBUG_INFO = NO; + PRODUCT_NAME = PureLayout; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; + 7955380EBD03ECE0CE978F559C9A7D2F /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 3E76906C21A6360E59BAB98FB678511A /* PNImagePickerViewController.xcconfig */; + buildSettings = { + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = dwarf; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_NO_COMMON_BLOCKS = YES; + GCC_PREFIX_HEADER = "Target Support Files/PNImagePickerViewController/PNImagePickerViewController-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/PNImagePickerViewController/Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MODULEMAP_FILE = "Target Support Files/PNImagePickerViewController/PNImagePickerViewController.modulemap"; + MTL_ENABLE_DEBUG_INFO = YES; + PRODUCT_NAME = PNImagePickerViewController; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + 811519CB8F683AC06F9C98B55AC40F11 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = YES; + ENABLE_NS_ASSERTIONS = NO; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_PREPROCESSOR_DEFINITIONS = ( + "POD_CONFIGURATION_RELEASE=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + STRIP_INSTALLED_PRODUCT = NO; + SYMROOT = "${SRCROOT}/../build"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 86B3AF85DF2958967D7E96849C2BE84C /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 214647B96EB8D7B1FA18DD92A6EA3917 /* Expecta.xcconfig */; + buildSettings = { + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = dwarf; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_NO_COMMON_BLOCKS = YES; + GCC_PREFIX_HEADER = "Target Support Files/Expecta/Expecta-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/Expecta/Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MODULEMAP_FILE = "Target Support Files/Expecta/Expecta.modulemap"; + MTL_ENABLE_DEBUG_INFO = YES; + PRODUCT_NAME = Expecta; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + 882EB4391EC2E701934974DA86F7343F /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "POD_CONFIGURATION_DEBUG=1", + "DEBUG=1", + "$(inherited)", + ); + GCC_SYMBOLS_PRIVATE_EXTERN = NO; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + ONLY_ACTIVE_ARCH = YES; + STRIP_INSTALLED_PRODUCT = NO; + SYMROOT = "${SRCROOT}/../build"; + }; + name = Debug; + }; + AAA03FA29AD636E5D24C5854E6FB4628 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 3E76906C21A6360E59BAB98FB678511A /* PNImagePickerViewController.xcconfig */; + buildSettings = { + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_NO_COMMON_BLOCKS = YES; + INFOPLIST_FILE = "Target Support Files/PNImagePickerViewController/ResourceBundle-PNImagePickerViewController-Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + PRODUCT_NAME = PNImagePickerViewController; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + WRAPPER_EXTENSION = bundle; + }; + name = Debug; + }; + BF4BF4B751BF8A15245688B66BA1CAE7 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 0CD0F5EFF1B3472519F5B4EE821A38E4 /* PureLayout.xcconfig */; + buildSettings = { + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = dwarf; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_NO_COMMON_BLOCKS = YES; + GCC_PREFIX_HEADER = "Target Support Files/PureLayout/PureLayout-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/PureLayout/Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MODULEMAP_FILE = "Target Support Files/PureLayout/PureLayout.modulemap"; + MTL_ENABLE_DEBUG_INFO = YES; + PRODUCT_NAME = PureLayout; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + C113BE0720F9B93B6FFDFDC800E8658D /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 2C6E94DA05F91DF35F74319DC6F0DF33 /* Specta.xcconfig */; + buildSettings = { + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = dwarf; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_NO_COMMON_BLOCKS = YES; + GCC_PREFIX_HEADER = "Target Support Files/Specta/Specta-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/Specta/Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MODULEMAP_FILE = "Target Support Files/Specta/Specta.modulemap"; + MTL_ENABLE_DEBUG_INFO = YES; + PRODUCT_NAME = Specta; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + E601195658655916E341917BC347BDD0 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = ACEB5B1D16C37F59E5D415018626CCA1 /* Pods-PNImagePickerViewController_Tests.debug.xcconfig */; + buildSettings = { + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = dwarf; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_NO_COMMON_BLOCKS = YES; + INFOPLIST_FILE = "Target Support Files/Pods-PNImagePickerViewController_Tests/Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MACH_O_TYPE = staticlib; + MODULEMAP_FILE = "Target Support Files/Pods-PNImagePickerViewController_Tests/Pods-PNImagePickerViewController_Tests.modulemap"; + MTL_ENABLE_DEBUG_INFO = YES; + OTHER_LDFLAGS = ""; + OTHER_LIBTOOLFLAGS = ""; + PODS_ROOT = "$(SRCROOT)"; + PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; + PRODUCT_NAME = Pods_PNImagePickerViewController_Tests; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + E92B824F17ED6F1BC5D3092D11112874 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 3E76906C21A6360E59BAB98FB678511A /* PNImagePickerViewController.xcconfig */; + buildSettings = { + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_NO_COMMON_BLOCKS = YES; + GCC_PREFIX_HEADER = "Target Support Files/PNImagePickerViewController/PNImagePickerViewController-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/PNImagePickerViewController/Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MODULEMAP_FILE = "Target Support Files/PNImagePickerViewController/PNImagePickerViewController.modulemap"; + MTL_ENABLE_DEBUG_INFO = NO; + PRODUCT_NAME = PNImagePickerViewController; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; + F24F328AA1CFC9A061F629C917D03F44 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 214647B96EB8D7B1FA18DD92A6EA3917 /* Expecta.xcconfig */; + buildSettings = { + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_NO_COMMON_BLOCKS = YES; + GCC_PREFIX_HEADER = "Target Support Files/Expecta/Expecta-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/Expecta/Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MODULEMAP_FILE = "Target Support Files/Expecta/Expecta.modulemap"; + MTL_ENABLE_DEBUG_INFO = NO; + PRODUCT_NAME = Expecta; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; + FC4AA29982CC7A0BCF0806798B1552EC /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 2BD49C93526619102F2D474766196B38 /* Pods-PNImagePickerViewController_Example.release.xcconfig */; + buildSettings = { + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_NO_COMMON_BLOCKS = YES; + INFOPLIST_FILE = "Target Support Files/Pods-PNImagePickerViewController_Example/Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MACH_O_TYPE = staticlib; + MODULEMAP_FILE = "Target Support Files/Pods-PNImagePickerViewController_Example/Pods-PNImagePickerViewController_Example.modulemap"; + MTL_ENABLE_DEBUG_INFO = NO; + OTHER_LDFLAGS = ""; + OTHER_LIBTOOLFLAGS = ""; + PODS_ROOT = "$(SRCROOT)"; + PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; + PRODUCT_NAME = Pods_PNImagePickerViewController_Example; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; + FEBBDDB572A6B5EB2376766424894472 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = D78F728DA45B9D043472FCF4315E60C7 /* Pods-PNImagePickerViewController_Tests.release.xcconfig */; + buildSettings = { + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_NO_COMMON_BLOCKS = YES; + INFOPLIST_FILE = "Target Support Files/Pods-PNImagePickerViewController_Tests/Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MACH_O_TYPE = staticlib; + MODULEMAP_FILE = "Target Support Files/Pods-PNImagePickerViewController_Tests/Pods-PNImagePickerViewController_Tests.modulemap"; + MTL_ENABLE_DEBUG_INFO = NO; + OTHER_LDFLAGS = ""; + OTHER_LIBTOOLFLAGS = ""; + PODS_ROOT = "$(SRCROOT)"; + PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; + PRODUCT_NAME = Pods_PNImagePickerViewController_Tests; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 1F383D29DD374DAB98FA28FE6DB19F4F /* Build configuration list for PBXNativeTarget "Pods-PNImagePickerViewController_Example" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 48C22ED69DEDF1DF7633F4DCDC508AA7 /* Debug */, + FC4AA29982CC7A0BCF0806798B1552EC /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 28EF1888BB5588EC5A14D296BD25A457 /* Build configuration list for PBXNativeTarget "PureLayout" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + BF4BF4B751BF8A15245688B66BA1CAE7 /* Debug */, + 7813B4E239095F012A7DD63CFA6457E3 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 2D8E8EC45A3A1A1D94AE762CB5028504 /* Build configuration list for PBXProject "Pods" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 882EB4391EC2E701934974DA86F7343F /* Debug */, + 811519CB8F683AC06F9C98B55AC40F11 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 6D67EE9FBEA41A7642E41234789E9570 /* Build configuration list for PBXNativeTarget "PNImagePickerViewController" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 7955380EBD03ECE0CE978F559C9A7D2F /* Debug */, + E92B824F17ED6F1BC5D3092D11112874 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 76F91EF3CC28EF7FFE902CF383943B85 /* Build configuration list for PBXNativeTarget "PNImagePickerViewController-PNImagePickerViewController" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + AAA03FA29AD636E5D24C5854E6FB4628 /* Debug */, + 1965B6BE6D14EE5813652BC17E8B70E0 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 7C7B4BE8DC7E24A96243E4D67565D719 /* Build configuration list for PBXNativeTarget "FBSnapshotTestCase" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1BD8423F9E51E0E25A5BC39E697CBF01 /* Debug */, + 12AE6F83274C7A824845A8BF52BA16DF /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + A965CE36E5BBB9F4B7E10CE04497D68D /* Build configuration list for PBXNativeTarget "Pods-PNImagePickerViewController_Tests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + E601195658655916E341917BC347BDD0 /* Debug */, + FEBBDDB572A6B5EB2376766424894472 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + D5B74CC207A82790DE2A82F49EDF170A /* Build configuration list for PBXNativeTarget "Expecta+Snapshots" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 373349C30AA02CB77851CFF553DFAE5C /* Debug */, + 2F914909F85A5B7FA381E7629A0FFB17 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + DC61702A42844E4ED762A73E8893436B /* Build configuration list for PBXNativeTarget "Expecta" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 86B3AF85DF2958967D7E96849C2BE84C /* Debug */, + F24F328AA1CFC9A061F629C917D03F44 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + FE7B905FF421B939093E504FA8416FB9 /* Build configuration list for PBXNativeTarget "Specta" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + C113BE0720F9B93B6FFDFDC800E8658D /* Debug */, + 435F223D245E301D06EA7C9385806DAE /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = D41D8CD98F00B204E9800998ECF8427E /* Project object */; +} diff --git a/Example/Pods/Pods.xcodeproj/xcshareddata/xcschemes/PNImagePickerViewController.xcscheme b/Example/Pods/Pods.xcodeproj/xcshareddata/xcschemes/PNImagePickerViewController.xcscheme new file mode 100644 index 0000000..2d07561 --- /dev/null +++ b/Example/Pods/Pods.xcodeproj/xcshareddata/xcschemes/PNImagePickerViewController.xcscheme @@ -0,0 +1,60 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Example/Pods/PureLayout/LICENSE b/Example/Pods/PureLayout/LICENSE new file mode 100755 index 0000000..5396bc0 --- /dev/null +++ b/Example/Pods/PureLayout/LICENSE @@ -0,0 +1,9 @@ +This code is distributed under the terms and conditions of the MIT license. + +Copyright (c) 2014-2015 Tyler Fox + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/Example/Pods/PureLayout/PureLayout/PureLayout/ALView+PureLayout.h b/Example/Pods/PureLayout/PureLayout/PureLayout/ALView+PureLayout.h new file mode 100755 index 0000000..d998e31 --- /dev/null +++ b/Example/Pods/PureLayout/PureLayout/PureLayout/ALView+PureLayout.h @@ -0,0 +1,213 @@ +// +// ALView+PureLayout.h +// https://github.com/PureLayout/PureLayout +// +// Copyright (c) 2012 Richard Turton +// Copyright (c) 2013-2015 Tyler Fox +// +// This code is distributed under the terms and conditions of the MIT license. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +// + +#import "PureLayoutDefines.h" + + +__PL_ASSUME_NONNULL_BEGIN + +#pragma mark ALView+PureLayout + +/** + A category on UIView/NSView that provides a simple yet powerful interface for creating Auto Layout constraints. + */ +@interface ALView (PureLayout) + + +#pragma mark Factory & Initializer Methods + +/** Creates and returns a new view that does not convert the autoresizing mask into constraints. */ ++ (instancetype)newAutoLayoutView; + +/** Initializes and returns a new view that does not convert the autoresizing mask into constraints. */ +- (instancetype)initForAutoLayout; + +/** Configures an existing view to not convert the autoresizing mask into constraints and returns the view. */ +- (instancetype)configureForAutoLayout; + + +#pragma mark Center & Align in Superview + +/** Centers the view in its superview. */ +- (__NSArray_of(NSLayoutConstraint *) *)autoCenterInSuperview; + +/** Aligns the view to the same axis of its superview. */ +- (NSLayoutConstraint *)autoAlignAxisToSuperviewAxis:(ALAxis)axis; + +#if __PureLayout_MinBaseSDK_iOS_8_0 + +/** Centers the view in its superview's margins. Available in iOS 8.0 and later. */ +- (__NSArray_of(NSLayoutConstraint *) *)autoCenterInSuperviewMargins; + +/** Aligns the view to the corresponding margin axis of its superview. Available in iOS 8.0 and later. */ +- (NSLayoutConstraint *)autoAlignAxisToSuperviewMarginAxis:(ALAxis)axis; + +#endif /* __PureLayout_MinBaseSDK_iOS_8_0 */ + + +#pragma mark Pin Edges to Superview + +/** Pins the given edge of the view to the same edge of its superview. */ +- (NSLayoutConstraint *)autoPinEdgeToSuperviewEdge:(ALEdge)edge; + +/** Pins the given edge of the view to the same edge of its superview with an inset. */ +- (NSLayoutConstraint *)autoPinEdgeToSuperviewEdge:(ALEdge)edge withInset:(CGFloat)inset; + +/** Pins the given edge of the view to the same edge of its superview with an inset as a maximum or minimum. */ +- (NSLayoutConstraint *)autoPinEdgeToSuperviewEdge:(ALEdge)edge withInset:(CGFloat)inset relation:(NSLayoutRelation)relation; + +/** Pins the edges of the view to the edges of its superview. */ +- (__NSArray_of(NSLayoutConstraint *) *)autoPinEdgesToSuperviewEdges; + +/** Pins the edges of the view to the edges of its superview with the given edge insets. */ +- (__NSArray_of(NSLayoutConstraint *) *)autoPinEdgesToSuperviewEdgesWithInsets:(ALEdgeInsets)insets; + +/** Pins 3 of the 4 edges of the view to the edges of its superview with the given edge insets, excluding one edge. */ +- (__NSArray_of(NSLayoutConstraint *) *)autoPinEdgesToSuperviewEdgesWithInsets:(ALEdgeInsets)insets excludingEdge:(ALEdge)edge; + +#if __PureLayout_MinBaseSDK_iOS_8_0 + +/** Pins the given edge of the view to the corresponding margin of its superview. Available in iOS 8.0 and later. */ +- (NSLayoutConstraint *)autoPinEdgeToSuperviewMargin:(ALEdge)edge; + +/** Pins the given edge of the view to the corresponding margin of its superview as a maximum or minimum. Available in iOS 8.0 and later. */ +- (NSLayoutConstraint *)autoPinEdgeToSuperviewMargin:(ALEdge)edge relation:(NSLayoutRelation)relation; + +/** Pins the edges of the view to the margins of its superview. Available in iOS 8.0 and later. */ +- (__NSArray_of(NSLayoutConstraint *) *)autoPinEdgesToSuperviewMargins; + +/** Pins 3 of the 4 edges of the view to the margins of its superview excluding one edge. Available in iOS 8.0 and later. */ +- (__NSArray_of(NSLayoutConstraint *) *)autoPinEdgesToSuperviewMarginsExcludingEdge:(ALEdge)edge; + +#endif /* __PureLayout_MinBaseSDK_iOS_8_0 */ + + +#pragma mark Pin Edges + +/** Pins an edge of the view to a given edge of another view. */ +- (NSLayoutConstraint *)autoPinEdge:(ALEdge)edge toEdge:(ALEdge)toEdge ofView:(ALView *)otherView; + +/** Pins an edge of the view to a given edge of another view with an offset. */ +- (NSLayoutConstraint *)autoPinEdge:(ALEdge)edge toEdge:(ALEdge)toEdge ofView:(ALView *)otherView withOffset:(CGFloat)offset; + +/** Pins an edge of the view to a given edge of another view with an offset as a maximum or minimum. */ +- (NSLayoutConstraint *)autoPinEdge:(ALEdge)edge toEdge:(ALEdge)toEdge ofView:(ALView *)otherView withOffset:(CGFloat)offset relation:(NSLayoutRelation)relation; + + +#pragma mark Align Axes + +/** Aligns an axis of the view to the same axis of another view. */ +- (NSLayoutConstraint *)autoAlignAxis:(ALAxis)axis toSameAxisOfView:(ALView *)otherView; + +/** Aligns an axis of the view to the same axis of another view with an offset. */ +- (NSLayoutConstraint *)autoAlignAxis:(ALAxis)axis toSameAxisOfView:(ALView *)otherView withOffset:(CGFloat)offset; + +/** Aligns an axis of the view to the same axis of another view with a multiplier. */ +- (NSLayoutConstraint *)autoAlignAxis:(ALAxis)axis toSameAxisOfView:(ALView *)otherView withMultiplier:(CGFloat)multiplier; + + +#pragma mark Match Dimensions + +/** Matches a dimension of the view to a given dimension of another view. */ +- (NSLayoutConstraint *)autoMatchDimension:(ALDimension)dimension toDimension:(ALDimension)toDimension ofView:(ALView *)otherView; + +/** Matches a dimension of the view to a given dimension of another view with an offset. */ +- (NSLayoutConstraint *)autoMatchDimension:(ALDimension)dimension toDimension:(ALDimension)toDimension ofView:(ALView *)otherView withOffset:(CGFloat)offset; + +/** Matches a dimension of the view to a given dimension of another view with an offset as a maximum or minimum. */ +- (NSLayoutConstraint *)autoMatchDimension:(ALDimension)dimension toDimension:(ALDimension)toDimension ofView:(ALView *)otherView withOffset:(CGFloat)offset relation:(NSLayoutRelation)relation; + +/** Matches a dimension of the view to a multiple of a given dimension of another view. */ +- (NSLayoutConstraint *)autoMatchDimension:(ALDimension)dimension toDimension:(ALDimension)toDimension ofView:(ALView *)otherView withMultiplier:(CGFloat)multiplier; + +/** Matches a dimension of the view to a multiple of a given dimension of another view as a maximum or minimum. */ +- (NSLayoutConstraint *)autoMatchDimension:(ALDimension)dimension toDimension:(ALDimension)toDimension ofView:(ALView *)otherView withMultiplier:(CGFloat)multiplier relation:(NSLayoutRelation)relation; + + +#pragma mark Set Dimensions + +/** Sets the view to a specific size. */ +- (__NSArray_of(NSLayoutConstraint *) *)autoSetDimensionsToSize:(CGSize)size; + +/** Sets the given dimension of the view to a specific size. */ +- (NSLayoutConstraint *)autoSetDimension:(ALDimension)dimension toSize:(CGFloat)size; + +/** Sets the given dimension of the view to a specific size as a maximum or minimum. */ +- (NSLayoutConstraint *)autoSetDimension:(ALDimension)dimension toSize:(CGFloat)size relation:(NSLayoutRelation)relation; + + +#pragma mark Set Content Compression Resistance & Hugging + +/** Sets the priority of content compression resistance for an axis. + NOTE: This method must be called from within the block passed into the method +[NSLayoutConstraint autoSetPriority:forConstraints:] */ +- (void)autoSetContentCompressionResistancePriorityForAxis:(ALAxis)axis; + +/** Sets the priority of content hugging for an axis. + NOTE: This method must be called from within the block passed into the method +[NSLayoutConstraint autoSetPriority:forConstraints:] */ +- (void)autoSetContentHuggingPriorityForAxis:(ALAxis)axis; + + +#pragma mark Constrain Any Attributes + +/** Constrains an attribute of the view to a given attribute of another view. */ +- (NSLayoutConstraint *)autoConstrainAttribute:(ALAttribute)attribute toAttribute:(ALAttribute)toAttribute ofView:(ALView *)otherView; + +/** Constrains an attribute of the view to a given attribute of another view with an offset. */ +- (NSLayoutConstraint *)autoConstrainAttribute:(ALAttribute)attribute toAttribute:(ALAttribute)toAttribute ofView:(ALView *)otherView withOffset:(CGFloat)offset; + +/** Constrains an attribute of the view to a given attribute of another view with an offset as a maximum or minimum. */ +- (NSLayoutConstraint *)autoConstrainAttribute:(ALAttribute)attribute toAttribute:(ALAttribute)toAttribute ofView:(ALView *)otherView withOffset:(CGFloat)offset relation:(NSLayoutRelation)relation; + +/** Constrains an attribute of the view to a given attribute of another view with a multiplier. */ +- (NSLayoutConstraint *)autoConstrainAttribute:(ALAttribute)attribute toAttribute:(ALAttribute)toAttribute ofView:(ALView *)otherView withMultiplier:(CGFloat)multiplier; + +/** Constrains an attribute of the view to a given attribute of another view with a multiplier as a maximum or minimum. */ +- (NSLayoutConstraint *)autoConstrainAttribute:(ALAttribute)attribute toAttribute:(ALAttribute)toAttribute ofView:(ALView *)otherView withMultiplier:(CGFloat)multiplier relation:(NSLayoutRelation)relation; + + +#pragma mark Pin to Layout Guides (iOS only) + +#if TARGET_OS_IPHONE + +/** Pins the top edge of the view to the top layout guide of the given view controller with an inset. Available on iOS only. */ +- (NSLayoutConstraint *)autoPinToTopLayoutGuideOfViewController:(UIViewController *)viewController withInset:(CGFloat)inset; + +/** Pins the top edge of the view to the top layout guide of the given view controller with an inset as a maximum or minimum. Available on iOS only. */ +- (NSLayoutConstraint *)autoPinToTopLayoutGuideOfViewController:(UIViewController *)viewController withInset:(CGFloat)inset relation:(NSLayoutRelation)relation; + +/** Pins the bottom edge of the view to the bottom layout guide of the given view controller with an inset. Available on iOS only. */ +- (NSLayoutConstraint *)autoPinToBottomLayoutGuideOfViewController:(UIViewController *)viewController withInset:(CGFloat)inset; + +/** Pins the bottom edge of the view to the bottom layout guide of the given view controller with an inset as a maximum or minimum. Available on iOS only. */ +- (NSLayoutConstraint *)autoPinToBottomLayoutGuideOfViewController:(UIViewController *)viewController withInset:(CGFloat)inset relation:(NSLayoutRelation)relation; + +#endif /* TARGET_OS_IPHONE */ + +@end + +__PL_ASSUME_NONNULL_END diff --git a/Example/Pods/PureLayout/PureLayout/PureLayout/ALView+PureLayout.m b/Example/Pods/PureLayout/PureLayout/PureLayout/ALView+PureLayout.m new file mode 100755 index 0000000..1985d90 --- /dev/null +++ b/Example/Pods/PureLayout/PureLayout/PureLayout/ALView+PureLayout.m @@ -0,0 +1,848 @@ +// +// ALView+PureLayout.m +// https://github.com/PureLayout/PureLayout +// +// Copyright (c) 2012 Richard Turton +// Copyright (c) 2013-2015 Tyler Fox +// +// This code is distributed under the terms and conditions of the MIT license. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +// + +#import "ALView+PureLayout.h" +#import "NSLayoutConstraint+PureLayout.h" +#import "NSArray+PureLayout.h" +#import "PureLayout+Internal.h" + + +#pragma mark - ALView+PureLayout + +@implementation ALView (PureLayout) + + +#pragma mark Factory & Initializer Methods + +/** + Creates and returns a new view that does not convert the autoresizing mask into constraints. + */ ++ (instancetype)newAutoLayoutView +{ + ALView *view = [self new]; + view.translatesAutoresizingMaskIntoConstraints = NO; + return view; +} + +/** + Initializes and returns a new view that does not convert the autoresizing mask into constraints. + */ +- (instancetype)initForAutoLayout +{ + self = [self init]; + if (self) { + self.translatesAutoresizingMaskIntoConstraints = NO; + } + return self; +} + +/** + Configures an existing view to not convert the autoresizing mask into constraints and returns the view. + */ +- (instancetype)configureForAutoLayout +{ + self.translatesAutoresizingMaskIntoConstraints = NO; + return self; +} + + +#pragma mark Center in Superview + +/** + Centers the view in its superview. + + @return An array of constraints added. + */ +- (__NSArray_of(NSLayoutConstraint *) *)autoCenterInSuperview +{ + __NSMutableArray_of(NSLayoutConstraint *) *constraints = [NSMutableArray new]; + [constraints addObject:[self autoAlignAxisToSuperviewAxis:ALAxisHorizontal]]; + [constraints addObject:[self autoAlignAxisToSuperviewAxis:ALAxisVertical]]; + return constraints; +} + +/** + Aligns the view to the same axis of its superview. + + @param axis The axis of this view and of its superview to align. + @return The constraint added. + */ +- (NSLayoutConstraint *)autoAlignAxisToSuperviewAxis:(ALAxis)axis +{ + self.translatesAutoresizingMaskIntoConstraints = NO; + ALView *superview = self.superview; + NSAssert(superview, @"View's superview must not be nil.\nView: %@", self); + return [self autoConstrainAttribute:(ALAttribute)axis toAttribute:(ALAttribute)axis ofView:superview]; +} + +#if __PureLayout_MinBaseSDK_iOS_8_0 + +/** + Centers the view in its superview, taking into account the layout margins of both the view and its superview. + + @return An array of constraints added. + */ +- (__NSArray_of(NSLayoutConstraint *) *)autoCenterInSuperviewMargins +{ + __NSMutableArray_of(NSLayoutConstraint *) *constraints = [NSMutableArray new]; + [constraints addObject:[self autoAlignAxisToSuperviewMarginAxis:ALAxisHorizontal]]; + [constraints addObject:[self autoAlignAxisToSuperviewMarginAxis:ALAxisVertical]]; + return constraints; +} + +/** + Aligns the view to the corresponding margin axis of its superview. + + @param axis The axis of this view to align to the corresponding margin axis of its superview. + @return The constraint added. + */ +- (NSLayoutConstraint *)autoAlignAxisToSuperviewMarginAxis:(ALAxis)axis +{ + self.translatesAutoresizingMaskIntoConstraints = NO; + ALView *superview = self.superview; + NSAssert(superview, @"View's superview must not be nil.\nView: %@", self); + ALMarginAxis marginAxis = [NSLayoutConstraint al_marginAxisForAxis:axis]; + return [self autoConstrainAttribute:(ALAttribute)axis toAttribute:(ALAttribute)marginAxis ofView:superview]; +} + +#endif /* __PureLayout_MinBaseSDK_iOS_8_0 */ + + +#pragma mark Pin Edges to Superview + +/** + Pins the given edge of the view to the same edge of its superview. + + @param edge The edge of this view and its superview to pin. + @return The constraint added. + */ +- (NSLayoutConstraint *)autoPinEdgeToSuperviewEdge:(ALEdge)edge +{ + return [self autoPinEdgeToSuperviewEdge:edge withInset:0.0]; +} + +/** + Pins the given edge of the view to the same edge of its superview with an inset. + + @param edge The edge of this view and its superview to pin. + @param inset The amount to inset this view's edge from the superview's edge. + @return The constraint added. + */ +- (NSLayoutConstraint *)autoPinEdgeToSuperviewEdge:(ALEdge)edge withInset:(CGFloat)inset +{ + return [self autoPinEdgeToSuperviewEdge:edge withInset:inset relation:NSLayoutRelationEqual]; +} + +/** + Pins the given edge of the view to the same edge of its superview with an inset as a maximum or minimum. + + @param edge The edge of this view and its superview to pin. + @param inset The amount to inset this view's edge from the superview's edge. + @param relation Whether the inset should be at least, at most, or exactly equal to the given value. + @return The constraint added. + */ +- (NSLayoutConstraint *)autoPinEdgeToSuperviewEdge:(ALEdge)edge withInset:(CGFloat)inset relation:(NSLayoutRelation)relation +{ + self.translatesAutoresizingMaskIntoConstraints = NO; + ALView *superview = self.superview; + NSAssert(superview, @"View's superview must not be nil.\nView: %@", self); + if (edge == ALEdgeBottom || edge == ALEdgeRight || edge == ALEdgeTrailing) { + // The bottom, right, and trailing insets (and relations, if an inequality) are inverted to become offsets + inset = -inset; + if (relation == NSLayoutRelationLessThanOrEqual) { + relation = NSLayoutRelationGreaterThanOrEqual; + } else if (relation == NSLayoutRelationGreaterThanOrEqual) { + relation = NSLayoutRelationLessThanOrEqual; + } + } + return [self autoPinEdge:edge toEdge:edge ofView:superview withOffset:inset relation:relation]; +} + +/** + Pins the edges of the view to the edges of its superview. + + @return An array of constraints added. + */ +- (__NSArray_of(NSLayoutConstraint *) *)autoPinEdgesToSuperviewEdges +{ + return [self autoPinEdgesToSuperviewEdgesWithInsets:ALEdgeInsetsZero]; +} + +/** + Pins the edges of the view to the edges of its superview with the given edge insets. + The insets.left corresponds to a leading edge constraint, and insets.right corresponds to a trailing edge constraint. + + @param insets The insets for this view's edges from its superview's edges. + @return An array of constraints added. + */ +- (__NSArray_of(NSLayoutConstraint *) *)autoPinEdgesToSuperviewEdgesWithInsets:(ALEdgeInsets)insets +{ + __NSMutableArray_of(NSLayoutConstraint *) *constraints = [NSMutableArray new]; + [constraints addObject:[self autoPinEdgeToSuperviewEdge:ALEdgeTop withInset:insets.top]]; + [constraints addObject:[self autoPinEdgeToSuperviewEdge:ALEdgeLeading withInset:insets.left]]; + [constraints addObject:[self autoPinEdgeToSuperviewEdge:ALEdgeBottom withInset:insets.bottom]]; + [constraints addObject:[self autoPinEdgeToSuperviewEdge:ALEdgeTrailing withInset:insets.right]]; + return constraints; +} + +/** + Pins 3 of the 4 edges of the view to the edges of its superview with the given edge insets, excluding one edge. + The insets.left corresponds to a leading edge constraint, and insets.right corresponds to a trailing edge constraint. + + @param insets The insets for this view's edges from its superview's edges. The inset corresponding to the excluded edge + will be ignored. + @param edge The edge of this view to exclude in pinning to its superview; this method will not apply any constraint to it. + @return An array of constraints added. + */ +- (__NSArray_of(NSLayoutConstraint *) *)autoPinEdgesToSuperviewEdgesWithInsets:(ALEdgeInsets)insets excludingEdge:(ALEdge)edge +{ + __NSMutableArray_of(NSLayoutConstraint *) *constraints = [NSMutableArray new]; + if (edge != ALEdgeTop) { + [constraints addObject:[self autoPinEdgeToSuperviewEdge:ALEdgeTop withInset:insets.top]]; + } + if (edge != ALEdgeLeading && edge != ALEdgeLeft) { + [constraints addObject:[self autoPinEdgeToSuperviewEdge:ALEdgeLeading withInset:insets.left]]; + } + if (edge != ALEdgeBottom) { + [constraints addObject:[self autoPinEdgeToSuperviewEdge:ALEdgeBottom withInset:insets.bottom]]; + } + if (edge != ALEdgeTrailing && edge != ALEdgeRight) { + [constraints addObject:[self autoPinEdgeToSuperviewEdge:ALEdgeTrailing withInset:insets.right]]; + } + return constraints; +} + +#if __PureLayout_MinBaseSDK_iOS_8_0 + +/** + Pins the given edge of the view to the corresponding margin of its superview. + + @param edge The edge of this view to pin to the corresponding margin of its superview. + @return The constraint added. + */ +- (NSLayoutConstraint *)autoPinEdgeToSuperviewMargin:(ALEdge)edge +{ + return [self autoPinEdgeToSuperviewMargin:edge relation:NSLayoutRelationEqual]; +} + +/** + Pins the given edge of the view to the corresponding margin of its superview as a maximum or minimum. + + @param edge The edge of this view to pin to the corresponding margin of its superview. + @param relation Whether the edge should be inset by at least, at most, or exactly the superview's margin. + @return The constraint added. + */ +- (NSLayoutConstraint *)autoPinEdgeToSuperviewMargin:(ALEdge)edge relation:(NSLayoutRelation)relation +{ + self.translatesAutoresizingMaskIntoConstraints = NO; + ALView *superview = self.superview; + NSAssert(superview, @"View's superview must not be nil.\nView: %@", self); + if (edge == ALEdgeBottom || edge == ALEdgeRight || edge == ALEdgeTrailing) { + // The bottom, right, and trailing relations are inverted + if (relation == NSLayoutRelationLessThanOrEqual) { + relation = NSLayoutRelationGreaterThanOrEqual; + } else if (relation == NSLayoutRelationGreaterThanOrEqual) { + relation = NSLayoutRelationLessThanOrEqual; + } + } + ALMargin margin = [NSLayoutConstraint al_marginForEdge:edge]; + return [self autoConstrainAttribute:(ALAttribute)edge toAttribute:(ALAttribute)margin ofView:superview withOffset:0.0 relation:relation]; +} + +/** + Pins the edges of the view to the margins of its superview. + + @return An array of constraints added. + */ +- (__NSArray_of(NSLayoutConstraint *) *)autoPinEdgesToSuperviewMargins +{ + __NSMutableArray_of(NSLayoutConstraint *) *constraints = [NSMutableArray new]; + [constraints addObject:[self autoPinEdgeToSuperviewMargin:ALEdgeTop]]; + [constraints addObject:[self autoPinEdgeToSuperviewMargin:ALEdgeLeading]]; + [constraints addObject:[self autoPinEdgeToSuperviewMargin:ALEdgeBottom]]; + [constraints addObject:[self autoPinEdgeToSuperviewMargin:ALEdgeTrailing]]; + return constraints; +} + +/** + Pins 3 of the 4 edges of the view to the margins of its superview, excluding one edge. + + @param edge The edge of this view to exclude in pinning to its superview; this method will not apply any constraint to it. + @return An array of constraints added. + */ +- (__NSArray_of(NSLayoutConstraint *) *)autoPinEdgesToSuperviewMarginsExcludingEdge:(ALEdge)edge +{ + __NSMutableArray_of(NSLayoutConstraint *) *constraints = [NSMutableArray new]; + if (edge != ALEdgeTop) { + [constraints addObject:[self autoPinEdgeToSuperviewMargin:ALEdgeTop]]; + } + if (edge != ALEdgeLeading && edge != ALEdgeLeft) { + [constraints addObject:[self autoPinEdgeToSuperviewMargin:ALEdgeLeading]]; + } + if (edge != ALEdgeBottom) { + [constraints addObject:[self autoPinEdgeToSuperviewMargin:ALEdgeBottom]]; + } + if (edge != ALEdgeTrailing && edge != ALEdgeRight) { + [constraints addObject:[self autoPinEdgeToSuperviewMargin:ALEdgeTrailing]]; + } + return constraints; +} + +#endif /* __PureLayout_MinBaseSDK_iOS_8_0 */ + + +#pragma mark Pin Edges + +/** + Pins an edge of the view to a given edge of another view. + + @param edge The edge of this view to pin. + @param toEdge The edge of the other view to pin to. + @param otherView The other view to pin to. Must be in the same view hierarchy as this view. + @return The constraint added. + */ +- (NSLayoutConstraint *)autoPinEdge:(ALEdge)edge toEdge:(ALEdge)toEdge ofView:(ALView *)otherView +{ + return [self autoPinEdge:edge toEdge:toEdge ofView:otherView withOffset:0.0]; +} + +/** + Pins an edge of the view to a given edge of another view with an offset. + + @param edge The edge of this view to pin. + @param toEdge The edge of the other view to pin to. + @param otherView The other view to pin to. Must be in the same view hierarchy as this view. + @param offset The offset between the edge of this view and the edge of the other view. + @return The constraint added. + */ +- (NSLayoutConstraint *)autoPinEdge:(ALEdge)edge toEdge:(ALEdge)toEdge ofView:(ALView *)otherView withOffset:(CGFloat)offset +{ + return [self autoPinEdge:edge toEdge:toEdge ofView:otherView withOffset:offset relation:NSLayoutRelationEqual]; +} + +/** + Pins an edge of the view to a given edge of another view with an offset as a maximum or minimum. + + @param edge The edge of this view to pin. + @param toEdge The edge of the other view to pin to. + @param otherView The other view to pin to. Must be in the same view hierarchy as this view. + @param offset The offset between the edge of this view and the edge of the other view. + @param relation Whether the offset should be at least, at most, or exactly equal to the given value. + @return The constraint added. + */ +- (NSLayoutConstraint *)autoPinEdge:(ALEdge)edge toEdge:(ALEdge)toEdge ofView:(ALView *)otherView withOffset:(CGFloat)offset relation:(NSLayoutRelation)relation +{ + return [self autoConstrainAttribute:(ALAttribute)edge toAttribute:(ALAttribute)toEdge ofView:otherView withOffset:offset relation:relation]; +} + + +#pragma mark Align Axes + +/** + Aligns an axis of the view to the same axis of another view. + + @param axis The axis of this view and the other view to align. + @param otherView The other view to align to. Must be in the same view hierarchy as this view. + @return The constraint added. + */ +- (NSLayoutConstraint *)autoAlignAxis:(ALAxis)axis toSameAxisOfView:(ALView *)otherView +{ + return [self autoAlignAxis:axis toSameAxisOfView:otherView withOffset:0.0]; +} + +/** + Aligns an axis of the view to the same axis of another view with an offset. + + @param axis The axis of this view and the other view to align. + @param otherView The other view to align to. Must be in the same view hierarchy as this view. + @param offset The offset between the axis of this view and the axis of the other view. + @return The constraint added. + */ +- (NSLayoutConstraint *)autoAlignAxis:(ALAxis)axis toSameAxisOfView:(ALView *)otherView withOffset:(CGFloat)offset +{ + return [self autoConstrainAttribute:(ALAttribute)axis toAttribute:(ALAttribute)axis ofView:otherView withOffset:offset]; +} + +/** + Aligns an axis of the view to the same axis of another view with a multiplier. + + @param axis The axis of this view and the other view to align. + @param otherView The other view to align to. Must be in the same view hierarchy as this view. + @param multiplier The multiplier between the axis of this view and the axis of the other view. + @return The constraint added. + */ +- (NSLayoutConstraint *)autoAlignAxis:(ALAxis)axis toSameAxisOfView:(ALView *)otherView withMultiplier:(CGFloat)multiplier +{ + return [self autoConstrainAttribute:(ALAttribute)axis toAttribute:(ALAttribute)axis ofView:otherView withMultiplier:multiplier]; +} + + +#pragma mark Match Dimensions + +/** + Matches a dimension of the view to a given dimension of another view. + + @param dimension The dimension of this view to pin. + @param toDimension The dimension of the other view to pin to. + @param otherView The other view to match to. Must be in the same view hierarchy as this view. + @return The constraint added. + */ +- (NSLayoutConstraint *)autoMatchDimension:(ALDimension)dimension toDimension:(ALDimension)toDimension ofView:(ALView *)otherView +{ + return [self autoMatchDimension:dimension toDimension:toDimension ofView:otherView withOffset:0.0]; +} + +/** + Matches a dimension of the view to a given dimension of another view with an offset. + + @param dimension The dimension of this view to pin. + @param toDimension The dimension of the other view to pin to. + @param otherView The other view to match to. Must be in the same view hierarchy as this view. + @param offset The offset between the dimension of this view and the dimension of the other view. + @return The constraint added. + */ +- (NSLayoutConstraint *)autoMatchDimension:(ALDimension)dimension toDimension:(ALDimension)toDimension ofView:(ALView *)otherView withOffset:(CGFloat)offset +{ + return [self autoMatchDimension:dimension toDimension:toDimension ofView:otherView withOffset:offset relation:NSLayoutRelationEqual]; +} + +/** + Matches a dimension of the view to a given dimension of another view with an offset as a maximum or minimum. + + @param dimension The dimension of this view to pin. + @param toDimension The dimension of the other view to pin to. + @param otherView The other view to match to. Must be in the same view hierarchy as this view. + @param offset The offset between the dimension of this view and the dimension of the other view. + @param relation Whether the offset should be at least, at most, or exactly equal to the given value. + @return The constraint added. + */ +- (NSLayoutConstraint *)autoMatchDimension:(ALDimension)dimension toDimension:(ALDimension)toDimension ofView:(ALView *)otherView withOffset:(CGFloat)offset relation:(NSLayoutRelation)relation +{ + return [self autoConstrainAttribute:(ALAttribute)dimension toAttribute:(ALAttribute)toDimension ofView:otherView withOffset:offset relation:relation]; +} + +/** + Matches a dimension of the view to a multiple of a given dimension of another view. + + @param dimension The dimension of this view to pin. + @param toDimension The dimension of the other view to pin to. + @param otherView The other view to match to. Must be in the same view hierarchy as this view. + @param multiplier The multiple of the other view's given dimension that this view's given dimension should be. + @return The constraint added. + */ +- (NSLayoutConstraint *)autoMatchDimension:(ALDimension)dimension toDimension:(ALDimension)toDimension ofView:(ALView *)otherView withMultiplier:(CGFloat)multiplier +{ + return [self autoMatchDimension:dimension toDimension:toDimension ofView:otherView withMultiplier:multiplier relation:NSLayoutRelationEqual]; +} + +/** + Matches a dimension of the view to a multiple of a given dimension of another view as a maximum or minimum. + + @param dimension The dimension of this view to pin. + @param toDimension The dimension of the other view to pin to. + @param otherView The other view to match to. Must be in the same view hierarchy as this view. + @param multiplier The multiple of the other view's given dimension that this view's given dimension should be. + @param relation Whether the multiple should be at least, at most, or exactly equal to the given value. + @return The constraint added. + */ +- (NSLayoutConstraint *)autoMatchDimension:(ALDimension)dimension toDimension:(ALDimension)toDimension ofView:(ALView *)otherView withMultiplier:(CGFloat)multiplier relation:(NSLayoutRelation)relation +{ + return [self autoConstrainAttribute:(ALAttribute)dimension toAttribute:(ALAttribute)toDimension ofView:otherView withMultiplier:multiplier relation:relation]; +} + + +#pragma mark Set Dimensions + +/** + Sets the view to a specific size. + + @param size The size to set this view's dimensions to. + @return An array of constraints added. + */ +- (__NSArray_of(NSLayoutConstraint *) *)autoSetDimensionsToSize:(CGSize)size +{ + __NSMutableArray_of(NSLayoutConstraint *) *constraints = [NSMutableArray new]; + [constraints addObject:[self autoSetDimension:ALDimensionWidth toSize:size.width]]; + [constraints addObject:[self autoSetDimension:ALDimensionHeight toSize:size.height]]; + return constraints; +} + +/** + Sets the given dimension of the view to a specific size. + + @param dimension The dimension of this view to set. + @param size The size to set the given dimension to. + @return The constraint added. + */ +- (NSLayoutConstraint *)autoSetDimension:(ALDimension)dimension toSize:(CGFloat)size +{ + return [self autoSetDimension:dimension toSize:size relation:NSLayoutRelationEqual]; +} + +/** + Sets the given dimension of the view to a specific size as a maximum or minimum. + + @param dimension The dimension of this view to set. + @param size The size to set the given dimension to. + @param relation Whether the size should be at least, at most, or exactly equal to the given value. + @return The constraint added. + */ +- (NSLayoutConstraint *)autoSetDimension:(ALDimension)dimension toSize:(CGFloat)size relation:(NSLayoutRelation)relation +{ + self.translatesAutoresizingMaskIntoConstraints = NO; + NSLayoutAttribute layoutAttribute = [NSLayoutConstraint al_layoutAttributeForAttribute:(ALAttribute)dimension]; + NSLayoutConstraint *constraint = [NSLayoutConstraint constraintWithItem:self attribute:layoutAttribute relatedBy:relation toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:0.0 constant:size]; + [constraint autoInstall]; + return constraint; +} + + +#pragma mark Set Content Compression Resistance & Hugging + +/** + Sets the priority of content compression resistance for an axis. + NOTE: This method must be called from within the block passed into the method +[autoSetPriority:forConstraints:] + + @param axis The axis to set the content compression resistance priority for. + */ +- (void)autoSetContentCompressionResistancePriorityForAxis:(ALAxis)axis +{ + NSAssert([NSLayoutConstraint al_isExecutingPriorityConstraintsBlock], @"%@ should only be called from within the block passed into the method +[autoSetPriority:forConstraints:]", NSStringFromSelector(_cmd)); + if ([NSLayoutConstraint al_isExecutingPriorityConstraintsBlock]) { + self.translatesAutoresizingMaskIntoConstraints = NO; + ALLayoutConstraintAxis constraintAxis = [NSLayoutConstraint al_constraintAxisForAxis:axis]; +#if TARGET_OS_IPHONE + [self setContentCompressionResistancePriority:[NSLayoutConstraint al_currentGlobalConstraintPriority] forAxis:constraintAxis]; +#else + [self setContentCompressionResistancePriority:[NSLayoutConstraint al_currentGlobalConstraintPriority] forOrientation:constraintAxis]; +#endif /* TARGET_OS_IPHONE */ + } +} + +/** + Sets the priority of content hugging for an axis. + NOTE: This method must be called from within the block passed into the method +[autoSetPriority:forConstraints:] + + @param axis The axis to set the content hugging priority for. + */ +- (void)autoSetContentHuggingPriorityForAxis:(ALAxis)axis +{ + NSAssert([NSLayoutConstraint al_isExecutingPriorityConstraintsBlock], @"%@ should only be called from within the block passed into the method +[autoSetPriority:forConstraints:]", NSStringFromSelector(_cmd)); + if ([NSLayoutConstraint al_isExecutingPriorityConstraintsBlock]) { + self.translatesAutoresizingMaskIntoConstraints = NO; + ALLayoutConstraintAxis constraintAxis = [NSLayoutConstraint al_constraintAxisForAxis:axis]; +#if TARGET_OS_IPHONE + [self setContentHuggingPriority:[NSLayoutConstraint al_currentGlobalConstraintPriority] forAxis:constraintAxis]; +#else + [self setContentHuggingPriority:[NSLayoutConstraint al_currentGlobalConstraintPriority] forOrientation:constraintAxis]; +#endif /* TARGET_OS_IPHONE */ + } +} + + +#pragma mark Constrain Any Attributes + +/** + Constrains an attribute of the view to a given attribute of another view. + This method can be used to constrain different types of attributes across two views. + + @param attribute Any attribute of this view to constrain. + @param toAttribute Any attribute of the other view to constrain to. + @param otherView The other view to constrain to. Must be in the same view hierarchy as this view. + @return The constraint added. + */ +- (NSLayoutConstraint *)autoConstrainAttribute:(ALAttribute)attribute toAttribute:(ALAttribute)toAttribute ofView:(ALView *)otherView +{ + return [self autoConstrainAttribute:attribute toAttribute:toAttribute ofView:otherView withOffset:0.0]; +} + +/** + Constrains an attribute of the view to a given attribute of another view with an offset. + This method can be used to constrain different types of attributes across two views. + + @param attribute Any attribute of this view to constrain. + @param toAttribute Any attribute of the other view to constrain to. + @param otherView The other view to constrain to. Must be in the same view hierarchy as this view. + @param offset The offset between the attribute of this view and the attribute of the other view. + @return The constraint added. + */ +- (NSLayoutConstraint *)autoConstrainAttribute:(ALAttribute)attribute toAttribute:(ALAttribute)toAttribute ofView:(ALView *)otherView withOffset:(CGFloat)offset +{ + return [self autoConstrainAttribute:attribute toAttribute:toAttribute ofView:otherView withOffset:offset relation:NSLayoutRelationEqual]; +} + +/** + Constrains an attribute of the view to a given attribute of another view with an offset as a maximum or minimum. + This method can be used to constrain different types of attributes across two views. + + @param attribute Any attribute of this view to constrain. + @param toAttribute Any attribute of the other view to constrain to. + @param otherView The other view to constrain to. Must be in the same view hierarchy as this view. + @param offset The offset between the attribute of this view and the attribute of the other view. + @param relation Whether the offset should be at least, at most, or exactly equal to the given value. + @return The constraint added. + */ +- (NSLayoutConstraint *)autoConstrainAttribute:(ALAttribute)attribute toAttribute:(ALAttribute)toAttribute ofView:(ALView *)otherView withOffset:(CGFloat)offset relation:(NSLayoutRelation)relation +{ + self.translatesAutoresizingMaskIntoConstraints = NO; + NSLayoutAttribute layoutAttribute = [NSLayoutConstraint al_layoutAttributeForAttribute:attribute]; + NSLayoutAttribute toLayoutAttribute = [NSLayoutConstraint al_layoutAttributeForAttribute:toAttribute]; + NSLayoutConstraint *constraint = [NSLayoutConstraint constraintWithItem:self attribute:layoutAttribute relatedBy:relation toItem:otherView attribute:toLayoutAttribute multiplier:1.0 constant:offset]; + [constraint autoInstall]; + return constraint; +} + +/** + Constrains an attribute of the view to a given attribute of another view with a multiplier. + This method can be used to constrain different types of attributes across two views. + + @param attribute Any attribute of this view to constrain. + @param toAttribute Any attribute of the other view to constrain to. + @param otherView The other view to constrain to. Must be in the same view hierarchy as this view. + @param multiplier The multiplier between the attribute of this view and the attribute of the other view. + @return The constraint added. + */ +- (NSLayoutConstraint *)autoConstrainAttribute:(ALAttribute)attribute toAttribute:(ALAttribute)toAttribute ofView:(ALView *)otherView withMultiplier:(CGFloat)multiplier +{ + return [self autoConstrainAttribute:attribute toAttribute:toAttribute ofView:otherView withMultiplier:multiplier relation:NSLayoutRelationEqual]; +} + +/** + Constrains an attribute of the view to a given attribute of another view with a multiplier as a maximum or minimum. + This method can be used to constrain different types of attributes across two views. + + @param attribute Any attribute of this view to constrain. + @param toAttribute Any attribute of the other view to constrain to. + @param otherView The other view to constrain to. Must be in the same view hierarchy as this view. + @param multiplier The multiplier between the attribute of this view and the attribute of the other view. + @param relation Whether the multiplier should be at least, at most, or exactly equal to the given value. + @return The constraint added. + */ +- (NSLayoutConstraint *)autoConstrainAttribute:(ALAttribute)attribute toAttribute:(ALAttribute)toAttribute ofView:(ALView *)otherView withMultiplier:(CGFloat)multiplier relation:(NSLayoutRelation)relation +{ + self.translatesAutoresizingMaskIntoConstraints = NO; + NSLayoutAttribute layoutAttribute = [NSLayoutConstraint al_layoutAttributeForAttribute:attribute]; + NSLayoutAttribute toLayoutAttribute = [NSLayoutConstraint al_layoutAttributeForAttribute:toAttribute]; + NSLayoutConstraint *constraint = [NSLayoutConstraint constraintWithItem:self attribute:layoutAttribute relatedBy:relation toItem:otherView attribute:toLayoutAttribute multiplier:multiplier constant:0.0]; + [constraint autoInstall]; + return constraint; +} + + +#pragma mark Pin to Layout Guides + +#if TARGET_OS_IPHONE + +/** + Pins the top edge of the view to the top layout guide of the given view controller with an inset. + For compatibility with iOS 6 (where layout guides do not exist), this method will simply pin the top edge of + the view to the top edge of the given view controller's view with an inset. + + @param viewController The view controller whose topLayoutGuide should be used to pin to. + @param inset The amount to inset this view's top edge from the layout guide. + @return The constraint added. + */ +- (NSLayoutConstraint *)autoPinToTopLayoutGuideOfViewController:(UIViewController *)viewController withInset:(CGFloat)inset +{ + return [self autoPinToTopLayoutGuideOfViewController:viewController withInset:inset relation:NSLayoutRelationEqual]; +} + +- (NSLayoutConstraint *)autoPinToTopLayoutGuideOfViewController:(UIViewController *)viewController withInset:(CGFloat)inset relation:(NSLayoutRelation)relation +{ + if (__PureLayout_MinSysVer_iOS_7_0) { + self.translatesAutoresizingMaskIntoConstraints = NO; + NSLayoutConstraint *constraint = [NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeTop relatedBy:relation toItem:viewController.topLayoutGuide attribute:NSLayoutAttributeBottom multiplier:1.0 constant:inset]; + [viewController.view al_addConstraint:constraint]; // Can't use autoInstall because the layout guide is not a view + return constraint; + } else { + // iOS 6 fallback + return [self autoPinEdge:ALEdgeTop toEdge:ALEdgeTop ofView:viewController.view withOffset:inset relation:relation]; + } +} + +/** + Pins the bottom edge of the view to the bottom layout guide of the given view controller with an inset. + For compatibility with iOS 6 (where layout guides do not exist), this method will simply pin the bottom edge of + the view to the bottom edge of the given view controller's view with an inset. + + @param viewController The view controller whose bottomLayoutGuide should be used to pin to. + @param inset The amount to inset this view's bottom edge from the layout guide. + @return The constraint added. + */ +- (NSLayoutConstraint *)autoPinToBottomLayoutGuideOfViewController:(UIViewController *)viewController withInset:(CGFloat)inset +{ + return [self autoPinToBottomLayoutGuideOfViewController:viewController withInset:inset relation:NSLayoutRelationEqual]; +} + +- (NSLayoutConstraint *)autoPinToBottomLayoutGuideOfViewController:(UIViewController *)viewController withInset:(CGFloat)inset relation:(NSLayoutRelation)relation +{ + // The bottom inset (and relation, if an inequality) is inverted to become an offset + inset = -inset; + if (relation == NSLayoutRelationLessThanOrEqual) { + relation = NSLayoutRelationGreaterThanOrEqual; + } else if (relation == NSLayoutRelationGreaterThanOrEqual) { + relation = NSLayoutRelationLessThanOrEqual; + } + if (__PureLayout_MinSysVer_iOS_7_0) { + self.translatesAutoresizingMaskIntoConstraints = NO; + NSLayoutConstraint *constraint = [NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeBottom relatedBy:relation toItem:viewController.bottomLayoutGuide attribute:NSLayoutAttributeTop multiplier:1.0 constant:inset]; + [viewController.view al_addConstraint:constraint]; // Can't use autoInstall because the layout guide is not a view + return constraint; + } else { + // iOS 6 fallback + return [self autoPinEdge:ALEdgeBottom toEdge:ALEdgeBottom ofView:viewController.view withOffset:inset relation:relation]; + } +} + +#endif /* TARGET_OS_IPHONE */ + + +#pragma mark Internal Methods + +/** + Adds the given constraint to this view after applying the global state to the constraint. + NOTE: This method is compatible with all versions of iOS, and should be used for older versions before the active + property on NSLayoutConstraint was introduced. + + This method should be the only one that calls the UIView/NSView addConstraint: method directly. + + @param constraint The constraint to set the global priority on and then add to this view. + */ +- (void)al_addConstraint:(NSLayoutConstraint *)constraint +{ + [NSLayoutConstraint al_applyGlobalStateToConstraint:constraint]; + if ([NSLayoutConstraint al_preventAutomaticConstraintInstallation]) { + [[NSLayoutConstraint al_currentArrayOfCreatedConstraints] addObject:constraint]; + } else { + [self addConstraint:constraint]; + } +} + +/** + Returns the common superview for this view and the given other view. + Raises an exception if this view and the other view do not share a common superview. + + @return The common superview for the two views. + */ +- (ALView *)al_commonSuperviewWithView:(ALView *)otherView +{ + ALView *commonSuperview = nil; + ALView *startView = self; + do { +#if TARGET_OS_IPHONE + if ([otherView isDescendantOfView:startView]) { + commonSuperview = startView; + } +#else + if ([otherView isDescendantOf:startView]) { + commonSuperview = startView; + } +#endif /* TARGET_OS_IPHONE */ + startView = startView.superview; + } while (startView && !commonSuperview); + NSAssert(commonSuperview, @"Can't constrain two views that do not share a common superview. Make sure that both views have been added into the same view hierarchy."); + return commonSuperview; +} + +/** + Aligns this view to another view with an alignment attribute. + + @param attribute The attribute to use to align the two views. + @param otherView The other view to align to. + @param axis The axis along which the views are distributed, used to validate the alignment attribute. + @return The constraint added. + */ +- (NSLayoutConstraint *)al_alignAttribute:(ALAttribute)attribute toView:(ALView *)otherView forAxis:(ALAxis)axis +{ + NSLayoutConstraint *constraint = nil; + switch (attribute) { + case ALAttributeVertical: + NSAssert(axis == ALAxisVertical, @"Cannot align views that are distributed horizontally with ALAttributeVertical."); + constraint = [self autoAlignAxis:ALAxisVertical toSameAxisOfView:otherView]; + break; + case ALAttributeHorizontal: + NSAssert(axis != ALAxisVertical, @"Cannot align views that are distributed vertically with ALAttributeHorizontal."); + constraint = [self autoAlignAxis:ALAxisHorizontal toSameAxisOfView:otherView]; + break; + case ALAttributeBaseline: // same value as ALAttributeLastBaseline + NSAssert(axis != ALAxisVertical, @"Cannot align views that are distributed vertically with ALAttributeBaseline."); + constraint = [self autoAlignAxis:ALAxisBaseline toSameAxisOfView:otherView]; + break; +#if __PureLayout_MinBaseSDK_iOS_8_0 + case ALAttributeFirstBaseline: + NSAssert(__PureLayout_MinSysVer_iOS_8_0, @"ALAttributeFirstBaseline is only supported on iOS 8.0 or higher."); + NSAssert(axis != ALAxisVertical, @"Cannot align views that are distributed vertically with ALAttributeFirstBaseline."); + constraint = [self autoAlignAxis:ALAxisFirstBaseline toSameAxisOfView:otherView]; + break; +#endif /* __PureLayout_MinBaseSDK_iOS_8_0 */ + case ALAttributeTop: + NSAssert(axis != ALAxisVertical, @"Cannot align views that are distributed vertically with ALAttributeTop."); + constraint = [self autoPinEdge:ALEdgeTop toEdge:ALEdgeTop ofView:otherView]; + break; + case ALAttributeLeft: + NSAssert(axis == ALAxisVertical, @"Cannot align views that are distributed horizontally with ALAttributeLeft."); + constraint = [self autoPinEdge:ALEdgeLeft toEdge:ALEdgeLeft ofView:otherView]; + break; + case ALAttributeBottom: + NSAssert(axis != ALAxisVertical, @"Cannot align views that are distributed vertically with ALAttributeBottom."); + constraint = [self autoPinEdge:ALEdgeBottom toEdge:ALEdgeBottom ofView:otherView]; + break; + case ALAttributeRight: + NSAssert(axis == ALAxisVertical, @"Cannot align views that are distributed horizontally with ALAttributeRight."); + constraint = [self autoPinEdge:ALEdgeRight toEdge:ALEdgeRight ofView:otherView]; + break; + case ALAttributeLeading: + NSAssert(axis == ALAxisVertical, @"Cannot align views that are distributed horizontally with ALAttributeLeading."); + constraint = [self autoPinEdge:ALEdgeLeading toEdge:ALEdgeLeading ofView:otherView]; + break; + case ALAttributeTrailing: + NSAssert(axis == ALAxisVertical, @"Cannot align views that are distributed horizontally with ALAttributeTrailing."); + constraint = [self autoPinEdge:ALEdgeTrailing toEdge:ALEdgeTrailing ofView:otherView]; + break; + + // All of the below attributes are invalid as alignment options. Listing them explicitly (even though they just fall through to the default case) to avoid an incomplete switch statement warning from the compiler. + case ALAttributeWidth: + case ALAttributeHeight: +#if __PureLayout_MinBaseSDK_iOS_8_0 + case ALAttributeMarginLeft: + case ALAttributeMarginRight: + case ALAttributeMarginTop: + case ALAttributeMarginBottom: + case ALAttributeMarginLeading: + case ALAttributeMarginTrailing: + case ALAttributeMarginAxisVertical: + case ALAttributeMarginAxisHorizontal: +#endif /* __PureLayout_MinBaseSDK_iOS_8_0 */ + default: + NSAssert(nil, @"Unsupported attribute for alignment."); + break; + } + return constraint; +} + +@end diff --git a/Example/Pods/PureLayout/PureLayout/PureLayout/NSArray+PureLayout.h b/Example/Pods/PureLayout/PureLayout/PureLayout/NSArray+PureLayout.h new file mode 100755 index 0000000..8616ec2 --- /dev/null +++ b/Example/Pods/PureLayout/PureLayout/PureLayout/NSArray+PureLayout.h @@ -0,0 +1,115 @@ +// +// NSArray+PureLayout.h +// https://github.com/PureLayout/PureLayout +// +// Copyright (c) 2012 Richard Turton +// Copyright (c) 2013-2015 Tyler Fox +// +// This code is distributed under the terms and conditions of the MIT license. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +// + +#import "PureLayoutDefines.h" + + +__PL_ASSUME_NONNULL_BEGIN + +#pragma mark NSArray+PureLayout + +/** + A category on NSArray that provides a simple yet powerful interface to: + - Manage an array of Auto Layout constraints + - Apply constraints to an array of views + */ +@interface NSArray (PureLayout) + + +#pragma mark Array of Constraints + +/** Activates the constraints in this array. */ +- (void)autoInstallConstraints; + +/** Deactivates the constraints in this array. */ +- (void)autoRemoveConstraints; + +#if __PureLayout_MinBaseSDK_iOS_8_0 || __PureLayout_MinBaseSDK_OSX_10_10 + +/** Sets the string as the identifier for the constraints in this array. Available in iOS 7.0 and OS X 10.9 and later. */ +- (instancetype)autoIdentifyConstraints:(NSString *)identifier; + +#endif /* __PureLayout_MinBaseSDK_iOS_8_0 || __PureLayout_MinBaseSDK_OSX_10_10 */ + + +#pragma mark Array of Views + +/** Aligns views in this array to one another along a given edge. */ +- (__NSArray_of(NSLayoutConstraint *) *)autoAlignViewsToEdge:(ALEdge)edge; + +/** Aligns views in this array to one another along a given axis. */ +- (__NSArray_of(NSLayoutConstraint *) *)autoAlignViewsToAxis:(ALAxis)axis; + +/** Matches a given dimension of all the views in this array. */ +- (__NSArray_of(NSLayoutConstraint *) *)autoMatchViewsDimension:(ALDimension)dimension; + +/** Sets the given dimension of all the views in this array to a given size. */ +- (__NSArray_of(NSLayoutConstraint *) *)autoSetViewsDimension:(ALDimension)dimension toSize:(CGFloat)size; + +/** Sets all of the views in this array to a given size. */ +- (__NSArray_of(NSLayoutConstraint *) *)autoSetViewsDimensionsToSize:(CGSize)size; + + +/** Distributes the views in this array equally along the selected axis in their superview. + Views will be the same size (variable) in the dimension along the axis and will have spacing (fixed) between them. */ +- (__NSArray_of(NSLayoutConstraint *) *)autoDistributeViewsAlongAxis:(ALAxis)axis + alignedTo:(ALAttribute)alignment + withFixedSpacing:(CGFloat)spacing; + +/** Distributes the views in this array equally along the selected axis in their superview. + Views will be the same size (variable) in the dimension along the axis and will have spacing (fixed) between them, with optional insets from the first and last views to their superview. */ +- (__NSArray_of(NSLayoutConstraint *) *)autoDistributeViewsAlongAxis:(ALAxis)axis + alignedTo:(ALAttribute)alignment + withFixedSpacing:(CGFloat)spacing + insetSpacing:(BOOL)shouldSpaceInsets; + +/** Distributes the views in this array equally along the selected axis in their superview. + Views will have spacing (fixed) between them, with optional insets from the first and last views to their superview, and optionally constrained to the same size in the dimension along the axis. */ +- (__NSArray_of(NSLayoutConstraint *) *)autoDistributeViewsAlongAxis:(ALAxis)axis + alignedTo:(ALAttribute)alignment + withFixedSpacing:(CGFloat)spacing + insetSpacing:(BOOL)shouldSpaceInsets + matchedSizes:(BOOL)shouldMatchSizes; + + +/** Distributes the views in this array equally along the selected axis in their superview. + Views will be the same size (fixed) in the dimension along the axis and will have spacing (variable) between them. */ +- (__NSArray_of(NSLayoutConstraint *) *)autoDistributeViewsAlongAxis:(ALAxis)axis + alignedTo:(ALAttribute)alignment + withFixedSize:(CGFloat)size; + +/** Distributes the views in this array equally along the selected axis in their superview. + Views will be the same size (fixed) in the dimension along the axis and will have spacing (variable) between them, with optional insets from the first and last views to their superview. */ +- (__NSArray_of(NSLayoutConstraint *) *)autoDistributeViewsAlongAxis:(ALAxis)axis + alignedTo:(ALAttribute)alignment + withFixedSize:(CGFloat)size + insetSpacing:(BOOL)shouldSpaceInsets; + +@end + +__PL_ASSUME_NONNULL_END diff --git a/Example/Pods/PureLayout/PureLayout/PureLayout/NSArray+PureLayout.m b/Example/Pods/PureLayout/PureLayout/PureLayout/NSArray+PureLayout.m new file mode 100755 index 0000000..b7e186f --- /dev/null +++ b/Example/Pods/PureLayout/PureLayout/PureLayout/NSArray+PureLayout.m @@ -0,0 +1,505 @@ +// +// NSArray+PureLayout.m +// https://github.com/PureLayout/PureLayout +// +// Copyright (c) 2012 Richard Turton +// Copyright (c) 2013-2015 Tyler Fox +// +// This code is distributed under the terms and conditions of the MIT license. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +// + +#import "NSArray+PureLayout.h" +#import "ALView+PureLayout.h" +#import "NSLayoutConstraint+PureLayout.h" +#import "PureLayout+Internal.h" + + +#pragma mark - NSArray+PureLayout + +@implementation NSArray (PureLayout) + + +#pragma mark Array of Constraints + +/** + Activates the constraints in this array. + */ +- (void)autoInstallConstraints +{ +#if __PureLayout_MinBaseSDK_iOS_8_0 || __PureLayout_MinBaseSDK_OSX_10_10 + if ([NSLayoutConstraint respondsToSelector:@selector(activateConstraints:)]) { + for (id object in self) { + if ([object isKindOfClass:[NSLayoutConstraint class]]) { + [NSLayoutConstraint al_applyGlobalStateToConstraint:object]; + } + } + if ([NSLayoutConstraint al_preventAutomaticConstraintInstallation]) { + [[NSLayoutConstraint al_currentArrayOfCreatedConstraints] addObjectsFromArray:self]; + } else { + [NSLayoutConstraint activateConstraints:self]; + } + return; + } +#endif /* __PureLayout_MinBaseSDK_iOS_8_0 || __PureLayout_MinBaseSDK_OSX_10_10 */ + + for (id object in self) { + if ([object isKindOfClass:[NSLayoutConstraint class]]) { + [((NSLayoutConstraint *)object) autoInstall]; + } + } +} + +/** + Deactivates the constraints in this array. + */ +- (void)autoRemoveConstraints +{ +#if __PureLayout_MinBaseSDK_iOS_8_0 || __PureLayout_MinBaseSDK_OSX_10_10 + if ([NSLayoutConstraint respondsToSelector:@selector(deactivateConstraints:)]) { + [NSLayoutConstraint deactivateConstraints:self]; + return; + } +#endif /* __PureLayout_MinBaseSDK_iOS_8_0 || __PureLayout_MinBaseSDK_OSX_10_10 */ + + for (id object in self) { + if ([object isKindOfClass:[NSLayoutConstraint class]]) { + [((NSLayoutConstraint *)object) autoRemove]; + } + } +} + +#if __PureLayout_MinBaseSDK_iOS_8_0 || __PureLayout_MinBaseSDK_OSX_10_10 + +/** + Sets the string as the identifier for the constraints in this array. Available in iOS 7.0 and OS X 10.9 and later. + The identifier will be printed along with each constraint's description. + This is helpful to document the constraints' purpose and aid in debugging. + + @param identifier A string used to identify the constraints in this array. + @return This array. + */ +- (instancetype)autoIdentifyConstraints:(NSString *)identifier +{ + for (id object in self) { + if ([object isKindOfClass:[NSLayoutConstraint class]]) { + [((NSLayoutConstraint *)object) autoIdentify:identifier]; + } + } + return self; +} + +#endif /* __PureLayout_MinBaseSDK_iOS_8_0 || __PureLayout_MinBaseSDK_OSX_10_10 */ + + +#pragma mark Array of Views + +/** + Aligns views in this array to one another along a given edge. + Note: This array must contain at least 2 views, and all views must share a common superview. + + @param edge The edge to which the views will be aligned. + @return An array of constraints added. + */ +- (__NSArray_of(NSLayoutConstraint *) *)autoAlignViewsToEdge:(ALEdge)edge +{ + NSAssert([self al_containsMinimumNumberOfViews:2], @"This array must contain at least 2 views."); + __NSMutableArray_of(NSLayoutConstraint *) *constraints = [NSMutableArray new]; + ALView *previousView = nil; + for (id object in self) { + if ([object isKindOfClass:[ALView class]]) { + ALView *view = (ALView *)object; + view.translatesAutoresizingMaskIntoConstraints = NO; + if (previousView) { + [constraints addObject:[view autoPinEdge:edge toEdge:edge ofView:previousView]]; + } + previousView = view; + } + } + return constraints; +} + +/** + Aligns views in this array to one another along a given axis. + Note: This array must contain at least 2 views, and all views must share a common superview. + + @param axis The axis to which the views will be aligned. + @return An array of constraints added. + */ +- (__NSArray_of(NSLayoutConstraint *) *)autoAlignViewsToAxis:(ALAxis)axis +{ + NSAssert([self al_containsMinimumNumberOfViews:2], @"This array must contain at least 2 views."); + __NSMutableArray_of(NSLayoutConstraint *) *constraints = [NSMutableArray new]; + ALView *previousView = nil; + for (id object in self) { + if ([object isKindOfClass:[ALView class]]) { + ALView *view = (ALView *)object; + view.translatesAutoresizingMaskIntoConstraints = NO; + if (previousView) { + [constraints addObject:[view autoAlignAxis:axis toSameAxisOfView:previousView]]; + } + previousView = view; + } + } + return constraints; +} + +/** + Matches a given dimension of all the views in this array. + Note: This array must contain at least 2 views, and all views must share a common superview. + + @param dimension The dimension to match for all of the views. + @return An array of constraints added. + */ +- (__NSArray_of(NSLayoutConstraint *) *)autoMatchViewsDimension:(ALDimension)dimension +{ + NSAssert([self al_containsMinimumNumberOfViews:2], @"This array must contain at least 2 views."); + __NSMutableArray_of(NSLayoutConstraint *) *constraints = [NSMutableArray new]; + ALView *previousView = nil; + for (id object in self) { + if ([object isKindOfClass:[ALView class]]) { + ALView *view = (ALView *)object; + view.translatesAutoresizingMaskIntoConstraints = NO; + if (previousView) { + [constraints addObject:[view autoMatchDimension:dimension toDimension:dimension ofView:previousView]]; + } + previousView = view; + } + } + return constraints; +} + +/** + Sets the given dimension of all the views in this array to a given size. + Note: This array must contain at least 1 view. + + @param dimension The dimension of each of the views to set. + @param size The size to set the given dimension of each view to. + @return An array of constraints added. + */ +- (__NSArray_of(NSLayoutConstraint *) *)autoSetViewsDimension:(ALDimension)dimension toSize:(CGFloat)size +{ + NSAssert([self al_containsMinimumNumberOfViews:1], @"This array must contain at least 1 view."); + __NSMutableArray_of(NSLayoutConstraint *) *constraints = [NSMutableArray new]; + for (id object in self) { + if ([object isKindOfClass:[ALView class]]) { + ALView *view = (ALView *)object; + view.translatesAutoresizingMaskIntoConstraints = NO; + [constraints addObject:[view autoSetDimension:dimension toSize:size]]; + } + } + return constraints; +} + +/** + Sets all of the views in this array to a given size. + Note: This array must contain at least 1 view. + + @param size The size to set each view's dimensions to. + @return An array of constraints added. + */ +- (__NSArray_of(NSLayoutConstraint *) *)autoSetViewsDimensionsToSize:(CGSize)size +{ + __NSMutableArray_of(NSLayoutConstraint *) *constraints = [NSMutableArray new]; + [constraints addObjectsFromArray:[self autoSetViewsDimension:ALDimensionWidth toSize:size.width]]; + [constraints addObjectsFromArray:[self autoSetViewsDimension:ALDimensionHeight toSize:size.height]]; + return constraints; +} + + +/** + Distributes the views in this array equally along the selected axis in their superview. + Views will be the same size (variable) in the dimension along the axis and will have spacing (fixed) between them, + including from the first and last views to their superview. + + @param axis The axis along which to distribute the views. + @param alignment The attribute to use to align all the views to one another. + @param spacing The fixed amount of spacing between each view. + @return An array of constraints added. + */ +- (__NSArray_of(NSLayoutConstraint *) *)autoDistributeViewsAlongAxis:(ALAxis)axis + alignedTo:(ALAttribute)alignment + withFixedSpacing:(CGFloat)spacing +{ + return [self autoDistributeViewsAlongAxis:axis + alignedTo:alignment + withFixedSpacing:spacing + insetSpacing:YES]; +} + +/** + Distributes the views in this array equally along the selected axis in their superview. + Views will be the same size (variable) in the dimension along the axis and will have spacing (fixed) between them. + The first and last views can optionally be inset from their superview by the same amount of spacing as between views. + + @param axis The axis along which to distribute the views. + @param alignment The attribute to use to align all the views to one another. + @param spacing The fixed amount of spacing between each view. + @param shouldSpaceInsets Whether the first and last views should be equally inset from their superview. + @return An array of constraints added. + */ +- (__NSArray_of(NSLayoutConstraint *) *)autoDistributeViewsAlongAxis:(ALAxis)axis + alignedTo:(ALAttribute)alignment + withFixedSpacing:(CGFloat)spacing + insetSpacing:(BOOL)shouldSpaceInsets +{ + return [self autoDistributeViewsAlongAxis:axis + alignedTo:alignment + withFixedSpacing:spacing + insetSpacing:shouldSpaceInsets + matchedSizes:YES]; +} + +/** + Distributes the views in this array equally along the selected axis in their superview. + Views will have fixed spacing between them, and can optionally be constrained to the same size in the dimension along the axis. + The first and last views can optionally be inset from their superview by the same amount of spacing as between views. + + @param axis The axis along which to distribute the views. + @param alignment The attribute to use to align all the views to one another. + @param spacing The fixed amount of spacing between each view. + @param shouldSpaceInsets Whether the first and last views should be equally inset from their superview. + @param shouldMatchSizes Whether all views will be constrained to be the same size in the dimension along the axis. + NOTE: All views must specify an intrinsic content size if passing NO, otherwise the layout will be ambiguous! + @return An array of constraints added. + */ +- (__NSArray_of(NSLayoutConstraint *) *)autoDistributeViewsAlongAxis:(ALAxis)axis + alignedTo:(ALAttribute)alignment + withFixedSpacing:(CGFloat)spacing + insetSpacing:(BOOL)shouldSpaceInsets + matchedSizes:(BOOL)shouldMatchSizes +{ + NSAssert([self al_containsMinimumNumberOfViews:1], @"This array must contain at least 1 view to distribute."); + ALDimension matchedDimension; + ALEdge firstEdge, lastEdge; + switch (axis) { + case ALAxisHorizontal: + case ALAxisBaseline: // same value as ALAxisLastBaseline +#if __PureLayout_MinBaseSDK_iOS_8_0 + case ALAxisFirstBaseline: +#endif /* __PureLayout_MinBaseSDK_iOS_8_0 */ + matchedDimension = ALDimensionWidth; + firstEdge = ALEdgeLeading; + lastEdge = ALEdgeTrailing; + break; + case ALAxisVertical: + matchedDimension = ALDimensionHeight; + firstEdge = ALEdgeTop; + lastEdge = ALEdgeBottom; + break; + default: + NSAssert(nil, @"Not a valid ALAxis."); + return nil; + } + CGFloat leadingSpacing = shouldSpaceInsets ? spacing : 0.0; + CGFloat trailingSpacing = shouldSpaceInsets ? spacing : 0.0; + + __NSMutableArray_of(NSLayoutConstraint *) *constraints = [NSMutableArray new]; + ALView *previousView = nil; + for (id object in self) { + if ([object isKindOfClass:[ALView class]]) { + ALView *view = (ALView *)object; + view.translatesAutoresizingMaskIntoConstraints = NO; + if (previousView) { + // Second, Third, ... View + [constraints addObject:[view autoPinEdge:firstEdge toEdge:lastEdge ofView:previousView withOffset:spacing]]; + if (shouldMatchSizes) { + [constraints addObject:[view autoMatchDimension:matchedDimension toDimension:matchedDimension ofView:previousView]]; + } + [constraints addObject:[view al_alignAttribute:alignment toView:previousView forAxis:axis]]; + } + else { + // First view + [constraints addObject:[view autoPinEdgeToSuperviewEdge:firstEdge withInset:leadingSpacing]]; + } + previousView = view; + } + } + if (previousView) { + // Last View + [constraints addObject:[previousView autoPinEdgeToSuperviewEdge:lastEdge withInset:trailingSpacing]]; + } + return constraints; +} + +/** + Distributes the views in this array equally along the selected axis in their superview. + Views will be the same size (fixed) in the dimension along the axis and will have spacing (variable) between them, + including from the first and last views to their superview. + + @param axis The axis along which to distribute the views. + @param alignment The attribute to use to align all the views to one another. + @param size The fixed size of each view in the dimension along the given axis. + @return An array of constraints added. + */ +- (__NSArray_of(NSLayoutConstraint *) *)autoDistributeViewsAlongAxis:(ALAxis)axis + alignedTo:(ALAttribute)alignment + withFixedSize:(CGFloat)size +{ + return [self autoDistributeViewsAlongAxis:axis + alignedTo:alignment + withFixedSize:size + insetSpacing:YES]; +} + +/** + Distributes the views in this array equally along the selected axis in their superview. + Views will be the same size (fixed) in the dimension along the axis and will have spacing (variable) between them. + The first and last views can optionally be inset from their superview by the same amount of spacing as between views. + + @param axis The axis along which to distribute the views. + @param alignment The attribute to use to align all the views to one another. + @param size The fixed size of each view in the dimension along the given axis. + @param shouldSpaceInsets Whether the first and last views should be equally inset from their superview. + @return An array of constraints added. + */ +- (__NSArray_of(NSLayoutConstraint *) *)autoDistributeViewsAlongAxis:(ALAxis)axis + alignedTo:(ALAttribute)alignment + withFixedSize:(CGFloat)size + insetSpacing:(BOOL)shouldSpaceInsets +{ + NSAssert([self al_containsMinimumNumberOfViews:1], @"This array must contain at least 1 view to distribute."); + ALDimension fixedDimension; + NSLayoutAttribute attribute; + switch (axis) { + case ALAxisHorizontal: + case ALAxisBaseline: // same value as ALAxisLastBaseline +#if __PureLayout_MinBaseSDK_iOS_8_0 + case ALAxisFirstBaseline: +#endif /* __PureLayout_MinBaseSDK_iOS_8_0 */ + fixedDimension = ALDimensionWidth; + attribute = NSLayoutAttributeCenterX; + break; + case ALAxisVertical: + fixedDimension = ALDimensionHeight; + attribute = NSLayoutAttributeCenterY; + break; + default: + NSAssert(nil, @"Not a valid ALAxis."); + return nil; + } +#if TARGET_OS_IPHONE +# if !defined(PURELAYOUT_APP_EXTENSIONS) + BOOL isRightToLeftLayout = [[UIApplication sharedApplication] userInterfaceLayoutDirection] == UIUserInterfaceLayoutDirectionRightToLeft; +# else + // App Extensions may not access -[UIApplication sharedApplication]; fall back to checking the bundle's preferred localization character direction + BOOL isRightToLeftLayout = [NSLocale characterDirectionForLanguage:[[NSBundle mainBundle] preferredLocalizations][0]] == NSLocaleLanguageDirectionRightToLeft; +# endif /* !defined(PURELAYOUT_APP_EXTENSIONS) */ +#else + BOOL isRightToLeftLayout = [[NSApplication sharedApplication] userInterfaceLayoutDirection] == NSUserInterfaceLayoutDirectionRightToLeft; +#endif /* TARGET_OS_IPHONE */ + BOOL shouldFlipOrder = isRightToLeftLayout && (axis != ALAxisVertical); // imitate the effect of leading/trailing when distributing horizontally + + __NSMutableArray_of(NSLayoutConstraint *) *constraints = [NSMutableArray new]; + __NSArray_of(ALView *) *views = [self al_copyViewsOnly]; + NSUInteger numberOfViews = [views count]; + ALView *commonSuperview = [views al_commonSuperviewOfViews]; + ALView *previousView = nil; + for (NSUInteger i = 0; i < numberOfViews; i++) { + ALView *view = shouldFlipOrder ? views[numberOfViews - i - 1] : views[i]; + view.translatesAutoresizingMaskIntoConstraints = NO; + [constraints addObject:[view autoSetDimension:fixedDimension toSize:size]]; + CGFloat multiplier, constant; + if (shouldSpaceInsets) { + multiplier = (i * 2.0 + 2.0) / (numberOfViews + 1.0); + constant = (multiplier - 1.0) * size / 2.0; + } else { + multiplier = (i * 2.0) / (numberOfViews - 1.0); + constant = (-multiplier + 1.0) * size / 2.0; + } + // If the multiplier is very close to 0, set it to the minimum value to prevent the second item in the constraint from being lost. Filed as rdar://19168380 + if (fabs(multiplier) < kMULTIPLIER_MIN_VALUE) { + multiplier = kMULTIPLIER_MIN_VALUE; + } + NSLayoutConstraint *constraint = [NSLayoutConstraint constraintWithItem:view attribute:attribute relatedBy:NSLayoutRelationEqual toItem:commonSuperview attribute:attribute multiplier:multiplier constant:constant]; + [constraint autoInstall]; + [constraints addObject:constraint]; + if (previousView) { + [constraints addObject:[view al_alignAttribute:alignment toView:previousView forAxis:axis]]; + } + previousView = view; + } + return constraints; +} + +#pragma mark Internal Helper Methods + +/** + Returns the common superview for the views in this array. If there is only one view in the array, its superview will be returned. + Raises an exception if the views in this array do not share a common superview. + + @return The common superview for the views in this array. + */ +- (ALView *)al_commonSuperviewOfViews +{ + ALView *commonSuperview = nil; + ALView *previousView = nil; + for (id object in self) { + if ([object isKindOfClass:[ALView class]]) { + ALView *view = (ALView *)object; + if (previousView) { + commonSuperview = [view al_commonSuperviewWithView:commonSuperview]; + } else { + commonSuperview = view.superview; + } + previousView = view; + } + } + NSAssert(commonSuperview, @"Can't constrain views that do not share a common superview. Make sure that all the views in this array have been added into the same view hierarchy."); + return commonSuperview; +} + +/** + Determines whether this array contains a minimum number of views. + + @param minimumNumberOfViews The minimum number of views to check for. + @return YES if this array contains at least the minimum number of views, NO otherwise. + */ +- (BOOL)al_containsMinimumNumberOfViews:(NSUInteger)minimumNumberOfViews +{ + NSUInteger numberOfViews = 0; + for (id object in self) { + if ([object isKindOfClass:[ALView class]]) { + numberOfViews++; + if (numberOfViews >= minimumNumberOfViews) { + return YES; + } + } + } + return numberOfViews >= minimumNumberOfViews; +} + +/** + Creates a copy of this array containing only the view objects in it. + + @return A new array containing only the views that are in this array. + */ +- (__NSArray_of(ALView *) *)al_copyViewsOnly +{ + __NSMutableArray_of(ALView *) *viewsOnlyArray = [NSMutableArray arrayWithCapacity:[self count]]; + for (id object in self) { + if ([object isKindOfClass:[ALView class]]) { + [viewsOnlyArray addObject:object]; + } + } + return viewsOnlyArray; +} + +@end diff --git a/Example/Pods/PureLayout/PureLayout/PureLayout/NSLayoutConstraint+PureLayout.h b/Example/Pods/PureLayout/PureLayout/PureLayout/NSLayoutConstraint+PureLayout.h new file mode 100755 index 0000000..950fb26 --- /dev/null +++ b/Example/Pods/PureLayout/PureLayout/PureLayout/NSLayoutConstraint+PureLayout.h @@ -0,0 +1,84 @@ +// +// NSLayoutConstraint+PureLayout.h +// https://github.com/PureLayout/PureLayout +// +// Copyright (c) 2013-2015 Tyler Fox +// +// This code is distributed under the terms and conditions of the MIT license. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +// + +#import "PureLayoutDefines.h" + + +__PL_ASSUME_NONNULL_BEGIN + +#pragma mark NSLayoutConstraint+PureLayout + +/** + A category on NSLayoutConstraint that allows constraints to be easily installed & removed. + */ +@interface NSLayoutConstraint (PureLayout) + + +#pragma mark Batch Constraint Creation + +/** Creates all of the constraints in the block, then installs (activates) them all at once. + All constraints created from calls to the PureLayout API in the block are returned in a single array. + This may be more efficient than installing (activating) each constraint one-by-one. */ ++ (__NSArray_of(NSLayoutConstraint *) *)autoCreateAndInstallConstraints:(ALConstraintsBlock)block; + +/** Creates all of the constraints in the block but prevents them from being automatically installed (activated). + All constraints created from calls to the PureLayout API in the block are returned in a single array. */ ++ (__NSArray_of(NSLayoutConstraint *) *)autoCreateConstraintsWithoutInstalling:(ALConstraintsBlock)block; + + +#pragma mark Set Priority For Constraints + +/** Sets the constraint priority to the given value for all constraints created using the PureLayout API within the given constraints block. + NOTE: This method will have no effect (and will NOT set the priority) on constraints created or added without using the PureLayout API! */ ++ (void)autoSetPriority:(ALLayoutPriority)priority forConstraints:(ALConstraintsBlock)block; + + +#pragma mark Identify Constraints + +#if __PureLayout_MinBaseSDK_iOS_8_0 || __PureLayout_MinBaseSDK_OSX_10_10 + +/** Sets the identifier for all constraints created using the PureLayout API within the given constraints block. + NOTE: This method will have no effect (and will NOT set the identifier) on constraints created or added without using the PureLayout API! */ ++ (void)autoSetIdentifier:(NSString *)identifier forConstraints:(ALConstraintsBlock)block; + +/** Sets the string as the identifier for this constraint. Available in iOS 7.0 and OS X 10.9 and later. */ +- (instancetype)autoIdentify:(NSString *)identifier; + +#endif /* __PureLayout_MinBaseSDK_iOS_8_0 || __PureLayout_MinBaseSDK_OSX_10_10 */ + + +#pragma mark Install & Remove Constraints + +/** Activates the the constraint. */ +- (void)autoInstall; + +/** Deactivates the constraint. */ +- (void)autoRemove; + +@end + +__PL_ASSUME_NONNULL_END diff --git a/Example/Pods/PureLayout/PureLayout/PureLayout/NSLayoutConstraint+PureLayout.m b/Example/Pods/PureLayout/PureLayout/PureLayout/NSLayoutConstraint+PureLayout.m new file mode 100755 index 0000000..5ba3676 --- /dev/null +++ b/Example/Pods/PureLayout/PureLayout/PureLayout/NSLayoutConstraint+PureLayout.m @@ -0,0 +1,552 @@ +// +// NSLayoutConstraint+PureLayout.m +// https://github.com/PureLayout/PureLayout +// +// Copyright (c) 2013-2015 Tyler Fox +// +// This code is distributed under the terms and conditions of the MIT license. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +// + +#import "NSLayoutConstraint+PureLayout.h" +#import "ALView+PureLayout.h" +#import "NSArray+PureLayout.h" +#import "PureLayout+Internal.h" + + +#pragma mark - NSLayoutConstraint+PureLayout + +@implementation NSLayoutConstraint (PureLayout) + +#pragma mark Batch Constraint Creation + +/** + A global variable that stores a stack of arrays of constraints created without being immediately installed. + When executing a constraints block passed into the +[autoCreateConstraintsWithoutInstalling:] method, a new + mutable array is pushed onto this stack, and all constraints created with PureLayout in the block are added + to this array. When the block finishes executing, the array is popped off this stack. Automatic constraint + installation is prevented if this stack contains at least 1 array. + + NOTE: Access to this variable is not synchronized (and should only be done on the main thread). + */ +static __NSMutableArray_of(__NSMutableArray_of(NSLayoutConstraint *) *) *_al_arraysOfCreatedConstraints = nil; + +/** + A global variable that is set to YES when installing a batch of constraints collected from a call to +[autoCreateAndInstallConstraints]. + When this flag is YES, constraints are installed immediately without checking for or adding to the +[al_currentArrayOfCreatedConstraints]. + This is necessary to properly handle nested calls to +[autoCreateAndInstallConstraints], where calls whose block contains other call(s) + should not return constraints from within the blocks of nested call(s). + */ +static BOOL _al_isInstallingCreatedConstraints = NO; + +/** + Accessor for the global state that stores arrays of constraints created without being installed. + */ ++ (__NSMutableArray_of(__NSMutableArray_of(NSLayoutConstraint *) *) *)al_arraysOfCreatedConstraints +{ + NSAssert([NSThread isMainThread], @"PureLayout is not thread safe, and must be used exclusively from the main thread."); + if (!_al_arraysOfCreatedConstraints) { + _al_arraysOfCreatedConstraints = [NSMutableArray new]; + } + return _al_arraysOfCreatedConstraints; +} + +/** + Accessor for the current mutable array of constraints created without being immediately installed. + */ ++ (__NSMutableArray_of(NSLayoutConstraint *) *)al_currentArrayOfCreatedConstraints +{ + return [[self al_arraysOfCreatedConstraints] lastObject]; +} + +/** + Accessor for the global state that determines whether automatic constraint installation should be prevented. + */ ++ (BOOL)al_preventAutomaticConstraintInstallation +{ + return (_al_isInstallingCreatedConstraints == NO) && ([[self al_arraysOfCreatedConstraints] count] > 0); +} + +/** + Creates all of the constraints in the block, then installs (activates) them all at once. + All constraints created from calls to the PureLayout API in the block are returned in a single array. + This may be more efficient than installing (activating) each constraint one-by-one. + + Note: calls to this method may be nested. The constraints returned from a call will NOT include constraints + created in nested calls; constraints are only returned from the inner-most call they are created within. + + @param block A block of method calls to the PureLayout API that create constraints. + @return An array of the constraints that were created from calls to the PureLayout API inside the block. + */ ++ (__NSArray_of(NSLayoutConstraint *) *)autoCreateAndInstallConstraints:(ALConstraintsBlock)block +{ + NSArray *createdConstraints = [self autoCreateConstraintsWithoutInstalling:block]; + _al_isInstallingCreatedConstraints = YES; + [createdConstraints autoInstallConstraints]; + _al_isInstallingCreatedConstraints = NO; + return createdConstraints; +} + +/** + Creates all of the constraints in the block but prevents them from being automatically installed (activated). + All constraints created from calls to the PureLayout API in the block are returned in a single array. + + Note: calls to this method may be nested. The constraints returned from a call will NOT include constraints + created in nested calls; constraints are only returned from the inner-most call they are created within. + + @param block A block of method calls to the PureLayout API that create constraints. + @return An array of the constraints that were created from calls to the PureLayout API inside the block. + */ ++ (__NSArray_of(NSLayoutConstraint *) *)autoCreateConstraintsWithoutInstalling:(ALConstraintsBlock)block +{ + NSAssert(block, @"The constraints block cannot be nil."); + NSArray *createdConstraints = nil; + if (block) { + [[self al_arraysOfCreatedConstraints] addObject:[NSMutableArray new]]; + block(); + createdConstraints = [self al_currentArrayOfCreatedConstraints]; + [[self al_arraysOfCreatedConstraints] removeLastObject]; + } + return createdConstraints; +} + + +#pragma mark Set Priority For Constraints + +/** + A global variable that stores a stack of layout priorities to set on constraints. + When executing a constraints block passed into the +[autoSetPriority:forConstraints:] method, the priority for + that call is pushed onto this stack, and when the block finishes executing, that priority is popped off this + stack. If this stack contains at least 1 priority, the priority at the top of the stack will be set for all + constraints created by this library (even if automatic constraint installation is being prevented). + NOTE: Access to this variable is not synchronized (and should only be done on the main thread). + */ +static __NSMutableArray_of(NSNumber *) *_al_globalConstraintPriorities = nil; + +/** + Accessor for the global stack of layout priorities. + */ ++ (__NSMutableArray_of(NSNumber *) *)al_globalConstraintPriorities +{ + NSAssert([NSThread isMainThread], @"PureLayout is not thread safe, and must be used exclusively from the main thread."); + if (!_al_globalConstraintPriorities) { + _al_globalConstraintPriorities = [NSMutableArray new]; + } + return _al_globalConstraintPriorities; +} + +/** + Returns the current layout priority to use for constraints. + When executing a constraints block passed into +[autoSetPriority:forConstraints:], this will return + the priority for the current block. Otherwise, the default Required priority is returned. + */ ++ (ALLayoutPriority)al_currentGlobalConstraintPriority +{ + __NSMutableArray_of(NSNumber *) *globalConstraintPriorities = [self al_globalConstraintPriorities]; + if ([globalConstraintPriorities count] == 0) { + return ALLayoutPriorityRequired; + } + return [[globalConstraintPriorities lastObject] floatValue]; +} + +/** + Accessor for the global state that determines if we're currently in the scope of a priority constraints block. + */ ++ (BOOL)al_isExecutingPriorityConstraintsBlock +{ + return [[self al_globalConstraintPriorities] count] > 0; +} + +/** + Sets the constraint priority to the given value for all constraints created using the PureLayout + API within the given constraints block. + + NOTE: This method will have no effect (and will NOT set the priority) on constraints created or added + without using the PureLayout API! + + @param priority The layout priority to be set on all constraints created in the constraints block. + @param block A block of method calls to the PureLayout API that create and install constraints. + */ ++ (void)autoSetPriority:(ALLayoutPriority)priority forConstraints:(ALConstraintsBlock)block +{ + NSAssert(block, @"The constraints block cannot be nil."); + if (block) { + [[self al_globalConstraintPriorities] addObject:@(priority)]; + block(); + [[self al_globalConstraintPriorities] removeLastObject]; + } +} + + +#pragma mark Identify Constraints + +#if __PureLayout_MinBaseSDK_iOS_8_0 || __PureLayout_MinBaseSDK_OSX_10_10 + +/** + A global variable that stores a stack of identifier strings to set on constraints. + When executing a constraints block passed into the +[autoSetIdentifier:forConstraints:] method, the identifier for + that call is pushed onto this stack, and when the block finishes executing, that identifier is popped off this + stack. If this stack contains at least 1 identifier, the identifier at the top of the stack will be set for all + constraints created by this library (even if automatic constraint installation is being prevented). + NOTE: Access to this variable is not synchronized (and should only be done on the main thread). + */ +static __NSMutableArray_of(NSString *) *_al_globalConstraintIdentifiers = nil; + +/** + Accessor for the global state of constraint identifiers. + */ ++ (__NSMutableArray_of(NSString *) *)al_globalConstraintIdentifiers +{ + NSAssert([NSThread isMainThread], @"PureLayout is not thread safe, and must be used exclusively from the main thread."); + if (!_al_globalConstraintIdentifiers) { + _al_globalConstraintIdentifiers = [NSMutableArray new]; + } + return _al_globalConstraintIdentifiers; +} + +/** + Returns the current identifier string to use for constraints. + When executing a constraints block passed into +[autoSetIdentifier:forConstraints:], this will return + the identifier for the current block. Otherwise, nil is returned. + */ ++ (NSString *)al_currentGlobalConstraintIdentifier +{ + __NSMutableArray_of(NSString *) *globalConstraintIdentifiers = [self al_globalConstraintIdentifiers]; + if ([globalConstraintIdentifiers count] == 0) { + return nil; + } + return [globalConstraintIdentifiers lastObject]; +} + +/** + Sets the identifier for all constraints created using the PureLayout API within the given constraints block. + + NOTE: This method will have no effect (and will NOT set the identifier) on constraints created or added + without using the PureLayout API! + + @param identifier A string used to identify all constraints created in the constraints block. + @param block A block of method calls to the PureLayout API that create and install constraints. + */ ++ (void)autoSetIdentifier:(NSString *)identifier forConstraints:(ALConstraintsBlock)block +{ + NSAssert(block, @"The constraints block cannot be nil."); + NSAssert(identifier, @"The identifier string cannot be nil."); + if (block) { + if (identifier) { + [[self al_globalConstraintIdentifiers] addObject:identifier]; + } + block(); + if (identifier) { + [[self al_globalConstraintIdentifiers] removeLastObject]; + } + } +} + +/** + Sets the string as the identifier for this constraint. Available in iOS 7.0 and OS X 10.9 and later. + The identifier will be printed along with the constraint's description. + This is helpful to document a constraint's purpose and aid in debugging. + + @param identifier A string used to identify this constraint. + @return This constraint. + */ +- (instancetype)autoIdentify:(NSString *)identifier +{ + if ([self respondsToSelector:@selector(setIdentifier:)]) { + self.identifier = identifier; + } + return self; +} + +#endif /* __PureLayout_MinBaseSDK_iOS_8_0 || __PureLayout_MinBaseSDK_OSX_10_10 */ + + +#pragma mark Install & Remove Constraints + +/** + Activates the constraint. + */ +- (void)autoInstall +{ +#if __PureLayout_MinBaseSDK_iOS_8_0 || __PureLayout_MinBaseSDK_OSX_10_10 + if ([self respondsToSelector:@selector(setActive:)]) { + [NSLayoutConstraint al_applyGlobalStateToConstraint:self]; + if ([NSLayoutConstraint al_preventAutomaticConstraintInstallation]) { + [[NSLayoutConstraint al_currentArrayOfCreatedConstraints] addObject:self]; + } else { + self.active = YES; + } + return; + } +#endif /* __PureLayout_MinBaseSDK_iOS_8_0 || __PureLayout_MinBaseSDK_OSX_10_10 */ + + NSAssert(self.firstItem || self.secondItem, @"Can't install a constraint with nil firstItem and secondItem."); + if (self.firstItem) { + if (self.secondItem) { + NSAssert([self.firstItem isKindOfClass:[ALView class]] && [self.secondItem isKindOfClass:[ALView class]], @"Can only automatically install a constraint if both items are views."); + ALView *commonSuperview = [self.firstItem al_commonSuperviewWithView:self.secondItem]; + [commonSuperview al_addConstraint:self]; + } else { + NSAssert([self.firstItem isKindOfClass:[ALView class]], @"Can only automatically install a constraint if the item is a view."); + [self.firstItem al_addConstraint:self]; + } + } else { + NSAssert([self.secondItem isKindOfClass:[ALView class]], @"Can only automatically install a constraint if the item is a view."); + [self.secondItem al_addConstraint:self]; + } +} + +/** + Deactivates the constraint. + */ +- (void)autoRemove +{ +#if __PureLayout_MinBaseSDK_iOS_8_0 || __PureLayout_MinBaseSDK_OSX_10_10 + if ([self respondsToSelector:@selector(setActive:)]) { + self.active = NO; + return; + } +#endif /* __PureLayout_MinBaseSDK_iOS_8_0 || __PureLayout_MinBaseSDK_OSX_10_10 */ + + if (self.secondItem) { + ALView *commonSuperview = [self.firstItem al_commonSuperviewWithView:self.secondItem]; + while (commonSuperview) { + if ([commonSuperview.constraints containsObject:self]) { + [commonSuperview removeConstraint:self]; + return; + } + commonSuperview = commonSuperview.superview; + } + } + else { + [self.firstItem removeConstraint:self]; + return; + } + NSAssert(nil, @"Failed to remove constraint: %@", self); +} + + +#pragma mark Internal Methods + +/** + Applies the global constraint priority and identifier to the given constraint. + This should be done before installing all constraints. + + @param constraint The constraint to set the global priority and identifier on. + */ ++ (void)al_applyGlobalStateToConstraint:(NSLayoutConstraint *)constraint +{ + if ([NSLayoutConstraint al_isExecutingPriorityConstraintsBlock]) { + constraint.priority = [NSLayoutConstraint al_currentGlobalConstraintPriority]; + } +#if __PureLayout_MinBaseSDK_iOS_8_0 || __PureLayout_MinBaseSDK_OSX_10_10 + NSString *globalConstraintIdentifier = [NSLayoutConstraint al_currentGlobalConstraintIdentifier]; + if (globalConstraintIdentifier) { + [constraint autoIdentify:globalConstraintIdentifier]; + } +#endif /* __PureLayout_MinBaseSDK_iOS_8_0 || __PureLayout_MinBaseSDK_OSX_10_10 */ +} + +/** + Returns the corresponding NSLayoutAttribute for the given ALAttribute. + + @return The layout attribute for the given ALAttribute. + */ ++ (NSLayoutAttribute)al_layoutAttributeForAttribute:(ALAttribute)attribute +{ + NSLayoutAttribute layoutAttribute = NSLayoutAttributeNotAnAttribute; + switch (attribute) { + case ALEdgeLeft: + layoutAttribute = NSLayoutAttributeLeft; + break; + case ALEdgeRight: + layoutAttribute = NSLayoutAttributeRight; + break; + case ALEdgeTop: + layoutAttribute = NSLayoutAttributeTop; + break; + case ALEdgeBottom: + layoutAttribute = NSLayoutAttributeBottom; + break; + case ALEdgeLeading: + layoutAttribute = NSLayoutAttributeLeading; + break; + case ALEdgeTrailing: + layoutAttribute = NSLayoutAttributeTrailing; + break; + case ALDimensionWidth: + layoutAttribute = NSLayoutAttributeWidth; + break; + case ALDimensionHeight: + layoutAttribute = NSLayoutAttributeHeight; + break; + case ALAxisVertical: + layoutAttribute = NSLayoutAttributeCenterX; + break; + case ALAxisHorizontal: + layoutAttribute = NSLayoutAttributeCenterY; + break; + case ALAxisBaseline: // same value as ALAxisLastBaseline + layoutAttribute = NSLayoutAttributeBaseline; + break; +#if __PureLayout_MinBaseSDK_iOS_8_0 + case ALAxisFirstBaseline: + NSAssert(__PureLayout_MinSysVer_iOS_8_0, @"ALAxisFirstBaseline is only supported on iOS 8.0 or higher."); + layoutAttribute = NSLayoutAttributeFirstBaseline; + break; + case ALMarginLeft: + NSAssert(__PureLayout_MinSysVer_iOS_8_0, @"ALEdgeLeftMargin is only supported on iOS 8.0 or higher."); + layoutAttribute = NSLayoutAttributeLeftMargin; + break; + case ALMarginRight: + NSAssert(__PureLayout_MinSysVer_iOS_8_0, @"ALEdgeRightMargin is only supported on iOS 8.0 or higher."); + layoutAttribute = NSLayoutAttributeRightMargin; + break; + case ALMarginTop: + NSAssert(__PureLayout_MinSysVer_iOS_8_0, @"ALEdgeTopMargin is only supported on iOS 8.0 or higher."); + layoutAttribute = NSLayoutAttributeTopMargin; + break; + case ALMarginBottom: + NSAssert(__PureLayout_MinSysVer_iOS_8_0, @"ALEdgeBottomMargin is only supported on iOS 8.0 or higher."); + layoutAttribute = NSLayoutAttributeBottomMargin; + break; + case ALMarginLeading: + NSAssert(__PureLayout_MinSysVer_iOS_8_0, @"ALEdgeLeadingMargin is only supported on iOS 8.0 or higher."); + layoutAttribute = NSLayoutAttributeLeadingMargin; + break; + case ALMarginTrailing: + NSAssert(__PureLayout_MinSysVer_iOS_8_0, @"ALEdgeTrailingMargin is only supported on iOS 8.0 or higher."); + layoutAttribute = NSLayoutAttributeTrailingMargin; + break; + case ALMarginAxisVertical: + NSAssert(__PureLayout_MinSysVer_iOS_8_0, @"ALAxisVerticalMargin is only supported on iOS 8.0 or higher."); + layoutAttribute = NSLayoutAttributeCenterXWithinMargins; + break; + case ALMarginAxisHorizontal: + NSAssert(__PureLayout_MinSysVer_iOS_8_0, @"ALAxisHorizontalMargin is only supported on iOS 8.0 or higher."); + layoutAttribute = NSLayoutAttributeCenterYWithinMargins; + break; +#endif /* __PureLayout_MinBaseSDK_iOS_8_0 */ + default: + NSAssert(nil, @"Not a valid ALAttribute."); + break; + } + return layoutAttribute; +} + +/** + Returns the corresponding ALLayoutConstraintAxis for the given ALAxis. + + @return The constraint axis for the given axis. + */ ++ (ALLayoutConstraintAxis)al_constraintAxisForAxis:(ALAxis)axis +{ + ALLayoutConstraintAxis constraintAxis; + switch (axis) { + case ALAxisVertical: + constraintAxis = ALLayoutConstraintAxisVertical; + break; + case ALAxisHorizontal: + case ALAxisBaseline: // same value as ALAxisLastBaseline +#if __PureLayout_MinBaseSDK_iOS_8_0 + case ALAxisFirstBaseline: +#endif /* __PureLayout_MinBaseSDK_iOS_8_0 */ + constraintAxis = ALLayoutConstraintAxisHorizontal; + break; + default: + NSAssert(nil, @"Not a valid ALAxis."); + constraintAxis = ALLayoutConstraintAxisHorizontal; // default to an arbitrary value to satisfy the compiler + break; + } + return constraintAxis; +} + +#if __PureLayout_MinBaseSDK_iOS_8_0 + +/** + Returns the corresponding margin for the given edge. + + @param edge The edge to convert to the corresponding margin. + @return The margin for the given edge. + */ ++ (ALMargin)al_marginForEdge:(ALEdge)edge +{ + NSAssert(__PureLayout_MinSysVer_iOS_8_0, @"Margin attributes are only supported on iOS 8.0 or higher."); + ALMargin margin; + switch (edge) { + case ALEdgeLeft: + margin = ALMarginLeft; + break; + case ALEdgeRight: + margin = ALMarginRight; + break; + case ALEdgeTop: + margin = ALMarginTop; + break; + case ALEdgeBottom: + margin = ALMarginBottom; + break; + case ALEdgeLeading: + margin = ALMarginLeading; + break; + case ALEdgeTrailing: + margin = ALMarginTrailing; + break; + default: + NSAssert(nil, @"Not a valid ALEdge."); + margin = ALMarginLeft; // default to an arbitrary value to satisfy the compiler + break; + } + return margin; +} + +/** + Returns the corresponding margin axis for the given axis. + + @param axis The axis to convert to the corresponding margin axis. + @return The margin axis for the given axis. + */ ++ (ALMarginAxis)al_marginAxisForAxis:(ALAxis)axis +{ + NSAssert(__PureLayout_MinSysVer_iOS_8_0, @"Margin attributes are only supported on iOS 8.0 or higher."); + ALMarginAxis marginAxis; + switch (axis) { + case ALAxisVertical: + marginAxis = ALMarginAxisVertical; + break; + case ALAxisHorizontal: + marginAxis = ALMarginAxisHorizontal; + break; + case ALAxisBaseline: + case ALAxisFirstBaseline: + NSAssert(nil, @"The baseline axis attributes do not have corresponding margin axis attributes."); + marginAxis = ALMarginAxisVertical; // default to an arbitrary value to satisfy the compiler + break; + default: + NSAssert(nil, @"Not a valid ALAxis."); + marginAxis = ALMarginAxisVertical; // default to an arbitrary value to satisfy the compiler + break; + } + return marginAxis; +} + +#endif /* __PureLayout_MinBaseSDK_iOS_8_0 */ + +@end diff --git a/Example/Pods/PureLayout/PureLayout/PureLayout/PureLayout+Internal.h b/Example/Pods/PureLayout/PureLayout/PureLayout/PureLayout+Internal.h new file mode 100644 index 0000000..3308d97 --- /dev/null +++ b/Example/Pods/PureLayout/PureLayout/PureLayout/PureLayout+Internal.h @@ -0,0 +1,87 @@ +// +// PureLayout+Internal.h +// https://github.com/PureLayout/PureLayout +// +// Copyright (c) 2014-2015 Tyler Fox +// +// This code is distributed under the terms and conditions of the MIT license. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +// + +#import "PureLayoutDefines.h" + + +// Using generics with NSMutableArray is so common in the internal implementation of PureLayout that it gets a dedicated preprocessor macro for better readability. +#define __NSMutableArray_of(type) __PL_GENERICS(NSMutableArray, type) + +__PL_ASSUME_NONNULL_BEGIN + +/** A constant that represents the smallest valid positive value for the multiplier of a constraint, + since a value of 0 will cause the second item to be lost in the internal auto layout engine. */ +static const CGFloat kMULTIPLIER_MIN_VALUE = (CGFloat)0.00001; // very small floating point numbers (e.g. CGFLOAT_MIN) can cause problems + + +/** + A category that exposes the internal (private) helper methods of the ALView+PureLayout category. + */ +@interface ALView (PureLayoutInternal) + +- (void)al_addConstraint:(NSLayoutConstraint *)constraint; +- (ALView *)al_commonSuperviewWithView:(ALView *)otherView; +- (NSLayoutConstraint *)al_alignAttribute:(ALAttribute)attribute toView:(ALView *)otherView forAxis:(ALAxis)axis; + +@end + + +/** + A category that exposes the internal (private) helper methods of the NSArray+PureLayout category. + */ +@interface NSArray (PureLayoutInternal) + +- (ALView *)al_commonSuperviewOfViews; +- (BOOL)al_containsMinimumNumberOfViews:(NSUInteger)minimumNumberOfViews; +- (__NSArray_of(ALView *) *)al_copyViewsOnly; + +@end + + +/** + A category that exposes the internal (private) helper methods of the NSLayoutConstraint+PureLayout category. + */ +@interface NSLayoutConstraint (PureLayoutInternal) + ++ (BOOL)al_preventAutomaticConstraintInstallation; ++ (__NSMutableArray_of(NSLayoutConstraint *) *)al_currentArrayOfCreatedConstraints; ++ (BOOL)al_isExecutingPriorityConstraintsBlock; ++ (ALLayoutPriority)al_currentGlobalConstraintPriority; +#if __PureLayout_MinBaseSDK_iOS_8_0 || __PureLayout_MinBaseSDK_OSX_10_10 ++ (NSString *)al_currentGlobalConstraintIdentifier; +#endif /* __PureLayout_MinBaseSDK_iOS_8_0 || __PureLayout_MinBaseSDK_OSX_10_10 */ ++ (void)al_applyGlobalStateToConstraint:(NSLayoutConstraint *)constraint; ++ (NSLayoutAttribute)al_layoutAttributeForAttribute:(ALAttribute)attribute; ++ (ALLayoutConstraintAxis)al_constraintAxisForAxis:(ALAxis)axis; +#if __PureLayout_MinBaseSDK_iOS_8_0 ++ (ALMargin)al_marginForEdge:(ALEdge)edge; ++ (ALMarginAxis)al_marginAxisForAxis:(ALAxis)axis; +#endif /* __PureLayout_MinBaseSDK_iOS_8_0 */ + +@end + +__PL_ASSUME_NONNULL_END diff --git a/Example/Pods/PureLayout/PureLayout/PureLayout/PureLayout.h b/Example/Pods/PureLayout/PureLayout/PureLayout/PureLayout.h new file mode 100755 index 0000000..ab615d3 --- /dev/null +++ b/Example/Pods/PureLayout/PureLayout/PureLayout/PureLayout.h @@ -0,0 +1,43 @@ +// +// PureLayout.h +// https://github.com/PureLayout/PureLayout +// +// Copyright (c) 2014-2015 Tyler Fox +// +// This code is distributed under the terms and conditions of the MIT license. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +// + +#ifndef PureLayout_h +#define PureLayout_h + +#import + +//! Project version number for PureLayout. +FOUNDATION_EXPORT double PureLayoutVersionNumber; + +//! Project version string for PureLayout. +FOUNDATION_EXPORT const unsigned char PureLayoutVersionString[]; + +#import "ALView+PureLayout.h" +#import "NSArray+PureLayout.h" +#import "NSLayoutConstraint+PureLayout.h" + +#endif /* PureLayout_h */ diff --git a/Example/Pods/PureLayout/PureLayout/PureLayout/PureLayoutDefines.h b/Example/Pods/PureLayout/PureLayout/PureLayout/PureLayoutDefines.h new file mode 100755 index 0000000..c880bd7 --- /dev/null +++ b/Example/Pods/PureLayout/PureLayout/PureLayout/PureLayoutDefines.h @@ -0,0 +1,224 @@ +// +// PureLayoutDefines.h +// https://github.com/PureLayout/PureLayout +// +// Copyright (c) 2014-2015 Tyler Fox +// +// This code is distributed under the terms and conditions of the MIT license. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +// + +#ifndef PureLayoutDefines_h +#define PureLayoutDefines_h + +#import + +// Define some preprocessor macros to check for a minimum Base SDK. These are used to prevent compile-time errors in older versions of Xcode. +#define __PureLayout_MinBaseSDK_iOS_8_0 (TARGET_OS_IPHONE && __IPHONE_OS_VERSION_MAX_ALLOWED > __IPHONE_7_1) +#define __PureLayout_MinBaseSDK_OSX_10_10 (!TARGET_OS_IPHONE && __MAC_OS_X_VERSION_MAX_ALLOWED > __MAC_10_9) + +// Define some preprocessor macros to check for a minimum System Version. These are used to prevent runtime crashes on older versions of iOS/OS X. +#define __PureLayout_MinSysVer_iOS_7_0 (TARGET_OS_IPHONE && floor(NSFoundationVersionNumber) > NSFoundationVersionNumber_iOS_6_1) +#define __PureLayout_MinSysVer_iOS_8_0 (TARGET_OS_IPHONE && floor(NSFoundationVersionNumber) > NSFoundationVersionNumber_iOS_7_1) +#define __PureLayout_MinSysVer_OSX_10_9 (!TARGET_OS_IPHONE && floor(NSFoundationVersionNumber) > NSFoundationVersionNumber10_8_4) + +// Define some preprocessor macros that allow nullability annotations to be adopted in a backwards-compatible manner. +#if __has_feature(nullability) +# define __PL_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_BEGIN +# define __PL_ASSUME_NONNULL_END NS_ASSUME_NONNULL_END +#else +# define __PL_ASSUME_NONNULL_BEGIN +# define __PL_ASSUME_NONNULL_END +#endif + +// Define some preprocessor macros that allow generics to be adopted in a backwards-compatible manner. +#if __has_feature(objc_generics) +# define __PL_GENERICS(class, ...) class<__VA_ARGS__> +#else +# define __PL_GENERICS(class, ...) class +#endif + +// Using generics with NSArray is so common in PureLayout that it gets a dedicated preprocessor macro for better readability. +#define __NSArray_of(type) __PL_GENERICS(NSArray, type) + +// Define generic AL-prefixed macros for the types/constants/etc that have slight naming variations across iOS and OS X, which allows the same code to be platform-independent. +#if TARGET_OS_IPHONE +# import +# define ALView UIView +# define ALEdgeInsets UIEdgeInsets +# define ALEdgeInsetsZero UIEdgeInsetsZero +# define ALEdgeInsetsMake UIEdgeInsetsMake +# define ALLayoutConstraintAxis UILayoutConstraintAxis +# define ALLayoutConstraintOrientation ALLayoutConstraintAxis +# define ALLayoutConstraintAxisHorizontal UILayoutConstraintAxisHorizontal +# define ALLayoutConstraintAxisVertical UILayoutConstraintAxisVertical +# define ALLayoutConstraintOrientationHorizontal ALLayoutConstraintAxisHorizontal +# define ALLayoutConstraintOrientationVertical ALLayoutConstraintAxisVertical +# define ALLayoutPriority UILayoutPriority +# define ALLayoutPriorityRequired UILayoutPriorityRequired +# define ALLayoutPriorityDefaultHigh UILayoutPriorityDefaultHigh +# define ALLayoutPriorityDefaultLow UILayoutPriorityDefaultLow +# define ALLayoutPriorityFittingSizeLevel UILayoutPriorityFittingSizeLevel +# define ALLayoutPriorityFittingSizeCompression ALLayoutPriorityFittingSizeLevel +#else +# import +# define ALView NSView +# define ALEdgeInsets NSEdgeInsets +# define ALEdgeInsetsZero NSEdgeInsetsMake(0, 0, 0, 0) +# define ALEdgeInsetsMake NSEdgeInsetsMake +# define ALLayoutConstraintOrientation NSLayoutConstraintOrientation +# define ALLayoutConstraintAxis ALLayoutConstraintOrientation +# define ALLayoutConstraintOrientationHorizontal NSLayoutConstraintOrientationHorizontal +# define ALLayoutConstraintOrientationVertical NSLayoutConstraintOrientationVertical +# define ALLayoutConstraintAxisHorizontal ALLayoutConstraintOrientationHorizontal +# define ALLayoutConstraintAxisVertical ALLayoutConstraintOrientationVertical +# define ALLayoutPriority NSLayoutPriority +# define ALLayoutPriorityRequired NSLayoutPriorityRequired +# define ALLayoutPriorityDefaultHigh NSLayoutPriorityDefaultHigh +# define ALLayoutPriorityDefaultLow NSLayoutPriorityDefaultLow +# define ALLayoutPriorityFittingSizeCompression NSLayoutPriorityFittingSizeCompression +# define ALLayoutPriorityFittingSizeLevel ALLayoutPriorityFittingSizeCompression +#endif /* TARGET_OS_IPHONE */ + + +#pragma mark PureLayout Attributes + +/** Constants that represent edges of a view. */ +typedef NS_ENUM(NSInteger, ALEdge) { + /** The left edge of the view. */ + ALEdgeLeft = NSLayoutAttributeLeft, + /** The right edge of the view. */ + ALEdgeRight = NSLayoutAttributeRight, + /** The top edge of the view. */ + ALEdgeTop = NSLayoutAttributeTop, + /** The bottom edge of the view. */ + ALEdgeBottom = NSLayoutAttributeBottom, + /** The leading edge of the view (left edge for left-to-right languages like English, right edge for right-to-left languages like Arabic). */ + ALEdgeLeading = NSLayoutAttributeLeading, + /** The trailing edge of the view (right edge for left-to-right languages like English, left edge for right-to-left languages like Arabic). */ + ALEdgeTrailing = NSLayoutAttributeTrailing +}; + +/** Constants that represent dimensions of a view. */ +typedef NS_ENUM(NSInteger, ALDimension) { + /** The width of the view. */ + ALDimensionWidth = NSLayoutAttributeWidth, + /** The height of the view. */ + ALDimensionHeight = NSLayoutAttributeHeight +}; + +/** Constants that represent axes of a view. */ +typedef NS_ENUM(NSInteger, ALAxis) { + /** A vertical line equidistant from the view's left and right edges. */ + ALAxisVertical = NSLayoutAttributeCenterX, + /** A horizontal line equidistant from the view's top and bottom edges. */ + ALAxisHorizontal = NSLayoutAttributeCenterY, + + /** A horizontal line at the baseline of the last line of text in the view. (For views that do not draw text, will be equivalent to ALEdgeBottom.) Same as ALAxisLastBaseline. */ + ALAxisBaseline = NSLayoutAttributeBaseline, + /** A horizontal line at the baseline of the last line of text in the view. (For views that do not draw text, will be equivalent to ALEdgeBottom.) */ + ALAxisLastBaseline = ALAxisBaseline, + #if __PureLayout_MinBaseSDK_iOS_8_0 + /** A horizontal line at the baseline of the first line of text in a view. (For views that do not draw text, will be equivalent to ALEdgeTop.) Available in iOS 8.0 and later. */ + ALAxisFirstBaseline = NSLayoutAttributeFirstBaseline + #endif /* __PureLayout_MinBaseSDK_iOS_8_0 */ +}; + +#if __PureLayout_MinBaseSDK_iOS_8_0 + +/** Constants that represent layout margins of a view. Available in iOS 8.0 and later. */ +typedef NS_ENUM(NSInteger, ALMargin) { + /** The left margin of the view, based on the view's layoutMargins left inset. */ + ALMarginLeft = NSLayoutAttributeLeftMargin, + /** The right margin of the view, based on the view's layoutMargins right inset. */ + ALMarginRight = NSLayoutAttributeRightMargin, + /** The top margin of the view, based on the view's layoutMargins top inset. */ + ALMarginTop = NSLayoutAttributeTopMargin, + /** The bottom margin of the view, based on the view's layoutMargins bottom inset. */ + ALMarginBottom = NSLayoutAttributeBottomMargin, + /** The leading margin of the view, based on the view's layoutMargins left/right (depending on language direction) inset. */ + ALMarginLeading = NSLayoutAttributeLeadingMargin, + /** The trailing margin of the view, based on the view's layoutMargins left/right (depending on language direction) inset. */ + ALMarginTrailing = NSLayoutAttributeTrailingMargin +}; + +/** Constants that represent axes of the layout margins of a view. Available in iOS 8.0 and later. */ +typedef NS_ENUM(NSInteger, ALMarginAxis) { + /** A vertical line equidistant from the view's left and right margins. */ + ALMarginAxisVertical = NSLayoutAttributeCenterXWithinMargins, + /** A horizontal line equidistant from the view's top and bottom margins. */ + ALMarginAxisHorizontal = NSLayoutAttributeCenterYWithinMargins +}; + +#endif /* __PureLayout_MinBaseSDK_iOS_8_0 */ + +/** An attribute of a view that can be used in auto layout constraints. These constants are identical to the more specific enum types: + ALEdge, ALAxis, ALDimension, ALMargin, ALMarginAxis. It is safe to cast a more specific enum type to the ALAttribute type. */ +typedef NS_ENUM(NSInteger, ALAttribute) { + /** The left edge of the view. */ + ALAttributeLeft = ALEdgeLeft, + /** The right edge of the view. */ + ALAttributeRight = ALEdgeRight, + /** The top edge of the view. */ + ALAttributeTop = ALEdgeTop, + /** The bottom edge of the view. */ + ALAttributeBottom = ALEdgeBottom, + /** The leading edge of the view (left edge for left-to-right languages like English, right edge for right-to-left languages like Arabic). */ + ALAttributeLeading = ALEdgeLeading, + /** The trailing edge of the view (right edge for left-to-right languages like English, left edge for right-to-left languages like Arabic). */ + ALAttributeTrailing = ALEdgeTrailing, + /** The width of the view. */ + ALAttributeWidth = ALDimensionWidth, + /** The height of the view. */ + ALAttributeHeight = ALDimensionHeight, + /** A vertical line equidistant from the view's left and right edges. */ + ALAttributeVertical = ALAxisVertical, + /** A horizontal line equidistant from the view's top and bottom edges. */ + ALAttributeHorizontal = ALAxisHorizontal, + /** A horizontal line at the baseline of the last line of text in the view. (For views that do not draw text, will be equivalent to ALEdgeBottom.) Same as ALAxisLastBaseline. */ + ALAttributeBaseline = ALAxisBaseline, + /** A horizontal line at the baseline of the last line of text in the view. (For views that do not draw text, will be equivalent to ALEdgeBottom.) */ + ALAttributeLastBaseline = ALAxisLastBaseline, +#if __PureLayout_MinBaseSDK_iOS_8_0 + /** A horizontal line at the baseline of the first line of text in a view. (For views that do not draw text, will be equivalent to ALEdgeTop.) Available in iOS 8.0 and later. */ + ALAttributeFirstBaseline = ALAxisFirstBaseline, + /** The left margin of the view, based on the view's layoutMargins left inset. */ + ALAttributeMarginLeft = ALMarginLeft, + /** The right margin of the view, based on the view's layoutMargins right inset. */ + ALAttributeMarginRight = ALMarginRight, + /** The top margin of the view, based on the view's layoutMargins top inset. */ + ALAttributeMarginTop = ALMarginTop, + /** The bottom margin of the view, based on the view's layoutMargins bottom inset. */ + ALAttributeMarginBottom = ALMarginBottom, + /** The leading margin of the view, based on the view's layoutMargins left/right (depending on language direction) inset. */ + ALAttributeMarginLeading = ALMarginLeading, + /** The trailing margin of the view, based on the view's layoutMargins left/right (depending on language direction) inset. */ + ALAttributeMarginTrailing = ALMarginTrailing, + /** A vertical line equidistant from the view's left and right margins. */ + ALAttributeMarginAxisVertical = ALMarginAxisVertical, + /** A horizontal line equidistant from the view's top and bottom margins. */ + ALAttributeMarginAxisHorizontal = ALMarginAxisHorizontal +#endif /* __PureLayout_MinBaseSDK_iOS_8_0 */ +}; + +/** A block containing method calls to the PureLayout API. Takes no arguments and has no return value. */ +typedef void(^ALConstraintsBlock)(void); + +#endif /* PureLayoutDefines_h */ diff --git a/Example/Pods/PureLayout/README.md b/Example/Pods/PureLayout/README.md new file mode 100644 index 0000000..b5e372c --- /dev/null +++ b/Example/Pods/PureLayout/README.md @@ -0,0 +1,219 @@ +# [![PureLayout](https://github.com/PureLayout/PureLayout/blob/master/Images/PureLayout.png?raw=true)](#) +[![Build Status](http://img.shields.io/travis/PureLayout/PureLayout.svg?style=flat)](https://travis-ci.org/PureLayout/PureLayout) [![Test Coverage](http://img.shields.io/coveralls/PureLayout/PureLayout.svg?style=flat)](https://coveralls.io/r/PureLayout/PureLayout) [![Version](http://img.shields.io/cocoapods/v/PureLayout.svg?style=flat)](http://cocoapods.org/?q=PureLayout) [![Platform](http://img.shields.io/cocoapods/p/PureLayout.svg?style=flat)](http://cocoapods.org/?q=PureLayout) [![License](http://img.shields.io/cocoapods/l/PureLayout.svg?style=flat)](LICENSE) + +The ultimate API for iOS & OS X Auto Layout — impressively simple, immensely powerful. PureLayout extends `UIView`/`NSView`, `NSArray`, and `NSLayoutConstraint` with a comprehensive Auto Layout API that is modeled after Apple's own frameworks. PureLayout is a cross-platform Objective-C library that works (and looks!) great in Swift. It is fully backwards-compatible with all versions of iOS and OS X that support Auto Layout. + +Writing Auto Layout code from scratch isn't easy. PureLayout provides a fully capable and developer-friendly interface for Auto Layout. It is designed for clarity and simplicity, and takes inspiration from the AutoLayout UI options available in Interface Builder while delivering far more flexibility. The API is also highly efficient, as it adds only a thin layer of third party code and is engineered for maximum performance. + +### Table of Contents + 1. [Setup](#setup) + 1. [API Cheat Sheet](#api-cheat-sheet) + 1. [Usage](#usage) + * [Sample Code](#sample-code-swift) + * [Example Apps](#example-apps) + 1. [PureLayout vs. the rest](#purelayout-vs-the-rest) + 1. [Problems, Suggestions, Pull Requests?](#problems-suggestions-pull-requests) + +## Setup +### Compatibility +The current release of PureLayout supports all versions of iOS and OS X since the introduction of Auto Layout on each platform, in both Swift and Objective-C, with a single codebase! + +* Xcode + * Language Support: **Swift** *(any version)*, **Objective-C** + * Fully Compatible With: **Xcode 7.0** + * Minimum Supported Version: **Xcode 5.0** +* iOS + * Fully Compatible With: **iOS 9.0** + * Minimum Deployment Target: **iOS 6.0** +* OS X + * Fully Compatible With: **OS X 10.11** + * Minimum Deployment Target: **OS X 10.7** + +### Using [CocoaPods](http://cocoapods.org) +1. Add the pod `PureLayout` to your [Podfile](http://guides.cocoapods.org/using/the-podfile.html). + + ```ruby + pod 'PureLayout' + ``` + +1. Run `pod install` from Terminal, then open your app's `.xcworkspace` file to launch Xcode. +1. Import the `PureLayout.h` umbrella header. + * With `use_frameworks!` in your Podfile + * Swift: `import PureLayout` + * Objective-C: `#import ` (or with Modules enabled: `@import PureLayout;`) + * Without `use_frameworks!` in your Podfile + * Swift: Add `#import "PureLayout.h"` to your bridging header. + * Objective-C: `#import "PureLayout.h"` + +That's it - now go write some beautiful Auto Layout code! + +### Using [Carthage](https://github.com/Carthage/Carthage) +1. Add the `PureLayout/PureLayout` project to your [Cartfile](https://github.com/Carthage/Carthage/blob/master/Documentation/Artifacts.md#cartfile). + + ```ogdl + github "PureLayout/PureLayout" + ``` + +1. Run `carthage update`, then follow the [additional steps required](https://github.com/Carthage/Carthage#adding-frameworks-to-an-application) to add the framework into your project. +1. Import the PureLayout framework/module. + * Swift: `import PureLayout` + * Objective-C: `#import ` (or with Modules enabled: `@import PureLayout;`) + +That's it - now go write some beautiful Auto Layout code! + +### Manually from GitHub +1. Download the source files in the [PureLayout subdirectory](PureLayout/PureLayout). +1. Add the source files to your Xcode project. +1. Import the `PureLayout.h` header. + * Swift: Add `#import "PureLayout.h"` to your bridging header. + * Objective-C: `#import "PureLayout.h"` + +That's it - now go write some beautiful Auto Layout code! + +### App Extensions +To use PureLayout in an App Extension, you need to do a bit of extra configuration to prevent usage of unavailable APIs. [Click here](https://github.com/PureLayout/PureLayout/wiki/App-Extensions) for more info. + +### Releases +Releases are tagged in the git commit history using [semantic versioning](http://semver.org). Check out the [releases and release notes](https://github.com/PureLayout/PureLayout/releases) for each version. + +## API Cheat Sheet +This is just a handy overview of the core API methods. Explore the [header files](PureLayout/PureLayout) for the full API, and find the complete documentation above the implementation of each method in the corresponding .m file. A couple of notes: + +* All of the public API methods are namespaced with the prefix `auto...`, which also makes it easy for Xcode to autocomplete as you type. +* Methods that create constraints also automatically install (activate) the constraint(s), then return the new constraint(s) for you to optionally store for later adjustment or removal. +* Many methods below also have a variant which includes a `relation:` parameter to make the constraint an inequality. + +### Attributes + +PureLayout defines view attributes that are used to create auto layout constraints. Here is an [illustration of the most common attributes](Images/PureLayout-CommonAttributes.png). + +There are 5 specific attribute types, which are used throughout most of the API: + +* `ALEdge` +* `ALDimension` +* `ALAxis` +* `ALMargin` *available in iOS 8.0 and higher only* +* `ALMarginAxis` *available in iOS 8.0 and higher only* + +Additionally, there is one generic attribute type, `ALAttribute`, which is effectively a union of all the specific types. You can think of this as the "supertype" of all of the specific attribute types, which means that it is always safe to cast a specific type to the generic `ALAttribute` type. (Note that the reverse is not true -- casting a generic ALAttribute to a specific attribute type is unsafe!) + +### [`UIView`/`NSView`](PureLayout/PureLayout/ALView%2BPureLayout.h) +``` +- autoSetContent(CompressionResistance|Hugging)PriorityForAxis: +- autoCenterInSuperview(Margins): // Margins variant iOS 8.0+ only +- autoAlignAxisToSuperview(Margin)Axis: // Margin variant iOS 8.0+ only +- autoPinEdgeToSuperview(Edge:|Margin:)(withInset:) // Margin variant iOS 8.0+ only +- autoPinEdgesToSuperview(Edges|Margins)(WithInsets:)(excludingEdge:) // Margins variant iOS 8.0+ only +- autoPinEdge:toEdge:ofView:(withOffset:) +- autoAlignAxis:toSameAxisOfView:(withOffset:|withMultiplier:) +- autoMatchDimension:toDimension:ofView:(withOffset:|withMultiplier:) +- autoSetDimension(s)ToSize: +- autoConstrainAttribute:toAttribute:ofView:(withOffset:|withMultiplier:) +- autoPinTo(Top|Bottom)LayoutGuideOfViewController:withInset: // iOS only +``` + +### [`NSArray`](PureLayout/PureLayout/NSArray%2BPureLayout.h) +``` +// Arrays of Constraints +- autoInstallConstraints +- autoRemoveConstraints +- autoIdentifyConstraints: // iOS 7.0+, OS X 10.9+ only + +// Arrays of Views +- autoAlignViewsToEdge: +- autoAlignViewsToAxis: +- autoMatchViewsDimension: +- autoSetViewsDimension:toSize: +- autoSetViewsDimensionsToSize: +- autoDistributeViewsAlongAxis:alignedTo:withFixedSpacing:(insetSpacing:)(matchedSizes:) +- autoDistributeViewsAlongAxis:alignedTo:withFixedSize:(insetSpacing:) +``` + +### [`NSLayoutConstraint`](PureLayout/PureLayout/NSLayoutConstraint%2BPureLayout.h) +``` ++ autoCreateAndInstallConstraints: ++ autoCreateConstraintsWithoutInstalling: ++ autoSetPriority:forConstraints: ++ autoSetIdentifier:forConstraints: // iOS 7.0+, OS X 10.9+ only +- autoIdentify: // iOS 7.0+, OS X 10.9+ only +- autoInstall +- autoRemove +``` + +## Usage +### Sample Code (Swift) +PureLayout dramatically simplifies writing Auto Layout code. Let's take a quick look at some examples, using PureLayout from Swift. + +Here's a constraint between two views created (and automatically activated) using PureLayout: + +```swift +view1.autoPinEdge(.Top, toEdge: .Bottom, ofView: view2) +``` + +Without PureLayout, here's the equivalent code you'd have to write using Apple's Foundation API directly: + +```swift +NSLayoutConstraint(item: view1, attribute: .Top, relatedBy: .Equal, toItem: view2, attribute: .Bottom, multiplier: 1.0, constant: 0.0).active = true +``` + +Many APIs of PureLayout create multiple constraints for you under the hood, letting you write highly readable layout code: + +```swift +// 2 constraints created & activated in one line! +logoImageView.autoCenterInSuperview() + +// 4 constraints created & activated in one line! +textContentView.autoPinEdgesToSuperviewEdgesWithInsets(UIEdgeInsets(top: 20.0, left: 5.0, bottom: 10.0, right: 5.0)) +``` + +PureLayout always returns the constraints it creates so you have full control: + +```swift +let constraint = skinnyView.autoMatchDimension(.Height, toDimension: .Width, ofView: tallView) +``` + +PureLayout supports all Auto Layout features including inequalities, priorities, layout margins, identifiers, and much more. It's a comprehensive, developer-friendly way to use Auto Layout. + +Check out the example apps below for many more demos of PureLayout in use. + +### Example Apps +Open the project included in the repository (requires Xcode 6 or higher). It contains [iOS](PureLayout/Example-iOS) (`Example-iOS` scheme) and [OS X](PureLayout/Example-Mac) (`Example-Mac` scheme) demos of the library being used in various scenarios. The demos in the iOS example app make a great introductory tutorial to PureLayout -- run each demo, review the code used to implement it, then practice by making some changes of your own to the demo code. + +Each demo in the iOS example app has a Swift and Objective-C version. **To compile & run the Swift demos, you must use Xcode 7.0 or higher (Swift 2.0) and choose the `Example-iOS-Xcode7` scheme.** When you run the example app, you can easily switch between using the Swift and Objective-C versions of the demos. To see the constraints in action while running the iOS demos, try using different device simulators, rotating the device to different orientations, as well as toggling the taller in-call status bar in the iOS Simulator. + +On OS X, while running the app, press any key to cycle through the demos. You can resize the window to see the constraints in action. + +### Tips and Tricks +Check out some [Tips and Tricks](https://github.com/PureLayout/PureLayout/wiki/Tips-and-Tricks) to keep in mind when using the API. + +## PureLayout vs. the rest +There are quite a few different ways to implement Auto Layout. Here is a quick overview of the available options: + +* Apple [NSLayoutConstraint SDK API](https://developer.apple.com/library/ios/documentation/AppKit/Reference/NSLayoutConstraint_Class/index.html#//apple_ref/occ/clm/NSLayoutConstraint/constraintWithItem:attribute:relatedBy:toItem:attribute:multiplier:constant:) + * Pros: Raw power + * Cons: Extremely verbose; tedious to write; difficult to read +* Apple [Visual Format Language](https://developer.apple.com/library/ios/documentation/UserExperience/Conceptual/AutolayoutPG/VisualFormatLanguage/VisualFormatLanguage.html) + * Pros: Concise; convenient + * Cons: Doesn't support some use cases; lacks compile-time checking and safety; must learn syntax; hard to debug +* Apple Interface Builder + * Pros: Visual; interactive; provides compile-time layout checking + * Cons: Difficult for complex layouts; cannot dynamically set constraints at runtime; encourages hardcoded magic numbers; not always WYSIWYG +* Apple [NSLayoutAnchor SDK API](https://developer.apple.com/library/prerelease/ios/documentation/AppKit/Reference/NSLayoutAnchor_ClassReference/index.html) + * Pros: Clean, readable, and type-safe API for creating individual constraints + * Cons: Only available in iOS 9.0 and OS X 10.11 and higher; requires manually activating each constraint; no API for creating multiple constraints at once +* **PureLayout** + * Pros: Compatible with Objective-C and Swift codebases; consistent with Cocoa API style; cross-platform API and implementation shared across iOS and OS X; fully backwards-compatible to iOS 6 & OS X 10.7; easy to use; type-safe; efficient + * Cons: Not the most concise expression of layout code +* High-level Auto Layout Libraries/DSLs ([Cartography](https://github.com/robb/Cartography), [SnapKit](https://github.com/SnapKit/SnapKit), [KeepLayout](https://github.com/iMartinKiss/KeepLayout)) + * Pros: Very clean, concise, and convenient + * Cons: Unique API style is foreign to Apple's APIs; mixed compatibility with Objective-C & Swift; greater dependency on third party code + +PureLayout takes a balanced approach to Auto Layout that makes it well suited for any project. + +## Problems, Suggestions, Pull Requests? +Please open a [new Issue here](https://github.com/PureLayout/PureLayout/issues/new) if you run into a problem specific to PureLayout, have a feature request, or want to share a comment. Note that general Auto Layout questions should be asked on [Stack Overflow](http://stackoverflow.com). + +Pull requests are encouraged and greatly appreciated! Please try to maintain consistency with the existing code style. If you're considering taking on significant changes or additions to the project, please communicate in advance by opening a new Issue. This allows everyone to get onboard with upcoming changes, ensures that changes align with the project's design philosophy, and avoids duplicated work. + +## Meta +Originally designed & built by Tyler Fox ([@smileyborg](https://github.com/smileyborg)). Currently maintained by Mickey Reiss ([@mickeyreiss](https://github.com/mickeyreiss)). Distributed with the MIT license. diff --git a/Example/Pods/Specta/LICENSE b/Example/Pods/Specta/LICENSE new file mode 100644 index 0000000..ca257c0 --- /dev/null +++ b/Example/Pods/Specta/LICENSE @@ -0,0 +1,20 @@ +Copyright (c) 2012-2014 Specta Team. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + diff --git a/Example/Pods/Specta/README.md b/Example/Pods/Specta/README.md new file mode 100644 index 0000000..431b121 --- /dev/null +++ b/Example/Pods/Specta/README.md @@ -0,0 +1,176 @@ +# Specta + +A light-weight TDD / BDD framework for Objective-C. + +### Status +[![Build Status](https://travis-ci.org/specta/specta.png)](https://travis-ci.org/specta/specta) +[![Coverage Status](https://coveralls.io/repos/specta/specta/badge.svg)](https://coveralls.io/r/specta/specta) + +## FEATURES + +* An Objective-C RSpec-like BDD DSL +* Quick and easy set up +* Built on top of XCTest +* Excellent Xcode integration + +## SCREENSHOT + +![Specta Screenshot](https://raw.githubusercontent.com/specta/specta/master/misc/specta_screenshot.jpg) + +## SETUP + +Use [CocoaPods](http://github.com/CocoaPods/CocoaPods), [Carthage](https://github.com/carthage/carthage) or [Set up manually](#setting-up-manually) + +### CocoaPods + +1. Add Specta to your project's `Podfile`: + + ```ruby + target :MyApp do + # your app dependencies + end + + target :MyAppTests do + pod 'Specta', '~> 1.0' + # pod 'Expecta', '~> 1.0' # expecta matchers + # pod 'OCMock', '~> 2.2' # OCMock + # pod 'OCHamcrest', '~> 3.0' # hamcrest matchers + # pod 'OCMockito', '~> 1.0' # OCMock + # pod 'LRMocky', '~> 0.9' # LRMocky + end + ``` + +2. Run `pod update` or `pod install` in your project directory. + +### Carthage + +1. Add Specta to your project's `Cartfile.private` + + ``` + github "specta/specta" ~> 1.0 + ``` + +2. Run `carthage update` in your project directory +3. Drag the appropriate `Specta.framework` for your platform (located in Carthage/Build/) into your application’s Xcode project, and add it to your test target(s). +4. If you are building for iOS, a new `Run Script Phase` must be added to copy the framework. The instructions can be found on [Carthage's getting started instructions](https://github.com/carthage/carthage#getting-started) + +### SETTING UP MANUALLY + +1. Clone from Github. +2. Run `rake` in project root to build. +3. Add a "Cocoa/Cocoa Touch Unit Testing Bundle" target if you don't already have one. +4. Copy and add all header files in `Products` folder to the Test target in your Xcode project. +5. For **OS X projects**, copy and add `Specta.framework` in `Products/osx` folder to the test target in your Xcode project. + For **iOS projects**, copy and add `Specta.framework` in `Products/ios` folder to the test target in your Xcode project. + You can alternatively use `libSpecta.a`, if you prefer to add it as a static library for your project. (iOS 7 and below require this) +6. Add `-ObjC` and `-all_load` to the "Other Linker Flags" build setting for the test target in your Xcode project. +7. If you encounter linking issues with `_llvm_*` symbols, ensure your target's "Generate Test Coverage Files" and "Instrument Program Flow" build settings are set to `Yes`. + +## EXAMPLE + +```objective-c +#import // #import "Specta.h" if you're using libSpecta.a + +SharedExamplesBegin(MySharedExamples) +// Global shared examples are shared across all spec files. + +sharedExamplesFor(@"foo", ^(NSDictionary *data) { + __block id bar = nil; + beforeEach(^{ + bar = data[@"bar"]; + }); + it(@"should not be nil", ^{ + XCTAssertNotNil(bar); + }); +}); + +SharedExamplesEnd + +SpecBegin(Thing) + +describe(@"Thing", ^{ + sharedExamplesFor(@"another shared behavior", ^(NSDictionary *data) { + // Locally defined shared examples can override global shared examples within its scope. + }); + + beforeAll(^{ + // This is run once and only once before all of the examples + // in this group and before any beforeEach blocks. + }); + + beforeEach(^{ + // This is run before each example. + }); + + it(@"should do stuff", ^{ + // This is an example block. Place your assertions here. + }); + + it(@"should do some stuff asynchronously", ^{ + waitUntil(^(DoneCallback done) { + // Async example blocks need to invoke done() callback. + done(); + }); + }); + + itShouldBehaveLike(@"a shared behavior", @{@"key" : @"obj"}); + + itShouldBehaveLike(@"another shared behavior", ^{ + // Use a block that returns a dictionary if you need the context to be evaluated lazily, + // e.g. to use an object prepared in a beforeEach block. + return @{@"key" : @"obj"}; + }); + + describe(@"Nested examples", ^{ + it(@"should do even more stuff", ^{ + // ... + }); + }); + + pending(@"pending example"); + + pending(@"another pending example", ^{ + // ... + }); + + afterEach(^{ + // This is run after each example. + }); + + afterAll(^{ + // This is run once and only once after all of the examples + // in this group and after any afterEach blocks. + }); +}); + +SpecEnd +``` + +* `beforeEach` and `afterEach` are also aliased as `before` and `after` respectively. +* `describe` is also aliased as `context`. +* `it` is also aliased as `example` and `specify`. +* `itShouldBehaveLike` is also aliased as `itBehavesLike`. +* Use `pending` or prepend `x` to `describe`, `context`, `example`, `it`, and `specify` to mark examples or groups as pending. +* Use `^(DoneCallback done)` as shown in the example above to make examples wait for completion. `done()` callback needs to be invoked to let Specta know that your test is complete. The default timeout is 10.0 seconds but this can be changed by calling the function `setAsyncSpecTimeout(NSTimeInterval timeout)`. +* `(before|after)(Each/All)` also accept `^(DoneCallback done)`s. +* Do `#define SPT_CEDAR_SYNTAX` before importing Specta if you prefer to write `SPEC_BEGIN` and `SPEC_END` instead of `SpecBegin` and `SpecEnd`. +* Prepend `f` to your `describe`, `context`, `example`, `it`, and `specify` to set focus on examples or groups. When specs are focused, all unfocused specs are skipped. +* To use original XCTest reporter, set an environment variable named `SPECTA_REPORTER_CLASS` to `SPTXCTestReporter` in your test scheme. +* Set an environment variable `SPECTA_NO_SHUFFLE` with value `1` to disable test shuffling. +* Set an environment variable `SPECTA_SEED` to specify the random seed for test shuffling. + +Standard XCTest matchers such as `XCTAssertEqualObjects` and `XCTAssertNil` work, but you probably want to add a nicer matcher framework - [Expecta](http://github.com/specta/expecta/) to your setup. Or if you really prefer, [OCHamcrest](https://github.com/jonreid/OCHamcrest) works fine too. Also, add a mocking framework: [OCMock](http://ocmock.org/). + +## RUNNING TESTS IN COMMAND LINE + +* Run `rake test` in the cloned folder. + +## CONTRIBUTION GUIDELINES + +* Please use only spaces and indent 2 spaces at a time. +* Please prefix instance variable names with a single underscore (`_`). +* Please prefix custom classes and functions defined in the global scope with `SPT`. + +## LICENSE + +Copyright (c) 2012-2015 [Specta Team](https://github.com/specta?tab=members). This software is licensed under the [MIT License](http://github.com/specta/specta/raw/master/LICENSE). diff --git a/Example/Pods/Specta/Specta/Specta/SPTCallSite.h b/Example/Pods/Specta/Specta/Specta/SPTCallSite.h new file mode 100644 index 0000000..adcd3b0 --- /dev/null +++ b/Example/Pods/Specta/Specta/Specta/SPTCallSite.h @@ -0,0 +1,12 @@ +#import + +@interface SPTCallSite : NSObject + +@property (nonatomic, copy, readonly) NSString *file; +@property (nonatomic, readonly) NSUInteger line; + ++ (instancetype)callSiteWithFile:(NSString *)file line:(NSUInteger)line; + +- (instancetype)initWithFile:(NSString *)file line:(NSUInteger)line; + +@end diff --git a/Example/Pods/Specta/Specta/Specta/SPTCallSite.m b/Example/Pods/Specta/Specta/Specta/SPTCallSite.m new file mode 100644 index 0000000..585cecd --- /dev/null +++ b/Example/Pods/Specta/Specta/Specta/SPTCallSite.m @@ -0,0 +1,18 @@ +#import "SPTCallSite.h" + +@implementation SPTCallSite + ++ (instancetype)callSiteWithFile:(NSString *)file line:(NSUInteger)line { + return [[self alloc] initWithFile:file line:line]; +} + +- (instancetype)initWithFile:(NSString *)file line:(NSUInteger)line { + self = [super init]; + if (self) { + _file = file; + _line = line; + } + return self; +} + +@end diff --git a/Example/Pods/Specta/Specta/Specta/SPTCompiledExample.h b/Example/Pods/Specta/Specta/Specta/SPTCompiledExample.h new file mode 100644 index 0000000..adb3aaa --- /dev/null +++ b/Example/Pods/Specta/Specta/Specta/SPTCompiledExample.h @@ -0,0 +1,17 @@ +#import +#import "SpectaTypes.h" + +@interface SPTCompiledExample : NSObject + +@property (nonatomic, copy) NSString *name; +@property (nonatomic, copy) NSString *testCaseName; +@property (nonatomic, copy) SPTSpecBlock block; + +@property (nonatomic) BOOL pending; +@property (nonatomic, getter=isFocused) BOOL focused; + +@property (nonatomic) SEL testMethodSelector; + +- (id)initWithName:(NSString *)name testCaseName:(NSString *)testCaseName block:(SPTSpecBlock)block pending:(BOOL)pending focused:(BOOL)focused; + +@end diff --git a/Example/Pods/Specta/Specta/Specta/SPTCompiledExample.m b/Example/Pods/Specta/Specta/Specta/SPTCompiledExample.m new file mode 100644 index 0000000..e762165 --- /dev/null +++ b/Example/Pods/Specta/Specta/Specta/SPTCompiledExample.m @@ -0,0 +1,17 @@ +#import "SPTCompiledExample.h" + +@implementation SPTCompiledExample + +- (id)initWithName:(NSString *)name testCaseName:(NSString *)testCaseName block:(SPTSpecBlock)block pending:(BOOL)pending focused:(BOOL)focused { + self = [super init]; + if (self) { + self.name = name; + self.testCaseName = testCaseName; + self.block = block; + self.pending = pending; + self.focused = focused; + } + return self; +} + +@end diff --git a/Example/Pods/Specta/Specta/Specta/SPTExample.h b/Example/Pods/Specta/Specta/Specta/SPTExample.h new file mode 100644 index 0000000..849aacb --- /dev/null +++ b/Example/Pods/Specta/Specta/Specta/SPTExample.h @@ -0,0 +1,17 @@ +#import +#import "SpectaTypes.h" + +@class SPTCallSite; + +@interface SPTExample : NSObject + +@property (nonatomic, copy) NSString *name; +@property (nonatomic, retain) SPTCallSite *callSite; +@property (nonatomic, copy) SPTVoidBlock block; + +@property (nonatomic) BOOL pending; +@property (nonatomic, getter=isFocused) BOOL focused; + +- (id)initWithName:(NSString *)name callSite:(SPTCallSite *)callSite focused:(BOOL)focused block:(SPTVoidBlock)block; + +@end diff --git a/Example/Pods/Specta/Specta/Specta/SPTExample.m b/Example/Pods/Specta/Specta/Specta/SPTExample.m new file mode 100644 index 0000000..e5905a9 --- /dev/null +++ b/Example/Pods/Specta/Specta/Specta/SPTExample.m @@ -0,0 +1,17 @@ +#import "SPTExample.h" + +@implementation SPTExample + +- (id)initWithName:(NSString *)name callSite:(SPTCallSite *)callSite focused:(BOOL)focused block:(SPTVoidBlock)block { + self = [super init]; + if (self) { + self.name = name; + self.callSite = callSite; + self.block = block; + self.focused = focused; + self.pending = block == nil; + } + return self; +} + +@end diff --git a/Example/Pods/Specta/Specta/Specta/SPTExampleGroup.h b/Example/Pods/Specta/Specta/Specta/SPTExampleGroup.h new file mode 100644 index 0000000..dce3db6 --- /dev/null +++ b/Example/Pods/Specta/Specta/Specta/SPTExampleGroup.h @@ -0,0 +1,36 @@ +#import +#import +#import "SpectaTypes.h" + +@class SPTExample; +@class SPTCallSite; + +@interface SPTExampleGroup : NSObject + +@property (nonatomic, copy) NSString *name; +@property (nonatomic, weak) SPTExampleGroup *root; +@property (nonatomic, weak) SPTExampleGroup *parent; +@property (nonatomic, strong) NSMutableArray *children; +@property (nonatomic, strong) NSMutableArray *beforeAllArray; +@property (nonatomic, strong) NSMutableArray *afterAllArray; +@property (nonatomic, strong) NSMutableArray *beforeEachArray; +@property (nonatomic, strong) NSMutableArray *afterEachArray; +@property (nonatomic, strong) NSMutableDictionary *sharedExamples; +@property (nonatomic) unsigned int exampleCount; +@property (nonatomic) unsigned int ranExampleCount; +@property (nonatomic) unsigned int pendingExampleCount; +@property (nonatomic, getter=isFocused) BOOL focused; + +- (id)initWithName:(NSString *)name parent:(SPTExampleGroup *)parent root:(SPTExampleGroup *)root; + +- (SPTExampleGroup *)addExampleGroupWithName:(NSString *)name focused:(BOOL)focused; +- (SPTExample *)addExampleWithName:(NSString *)name callSite:(SPTCallSite *)callSite focused:(BOOL)focused block:(SPTVoidBlock)block; + +- (void)addBeforeAllBlock:(SPTVoidBlock)block; +- (void)addAfterAllBlock:(SPTVoidBlock)block; +- (void)addBeforeEachBlock:(SPTVoidBlock)block; +- (void)addAfterEachBlock:(SPTVoidBlock)block; + +- (NSArray *)compileExamplesWithStack:(NSArray *)stack; + +@end diff --git a/Example/Pods/Specta/Specta/Specta/SPTExampleGroup.m b/Example/Pods/Specta/Specta/Specta/SPTExampleGroup.m new file mode 100644 index 0000000..cf51800 --- /dev/null +++ b/Example/Pods/Specta/Specta/Specta/SPTExampleGroup.m @@ -0,0 +1,335 @@ +#import "SPTExampleGroup.h" +#import "SPTExample.h" +#import "SPTCompiledExample.h" +#import "SPTSpec.h" +#import "SpectaUtility.h" +#import "XCTest+Private.h" +#import "SPTGlobalBeforeAfterEach.h" +#import +#import + +static NSArray *ClassesWithClassMethod(SEL classMethodSelector) { + NSMutableArray *classesWithClassMethod = [[NSMutableArray alloc] init]; + + int numberOfClasses = objc_getClassList(NULL, 0); + if (numberOfClasses > 0) { + Class *classes = (Class *)malloc(sizeof(Class) *numberOfClasses); + numberOfClasses = objc_getClassList(classes, numberOfClasses); + + for(int classIndex = 0; classIndex < numberOfClasses; classIndex++) { + Class aClass = classes[classIndex]; + + if (class_conformsToProtocol(aClass, @protocol(SPTGlobalBeforeAfterEach))) { + Method globalMethod = class_getClassMethod(aClass, classMethodSelector); + if (globalMethod) { + [classesWithClassMethod addObject:aClass]; + } + } + } + + free(classes); + } + + return classesWithClassMethod; +} + +static void runExampleBlock(void (^block)(), NSString *name) { + if (!SPTIsBlock(block)) { + return; + } + + ((SPTVoidBlock)block)(); +} + +typedef NS_ENUM(NSInteger, SPTExampleGroupOrder) { + SPTExampleGroupOrderOutermostFirst = 1, + SPTExampleGroupOrderInnermostFirst +}; + +@interface SPTExampleGroup () + +- (void)incrementExampleCount; +- (void)incrementPendingExampleCount; +- (void)resetRanExampleCountIfNeeded; +- (void)incrementRanExampleCount; +- (void)runBeforeHooks:(NSString *)compiledName; +- (void)runBeforeAllHooks:(NSString *)compiledName; +- (void)runBeforeEachHooks:(NSString *)compiledName; +- (void)runAfterHooks:(NSString *)compiledName; +- (void)runAfterEachHooks:(NSString *)compiledName; +- (void)runAfterAllHooks:(NSString *)compiledName; + +@end + +@implementation SPTExampleGroup + +- (id)init { + self = [super init]; + if (self) { + self.name = nil; + self.root = nil; + self.parent = nil; + self.children = [NSMutableArray array]; + self.beforeAllArray = [NSMutableArray array]; + self.afterAllArray = [NSMutableArray array]; + self.beforeEachArray = [NSMutableArray array]; + self.afterEachArray = [NSMutableArray array]; + self.sharedExamples = [NSMutableDictionary dictionary]; + self.exampleCount = 0; + self.pendingExampleCount = 0; + self.ranExampleCount = 0; + } + return self; +} + +- (id)initWithName:(NSString *)name parent:(SPTExampleGroup *)parent root:(SPTExampleGroup *)root { + self = [self init]; + if (self) { + self.name = name; + self.parent = parent; + self.root = root; + } + return self; +} + +- (SPTExampleGroup *)addExampleGroupWithName:(NSString *)name focused:(BOOL)focused { + SPTExampleGroup *group = [[SPTExampleGroup alloc] initWithName:name parent:self root:self.root]; + group.focused = focused; + [self.children addObject:group]; + return group; +} + +- (SPTExample *)addExampleWithName:(NSString *)name callSite:(SPTCallSite *)callSite focused:(BOOL)focused block:(SPTVoidBlock)block { + SPTExample *example; + @synchronized(self) { + example = [[SPTExample alloc] initWithName:name callSite:callSite focused:focused block:block]; + [self.children addObject:example]; + + [self incrementExampleCount]; + if (example.pending) { + [self incrementPendingExampleCount]; + } + } + return example; +} + +- (void)incrementExampleCount { + SPTExampleGroup *group = self; + while (group != nil) { + group.exampleCount ++; + group = group.parent; + } +} + +- (void)incrementPendingExampleCount { + SPTExampleGroup *group = self; + while (group != nil) { + group.pendingExampleCount ++; + group = group.parent; + } +} + +- (void)resetRanExampleCountIfNeeded { + SPTExampleGroup *group = self; + while (group != nil) { + if (group.ranExampleCount >= group.exampleCount) { + group.ranExampleCount = 0; + } + group = group.parent; + } +} + +- (void)incrementRanExampleCount { + SPTExampleGroup *group = self; + while (group != nil) { + group.ranExampleCount ++; + group = group.parent; + } +} + +- (void)addBeforeAllBlock:(SPTVoidBlock)block { + if (!block) return; + [self.beforeAllArray addObject:[block copy]]; +} + +- (void)addAfterAllBlock:(SPTVoidBlock)block { + if (!block) return; + [self.afterAllArray addObject:[block copy]]; +} + +- (void)addBeforeEachBlock:(SPTVoidBlock)block { + if (!block) return; + [self.beforeEachArray addObject:[block copy]]; +} + +- (void)addAfterEachBlock:(SPTVoidBlock)block { + if (!block) return; + [self.afterEachArray addObject:[block copy]]; +} + +- (void)runGlobalBeforeEachHooks:(NSString *)compiledName { + static NSArray *globalBeforeEachClasses; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + globalBeforeEachClasses = ClassesWithClassMethod(@selector(beforeEach)); + }); + + for (Class class in globalBeforeEachClasses) { + [class beforeEach]; + } +} + +- (void)runGlobalAfterEachHooks:(NSString *)compiledName { + static NSArray *globalAfterEachClasses; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + globalAfterEachClasses = ClassesWithClassMethod(@selector(afterEach)); + }); + + for (Class class in globalAfterEachClasses) { + [class afterEach]; + } +} + +// Builds an array of example groups that enclose the current group. +// When in innermost-first order, the most deeply nested example groups, +// beginning with self, are placed at the beginning of the array. +// When in outermost-first order, the opposite is true, and the last +// group in the array (self) is the most deeply nested. +- (NSArray *)exampleGroupStackInOrder:(SPTExampleGroupOrder)order { + NSMutableArray *groups = [NSMutableArray array]; + SPTExampleGroup *group = self; + while (group != nil) { + switch (order) { + case SPTExampleGroupOrderOutermostFirst: + [groups insertObject:group atIndex:0]; + break; + case SPTExampleGroupOrderInnermostFirst: + [groups addObject:group]; + break; + } + group = group.parent; + } + + return [groups copy]; +} + +- (void)runBeforeHooks:(NSString *)compiledName { + [self runBeforeAllHooks:compiledName]; + [self runBeforeEachHooks:compiledName]; +} + +- (void)runBeforeAllHooks:(NSString *)compiledName { + for(SPTExampleGroup *group in [self exampleGroupStackInOrder:SPTExampleGroupOrderOutermostFirst]) { + if (group.ranExampleCount == 0) { + for (id beforeAllBlock in group.beforeAllArray) { + runExampleBlock(beforeAllBlock, [NSString stringWithFormat:@"%@ - before all block", compiledName]); + } + } + } +} + +- (void)runBeforeEachHooks:(NSString *)compiledName { + [self runGlobalBeforeEachHooks:compiledName]; + for (SPTExampleGroup *group in [self exampleGroupStackInOrder:SPTExampleGroupOrderOutermostFirst]) { + for (id beforeEachBlock in group.beforeEachArray) { + runExampleBlock(beforeEachBlock, [NSString stringWithFormat:@"%@ - before each block", compiledName]); + } + } +} + +- (void)runAfterHooks:(NSString *)compiledName { + [self runAfterEachHooks:compiledName]; + [self runAfterAllHooks:compiledName]; +} + +- (void)runAfterEachHooks:(NSString *)compiledName { + for (SPTExampleGroup *group in [self exampleGroupStackInOrder:SPTExampleGroupOrderInnermostFirst]) { + for (id afterEachBlock in group.afterEachArray) { + runExampleBlock(afterEachBlock, [NSString stringWithFormat:@"%@ - after each block", compiledName]); + } + } + [self runGlobalAfterEachHooks:compiledName]; +} + +- (void)runAfterAllHooks:(NSString *)compiledName { + for (SPTExampleGroup *group in [self exampleGroupStackInOrder:SPTExampleGroupOrderInnermostFirst]) { + if (group.ranExampleCount == group.exampleCount) { + for (id afterAllBlock in group.afterAllArray) { + runExampleBlock(afterAllBlock, [NSString stringWithFormat:@"%@ - after all block", compiledName]); + } + } + } +} + +- (BOOL)isFocusedOrHasFocusedAncestor { + SPTExampleGroup *ancestor = self; + while (ancestor != nil) { + if (ancestor.focused) { + return YES; + } else { + ancestor = ancestor.parent; + } + } + + return NO; +} + +- (NSArray *)compileExamplesWithStack:(NSArray *)stack { + BOOL groupIsFocusedOrHasFocusedAncestor = [self isFocusedOrHasFocusedAncestor]; + + NSArray *compiled = @[]; + + for(id child in self.children) { + if ([child isKindOfClass:[SPTExampleGroup class]]) { + SPTExampleGroup *group = child; + NSArray *newStack = [stack arrayByAddingObject:group]; + compiled = [compiled arrayByAddingObjectsFromArray:[group compileExamplesWithStack:newStack]]; + + } else if ([child isKindOfClass:[SPTExample class]]) { + SPTExample *example = child; + NSArray *newStack = [stack arrayByAddingObject:example]; + + NSString *compiledName = [spt_map(newStack, ^id(id obj, NSUInteger idx) { + return [obj name]; + }) componentsJoinedByString:@" "]; + + NSString *testCaseName = [spt_map(newStack, ^id(id obj, NSUInteger idx) { + return spt_underscorize([obj name]); + }) componentsJoinedByString:@"__"]; + + // If example is pending, run only before- and after-all hooks. + // Otherwise, run the example and all before and after hooks. + SPTSpecBlock compiledBlock = example.pending ? ^(SPTSpec *spec){ + @synchronized(self.root) { + [self resetRanExampleCountIfNeeded]; + [self runBeforeAllHooks:compiledName]; + [self incrementRanExampleCount]; + [self runAfterAllHooks:compiledName]; + } + } : ^(SPTSpec *spec) { + @synchronized(self.root) { + [self resetRanExampleCountIfNeeded]; + [self runBeforeHooks:compiledName]; + } + @try { + runExampleBlock(example.block, compiledName); + } + @catch(NSException *e) { + [spec spt_handleException:e]; + } + @finally { + @synchronized(self.root) { + [self incrementRanExampleCount]; + [self runAfterHooks:compiledName]; + } + } + }; + SPTCompiledExample *compiledExample = [[SPTCompiledExample alloc] initWithName:compiledName testCaseName:testCaseName block:compiledBlock pending:example.pending focused:(groupIsFocusedOrHasFocusedAncestor || example.focused)]; + compiled = [compiled arrayByAddingObject:compiledExample]; + } + } + return compiled; +} + +@end diff --git a/Example/Pods/Specta/Specta/Specta/SPTExcludeGlobalBeforeAfterEach.h b/Example/Pods/Specta/Specta/Specta/SPTExcludeGlobalBeforeAfterEach.h new file mode 100644 index 0000000..9581f0b --- /dev/null +++ b/Example/Pods/Specta/Specta/Specta/SPTExcludeGlobalBeforeAfterEach.h @@ -0,0 +1,10 @@ +/* + * Copyright (c) 2015 Specta Team. All rights reserved. + */ +#import + +// This protocol was used for blacklisting classes for global beforeEach and afterEach blocks. +// Now, instead, classes are whitelisted by implementing the SPTGlobalBeforeAfterEach protocol. +__deprecated_msg("Please whitelist classes instead with the SPTGlobalBeforeAfterEach protocol") +@protocol SPTExcludeGlobalBeforeAfterEach +@end diff --git a/Example/Pods/Specta/Specta/Specta/SPTGlobalBeforeAfterEach.h b/Example/Pods/Specta/Specta/Specta/SPTGlobalBeforeAfterEach.h new file mode 100644 index 0000000..490359d --- /dev/null +++ b/Example/Pods/Specta/Specta/Specta/SPTGlobalBeforeAfterEach.h @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2015 Specta Team. All rights reserved. + */ +#import + +// This protocol is used for whitelisting classes for global beforeEach and afterEach blocks. +// If you want a class to participate in those just add this protocol to a category and it will be +// included. +@protocol SPTGlobalBeforeAfterEach + +@optional ++ (void)beforeEach; ++ (void)afterEach; + +@end diff --git a/Example/Pods/Specta/Specta/Specta/SPTSharedExampleGroups.h b/Example/Pods/Specta/Specta/Specta/SPTSharedExampleGroups.h new file mode 100644 index 0000000..090acba --- /dev/null +++ b/Example/Pods/Specta/Specta/Specta/SPTSharedExampleGroups.h @@ -0,0 +1,17 @@ +#import +#import +#import + +@class _XCTestCaseImplementation; + +@class SPTExampleGroup; + +@interface SPTSharedExampleGroups : XCTestCase + ++ (void)addSharedExampleGroupWithName:(NSString *)name block:(SPTDictionaryBlock)block exampleGroup:(SPTExampleGroup *)exampleGroup; ++ (SPTDictionaryBlock)sharedExampleGroupWithName:(NSString *)name exampleGroup:(SPTExampleGroup *)exampleGroup; + +- (void)sharedExampleGroups; + +@end + diff --git a/Example/Pods/Specta/Specta/Specta/SPTSharedExampleGroups.m b/Example/Pods/Specta/Specta/Specta/SPTSharedExampleGroups.m new file mode 100644 index 0000000..35b405c --- /dev/null +++ b/Example/Pods/Specta/Specta/Specta/SPTSharedExampleGroups.m @@ -0,0 +1,74 @@ +#import "SPTSharedExampleGroups.h" +#import "SPTExampleGroup.h" +#import "SPTSpec.h" +#import "SpectaUtility.h" +#import + +NSMutableDictionary *globalSharedExampleGroups = nil; +BOOL initialized = NO; + +@implementation SPTSharedExampleGroups + ++ (void)initialize { + Class SPTSharedExampleGroupsClass = [SPTSharedExampleGroups class]; + if ([self class] == SPTSharedExampleGroupsClass) { + if (!initialized) { + initialized = YES; + globalSharedExampleGroups = [[NSMutableDictionary alloc] init]; + + Class *classes = NULL; + int numClasses = objc_getClassList(NULL, 0); + + if (numClasses > 0) { + classes = (Class *)malloc(sizeof(Class) * numClasses); + numClasses = objc_getClassList(classes, numClasses); + + Class klass, superClass; + for(uint i = 0; i < numClasses; i++) { + klass = classes[i]; + superClass = class_getSuperclass(klass); + if (superClass == SPTSharedExampleGroupsClass) { + [[[klass alloc] init] sharedExampleGroups]; + } + } + + free(classes); + } + } + } +} + ++ (void)addSharedExampleGroupWithName:(NSString *)name block:(SPTDictionaryBlock)block exampleGroup:(SPTExampleGroup *)exampleGroup { + (exampleGroup == nil ? globalSharedExampleGroups : exampleGroup.sharedExamples)[name] = [block copy]; +} + ++ (SPTDictionaryBlock)sharedExampleGroupWithName:(NSString *)name exampleGroup:(SPTExampleGroup *)exampleGroup { + SPTDictionaryBlock sharedExampleGroup = nil; + while (exampleGroup != nil) { + if ((sharedExampleGroup = exampleGroup.sharedExamples[name])) { + return sharedExampleGroup; + } + exampleGroup = exampleGroup.parent; + } + return globalSharedExampleGroups[name]; +} + +- (void)sharedExampleGroups {} + +- (void)spt_handleException:(NSException *)exception { + [SPTCurrentSpec spt_handleException:exception]; +} + +- (void)recordFailureWithDescription:(NSString *)description inFile:(NSString *)filename atLine:(NSUInteger)lineNumber expected:(BOOL)expected { + [SPTCurrentSpec recordFailureWithDescription:description inFile:filename atLine:lineNumber expected:expected]; +} + +- (void)_recordUnexpectedFailureWithDescription:(NSString *)description exception:(NSException *)exception { + [SPTCurrentSpec _recordUnexpectedFailureWithDescription:description exception:exception]; +} + +- (_XCTestCaseImplementation *)internalImplementation { + return [SPTCurrentSpec internalImplementation]; +} + +@end diff --git a/Example/Pods/Specta/Specta/Specta/SPTSpec.h b/Example/Pods/Specta/Specta/Specta/SPTSpec.h new file mode 100644 index 0000000..ada4ea2 --- /dev/null +++ b/Example/Pods/Specta/Specta/Specta/SPTSpec.h @@ -0,0 +1,28 @@ +#import +#import + +@class + SPTTestSuite +, SPTCompiledExample +; + +@interface SPTSpec : XCTestCase + +@property (strong) XCTestCaseRun *spt_run; +@property (nonatomic) BOOL spt_pending; +@property (nonatomic) BOOL spt_skipped; + ++ (BOOL)spt_isDisabled; ++ (void)spt_setDisabled:(BOOL)disabled; ++ (BOOL)spt_focusedExamplesExist; ++ (SEL)spt_convertToTestMethod:(SPTCompiledExample *)example; ++ (SPTTestSuite *)spt_testSuite; ++ (void)spt_setCurrentTestSuite; ++ (void)spt_unsetCurrentTestSuite; ++ (void)spt_setCurrentTestSuiteFileName:(NSString *)fileName lineNumber:(NSUInteger)lineNumber; + +- (void)spec; +- (BOOL)spt_shouldRunExample:(SPTCompiledExample *)example; +- (void)spt_runExample:(SPTCompiledExample *)example; + +@end diff --git a/Example/Pods/Specta/Specta/Specta/SPTSpec.m b/Example/Pods/Specta/Specta/Specta/SPTSpec.m new file mode 100644 index 0000000..35ad313 --- /dev/null +++ b/Example/Pods/Specta/Specta/Specta/SPTSpec.m @@ -0,0 +1,210 @@ +#import "SPTSpec.h" +#import "SPTTestSuite.h" +#import "SPTCompiledExample.h" +#import "SPTSharedExampleGroups.h" +#import "SpectaUtility.h" +#import +#import "XCTest+Private.h" + +@implementation SPTSpec + ++ (void)initialize { + [SPTSharedExampleGroups initialize]; + SPTTestSuite *testSuite = [[SPTTestSuite alloc] init]; + SPTSpec *spec = [[[self class] alloc] init]; + NSString *specName = NSStringFromClass([self class]); + objc_setAssociatedObject(self, "spt_testSuite", testSuite, OBJC_ASSOCIATION_RETAIN_NONATOMIC); + [self spt_setCurrentTestSuite]; + @try { + [spec spec]; + } + @catch (NSException *exception) { + fprintf(stderr, "%s: An exception has occured outside of tests, aborting.\n\n%s (%s) \n", [specName UTF8String], [[exception name] UTF8String], [[exception reason] UTF8String]); + if ([exception respondsToSelector:@selector(callStackSymbols)]) { + NSArray *callStackSymbols = [exception callStackSymbols]; + if (callStackSymbols) { + NSString *callStack = [NSString stringWithFormat:@"\n Call Stack:\n %@\n", [callStackSymbols componentsJoinedByString:@"\n "]]; + fprintf(stderr, "%s", [callStack UTF8String]); + } + } + exit(1); + } + @finally { + [self spt_unsetCurrentTestSuite]; + } + [testSuite compile]; + [[self class] testInvocations]; + [super initialize]; +} + ++ (SPTTestSuite *)spt_testSuite { + return objc_getAssociatedObject(self, "spt_testSuite"); +} + ++ (BOOL)spt_isDisabled { + return [self spt_testSuite].disabled; +} + ++ (void)spt_setDisabled:(BOOL)disabled { + [self spt_testSuite].disabled = disabled; +} + ++ (NSArray *)spt_allSpecClasses { + static NSArray *allSpecClasses = nil; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + + NSMutableArray *specClasses = [[NSMutableArray alloc] init]; + + int numberOfClasses = objc_getClassList(NULL, 0); + if (numberOfClasses > 0) { + Class *classes = (Class *)malloc(sizeof(Class) * numberOfClasses); + numberOfClasses = objc_getClassList(classes, numberOfClasses); + + for (int classIndex = 0; classIndex < numberOfClasses; classIndex++) { + Class aClass = classes[classIndex]; + if (spt_isSpecClass(aClass)) { + [specClasses addObject:aClass]; + } + } + + free(classes); + } + + allSpecClasses = [specClasses copy]; + }); + + return allSpecClasses; +} + ++ (BOOL)spt_focusedExamplesExist { + for (Class specClass in [self spt_allSpecClasses]) { + SPTTestSuite *testSuite = [specClass spt_testSuite]; + if (testSuite.disabled == NO && [testSuite hasFocusedExamples]) { + return YES; + } + } + + return NO; +} + ++ (SEL)spt_convertToTestMethod:(SPTCompiledExample *)example { + @synchronized(example) { + if (!example.testMethodSelector) { + IMP imp = imp_implementationWithBlock(^(SPTSpec *self) { + [self spt_runExample:example]; + }); + + SEL sel; + unsigned int i = 0; + + do { + i++; + if (i == 1) { + sel = NSSelectorFromString([NSString stringWithFormat:@"test_%@", example.testCaseName]); + } else { + sel = NSSelectorFromString([NSString stringWithFormat:@"test_%@_%u", example.testCaseName, i]); + } + } while([self instancesRespondToSelector:sel]); + + class_addMethod(self, sel, imp, "@@:"); + example.testMethodSelector = sel; + } + } + + return example.testMethodSelector; +} + ++ (void)spt_setCurrentTestSuite { + SPTTestSuite *testSuite = [self spt_testSuite]; + [[NSThread currentThread] threadDictionary][spt_kCurrentTestSuiteKey] = testSuite; +} + ++ (void)spt_unsetCurrentTestSuite { + [[[NSThread currentThread] threadDictionary] removeObjectForKey:spt_kCurrentTestSuiteKey]; +} + ++ (void)spt_setCurrentTestSuiteFileName:(NSString *)fileName lineNumber:(NSUInteger)lineNumber { + SPTTestSuite *testSuite = [self spt_testSuite]; + testSuite.fileName = fileName; + testSuite.lineNumber = lineNumber; +} + +- (void)spec {} + +- (BOOL)spt_shouldRunExample:(SPTCompiledExample *)example { + return [[self class] spt_isDisabled] == NO && + (example.focused || [[self class] spt_focusedExamplesExist] == NO); +} + +- (void)spt_runExample:(SPTCompiledExample *)example { + [[NSThread currentThread] threadDictionary][spt_kCurrentSpecKey] = self; + + if ([self spt_shouldRunExample:example]) { + self.spt_pending = example.pending; + example.block(self); + } else if (!example.pending) { + self.spt_skipped = YES; + } + + [[[NSThread currentThread] threadDictionary] removeObjectForKey:spt_kCurrentSpecKey]; +} + +#pragma mark - XCTestCase overrides + ++ (NSArray *)testInvocations { + NSArray *compiledExamples = [self spt_testSuite].compiledExamples; + [NSMutableArray arrayWithCapacity:[compiledExamples count]]; + + NSMutableSet *addedSelectors = [NSMutableSet setWithCapacity:[compiledExamples count]]; + NSMutableArray *selectors = [NSMutableArray arrayWithCapacity:[compiledExamples count]]; + + // dynamically generate test methods with compiled examples + for (SPTCompiledExample *example in compiledExamples) { + SEL sel = [self spt_convertToTestMethod:example]; + NSString *selName = NSStringFromSelector(sel); + [selectors addObject: selName]; + [addedSelectors addObject: selName]; + } + + // look for any other test methods that may be present in class. + unsigned int n; + Method *imethods = class_copyMethodList(self, &n); + + for (NSUInteger i = 0; i < n; i++) { + struct objc_method_description *desc = method_getDescription(imethods[i]); + + char *types = desc->types; + SEL sel = desc->name; + NSString *selName = NSStringFromSelector(sel); + + if (strcmp(types, "@@:") == 0 && [selName hasPrefix:@"test"] && ![addedSelectors containsObject:selName]) { + [selectors addObject:NSStringFromSelector(sel)]; + } + } + + free(imethods); + + // create invocations from test method selectors + NSMutableArray *invocations = [NSMutableArray arrayWithCapacity:[selectors count]]; + for (NSString *selName in selectors) { + SEL sel = NSSelectorFromString(selName); + NSInvocation *inv = [NSInvocation invocationWithMethodSignature:[self instanceMethodSignatureForSelector:sel]]; + [inv setSelector:sel]; + [invocations addObject:inv]; + } + + return spt_shuffle(invocations); +} + +- (void)recordFailureWithDescription:(NSString *)description inFile:(NSString *)filename atLine:(NSUInteger)lineNumber expected:(BOOL)expected { + SPTSpec *currentSpec = SPTCurrentSpec; + [currentSpec.spt_run recordFailureWithDescription:description inFile:filename atLine:lineNumber expected:expected]; +} + +- (void)performTest:(XCTestRun *)run { + self.spt_run = (XCTestCaseRun *)run; + [super performTest:run]; +} + +@end diff --git a/Example/Pods/Specta/Specta/Specta/SPTTestSuite.h b/Example/Pods/Specta/Specta/Specta/SPTTestSuite.h new file mode 100644 index 0000000..9bd9016 --- /dev/null +++ b/Example/Pods/Specta/Specta/Specta/SPTTestSuite.h @@ -0,0 +1,21 @@ +#import + +@class + SPTExample +, SPTExampleGroup +; + +@interface SPTTestSuite : NSObject + +@property (nonatomic, strong) SPTExampleGroup *rootGroup; +@property (nonatomic, strong) NSMutableArray *groupStack; +@property (nonatomic, strong) NSArray *compiledExamples; +@property (nonatomic, copy) NSString *fileName; +@property (nonatomic) NSUInteger lineNumber; +@property (nonatomic, getter = isDisabled) BOOL disabled; +@property (nonatomic) BOOL hasFocusedExamples; + +- (SPTExampleGroup *)currentGroup; +- (void)compile; + +@end diff --git a/Example/Pods/Specta/Specta/Specta/SPTTestSuite.m b/Example/Pods/Specta/Specta/Specta/SPTTestSuite.m new file mode 100644 index 0000000..7053edd --- /dev/null +++ b/Example/Pods/Specta/Specta/Specta/SPTTestSuite.m @@ -0,0 +1,31 @@ +#import "SPTTestSuite.h" +#import "SPTExampleGroup.h" +#import "SPTCompiledExample.h" + +@implementation SPTTestSuite + +- (id)init { + self = [super init]; + if (self) { + self.rootGroup = [[SPTExampleGroup alloc] init]; + self.rootGroup.root = self.rootGroup; + self.groupStack = [NSMutableArray arrayWithObject:self.rootGroup]; + } + return self; +} + +- (SPTExampleGroup *)currentGroup { + return [self.groupStack lastObject]; +} + +- (void)compile { + self.compiledExamples = [self.rootGroup compileExamplesWithStack:@[]]; + for (SPTCompiledExample *example in self.compiledExamples) { + if (example.focused) { + self.hasFocusedExamples = YES; + break; + } + } +} + +@end diff --git a/Example/Pods/Specta/Specta/Specta/Specta.h b/Example/Pods/Specta/Specta/Specta/Specta.h new file mode 100644 index 0000000..dda17f9 --- /dev/null +++ b/Example/Pods/Specta/Specta/Specta/Specta.h @@ -0,0 +1,14 @@ +#import +#import + +//! Project version number for Specta. +FOUNDATION_EXPORT double SpectaVersionNumber; + +//! Project version string for Specta. +FOUNDATION_EXPORT const unsigned char SpectaVersionString[]; + +// In this header, you should import all the public headers of your framework using statements like #import + +#import +#import +#import diff --git a/Example/Pods/Specta/Specta/Specta/SpectaDSL.h b/Example/Pods/Specta/Specta/Specta/SpectaDSL.h new file mode 100644 index 0000000..284d4f5 --- /dev/null +++ b/Example/Pods/Specta/Specta/Specta/SpectaDSL.h @@ -0,0 +1,90 @@ +#import + +#define SpecBegin(name) _SPTSpecBegin(name, __FILE__, __LINE__) +#define SpecEnd _SPTSpecEnd + +#define SharedExamplesBegin(name) _SPTSharedExampleGroupsBegin(name) +#define SharedExamplesEnd _SPTSharedExampleGroupsEnd +#define SharedExampleGroupsBegin(name) _SPTSharedExampleGroupsBegin(name) +#define SharedExampleGroupsEnd _SPTSharedExampleGroupsEnd + +typedef void (^DoneCallback)(void); + +OBJC_EXTERN void describe(NSString *name, void (^block)()); +OBJC_EXTERN void fdescribe(NSString *name, void (^block)()); + +OBJC_EXTERN void context(NSString *name, void (^block)()); +OBJC_EXTERN void fcontext(NSString *name, void (^block)()); + +OBJC_EXTERN void it(NSString *name, void (^block)()); +OBJC_EXTERN void fit(NSString *name, void (^block)()); + +OBJC_EXTERN void example(NSString *name, void (^block)()); +OBJC_EXTERN void fexample(NSString *name, void (^block)()); + +OBJC_EXTERN void specify(NSString *name, void (^block)()); +OBJC_EXTERN void fspecify(NSString *name, void (^block)()); + +#define pending(...) spt_pending_(__VA_ARGS__, nil) +#define xdescribe(...) spt_pending_(__VA_ARGS__, nil) +#define xcontext(...) spt_pending_(__VA_ARGS__, nil) +#define xexample(...) spt_pending_(__VA_ARGS__, nil) +#define xit(...) spt_pending_(__VA_ARGS__, nil) +#define xspecify(...) spt_pending_(__VA_ARGS__, nil) + +OBJC_EXTERN void beforeAll(void (^block)()); +OBJC_EXTERN void afterAll(void (^block)()); + +OBJC_EXTERN void beforeEach(void (^block)()); +OBJC_EXTERN void afterEach(void (^block)()); + +OBJC_EXTERN void before(void (^block)()); +OBJC_EXTERN void after(void (^block)()); + +OBJC_EXTERN void sharedExamplesFor(NSString *name, void (^block)(NSDictionary *data)); +OBJC_EXTERN void sharedExamples(NSString *name, void (^block)(NSDictionary *data)); + +#define itShouldBehaveLike(...) spt_itShouldBehaveLike_(@(__FILE__), __LINE__, __VA_ARGS__) +#define itBehavesLike(...) spt_itShouldBehaveLike_(@(__FILE__), __LINE__, __VA_ARGS__) + +OBJC_EXTERN void waitUntil(void (^block)(DoneCallback done)); +/** + * Runs the @c block and waits until the @c done block is called or the + * @c timeout has passed. + * + * @param timeout timeout for this @c block only; does not affect the global + * timeout, as @c setAsyncSpecTimeout() does. + * @param ^block runs test code + */ +OBJC_EXTERN void waitUntilTimeout(NSTimeInterval timeout, void (^block)(DoneCallback done)); + +OBJC_EXTERN void setAsyncSpecTimeout(NSTimeInterval timeout); + +// ---------------------------------------------------------------------------- + +#define _SPTSpecBegin(name, file, line) \ +@interface name##Spec : SPTSpec \ +@end \ +@implementation name##Spec \ +- (void)spec { \ + [[self class] spt_setCurrentTestSuiteFileName:(@(file)) lineNumber:(line)]; + +#define _SPTSpecEnd \ +} \ +@end + +#define _SPTSharedExampleGroupsBegin(name) \ +@interface name##SharedExampleGroups : SPTSharedExampleGroups \ +@end \ +@implementation name##SharedExampleGroups \ +- (void)sharedExampleGroups { + +#define _SPTSharedExampleGroupsEnd \ +} \ +@end + +OBJC_EXTERN void spt_it_(NSString *name, NSString *fileName, NSUInteger lineNumber, void (^block)()); +OBJC_EXTERN void spt_fit_(NSString *name, NSString *fileName, NSUInteger lineNumber, void (^block)()); +OBJC_EXTERN void spt_pending_(NSString *name, ...); +OBJC_EXTERN void spt_itShouldBehaveLike_(NSString *fileName, NSUInteger lineNumber, NSString *name, id dictionaryOrBlock); +OBJC_EXTERN void spt_itShouldBehaveLike_block(NSString *fileName, NSUInteger lineNumber, NSString *name, NSDictionary *(^block)()); diff --git a/Example/Pods/Specta/Specta/Specta/SpectaDSL.m b/Example/Pods/Specta/Specta/Specta/SpectaDSL.m new file mode 100644 index 0000000..10edcd5 --- /dev/null +++ b/Example/Pods/Specta/Specta/Specta/SpectaDSL.m @@ -0,0 +1,189 @@ +#import "SpectaDSL.h" +#import "SpectaTypes.h" +#import "SpectaUtility.h" +#import "SPTTestSuite.h" +#import "SPTExampleGroup.h" +#import "SPTSharedExampleGroups.h" +#import "SPTSpec.h" +#import "SPTCallSite.h" +#import + +static NSTimeInterval asyncSpecTimeout = 10.0; + +static void spt_defineItBlock(NSString *name, NSString *fileName, NSUInteger lineNumber, BOOL focused, void (^block)()) { + SPTReturnUnlessBlockOrNil(block); + SPTCallSite *site = nil; + if (lineNumber && fileName) { + site = [SPTCallSite callSiteWithFile:fileName line:lineNumber]; + } + [SPTCurrentGroup addExampleWithName:name callSite:site focused:focused block:block]; +} + +static void spt_defineDescribeBlock(NSString *name, BOOL focused, void (^block)()) { + if (block) { + [SPTGroupStack addObject:[SPTCurrentGroup addExampleGroupWithName:name focused:focused]]; + block(); + [SPTGroupStack removeLastObject]; + } else { + spt_defineItBlock(name, nil, 0, focused, nil); + } +} + +void spt_it_(NSString *name, NSString *fileName, NSUInteger lineNumber, void (^block)()) { + spt_defineItBlock(name, fileName, lineNumber, NO, block); +} + +void spt_fit_(NSString *name, NSString *fileName, NSUInteger lineNumber, void (^block)()) { + spt_defineItBlock(name, fileName, lineNumber, YES, block); +} + +void spt_pending_(NSString *name, ...) { + spt_defineItBlock(name, nil, 0, NO, nil); +} + +void spt_itShouldBehaveLike_(NSString *fileName, NSUInteger lineNumber, NSString *name, id dictionaryOrBlock) { + SPTDictionaryBlock block = [SPTSharedExampleGroups sharedExampleGroupWithName:name exampleGroup:SPTCurrentGroup]; + if (block) { + if (SPTIsBlock(dictionaryOrBlock)) { + id (^dataBlock)(void) = [dictionaryOrBlock copy]; + + describe(name, ^{ + __block NSMutableDictionary *dataDict = [[NSMutableDictionary alloc] init]; + + beforeEach(^{ + NSDictionary *blockData = dataBlock(); + [dataDict removeAllObjects]; + [dataDict addEntriesFromDictionary:blockData]; + }); + + block(dataDict); + + afterAll(^{ + dataDict = nil; + }); + }); + } else { + NSDictionary *data = dictionaryOrBlock; + + describe(name, ^{ + block(data); + }); + } + } else { + SPTSpec *currentSpec = SPTCurrentSpec; + if (currentSpec) { + [currentSpec recordFailureWithDescription:@"itShouldBehaveLike should not be invoked inside an example block!" inFile:fileName atLine:lineNumber expected:NO]; + } else { + it(name, ^{ + [SPTCurrentSpec recordFailureWithDescription:[NSString stringWithFormat:@"Shared example group \"%@\" does not exist.", name] inFile:fileName atLine:lineNumber expected:NO]; + }); + } + } +} + +void spt_itShouldBehaveLike_block(NSString *fileName, NSUInteger lineNumber, NSString *name, NSDictionary *(^block)()) { + spt_itShouldBehaveLike_(fileName, lineNumber, name, (id)block); +} + +void describe(NSString *name, void (^block)()) { + spt_defineDescribeBlock(name, NO, block); +} + +void fdescribe(NSString *name, void (^block)()) { + spt_defineDescribeBlock(name, YES, block); +} + +void context(NSString *name, void (^block)()) { + describe(name, block); +} + +void fcontext(NSString *name, void (^block)()) { + fdescribe(name, block); +} + +void it(NSString *name, void (^block)()) { + spt_defineItBlock(name, nil, 0, NO, block); +} + +void fit(NSString *name, void (^block)()) { + spt_defineItBlock(name, nil, 0, YES, block); +} + +void example(NSString *name, void (^block)()) { + it(name, block); +} + +void fexample(NSString *name, void (^block)()) { + fit(name, block); +} + +void specify(NSString *name, void (^block)()) { + it(name, block); +} + +void fspecify(NSString *name, void (^block)()) { + fit(name, block); +} + +void beforeAll(void (^block)()) { + SPTReturnUnlessBlockOrNil(block); + [SPTCurrentGroup addBeforeAllBlock:block]; +} + +void afterAll(void (^block)()) { + SPTReturnUnlessBlockOrNil(block); + [SPTCurrentGroup addAfterAllBlock:block]; +} + +void beforeEach(void (^block)()) { + SPTReturnUnlessBlockOrNil(block); + [SPTCurrentGroup addBeforeEachBlock:block]; +} + +void afterEach(void (^block)()) { + SPTReturnUnlessBlockOrNil(block); + [SPTCurrentGroup addAfterEachBlock:block]; +} + +void before(void (^block)()) { + beforeEach(block); +} + +void after(void (^block)()) { + afterEach(block); +} + +void sharedExamplesFor(NSString *name, void (^block)(NSDictionary *data)) { + [SPTSharedExampleGroups addSharedExampleGroupWithName:name block:block exampleGroup:SPTCurrentGroup]; +} + +void sharedExamples(NSString *name, void (^block)(NSDictionary *data)) { + sharedExamplesFor(name, block); +} + +void waitUntil(void (^block)(DoneCallback done)) { + waitUntilTimeout(asyncSpecTimeout, block); +} + +void waitUntilTimeout(NSTimeInterval timeout, void (^block)(DoneCallback done)) { + __block uint32_t complete = 0; + dispatch_async(dispatch_get_main_queue(), ^{ + block(^{ + OSAtomicOr32Barrier(1, &complete); + }); + }); + NSDate *timeoutDate = [NSDate dateWithTimeIntervalSinceNow:timeout]; + while (!complete && [timeoutDate timeIntervalSinceNow] > 0) { + [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.01]]; + } + if (!complete) { + NSString *message = [NSString stringWithFormat:@"failed to invoke done() callback before timeout (%f seconds)", timeout]; + SPTSpec *currentSpec = SPTCurrentSpec; + SPTTestSuite *testSuite = [[currentSpec class] spt_testSuite]; + [currentSpec recordFailureWithDescription:message inFile:testSuite.fileName atLine:testSuite.lineNumber expected:YES]; + } +} + +void setAsyncSpecTimeout(NSTimeInterval timeout) { + asyncSpecTimeout = timeout; +} diff --git a/Example/Pods/Specta/Specta/Specta/SpectaTypes.h b/Example/Pods/Specta/Specta/Specta/SpectaTypes.h new file mode 100644 index 0000000..f1f0ae3 --- /dev/null +++ b/Example/Pods/Specta/Specta/Specta/SpectaTypes.h @@ -0,0 +1,5 @@ +@class SPTSpec; + +typedef void (^SPTVoidBlock)(); +typedef void (^SPTSpecBlock)(SPTSpec *spec); +typedef void (^SPTDictionaryBlock)(NSDictionary *dictionary); diff --git a/Example/Pods/Specta/Specta/Specta/SpectaUtility.h b/Example/Pods/Specta/Specta/Specta/SpectaUtility.h new file mode 100644 index 0000000..a3a8f07 --- /dev/null +++ b/Example/Pods/Specta/Specta/Specta/SpectaUtility.h @@ -0,0 +1,18 @@ +#import + +extern NSString * const spt_kCurrentTestSuiteKey; +extern NSString * const spt_kCurrentSpecKey; + +#define SPTCurrentTestSuite [[NSThread mainThread] threadDictionary][spt_kCurrentTestSuiteKey] +#define SPTCurrentSpec [[NSThread mainThread] threadDictionary][spt_kCurrentSpecKey] +#define SPTCurrentGroup [SPTCurrentTestSuite currentGroup] +#define SPTGroupStack [SPTCurrentTestSuite groupStack] + +#define SPTReturnUnlessBlockOrNil(block) if ((block) && !SPTIsBlock((block))) return; +#define SPTIsBlock(obj) [(obj) isKindOfClass:NSClassFromString(@"NSBlock")] + +BOOL spt_isSpecClass(Class aClass); +NSString *spt_underscorize(NSString *string); +NSArray *spt_map(NSArray *array, id (^block)(id obj, NSUInteger idx)); +NSArray *spt_shuffle(NSArray *array); +unsigned int spt_seed(); diff --git a/Example/Pods/Specta/Specta/Specta/SpectaUtility.m b/Example/Pods/Specta/Specta/Specta/SpectaUtility.m new file mode 100644 index 0000000..9b2ee80 --- /dev/null +++ b/Example/Pods/Specta/Specta/Specta/SpectaUtility.m @@ -0,0 +1,79 @@ +#import "SpectaUtility.h" +#import "SPTSpec.h" +#import + +NSString * const spt_kCurrentTestSuiteKey = @"SPTCurrentTestSuite"; +NSString * const spt_kCurrentSpecKey = @"SPTCurrentSpec"; + +static unsigned int seed = 0; + +BOOL spt_isSpecClass(Class aClass) { + Class superclass = class_getSuperclass(aClass); + while (superclass != Nil) { + if (superclass == [SPTSpec class]) { + return YES; + } else { + superclass = class_getSuperclass(superclass); + } + } + return NO; +} + +NSString *spt_underscorize(NSString *string) { + static NSMutableCharacterSet *invalidCharSet; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + invalidCharSet = [[NSMutableCharacterSet alloc] init]; + [invalidCharSet formUnionWithCharacterSet:[NSCharacterSet controlCharacterSet]]; + [invalidCharSet formUnionWithCharacterSet:[NSCharacterSet illegalCharacterSet]]; + [invalidCharSet formUnionWithCharacterSet:[NSCharacterSet newlineCharacterSet]]; + [invalidCharSet formUnionWithCharacterSet:[NSCharacterSet nonBaseCharacterSet]]; + [invalidCharSet formUnionWithCharacterSet:[NSCharacterSet punctuationCharacterSet]]; + [invalidCharSet formUnionWithCharacterSet:[NSCharacterSet symbolCharacterSet]]; + }); + NSString *stripped = [string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; + stripped = [[stripped componentsSeparatedByCharactersInSet:invalidCharSet] componentsJoinedByString:@""]; + + NSArray *components = [stripped componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]; + stripped = [[components objectsAtIndexes:[components indexesOfObjectsPassingTest:^BOOL(id obj, NSUInteger idx, BOOL *stop) { + return ![obj isEqualToString:@""]; + }]] componentsJoinedByString:@"_"]; + return stripped; +} + +NSArray *spt_map(NSArray *array, id (^block)(id obj, NSUInteger idx)) { + NSMutableArray *mapped = [NSMutableArray arrayWithCapacity:[array count]]; + [array enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { + [mapped addObject:block(obj, idx)]; + }]; + return mapped; +} + +NSArray *spt_shuffle(NSArray *array) { + if (![[[[NSProcessInfo processInfo] environment] objectForKey:@"SPECTA_SHUFFLE"] isEqualToString:@"1"]) { + return array; + } + spt_seed(); + NSMutableArray *shuffled = [array mutableCopy]; + NSUInteger count = [shuffled count]; + for (NSUInteger i = 0; i < count; i++) { + NSUInteger r = random() % count; + [shuffled exchangeObjectAtIndex:i withObjectAtIndex:r]; + } + return shuffled; +} + +unsigned int spt_seed() { + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + NSString *envSeed = [[[NSProcessInfo processInfo] environment] objectForKey:@"SPECTA_SEED"]; + if (envSeed) { + sscanf([envSeed UTF8String], "%u", &seed); + } else { + seed = arc4random(); + } + srandom(seed); + printf("Test Seed: %u\n", seed); + }); + return seed; +} diff --git a/Example/Pods/Specta/Specta/Specta/XCTest+Private.h b/Example/Pods/Specta/Specta/Specta/XCTest+Private.h new file mode 100644 index 0000000..c88fcc9 --- /dev/null +++ b/Example/Pods/Specta/Specta/Specta/XCTest+Private.h @@ -0,0 +1,41 @@ +#import + +#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 90000 || __MAC_OS_X_VERSION_MAX_ALLOWED >= 101100 + +@interface XCTestObservationCenter (SPTTestSuspention) + +- (void)_suspendObservationForBlock:(void (^)(void))block; + +@end + +#else + +@interface XCTestObservationCenter : NSObject + ++ (id)sharedObservationCenter; +- (void)_suspendObservationForBlock:(void (^)(void))block; + +@end + +@protocol XCTestObservation +@end + + +#endif + +@interface _XCTestDriverTestObserver : NSObject + +- (void)stopObserving; +- (void)startObserving; + +@end + +@interface _XCTestCaseImplementation : NSObject +@end + +@interface XCTestCase () + +- (_XCTestCaseImplementation *)internalImplementation; +- (void)_recordUnexpectedFailureWithDescription:(NSString *)description exception:(NSException *)exception; + +@end diff --git a/Example/Pods/Specta/Specta/Specta/XCTestCase+Specta.h b/Example/Pods/Specta/Specta/Specta/XCTestCase+Specta.h new file mode 100644 index 0000000..9ca8f8a --- /dev/null +++ b/Example/Pods/Specta/Specta/Specta/XCTestCase+Specta.h @@ -0,0 +1,7 @@ +#import + +@interface XCTestCase (Specta) + +- (void)spt_handleException:(NSException *)exception; + +@end diff --git a/Example/Pods/Specta/Specta/Specta/XCTestCase+Specta.m b/Example/Pods/Specta/Specta/Specta/XCTestCase+Specta.m new file mode 100644 index 0000000..4c503ee --- /dev/null +++ b/Example/Pods/Specta/Specta/Specta/XCTestCase+Specta.m @@ -0,0 +1,65 @@ +#import +#import "XCTestCase+Specta.h" +#import "SPTSpec.h" +#import "SPTExample.h" +#import "SPTSharedExampleGroups.h" +#import "SpectaUtility.h" +#import "XCTest+Private.h" + +@interface XCTestCase (xct_allSubclasses) + +- (NSArray *)allSubclasses; +- (void)_dequeueFailures; + +@end + +@implementation XCTestCase (Specta) + ++ (void)load { + Method allSubclasses = class_getClassMethod(self, @selector(allSubclasses)); + Method allSubclasses_swizzle = class_getClassMethod(self , @selector(spt_allSubclasses_swizzle)); + method_exchangeImplementations(allSubclasses, allSubclasses_swizzle); + + Method dequeueFailures = class_getInstanceMethod(self, @selector(_dequeueFailures)); + Method dequeueFailures_swizzle = class_getInstanceMethod(self, @selector(spt_dequeueFailures)); + method_exchangeImplementations(dequeueFailures, dequeueFailures_swizzle); +} + ++ (NSArray *)spt_allSubclasses_swizzle { + NSArray *subclasses = [self spt_allSubclasses_swizzle]; // call original + NSMutableArray *filtered = [NSMutableArray arrayWithCapacity:[subclasses count]]; + // exclude SPTSpec base class and all subclasses of SPTSharedExampleGroups + for (id subclass in subclasses) { + if (subclass != [SPTSpec class] && ![subclass isKindOfClass:[SPTSharedExampleGroups class]]) { + [filtered addObject:subclass]; + } + } + return spt_shuffle(filtered); +} + +- (void)spt_dequeueFailures { + void(^dequeueFailures)() = ^() { + [self spt_dequeueFailures]; + }; + + if ([NSThread isMainThread]) { + dequeueFailures(); + } else { + dispatch_sync(dispatch_get_main_queue(), dequeueFailures); + } +} + +- (void)spt_handleException:(NSException *)exception { + NSString *description = [exception reason]; + if ([exception userInfo]) { + id line = [exception userInfo][@"line"]; + id file = [exception userInfo][@"file"]; + if ([line isKindOfClass:[NSNumber class]] && [file isKindOfClass:[NSString class]]) { + [self recordFailureWithDescription:description inFile:file atLine:[line unsignedIntegerValue] expected:YES]; + return; + } + } + [self _recordUnexpectedFailureWithDescription:description exception:exception]; +} + +@end diff --git a/Example/Pods/Target Support Files/Expecta+Snapshots/Expecta+Snapshots-dummy.m b/Example/Pods/Target Support Files/Expecta+Snapshots/Expecta+Snapshots-dummy.m new file mode 100644 index 0000000..a28cba4 --- /dev/null +++ b/Example/Pods/Target Support Files/Expecta+Snapshots/Expecta+Snapshots-dummy.m @@ -0,0 +1,5 @@ +#import +@interface PodsDummy_Expecta_Snapshots : NSObject +@end +@implementation PodsDummy_Expecta_Snapshots +@end diff --git a/Example/Pods/Target Support Files/Expecta+Snapshots/Expecta+Snapshots-prefix.pch b/Example/Pods/Target Support Files/Expecta+Snapshots/Expecta+Snapshots-prefix.pch new file mode 100644 index 0000000..aa992a4 --- /dev/null +++ b/Example/Pods/Target Support Files/Expecta+Snapshots/Expecta+Snapshots-prefix.pch @@ -0,0 +1,4 @@ +#ifdef __OBJC__ +#import +#endif + diff --git a/Example/Pods/Target Support Files/Expecta+Snapshots/Expecta+Snapshots-umbrella.h b/Example/Pods/Target Support Files/Expecta+Snapshots/Expecta+Snapshots-umbrella.h new file mode 100644 index 0000000..f065e56 --- /dev/null +++ b/Example/Pods/Target Support Files/Expecta+Snapshots/Expecta+Snapshots-umbrella.h @@ -0,0 +1,8 @@ +#import + +#import "ExpectaObject+FBSnapshotTest.h" +#import "EXPMatchers+FBSnapshotTest.h" + +FOUNDATION_EXPORT double Expecta_SnapshotsVersionNumber; +FOUNDATION_EXPORT const unsigned char Expecta_SnapshotsVersionString[]; + diff --git a/Example/Pods/Target Support Files/Expecta+Snapshots/Expecta+Snapshots.modulemap b/Example/Pods/Target Support Files/Expecta+Snapshots/Expecta+Snapshots.modulemap new file mode 100644 index 0000000..15f364a --- /dev/null +++ b/Example/Pods/Target Support Files/Expecta+Snapshots/Expecta+Snapshots.modulemap @@ -0,0 +1,6 @@ +framework module Expecta_Snapshots { + umbrella header "Expecta+Snapshots-umbrella.h" + + export * + module * { export * } +} diff --git a/Example/Pods/Target Support Files/Expecta+Snapshots/Expecta+Snapshots.xcconfig b/Example/Pods/Target Support Files/Expecta+Snapshots/Expecta+Snapshots.xcconfig new file mode 100644 index 0000000..86db3e6 --- /dev/null +++ b/Example/Pods/Target Support Files/Expecta+Snapshots/Expecta+Snapshots.xcconfig @@ -0,0 +1,7 @@ +FRAMEWORK_SEARCH_PATHS = $(inherited) "$(PLATFORM_DIR)/Developer/Library/Frameworks" +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +HEADER_SEARCH_PATHS = "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Public" +OTHER_LDFLAGS = -framework "Foundation" -framework "XCTest" +PODS_ROOT = ${SRCROOT} +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES diff --git a/Example/Pods/Target Support Files/Expecta+Snapshots/Info.plist b/Example/Pods/Target Support Files/Expecta+Snapshots/Info.plist new file mode 100644 index 0000000..0a12077 --- /dev/null +++ b/Example/Pods/Target Support Files/Expecta+Snapshots/Info.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIdentifier + ${PRODUCT_BUNDLE_IDENTIFIER} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + FMWK + CFBundleShortVersionString + 2.0.0 + CFBundleSignature + ???? + CFBundleVersion + ${CURRENT_PROJECT_VERSION} + NSPrincipalClass + + + diff --git a/Example/Pods/Target Support Files/Expecta/Expecta-dummy.m b/Example/Pods/Target Support Files/Expecta/Expecta-dummy.m new file mode 100644 index 0000000..c4c252a --- /dev/null +++ b/Example/Pods/Target Support Files/Expecta/Expecta-dummy.m @@ -0,0 +1,5 @@ +#import +@interface PodsDummy_Expecta : NSObject +@end +@implementation PodsDummy_Expecta +@end diff --git a/Example/Pods/Target Support Files/Expecta/Expecta-prefix.pch b/Example/Pods/Target Support Files/Expecta/Expecta-prefix.pch new file mode 100644 index 0000000..aa992a4 --- /dev/null +++ b/Example/Pods/Target Support Files/Expecta/Expecta-prefix.pch @@ -0,0 +1,4 @@ +#ifdef __OBJC__ +#import +#endif + diff --git a/Example/Pods/Target Support Files/Expecta/Expecta-umbrella.h b/Example/Pods/Target Support Files/Expecta/Expecta-umbrella.h new file mode 100644 index 0000000..79e1308 --- /dev/null +++ b/Example/Pods/Target Support Files/Expecta/Expecta-umbrella.h @@ -0,0 +1,45 @@ +#import + +#import "EXPBlockDefinedMatcher.h" +#import "EXPDefines.h" +#import "EXPDoubleTuple.h" +#import "Expecta.h" +#import "ExpectaObject.h" +#import "ExpectaSupport.h" +#import "EXPExpect.h" +#import "EXPFloatTuple.h" +#import "EXPMatcher.h" +#import "EXPUnsupportedObject.h" +#import "EXPMatcherHelpers.h" +#import "EXPMatchers+beCloseTo.h" +#import "EXPMatchers+beFalsy.h" +#import "EXPMatchers+beginWith.h" +#import "EXPMatchers+beGreaterThan.h" +#import "EXPMatchers+beGreaterThanOrEqualTo.h" +#import "EXPMatchers+beIdenticalTo.h" +#import "EXPMatchers+beInstanceOf.h" +#import "EXPMatchers+beInTheRangeOf.h" +#import "EXPMatchers+beKindOf.h" +#import "EXPMatchers+beLessThan.h" +#import "EXPMatchers+beLessThanOrEqualTo.h" +#import "EXPMatchers+beNil.h" +#import "EXPMatchers+beSubclassOf.h" +#import "EXPMatchers+beSupersetOf.h" +#import "EXPMatchers+beTruthy.h" +#import "EXPMatchers+conformTo.h" +#import "EXPMatchers+contain.h" +#import "EXPMatchers+endWith.h" +#import "EXPMatchers+equal.h" +#import "EXPMatchers+haveCountOf.h" +#import "EXPMatchers+match.h" +#import "EXPMatchers+postNotification.h" +#import "EXPMatchers+raise.h" +#import "EXPMatchers+raiseWithReason.h" +#import "EXPMatchers+respondTo.h" +#import "EXPMatchers.h" +#import "NSObject+Expecta.h" +#import "NSValue+Expecta.h" + +FOUNDATION_EXPORT double ExpectaVersionNumber; +FOUNDATION_EXPORT const unsigned char ExpectaVersionString[]; + diff --git a/Example/Pods/Target Support Files/Expecta/Expecta.modulemap b/Example/Pods/Target Support Files/Expecta/Expecta.modulemap new file mode 100644 index 0000000..e06f902 --- /dev/null +++ b/Example/Pods/Target Support Files/Expecta/Expecta.modulemap @@ -0,0 +1,6 @@ +framework module Expecta { + umbrella header "Expecta-umbrella.h" + + export * + module * { export * } +} diff --git a/Example/Pods/Target Support Files/Expecta/Expecta.xcconfig b/Example/Pods/Target Support Files/Expecta/Expecta.xcconfig new file mode 100644 index 0000000..bd75300 --- /dev/null +++ b/Example/Pods/Target Support Files/Expecta/Expecta.xcconfig @@ -0,0 +1,8 @@ +ENABLE_BITCODE = NO +FRAMEWORK_SEARCH_PATHS = $(inherited) "$(PLATFORM_DIR)/Developer/Library/Frameworks" +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +HEADER_SEARCH_PATHS = "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Public" +OTHER_LDFLAGS = -framework "Foundation" -framework "XCTest" +PODS_ROOT = ${SRCROOT} +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES diff --git a/Example/Pods/Target Support Files/Expecta/Info.plist b/Example/Pods/Target Support Files/Expecta/Info.plist new file mode 100644 index 0000000..a5730fa --- /dev/null +++ b/Example/Pods/Target Support Files/Expecta/Info.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIdentifier + ${PRODUCT_BUNDLE_IDENTIFIER} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0.5 + CFBundleSignature + ???? + CFBundleVersion + ${CURRENT_PROJECT_VERSION} + NSPrincipalClass + + + diff --git a/Example/Pods/Target Support Files/FBSnapshotTestCase/FBSnapshotTestCase-dummy.m b/Example/Pods/Target Support Files/FBSnapshotTestCase/FBSnapshotTestCase-dummy.m new file mode 100644 index 0000000..fb0c8fe --- /dev/null +++ b/Example/Pods/Target Support Files/FBSnapshotTestCase/FBSnapshotTestCase-dummy.m @@ -0,0 +1,5 @@ +#import +@interface PodsDummy_FBSnapshotTestCase : NSObject +@end +@implementation PodsDummy_FBSnapshotTestCase +@end diff --git a/Example/Pods/Target Support Files/FBSnapshotTestCase/FBSnapshotTestCase-prefix.pch b/Example/Pods/Target Support Files/FBSnapshotTestCase/FBSnapshotTestCase-prefix.pch new file mode 100644 index 0000000..aa992a4 --- /dev/null +++ b/Example/Pods/Target Support Files/FBSnapshotTestCase/FBSnapshotTestCase-prefix.pch @@ -0,0 +1,4 @@ +#ifdef __OBJC__ +#import +#endif + diff --git a/Example/Pods/Target Support Files/FBSnapshotTestCase/FBSnapshotTestCase.modulemap b/Example/Pods/Target Support Files/FBSnapshotTestCase/FBSnapshotTestCase.modulemap new file mode 100644 index 0000000..733e78b --- /dev/null +++ b/Example/Pods/Target Support Files/FBSnapshotTestCase/FBSnapshotTestCase.modulemap @@ -0,0 +1,15 @@ +framework module FBSnapshotTestCase { + umbrella header "FBSnapshotTestCase.h" + + export * + module * { export * } + + header "FBSnapshotTestCase.h" + header "FBSnapshotTestCasePlatform.h" + header "FBSnapshotTestController.h" + + private header "UIImage+Compare.h" + private header "UIImage+Diff.h" + private header "UIImage+Snapshot.h" +} + diff --git a/Example/Pods/Target Support Files/FBSnapshotTestCase/FBSnapshotTestCase.xcconfig b/Example/Pods/Target Support Files/FBSnapshotTestCase/FBSnapshotTestCase.xcconfig new file mode 100644 index 0000000..08f0943 --- /dev/null +++ b/Example/Pods/Target Support Files/FBSnapshotTestCase/FBSnapshotTestCase.xcconfig @@ -0,0 +1,9 @@ +ENABLE_BITCODE = NO +FRAMEWORK_SEARCH_PATHS = $(inherited) "$(PLATFORM_DIR)/Developer/Library/Frameworks" +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +HEADER_SEARCH_PATHS = "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Public" +OTHER_LDFLAGS = -framework "Foundation" -framework "QuartzCore" -framework "UIKit" -framework "XCTest" +OTHER_SWIFT_FLAGS = $(inherited) "-D" "COCOAPODS" +PODS_ROOT = ${SRCROOT} +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES diff --git a/Example/Pods/Target Support Files/FBSnapshotTestCase/Info.plist b/Example/Pods/Target Support Files/FBSnapshotTestCase/Info.plist new file mode 100644 index 0000000..4fcad82 --- /dev/null +++ b/Example/Pods/Target Support Files/FBSnapshotTestCase/Info.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIdentifier + ${PRODUCT_BUNDLE_IDENTIFIER} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + FMWK + CFBundleShortVersionString + 2.0.7 + CFBundleSignature + ???? + CFBundleVersion + ${CURRENT_PROJECT_VERSION} + NSPrincipalClass + + + diff --git a/Example/Pods/Target Support Files/PNImagePickerViewController/Info.plist b/Example/Pods/Target Support Files/PNImagePickerViewController/Info.plist new file mode 100644 index 0000000..161a9d3 --- /dev/null +++ b/Example/Pods/Target Support Files/PNImagePickerViewController/Info.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIdentifier + ${PRODUCT_BUNDLE_IDENTIFIER} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + FMWK + CFBundleShortVersionString + 0.1.0 + CFBundleSignature + ???? + CFBundleVersion + ${CURRENT_PROJECT_VERSION} + NSPrincipalClass + + + diff --git a/Example/Pods/Target Support Files/PNImagePickerViewController/PNImagePickerViewController-dummy.m b/Example/Pods/Target Support Files/PNImagePickerViewController/PNImagePickerViewController-dummy.m new file mode 100644 index 0000000..b3fc4f8 --- /dev/null +++ b/Example/Pods/Target Support Files/PNImagePickerViewController/PNImagePickerViewController-dummy.m @@ -0,0 +1,5 @@ +#import +@interface PodsDummy_PNImagePickerViewController : NSObject +@end +@implementation PodsDummy_PNImagePickerViewController +@end diff --git a/Example/Pods/Target Support Files/PNImagePickerViewController/PNImagePickerViewController-prefix.pch b/Example/Pods/Target Support Files/PNImagePickerViewController/PNImagePickerViewController-prefix.pch new file mode 100644 index 0000000..aa992a4 --- /dev/null +++ b/Example/Pods/Target Support Files/PNImagePickerViewController/PNImagePickerViewController-prefix.pch @@ -0,0 +1,4 @@ +#ifdef __OBJC__ +#import +#endif + diff --git a/Example/Pods/Target Support Files/PNImagePickerViewController/PNImagePickerViewController-umbrella.h b/Example/Pods/Target Support Files/PNImagePickerViewController/PNImagePickerViewController-umbrella.h new file mode 100644 index 0000000..fce9245 --- /dev/null +++ b/Example/Pods/Target Support Files/PNImagePickerViewController/PNImagePickerViewController-umbrella.h @@ -0,0 +1,9 @@ +#import + +#import "NSString+HexColor.h" +#import "PNCollectionViewCell.h" +#import "PNImagePickerViewController.h" + +FOUNDATION_EXPORT double PNImagePickerViewControllerVersionNumber; +FOUNDATION_EXPORT const unsigned char PNImagePickerViewControllerVersionString[]; + diff --git a/Example/Pods/Target Support Files/PNImagePickerViewController/PNImagePickerViewController.modulemap b/Example/Pods/Target Support Files/PNImagePickerViewController/PNImagePickerViewController.modulemap new file mode 100644 index 0000000..9090d07 --- /dev/null +++ b/Example/Pods/Target Support Files/PNImagePickerViewController/PNImagePickerViewController.modulemap @@ -0,0 +1,6 @@ +framework module PNImagePickerViewController { + umbrella header "PNImagePickerViewController-umbrella.h" + + export * + module * { export * } +} diff --git a/Example/Pods/Target Support Files/PNImagePickerViewController/PNImagePickerViewController.xcconfig b/Example/Pods/Target Support Files/PNImagePickerViewController/PNImagePickerViewController.xcconfig new file mode 100644 index 0000000..5b52139 --- /dev/null +++ b/Example/Pods/Target Support Files/PNImagePickerViewController/PNImagePickerViewController.xcconfig @@ -0,0 +1,6 @@ +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +HEADER_SEARCH_PATHS = "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Public" +OTHER_LDFLAGS = -framework "Photos" -framework "PhotosUI" +PODS_ROOT = ${SRCROOT} +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES diff --git a/Example/Pods/Target Support Files/PNImagePickerViewController/ResourceBundle-PNImagePickerViewController-Info.plist b/Example/Pods/Target Support Files/PNImagePickerViewController/ResourceBundle-PNImagePickerViewController-Info.plist new file mode 100644 index 0000000..aec6281 --- /dev/null +++ b/Example/Pods/Target Support Files/PNImagePickerViewController/ResourceBundle-PNImagePickerViewController-Info.plist @@ -0,0 +1,24 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleIdentifier + ${PRODUCT_BUNDLE_IDENTIFIER} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + BNDL + CFBundleShortVersionString + 0.1.0 + CFBundleSignature + ???? + CFBundleVersion + ${CURRENT_PROJECT_VERSION} + NSPrincipalClass + + + diff --git a/Example/Pods/Target Support Files/Pods-PNImagePickerViewController_Example/Info.plist b/Example/Pods/Target Support Files/Pods-PNImagePickerViewController_Example/Info.plist new file mode 100644 index 0000000..2243fe6 --- /dev/null +++ b/Example/Pods/Target Support Files/Pods-PNImagePickerViewController_Example/Info.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIdentifier + ${PRODUCT_BUNDLE_IDENTIFIER} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0.0 + CFBundleSignature + ???? + CFBundleVersion + ${CURRENT_PROJECT_VERSION} + NSPrincipalClass + + + diff --git a/Example/Pods/Target Support Files/Pods-PNImagePickerViewController_Example/Pods-PNImagePickerViewController_Example-acknowledgements.markdown b/Example/Pods/Target Support Files/Pods-PNImagePickerViewController_Example/Pods-PNImagePickerViewController_Example-acknowledgements.markdown new file mode 100644 index 0000000..88a3679 --- /dev/null +++ b/Example/Pods/Target Support Files/Pods-PNImagePickerViewController_Example/Pods-PNImagePickerViewController_Example-acknowledgements.markdown @@ -0,0 +1,39 @@ +# Acknowledgements +This application makes use of the following third party libraries: + +## PNImagePickerViewController + +Copyright (c) 2016 Giuseppe Nucifora + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + + +## PureLayout + +This code is distributed under the terms and conditions of the MIT license. + +Copyright (c) 2014-2015 Tyler Fox + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Generated by CocoaPods - https://cocoapods.org diff --git a/Example/Pods/Target Support Files/Pods-PNImagePickerViewController_Example/Pods-PNImagePickerViewController_Example-acknowledgements.plist b/Example/Pods/Target Support Files/Pods-PNImagePickerViewController_Example/Pods-PNImagePickerViewController_Example-acknowledgements.plist new file mode 100644 index 0000000..7ed9665 --- /dev/null +++ b/Example/Pods/Target Support Files/Pods-PNImagePickerViewController_Example/Pods-PNImagePickerViewController_Example-acknowledgements.plist @@ -0,0 +1,73 @@ + + + + + PreferenceSpecifiers + + + FooterText + This application makes use of the following third party libraries: + Title + Acknowledgements + Type + PSGroupSpecifier + + + FooterText + Copyright (c) 2016 Giuseppe Nucifora <me@giuseppenucifora.com> + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + + Title + PNImagePickerViewController + Type + PSGroupSpecifier + + + FooterText + This code is distributed under the terms and conditions of the MIT license. + +Copyright (c) 2014-2015 Tyler Fox + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + Title + PureLayout + Type + PSGroupSpecifier + + + FooterText + Generated by CocoaPods - https://cocoapods.org + Title + + Type + PSGroupSpecifier + + + StringsTable + Acknowledgements + Title + Acknowledgements + + diff --git a/Example/Pods/Target Support Files/Pods-PNImagePickerViewController_Example/Pods-PNImagePickerViewController_Example-dummy.m b/Example/Pods/Target Support Files/Pods-PNImagePickerViewController_Example/Pods-PNImagePickerViewController_Example-dummy.m new file mode 100644 index 0000000..24f94fb --- /dev/null +++ b/Example/Pods/Target Support Files/Pods-PNImagePickerViewController_Example/Pods-PNImagePickerViewController_Example-dummy.m @@ -0,0 +1,5 @@ +#import +@interface PodsDummy_Pods_PNImagePickerViewController_Example : NSObject +@end +@implementation PodsDummy_Pods_PNImagePickerViewController_Example +@end diff --git a/Example/Pods/Target Support Files/Pods-PNImagePickerViewController_Example/Pods-PNImagePickerViewController_Example-frameworks.sh b/Example/Pods/Target Support Files/Pods-PNImagePickerViewController_Example/Pods-PNImagePickerViewController_Example-frameworks.sh new file mode 100755 index 0000000..b3c9031 --- /dev/null +++ b/Example/Pods/Target Support Files/Pods-PNImagePickerViewController_Example/Pods-PNImagePickerViewController_Example-frameworks.sh @@ -0,0 +1,93 @@ +#!/bin/sh +set -e + +echo "mkdir -p ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" +mkdir -p "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" + +SWIFT_STDLIB_PATH="${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" + +install_framework() +{ + if [ -r "${BUILT_PRODUCTS_DIR}/$1" ]; then + local source="${BUILT_PRODUCTS_DIR}/$1" + elif [ -r "${BUILT_PRODUCTS_DIR}/$(basename "$1")" ]; then + local source="${BUILT_PRODUCTS_DIR}/$(basename "$1")" + elif [ -r "$1" ]; then + local source="$1" + fi + + local destination="${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" + + if [ -L "${source}" ]; then + echo "Symlinked..." + source="$(readlink "${source}")" + fi + + # use filter instead of exclude so missing patterns dont' throw errors + echo "rsync -av --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${destination}\"" + rsync -av --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${destination}" + + local basename + basename="$(basename -s .framework "$1")" + binary="${destination}/${basename}.framework/${basename}" + if ! [ -r "$binary" ]; then + binary="${destination}/${basename}" + fi + + # Strip invalid architectures so "fat" simulator / device frameworks work on device + if [[ "$(file "$binary")" == *"dynamically linked shared library"* ]]; then + strip_invalid_archs "$binary" + fi + + # Resign the code if required by the build settings to avoid unstable apps + code_sign_if_enabled "${destination}/$(basename "$1")" + + # Embed linked Swift runtime libraries. No longer necessary as of Xcode 7. + if [ "${XCODE_VERSION_MAJOR}" -lt 7 ]; then + local swift_runtime_libs + swift_runtime_libs=$(xcrun otool -LX "$binary" | grep --color=never @rpath/libswift | sed -E s/@rpath\\/\(.+dylib\).*/\\1/g | uniq -u && exit ${PIPESTATUS[0]}) + for lib in $swift_runtime_libs; do + echo "rsync -auv \"${SWIFT_STDLIB_PATH}/${lib}\" \"${destination}\"" + rsync -auv "${SWIFT_STDLIB_PATH}/${lib}" "${destination}" + code_sign_if_enabled "${destination}/${lib}" + done + fi +} + +# Signs a framework with the provided identity +code_sign_if_enabled() { + if [ -n "${EXPANDED_CODE_SIGN_IDENTITY}" -a "${CODE_SIGNING_REQUIRED}" != "NO" -a "${CODE_SIGNING_ALLOWED}" != "NO" ]; then + # Use the current code_sign_identitiy + echo "Code Signing $1 with Identity ${EXPANDED_CODE_SIGN_IDENTITY_NAME}" + echo "/usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} --preserve-metadata=identifier,entitlements \"$1\"" + /usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} --preserve-metadata=identifier,entitlements "$1" + fi +} + +# Strip invalid architectures +strip_invalid_archs() { + binary="$1" + # Get architectures for current file + archs="$(lipo -info "$binary" | rev | cut -d ':' -f1 | rev)" + stripped="" + for arch in $archs; do + if ! [[ "${VALID_ARCHS}" == *"$arch"* ]]; then + # Strip non-valid architectures in-place + lipo -remove "$arch" -output "$binary" "$binary" || exit 1 + stripped="$stripped $arch" + fi + done + if [[ "$stripped" ]]; then + echo "Stripped $binary of architectures:$stripped" + fi +} + + +if [[ "$CONFIGURATION" == "Debug" ]]; then + install_framework "Pods-PNImagePickerViewController_Example/PNImagePickerViewController.framework" + install_framework "Pods-PNImagePickerViewController_Example/PureLayout.framework" +fi +if [[ "$CONFIGURATION" == "Release" ]]; then + install_framework "Pods-PNImagePickerViewController_Example/PNImagePickerViewController.framework" + install_framework "Pods-PNImagePickerViewController_Example/PureLayout.framework" +fi diff --git a/Example/Pods/Target Support Files/Pods-PNImagePickerViewController_Example/Pods-PNImagePickerViewController_Example-resources.sh b/Example/Pods/Target Support Files/Pods-PNImagePickerViewController_Example/Pods-PNImagePickerViewController_Example-resources.sh new file mode 100755 index 0000000..fa69136 --- /dev/null +++ b/Example/Pods/Target Support Files/Pods-PNImagePickerViewController_Example/Pods-PNImagePickerViewController_Example-resources.sh @@ -0,0 +1,102 @@ +#!/bin/sh +set -e + +mkdir -p "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" + +RESOURCES_TO_COPY=${PODS_ROOT}/resources-to-copy-${TARGETNAME}.txt +> "$RESOURCES_TO_COPY" + +XCASSET_FILES=() + +realpath() { + DIRECTORY="$(cd "${1%/*}" && pwd)" + FILENAME="${1##*/}" + echo "$DIRECTORY/$FILENAME" +} + +install_resource() +{ + if [[ "$1" = /* ]] ; then + RESOURCE_PATH="$1" + else + RESOURCE_PATH="${PODS_ROOT}/$1" + fi + if [[ ! -e "$RESOURCE_PATH" ]] ; then + cat << EOM +error: Resource "$RESOURCE_PATH" not found. Run 'pod install' to update the copy resources script. +EOM + exit 1 + fi + case $RESOURCE_PATH in + *.storyboard) + echo "ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile ${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .storyboard`.storyboardc $RESOURCE_PATH --sdk ${SDKROOT}" + ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .storyboard`.storyboardc" "$RESOURCE_PATH" --sdk "${SDKROOT}" + ;; + *.xib) + echo "ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile ${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .xib`.nib $RESOURCE_PATH --sdk ${SDKROOT}" + ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .xib`.nib" "$RESOURCE_PATH" --sdk "${SDKROOT}" + ;; + *.framework) + echo "mkdir -p ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" + mkdir -p "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" + echo "rsync -av $RESOURCE_PATH ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" + rsync -av "$RESOURCE_PATH" "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" + ;; + *.xcdatamodel) + echo "xcrun momc \"$RESOURCE_PATH\" \"${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH"`.mom\"" + xcrun momc "$RESOURCE_PATH" "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodel`.mom" + ;; + *.xcdatamodeld) + echo "xcrun momc \"$RESOURCE_PATH\" \"${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd\"" + xcrun momc "$RESOURCE_PATH" "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd" + ;; + *.xcmappingmodel) + echo "xcrun mapc \"$RESOURCE_PATH\" \"${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm\"" + xcrun mapc "$RESOURCE_PATH" "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm" + ;; + *.xcassets) + ABSOLUTE_XCASSET_FILE=$(realpath "$RESOURCE_PATH") + XCASSET_FILES+=("$ABSOLUTE_XCASSET_FILE") + ;; + *) + echo "$RESOURCE_PATH" + echo "$RESOURCE_PATH" >> "$RESOURCES_TO_COPY" + ;; + esac +} + +mkdir -p "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" +rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" +if [[ "${ACTION}" == "install" ]] && [[ "${SKIP_INSTALL}" == "NO" ]]; then + mkdir -p "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" + rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" +fi +rm -f "$RESOURCES_TO_COPY" + +if [[ -n "${WRAPPER_EXTENSION}" ]] && [ "`xcrun --find actool`" ] && [ -n "$XCASSET_FILES" ] +then + case "${TARGETED_DEVICE_FAMILY}" in + 1,2) + TARGET_DEVICE_ARGS="--target-device ipad --target-device iphone" + ;; + 1) + TARGET_DEVICE_ARGS="--target-device iphone" + ;; + 2) + TARGET_DEVICE_ARGS="--target-device ipad" + ;; + *) + TARGET_DEVICE_ARGS="--target-device mac" + ;; + esac + + # Find all other xcassets (this unfortunately includes those of path pods and other targets). + OTHER_XCASSETS=$(find "$PWD" -iname "*.xcassets" -type d) + while read line; do + if [[ $line != "`realpath $PODS_ROOT`*" ]]; then + XCASSET_FILES+=("$line") + fi + done <<<"$OTHER_XCASSETS" + + 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}" +fi diff --git a/Example/Pods/Target Support Files/Pods-PNImagePickerViewController_Example/Pods-PNImagePickerViewController_Example-umbrella.h b/Example/Pods/Target Support Files/Pods-PNImagePickerViewController_Example/Pods-PNImagePickerViewController_Example-umbrella.h new file mode 100644 index 0000000..5909071 --- /dev/null +++ b/Example/Pods/Target Support Files/Pods-PNImagePickerViewController_Example/Pods-PNImagePickerViewController_Example-umbrella.h @@ -0,0 +1,6 @@ +#import + + +FOUNDATION_EXPORT double Pods_PNImagePickerViewController_ExampleVersionNumber; +FOUNDATION_EXPORT const unsigned char Pods_PNImagePickerViewController_ExampleVersionString[]; + diff --git a/Example/Pods/Target Support Files/Pods-PNImagePickerViewController_Example/Pods-PNImagePickerViewController_Example.debug.xcconfig b/Example/Pods/Target Support Files/Pods-PNImagePickerViewController_Example/Pods-PNImagePickerViewController_Example.debug.xcconfig new file mode 100644 index 0000000..6661632 --- /dev/null +++ b/Example/Pods/Target Support Files/Pods-PNImagePickerViewController_Example/Pods-PNImagePickerViewController_Example.debug.xcconfig @@ -0,0 +1,6 @@ +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' +OTHER_CFLAGS = $(inherited) -iquote "$CONFIGURATION_BUILD_DIR/PNImagePickerViewController.framework/Headers" -iquote "$CONFIGURATION_BUILD_DIR/PureLayout.framework/Headers" +OTHER_LDFLAGS = $(inherited) -framework "PNImagePickerViewController" -framework "PureLayout" +PODS_FRAMEWORK_BUILD_PATH = "$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/Pods-PNImagePickerViewController_Example" +PODS_ROOT = ${SRCROOT}/Pods diff --git a/Example/Pods/Target Support Files/Pods-PNImagePickerViewController_Example/Pods-PNImagePickerViewController_Example.modulemap b/Example/Pods/Target Support Files/Pods-PNImagePickerViewController_Example/Pods-PNImagePickerViewController_Example.modulemap new file mode 100644 index 0000000..21809c0 --- /dev/null +++ b/Example/Pods/Target Support Files/Pods-PNImagePickerViewController_Example/Pods-PNImagePickerViewController_Example.modulemap @@ -0,0 +1,6 @@ +framework module Pods_PNImagePickerViewController_Example { + umbrella header "Pods-PNImagePickerViewController_Example-umbrella.h" + + export * + module * { export * } +} diff --git a/Example/Pods/Target Support Files/Pods-PNImagePickerViewController_Example/Pods-PNImagePickerViewController_Example.release.xcconfig b/Example/Pods/Target Support Files/Pods-PNImagePickerViewController_Example/Pods-PNImagePickerViewController_Example.release.xcconfig new file mode 100644 index 0000000..6661632 --- /dev/null +++ b/Example/Pods/Target Support Files/Pods-PNImagePickerViewController_Example/Pods-PNImagePickerViewController_Example.release.xcconfig @@ -0,0 +1,6 @@ +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' +OTHER_CFLAGS = $(inherited) -iquote "$CONFIGURATION_BUILD_DIR/PNImagePickerViewController.framework/Headers" -iquote "$CONFIGURATION_BUILD_DIR/PureLayout.framework/Headers" +OTHER_LDFLAGS = $(inherited) -framework "PNImagePickerViewController" -framework "PureLayout" +PODS_FRAMEWORK_BUILD_PATH = "$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/Pods-PNImagePickerViewController_Example" +PODS_ROOT = ${SRCROOT}/Pods diff --git a/Example/Pods/Target Support Files/Pods-PNImagePickerViewController_Tests/Info.plist b/Example/Pods/Target Support Files/Pods-PNImagePickerViewController_Tests/Info.plist new file mode 100644 index 0000000..2243fe6 --- /dev/null +++ b/Example/Pods/Target Support Files/Pods-PNImagePickerViewController_Tests/Info.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIdentifier + ${PRODUCT_BUNDLE_IDENTIFIER} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0.0 + CFBundleSignature + ???? + CFBundleVersion + ${CURRENT_PROJECT_VERSION} + NSPrincipalClass + + + diff --git a/Example/Pods/Target Support Files/Pods-PNImagePickerViewController_Tests/Pods-PNImagePickerViewController_Tests-acknowledgements.markdown b/Example/Pods/Target Support Files/Pods-PNImagePickerViewController_Tests/Pods-PNImagePickerViewController_Tests-acknowledgements.markdown new file mode 100644 index 0000000..04d959f --- /dev/null +++ b/Example/Pods/Target Support Files/Pods-PNImagePickerViewController_Tests/Pods-PNImagePickerViewController_Tests-acknowledgements.markdown @@ -0,0 +1,145 @@ +# Acknowledgements +This application makes use of the following third party libraries: + +## PNImagePickerViewController + +Copyright (c) 2016 Giuseppe Nucifora + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + + +## PureLayout + +This code is distributed under the terms and conditions of the MIT license. + +Copyright (c) 2014-2015 Tyler Fox + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + +## Expecta + +Copyright (c) 2011-2015 Specta Team - https://github.com/specta + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + + +## Expecta+Snapshots + +MIT License + +Copyright (c) 2014 Daniel Doubrovkine, Artsy Inc. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + +## FBSnapshotTestCase + +BSD License + +For the FBSnapshotTestCase software + +Copyright (c) 2013, Facebook, Inc. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + * Neither the name Facebook nor the names of its contributors may be used to + endorse or promote products derived from this software without specific + prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +## Specta + +Copyright (c) 2012-2014 Specta Team. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + + +Generated by CocoaPods - https://cocoapods.org diff --git a/Example/Pods/Target Support Files/Pods-PNImagePickerViewController_Tests/Pods-PNImagePickerViewController_Tests-acknowledgements.plist b/Example/Pods/Target Support Files/Pods-PNImagePickerViewController_Tests/Pods-PNImagePickerViewController_Tests-acknowledgements.plist new file mode 100644 index 0000000..21c783d --- /dev/null +++ b/Example/Pods/Target Support Files/Pods-PNImagePickerViewController_Tests/Pods-PNImagePickerViewController_Tests-acknowledgements.plist @@ -0,0 +1,195 @@ + + + + + PreferenceSpecifiers + + + FooterText + This application makes use of the following third party libraries: + Title + Acknowledgements + Type + PSGroupSpecifier + + + FooterText + Copyright (c) 2016 Giuseppe Nucifora <me@giuseppenucifora.com> + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + + Title + PNImagePickerViewController + Type + PSGroupSpecifier + + + FooterText + This code is distributed under the terms and conditions of the MIT license. + +Copyright (c) 2014-2015 Tyler Fox + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + Title + PureLayout + Type + PSGroupSpecifier + + + FooterText + Copyright (c) 2011-2015 Specta Team - https://github.com/specta + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + + Title + Expecta + Type + PSGroupSpecifier + + + FooterText + MIT License + +Copyright (c) 2014 Daniel Doubrovkine, Artsy Inc. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + Title + Expecta+Snapshots + Type + PSGroupSpecifier + + + FooterText + BSD License + +For the FBSnapshotTestCase software + +Copyright (c) 2013, Facebook, Inc. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + * Neither the name Facebook nor the names of its contributors may be used to + endorse or promote products derived from this software without specific + prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + Title + FBSnapshotTestCase + Type + PSGroupSpecifier + + + FooterText + Copyright (c) 2012-2014 Specta Team. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + + + Title + Specta + Type + PSGroupSpecifier + + + FooterText + Generated by CocoaPods - https://cocoapods.org + Title + + Type + PSGroupSpecifier + + + StringsTable + Acknowledgements + Title + Acknowledgements + + diff --git a/Example/Pods/Target Support Files/Pods-PNImagePickerViewController_Tests/Pods-PNImagePickerViewController_Tests-dummy.m b/Example/Pods/Target Support Files/Pods-PNImagePickerViewController_Tests/Pods-PNImagePickerViewController_Tests-dummy.m new file mode 100644 index 0000000..0f5158b --- /dev/null +++ b/Example/Pods/Target Support Files/Pods-PNImagePickerViewController_Tests/Pods-PNImagePickerViewController_Tests-dummy.m @@ -0,0 +1,5 @@ +#import +@interface PodsDummy_Pods_PNImagePickerViewController_Tests : NSObject +@end +@implementation PodsDummy_Pods_PNImagePickerViewController_Tests +@end diff --git a/Example/Pods/Target Support Files/Pods-PNImagePickerViewController_Tests/Pods-PNImagePickerViewController_Tests-frameworks.sh b/Example/Pods/Target Support Files/Pods-PNImagePickerViewController_Tests/Pods-PNImagePickerViewController_Tests-frameworks.sh new file mode 100755 index 0000000..d6d31af --- /dev/null +++ b/Example/Pods/Target Support Files/Pods-PNImagePickerViewController_Tests/Pods-PNImagePickerViewController_Tests-frameworks.sh @@ -0,0 +1,101 @@ +#!/bin/sh +set -e + +echo "mkdir -p ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" +mkdir -p "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" + +SWIFT_STDLIB_PATH="${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" + +install_framework() +{ + if [ -r "${BUILT_PRODUCTS_DIR}/$1" ]; then + local source="${BUILT_PRODUCTS_DIR}/$1" + elif [ -r "${BUILT_PRODUCTS_DIR}/$(basename "$1")" ]; then + local source="${BUILT_PRODUCTS_DIR}/$(basename "$1")" + elif [ -r "$1" ]; then + local source="$1" + fi + + local destination="${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" + + if [ -L "${source}" ]; then + echo "Symlinked..." + source="$(readlink "${source}")" + fi + + # use filter instead of exclude so missing patterns dont' throw errors + echo "rsync -av --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${destination}\"" + rsync -av --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${destination}" + + local basename + basename="$(basename -s .framework "$1")" + binary="${destination}/${basename}.framework/${basename}" + if ! [ -r "$binary" ]; then + binary="${destination}/${basename}" + fi + + # Strip invalid architectures so "fat" simulator / device frameworks work on device + if [[ "$(file "$binary")" == *"dynamically linked shared library"* ]]; then + strip_invalid_archs "$binary" + fi + + # Resign the code if required by the build settings to avoid unstable apps + code_sign_if_enabled "${destination}/$(basename "$1")" + + # Embed linked Swift runtime libraries. No longer necessary as of Xcode 7. + if [ "${XCODE_VERSION_MAJOR}" -lt 7 ]; then + local swift_runtime_libs + swift_runtime_libs=$(xcrun otool -LX "$binary" | grep --color=never @rpath/libswift | sed -E s/@rpath\\/\(.+dylib\).*/\\1/g | uniq -u && exit ${PIPESTATUS[0]}) + for lib in $swift_runtime_libs; do + echo "rsync -auv \"${SWIFT_STDLIB_PATH}/${lib}\" \"${destination}\"" + rsync -auv "${SWIFT_STDLIB_PATH}/${lib}" "${destination}" + code_sign_if_enabled "${destination}/${lib}" + done + fi +} + +# Signs a framework with the provided identity +code_sign_if_enabled() { + if [ -n "${EXPANDED_CODE_SIGN_IDENTITY}" -a "${CODE_SIGNING_REQUIRED}" != "NO" -a "${CODE_SIGNING_ALLOWED}" != "NO" ]; then + # Use the current code_sign_identitiy + echo "Code Signing $1 with Identity ${EXPANDED_CODE_SIGN_IDENTITY_NAME}" + echo "/usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} --preserve-metadata=identifier,entitlements \"$1\"" + /usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} --preserve-metadata=identifier,entitlements "$1" + fi +} + +# Strip invalid architectures +strip_invalid_archs() { + binary="$1" + # Get architectures for current file + archs="$(lipo -info "$binary" | rev | cut -d ':' -f1 | rev)" + stripped="" + for arch in $archs; do + if ! [[ "${VALID_ARCHS}" == *"$arch"* ]]; then + # Strip non-valid architectures in-place + lipo -remove "$arch" -output "$binary" "$binary" || exit 1 + stripped="$stripped $arch" + fi + done + if [[ "$stripped" ]]; then + echo "Stripped $binary of architectures:$stripped" + fi +} + + +if [[ "$CONFIGURATION" == "Debug" ]]; then + install_framework "Pods-PNImagePickerViewController_Tests/PNImagePickerViewController.framework" + install_framework "Pods-PNImagePickerViewController_Tests/PureLayout.framework" + install_framework "Pods-PNImagePickerViewController_Tests/Expecta.framework" + install_framework "Pods-PNImagePickerViewController_Tests/Expecta_Snapshots.framework" + install_framework "Pods-PNImagePickerViewController_Tests/FBSnapshotTestCase.framework" + install_framework "Pods-PNImagePickerViewController_Tests/Specta.framework" +fi +if [[ "$CONFIGURATION" == "Release" ]]; then + install_framework "Pods-PNImagePickerViewController_Tests/PNImagePickerViewController.framework" + install_framework "Pods-PNImagePickerViewController_Tests/PureLayout.framework" + install_framework "Pods-PNImagePickerViewController_Tests/Expecta.framework" + install_framework "Pods-PNImagePickerViewController_Tests/Expecta_Snapshots.framework" + install_framework "Pods-PNImagePickerViewController_Tests/FBSnapshotTestCase.framework" + install_framework "Pods-PNImagePickerViewController_Tests/Specta.framework" +fi diff --git a/Example/Pods/Target Support Files/Pods-PNImagePickerViewController_Tests/Pods-PNImagePickerViewController_Tests-resources.sh b/Example/Pods/Target Support Files/Pods-PNImagePickerViewController_Tests/Pods-PNImagePickerViewController_Tests-resources.sh new file mode 100755 index 0000000..fa69136 --- /dev/null +++ b/Example/Pods/Target Support Files/Pods-PNImagePickerViewController_Tests/Pods-PNImagePickerViewController_Tests-resources.sh @@ -0,0 +1,102 @@ +#!/bin/sh +set -e + +mkdir -p "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" + +RESOURCES_TO_COPY=${PODS_ROOT}/resources-to-copy-${TARGETNAME}.txt +> "$RESOURCES_TO_COPY" + +XCASSET_FILES=() + +realpath() { + DIRECTORY="$(cd "${1%/*}" && pwd)" + FILENAME="${1##*/}" + echo "$DIRECTORY/$FILENAME" +} + +install_resource() +{ + if [[ "$1" = /* ]] ; then + RESOURCE_PATH="$1" + else + RESOURCE_PATH="${PODS_ROOT}/$1" + fi + if [[ ! -e "$RESOURCE_PATH" ]] ; then + cat << EOM +error: Resource "$RESOURCE_PATH" not found. Run 'pod install' to update the copy resources script. +EOM + exit 1 + fi + case $RESOURCE_PATH in + *.storyboard) + echo "ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile ${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .storyboard`.storyboardc $RESOURCE_PATH --sdk ${SDKROOT}" + ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .storyboard`.storyboardc" "$RESOURCE_PATH" --sdk "${SDKROOT}" + ;; + *.xib) + echo "ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile ${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .xib`.nib $RESOURCE_PATH --sdk ${SDKROOT}" + ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .xib`.nib" "$RESOURCE_PATH" --sdk "${SDKROOT}" + ;; + *.framework) + echo "mkdir -p ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" + mkdir -p "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" + echo "rsync -av $RESOURCE_PATH ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" + rsync -av "$RESOURCE_PATH" "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" + ;; + *.xcdatamodel) + echo "xcrun momc \"$RESOURCE_PATH\" \"${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH"`.mom\"" + xcrun momc "$RESOURCE_PATH" "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodel`.mom" + ;; + *.xcdatamodeld) + echo "xcrun momc \"$RESOURCE_PATH\" \"${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd\"" + xcrun momc "$RESOURCE_PATH" "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd" + ;; + *.xcmappingmodel) + echo "xcrun mapc \"$RESOURCE_PATH\" \"${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm\"" + xcrun mapc "$RESOURCE_PATH" "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm" + ;; + *.xcassets) + ABSOLUTE_XCASSET_FILE=$(realpath "$RESOURCE_PATH") + XCASSET_FILES+=("$ABSOLUTE_XCASSET_FILE") + ;; + *) + echo "$RESOURCE_PATH" + echo "$RESOURCE_PATH" >> "$RESOURCES_TO_COPY" + ;; + esac +} + +mkdir -p "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" +rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" +if [[ "${ACTION}" == "install" ]] && [[ "${SKIP_INSTALL}" == "NO" ]]; then + mkdir -p "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" + rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" +fi +rm -f "$RESOURCES_TO_COPY" + +if [[ -n "${WRAPPER_EXTENSION}" ]] && [ "`xcrun --find actool`" ] && [ -n "$XCASSET_FILES" ] +then + case "${TARGETED_DEVICE_FAMILY}" in + 1,2) + TARGET_DEVICE_ARGS="--target-device ipad --target-device iphone" + ;; + 1) + TARGET_DEVICE_ARGS="--target-device iphone" + ;; + 2) + TARGET_DEVICE_ARGS="--target-device ipad" + ;; + *) + TARGET_DEVICE_ARGS="--target-device mac" + ;; + esac + + # Find all other xcassets (this unfortunately includes those of path pods and other targets). + OTHER_XCASSETS=$(find "$PWD" -iname "*.xcassets" -type d) + while read line; do + if [[ $line != "`realpath $PODS_ROOT`*" ]]; then + XCASSET_FILES+=("$line") + fi + done <<<"$OTHER_XCASSETS" + + 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}" +fi diff --git a/Example/Pods/Target Support Files/Pods-PNImagePickerViewController_Tests/Pods-PNImagePickerViewController_Tests-umbrella.h b/Example/Pods/Target Support Files/Pods-PNImagePickerViewController_Tests/Pods-PNImagePickerViewController_Tests-umbrella.h new file mode 100644 index 0000000..fde82cd --- /dev/null +++ b/Example/Pods/Target Support Files/Pods-PNImagePickerViewController_Tests/Pods-PNImagePickerViewController_Tests-umbrella.h @@ -0,0 +1,6 @@ +#import + + +FOUNDATION_EXPORT double Pods_PNImagePickerViewController_TestsVersionNumber; +FOUNDATION_EXPORT const unsigned char Pods_PNImagePickerViewController_TestsVersionString[]; + diff --git a/Example/Pods/Target Support Files/Pods-PNImagePickerViewController_Tests/Pods-PNImagePickerViewController_Tests.debug.xcconfig b/Example/Pods/Target Support Files/Pods-PNImagePickerViewController_Tests/Pods-PNImagePickerViewController_Tests.debug.xcconfig new file mode 100644 index 0000000..bc24e87 --- /dev/null +++ b/Example/Pods/Target Support Files/Pods-PNImagePickerViewController_Tests/Pods-PNImagePickerViewController_Tests.debug.xcconfig @@ -0,0 +1,8 @@ +EMBEDDED_CONTENT_CONTAINS_SWIFT = YES +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' +OTHER_CFLAGS = $(inherited) -iquote "$CONFIGURATION_BUILD_DIR/Expecta.framework/Headers" -iquote "$CONFIGURATION_BUILD_DIR/Expecta_Snapshots.framework/Headers" -iquote "$CONFIGURATION_BUILD_DIR/FBSnapshotTestCase.framework/Headers" -iquote "$CONFIGURATION_BUILD_DIR/PNImagePickerViewController.framework/Headers" -iquote "$CONFIGURATION_BUILD_DIR/PureLayout.framework/Headers" -iquote "$CONFIGURATION_BUILD_DIR/Specta.framework/Headers" +OTHER_LDFLAGS = $(inherited) -framework "Expecta" -framework "Expecta_Snapshots" -framework "FBSnapshotTestCase" -framework "PNImagePickerViewController" -framework "PureLayout" -framework "Specta" +OTHER_SWIFT_FLAGS = $(inherited) "-D" "COCOAPODS" +PODS_FRAMEWORK_BUILD_PATH = "$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/Pods-PNImagePickerViewController_Tests" +PODS_ROOT = ${SRCROOT}/Pods diff --git a/Example/Pods/Target Support Files/Pods-PNImagePickerViewController_Tests/Pods-PNImagePickerViewController_Tests.modulemap b/Example/Pods/Target Support Files/Pods-PNImagePickerViewController_Tests/Pods-PNImagePickerViewController_Tests.modulemap new file mode 100644 index 0000000..a5f8b7f --- /dev/null +++ b/Example/Pods/Target Support Files/Pods-PNImagePickerViewController_Tests/Pods-PNImagePickerViewController_Tests.modulemap @@ -0,0 +1,6 @@ +framework module Pods_PNImagePickerViewController_Tests { + umbrella header "Pods-PNImagePickerViewController_Tests-umbrella.h" + + export * + module * { export * } +} diff --git a/Example/Pods/Target Support Files/Pods-PNImagePickerViewController_Tests/Pods-PNImagePickerViewController_Tests.release.xcconfig b/Example/Pods/Target Support Files/Pods-PNImagePickerViewController_Tests/Pods-PNImagePickerViewController_Tests.release.xcconfig new file mode 100644 index 0000000..bc24e87 --- /dev/null +++ b/Example/Pods/Target Support Files/Pods-PNImagePickerViewController_Tests/Pods-PNImagePickerViewController_Tests.release.xcconfig @@ -0,0 +1,8 @@ +EMBEDDED_CONTENT_CONTAINS_SWIFT = YES +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' +OTHER_CFLAGS = $(inherited) -iquote "$CONFIGURATION_BUILD_DIR/Expecta.framework/Headers" -iquote "$CONFIGURATION_BUILD_DIR/Expecta_Snapshots.framework/Headers" -iquote "$CONFIGURATION_BUILD_DIR/FBSnapshotTestCase.framework/Headers" -iquote "$CONFIGURATION_BUILD_DIR/PNImagePickerViewController.framework/Headers" -iquote "$CONFIGURATION_BUILD_DIR/PureLayout.framework/Headers" -iquote "$CONFIGURATION_BUILD_DIR/Specta.framework/Headers" +OTHER_LDFLAGS = $(inherited) -framework "Expecta" -framework "Expecta_Snapshots" -framework "FBSnapshotTestCase" -framework "PNImagePickerViewController" -framework "PureLayout" -framework "Specta" +OTHER_SWIFT_FLAGS = $(inherited) "-D" "COCOAPODS" +PODS_FRAMEWORK_BUILD_PATH = "$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/Pods-PNImagePickerViewController_Tests" +PODS_ROOT = ${SRCROOT}/Pods diff --git a/Example/Pods/Target Support Files/PureLayout/Info.plist b/Example/Pods/Target Support Files/PureLayout/Info.plist new file mode 100644 index 0000000..b0b461e --- /dev/null +++ b/Example/Pods/Target Support Files/PureLayout/Info.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIdentifier + ${PRODUCT_BUNDLE_IDENTIFIER} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + FMWK + CFBundleShortVersionString + 3.0.1 + CFBundleSignature + ???? + CFBundleVersion + ${CURRENT_PROJECT_VERSION} + NSPrincipalClass + + + diff --git a/Example/Pods/Target Support Files/PureLayout/PureLayout-dummy.m b/Example/Pods/Target Support Files/PureLayout/PureLayout-dummy.m new file mode 100644 index 0000000..de09ca1 --- /dev/null +++ b/Example/Pods/Target Support Files/PureLayout/PureLayout-dummy.m @@ -0,0 +1,5 @@ +#import +@interface PodsDummy_PureLayout : NSObject +@end +@implementation PodsDummy_PureLayout +@end diff --git a/Example/Pods/Target Support Files/PureLayout/PureLayout-prefix.pch b/Example/Pods/Target Support Files/PureLayout/PureLayout-prefix.pch new file mode 100644 index 0000000..aa992a4 --- /dev/null +++ b/Example/Pods/Target Support Files/PureLayout/PureLayout-prefix.pch @@ -0,0 +1,4 @@ +#ifdef __OBJC__ +#import +#endif + diff --git a/Example/Pods/Target Support Files/PureLayout/PureLayout-umbrella.h b/Example/Pods/Target Support Files/PureLayout/PureLayout-umbrella.h new file mode 100644 index 0000000..b50c609 --- /dev/null +++ b/Example/Pods/Target Support Files/PureLayout/PureLayout-umbrella.h @@ -0,0 +1,12 @@ +#import + +#import "ALView+PureLayout.h" +#import "NSArray+PureLayout.h" +#import "NSLayoutConstraint+PureLayout.h" +#import "PureLayout+Internal.h" +#import "PureLayout.h" +#import "PureLayoutDefines.h" + +FOUNDATION_EXPORT double PureLayoutVersionNumber; +FOUNDATION_EXPORT const unsigned char PureLayoutVersionString[]; + diff --git a/Example/Pods/Target Support Files/PureLayout/PureLayout.modulemap b/Example/Pods/Target Support Files/PureLayout/PureLayout.modulemap new file mode 100644 index 0000000..fd62d58 --- /dev/null +++ b/Example/Pods/Target Support Files/PureLayout/PureLayout.modulemap @@ -0,0 +1,6 @@ +framework module PureLayout { + umbrella header "PureLayout-umbrella.h" + + export * + module * { export * } +} diff --git a/Example/Pods/Target Support Files/PureLayout/PureLayout.xcconfig b/Example/Pods/Target Support Files/PureLayout/PureLayout.xcconfig new file mode 100644 index 0000000..5b4e8a0 --- /dev/null +++ b/Example/Pods/Target Support Files/PureLayout/PureLayout.xcconfig @@ -0,0 +1,5 @@ +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +HEADER_SEARCH_PATHS = "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Public" +PODS_ROOT = ${SRCROOT} +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES diff --git a/Example/Pods/Target Support Files/Specta/Info.plist b/Example/Pods/Target Support Files/Specta/Info.plist new file mode 100644 index 0000000..a5730fa --- /dev/null +++ b/Example/Pods/Target Support Files/Specta/Info.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIdentifier + ${PRODUCT_BUNDLE_IDENTIFIER} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0.5 + CFBundleSignature + ???? + CFBundleVersion + ${CURRENT_PROJECT_VERSION} + NSPrincipalClass + + + diff --git a/Example/Pods/Target Support Files/Specta/Specta-dummy.m b/Example/Pods/Target Support Files/Specta/Specta-dummy.m new file mode 100644 index 0000000..fdae423 --- /dev/null +++ b/Example/Pods/Target Support Files/Specta/Specta-dummy.m @@ -0,0 +1,5 @@ +#import +@interface PodsDummy_Specta : NSObject +@end +@implementation PodsDummy_Specta +@end diff --git a/Example/Pods/Target Support Files/Specta/Specta-prefix.pch b/Example/Pods/Target Support Files/Specta/Specta-prefix.pch new file mode 100644 index 0000000..aa992a4 --- /dev/null +++ b/Example/Pods/Target Support Files/Specta/Specta-prefix.pch @@ -0,0 +1,4 @@ +#ifdef __OBJC__ +#import +#endif + diff --git a/Example/Pods/Target Support Files/Specta/Specta-umbrella.h b/Example/Pods/Target Support Files/Specta/Specta-umbrella.h new file mode 100644 index 0000000..c6cc903 --- /dev/null +++ b/Example/Pods/Target Support Files/Specta/Specta-umbrella.h @@ -0,0 +1,21 @@ +#import + +#import "Specta.h" +#import "SpectaDSL.h" +#import "SpectaTypes.h" +#import "SpectaUtility.h" +#import "SPTCallSite.h" +#import "SPTCompiledExample.h" +#import "SPTExample.h" +#import "SPTExampleGroup.h" +#import "SPTExcludeGlobalBeforeAfterEach.h" +#import "SPTGlobalBeforeAfterEach.h" +#import "SPTSharedExampleGroups.h" +#import "SPTSpec.h" +#import "SPTTestSuite.h" +#import "XCTest+Private.h" +#import "XCTestCase+Specta.h" + +FOUNDATION_EXPORT double SpectaVersionNumber; +FOUNDATION_EXPORT const unsigned char SpectaVersionString[]; + diff --git a/Example/Pods/Target Support Files/Specta/Specta.modulemap b/Example/Pods/Target Support Files/Specta/Specta.modulemap new file mode 100644 index 0000000..c1629fb --- /dev/null +++ b/Example/Pods/Target Support Files/Specta/Specta.modulemap @@ -0,0 +1,6 @@ +framework module Specta { + umbrella header "Specta-umbrella.h" + + export * + module * { export * } +} diff --git a/Example/Pods/Target Support Files/Specta/Specta.xcconfig b/Example/Pods/Target Support Files/Specta/Specta.xcconfig new file mode 100644 index 0000000..bd75300 --- /dev/null +++ b/Example/Pods/Target Support Files/Specta/Specta.xcconfig @@ -0,0 +1,8 @@ +ENABLE_BITCODE = NO +FRAMEWORK_SEARCH_PATHS = $(inherited) "$(PLATFORM_DIR)/Developer/Library/Frameworks" +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +HEADER_SEARCH_PATHS = "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Public" +OTHER_LDFLAGS = -framework "Foundation" -framework "XCTest" +PODS_ROOT = ${SRCROOT} +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES diff --git a/PNImagePickerViewController.podspec b/PNImagePickerViewController.podspec index 0e2a16c..ec14a28 100644 --- a/PNImagePickerViewController.podspec +++ b/PNImagePickerViewController.podspec @@ -9,15 +9,14 @@ Pod::Spec.new do |s| s.name = "PNImagePickerViewController" s.version = "0.1.0" - s.summary = "A short description of PNImagePickerViewController." +s.summary = "PNImagePickerViewController is a fork of jacobsieradzki/JSImagePickerController with iOS8+ PhotoKit support." # This description is used to generate tags and improve search results. # * Think: What does it do? Why did you write it? What is the focus? # * Try to keep it short, snappy and to the point. # * Write the description between the DESC delimiters below. # * Finally, don't worry about the indent, CocoaPods strips it! - s.description = <<-DESC - DESC +# s.description = <<-DESC DESC s.homepage = "https://github.com//PNImagePickerViewController" # s.screenshots = "www.example.com/screenshots_1", "www.example.com/screenshots_2" @@ -35,6 +34,6 @@ Pod::Spec.new do |s| } # s.public_header_files = 'Pod/Classes/**/*.h' - # s.frameworks = 'UIKit', 'MapKit' - # s.dependency 'AFNetworking', '~> 2.3' + s.frameworks = 'Photos', 'PhotosUI' + s.dependency 'PureLayout' end diff --git a/Pod/Classes/Colors/NSString+HexColor.h b/Pod/Classes/Colors/NSString+HexColor.h new file mode 100755 index 0000000..d9af74c --- /dev/null +++ b/Pod/Classes/Colors/NSString+HexColor.h @@ -0,0 +1,15 @@ +// +// NSString+HexColor.h +// Packman +// +// Created by Giuseppe Nucifora on 20/10/12. +// Copyright (c) 2015 Purplenetwork S.r.l. All rights reserved. +// + +#import + +@interface NSString (HexColor) + +- (UIColor*)colorFromHex; + +@end \ No newline at end of file diff --git a/Pod/Classes/Colors/NSString+HexColor.m b/Pod/Classes/Colors/NSString+HexColor.m new file mode 100755 index 0000000..32c8746 --- /dev/null +++ b/Pod/Classes/Colors/NSString+HexColor.m @@ -0,0 +1,54 @@ +// +// NSString+HexColor.m +// Packman +// +// Created by Giuseppe Nucifora on 20/10/12. +// Copyright (c) 2012 Purplenetwork S.r.l. All rights reserved. +// + +#import "NSString+HexColor.h" + +@implementation NSString (HexColor) + +- (UIColor*)colorFromHex +{ + NSString *hexColor = [[self stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] uppercaseString]; + + if ([hexColor length] < 6) + return [UIColor blackColor]; + if ([hexColor hasPrefix:@"#"]) + hexColor = [hexColor substringFromIndex:1]; + if ([hexColor length] != 6 && [hexColor length] != 8) + return [UIColor blackColor]; + + NSRange range; + range.location = 0; + range.length = 2; + + NSString *rString = [hexColor substringWithRange:range]; + + range.location = 2; + NSString *gString = [hexColor substringWithRange:range]; + + range.location = 4; + NSString *bString = [hexColor substringWithRange:range]; + + range.location = 6; + NSString *aString = @"FF"; + if ([hexColor length] == 8) + aString = [hexColor substringWithRange:range]; + + // Scan values + unsigned int r, g, b, a; + [[NSScanner scannerWithString:rString] scanHexInt:&r]; + [[NSScanner scannerWithString:gString] scanHexInt:&g]; + [[NSScanner scannerWithString:bString] scanHexInt:&b]; + [[NSScanner scannerWithString:aString] scanHexInt:&a]; + + return [UIColor colorWithRed:((float) r / 255.0f) + green:((float) g / 255.0f) + blue:((float) b / 255.0f) + alpha:((float) a / 255.0f)]; +} + +@end \ No newline at end of file diff --git a/Pod/Classes/PNCollectionViewCell.h b/Pod/Classes/PNCollectionViewCell.h new file mode 100644 index 0000000..9bd7ccb --- /dev/null +++ b/Pod/Classes/PNCollectionViewCell.h @@ -0,0 +1,19 @@ +// +// PNCollectionViewCell.h +// Pods +// +// Created by Giuseppe Nucifora on 09/02/16. +// +// + +#import + +@interface PNCollectionViewCell : UICollectionViewCell + +@property (nonatomic, assign) BOOL didUpdateConstraints; +@property (nonatomic, strong) UIImage *photoImage; + ++ (NSString*) cellIdentifier; + + +@end diff --git a/Pod/Classes/PNCollectionViewCell.m b/Pod/Classes/PNCollectionViewCell.m new file mode 100644 index 0000000..4351c82 --- /dev/null +++ b/Pod/Classes/PNCollectionViewCell.m @@ -0,0 +1,77 @@ +// +// PNCollectionViewCell.m +// Pods +// +// Created by Giuseppe Nucifora on 09/02/16. +// +// + +#import "PNCollectionViewCell.h" +#import + +@interface PNCollectionViewCell() + +@property (nonatomic, strong) UIImageView *photoImageView; + +@end + +@implementation PNCollectionViewCell + ++ (NSString *)cellIdentifier { + return [NSStringFromClass([self class]) stringByAppendingString:@"Identifier"]; +} + +- (instancetype) init { + self = [super init]; + + if (self) { + [self.contentView setTranslatesAutoresizingMaskIntoConstraints:NO]; + + _photoImageView = [UIImageView newAutoLayoutView]; + [_photoImageView setContentMode:UIViewContentModeScaleAspectFill]; + + [self.contentView addSubview:_photoImageView]; + } + return self; +} + +- (instancetype) initWithFrame:(CGRect)frame { + self = [super initWithFrame:frame]; + if (self) { + [self.contentView setTranslatesAutoresizingMaskIntoConstraints:NO]; + + _photoImageView = [UIImageView newAutoLayoutView]; + [_photoImageView setContentMode:UIViewContentModeScaleAspectFill]; + + [self.contentView addSubview:_photoImageView]; + } + return self; +} + +- (void) updateConstraints { + + [super updateConstraints]; + + if (!self.didUpdateConstraints) { + + self.didUpdateConstraints = YES; + + + [self.contentView autoPinEdgesToSuperviewEdges]; + + [_photoImageView autoPinEdgeToSuperviewEdge:ALEdgeTop withInset:5]; + [_photoImageView autoPinEdgeToSuperviewEdge:ALEdgeBottom withInset:5]; + [_photoImageView autoPinEdgeToSuperviewEdge:ALEdgeLeading withInset:10]; + [_photoImageView autoPinEdgeToSuperviewEdge:ALEdgeTrailing withInset:10]; + [_photoImageView autoAlignAxisToSuperviewAxis:ALAxisVertical]; + [_photoImageView autoAlignAxisToSuperviewAxis:ALAxisHorizontal]; + } +} + +- (void) setPhotoImage:(UIImage *)photoImage { + if (photoImage) { + [_photoImageView setImage:photoImage]; + } +} + +@end diff --git a/Pod/Classes/PNImagePickerViewController.h b/Pod/Classes/PNImagePickerViewController.h new file mode 100644 index 0000000..de310e5 --- /dev/null +++ b/Pod/Classes/PNImagePickerViewController.h @@ -0,0 +1,86 @@ +// +// PNCollectionViewCell.h +// Pods +// +// Created by Giuseppe Nucifora on 09/02/16. +// +// + +#import + +@class PNImagePickerViewController ; + +@protocol PNImagePickerViewControllerDelegate + +@required + +- (void)imagePicker:(PNImagePickerViewController *)imagePicker didSelectImage:(UIImage *)image; + +- (void)imagePicker:(PNImagePickerViewController *)imagePicker donwloadImageWithProgress:(double )progress; + +@optional + +- (void)imagePickerDidOpen; + +- (void)imagePickerWillOpen; + +- (void)imagePickerWillClose; + +- (void)imagePickerDidClose; + +- (void)imagePickerDidCancel; + +@end + +@interface PNImagePickerViewController : UIViewController + +- (void)setAnimationTime:(NSTimeInterval)animationTime; + +- (void)showImagePickerInController:(UIViewController *)controller; + +- (void)showImagePickerInController:(UIViewController *)controller animated:(BOOL)animated; + +- (void)dismiss; + +- (void)dismissAnimated:(BOOL)animated; + + +@property (nonatomic, assign) id delegate; + +@property (readonly) bool isVisible; + +@property (nonatomic, strong) UICollectionView *collectionView; + +@property (nonatomic, strong) UIButton *photoLibraryBtn; + +@property (nonatomic, strong) UIButton *cameraBtn; + +@property (nonatomic, strong) UIButton *cancelBtn; + +@property (nonatomic) CGSize targetSize; + +@end + + + + + +@interface TransitionDelegate : NSObject + +@end + + + + + + +@interface AnimatedTransitioning : NSObject + +@property (nonatomic, assign) BOOL isPresenting; + +@end + + + + + diff --git a/Pod/Classes/PNImagePickerViewController.m b/Pod/Classes/PNImagePickerViewController.m new file mode 100644 index 0000000..a4e6811 --- /dev/null +++ b/Pod/Classes/PNImagePickerViewController.m @@ -0,0 +1,435 @@ +// +// PNCollectionViewCell.h +// Pods +// +// Created by Giuseppe Nucifora on 09/02/16. +// +// + +#import "PNImagePickerViewController.h" +#import +#import +#import +#import "PNCollectionViewCell.h" +#import "NSString+HexColor.h" + + +#pragma mark - PNImagePickerViewController - + +@interface PNImagePickerViewController () + +#define imagePickerHeight 280.0f + +@property (readwrite) bool isVisible; +@property (readwrite) bool haveCamera; +@property (nonatomic) NSTimeInterval animationTime; + +@property (nonatomic, strong) UIViewController *targetController; +@property (nonatomic, strong) UIWindow *window; + +@property (nonatomic, strong) UIView *backgroundView; +@property (nonatomic, strong) UIView *imagePickerView; + +@property (nonatomic) CGRect imagePickerFrame; +@property (nonatomic) CGRect hiddenFrame; + +@property (nonatomic) TransitionDelegate *transitionController; + +@property (nonatomic, strong) NSMutableArray *assets; + +@end + +@implementation PNImagePickerViewController + +@synthesize delegate; +@synthesize transitionController; + +- (id)init { + self = [super init]; + if (self) { + self.assets = [[NSMutableArray alloc] init]; + _targetSize = CGSizeMake(1024, 1024); + [self setupView]; + } + return self; +} + +- (void)setupView { + self.view.backgroundColor = [UIColor clearColor]; + self.window = [UIApplication sharedApplication].keyWindow; + + self.haveCamera = [UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]; + CGFloat localImagePickerHeight = imagePickerHeight; + if (!self.haveCamera) { + localImagePickerHeight -= 47.0f; + } + self.imagePickerFrame = CGRectMake(0, [UIScreen mainScreen].bounds.size.height-localImagePickerHeight, [UIScreen mainScreen].bounds.size.width, localImagePickerHeight); + self.hiddenFrame = CGRectMake(0, [UIScreen mainScreen].bounds.size.height, [UIScreen mainScreen].bounds.size.width, localImagePickerHeight); + self.imagePickerView = [[UIView alloc] initWithFrame:self.hiddenFrame]; + self.imagePickerView.backgroundColor = [UIColor whiteColor]; + + + + self.backgroundView = [[UIView alloc] initWithFrame:[UIScreen mainScreen].bounds]; + self.backgroundView.backgroundColor = [UIColor colorWithWhite:0.1 alpha:0.7]; + self.backgroundView.alpha = 0; + UITapGestureRecognizer *dismissTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(dismiss)]; + self.backgroundView.userInteractionEnabled = YES; + [self.backgroundView addGestureRecognizer:dismissTap]; + + + + self.animationTime = 0.2; + + [self.window addSubview:self.backgroundView]; + [self.window addSubview:self.imagePickerView]; + + UIButton *btn = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, self.imagePickerView.frame.size.width, 50)]; + [btn setTitle:@"Hello!" forState:UIControlStateNormal]; + [btn setTitleColor:[UIColor blueColor] forState:UIControlStateNormal]; + [btn addTarget:self action:@selector(setDefaults) forControlEvents:UIControlEventTouchUpInside]; + + [self.imagePickerView addSubview:btn]; + + [self imagePickerViewSetup]; + [self getCameraRollImages]; +} + +- (void)imagePickerViewSetup { + CGFloat screenWidth = [UIScreen mainScreen].bounds.size.width; + + const CGRect collectionViewFrame = CGRectMake(7, 8, screenWidth-7-7, 122); + const CGRect libraryBtnFrame = CGRectMake(0, 149, screenWidth, 30); + const CGRect cameraBtnFrame = CGRectMake(0, self.haveCamera ? 196 : 0, screenWidth, 30); + const CGRect cancelBtnFrame = CGRectMake(0, self.haveCamera ? 242 : 196, screenWidth, 30); + + UICollectionViewFlowLayout *aFlowLayout = [[UICollectionViewFlowLayout alloc] init]; + [aFlowLayout setScrollDirection:UICollectionViewScrollDirectionHorizontal]; + self.collectionView = [[UICollectionView alloc] initWithFrame:collectionViewFrame collectionViewLayout:aFlowLayout]; + [self.collectionView setBackgroundColor:[UIColor whiteColor]]; + self.collectionView.showsHorizontalScrollIndicator = NO; + self.collectionView.showsVerticalScrollIndicator = NO; + self.collectionView.delegate = self; + self.collectionView.dataSource = self; + [self.collectionView registerClass:[PNCollectionViewCell class] forCellWithReuseIdentifier:[PNCollectionViewCell cellIdentifier]]; + + UIFont *btnFont = [UIFont systemFontOfSize:19.0]; + + self.photoLibraryBtn = [[UIButton alloc] initWithFrame:libraryBtnFrame]; + [self.photoLibraryBtn setTitle:@"Photo Library" forState:UIControlStateNormal]; + self.photoLibraryBtn.titleLabel.font = btnFont; + [self.photoLibraryBtn addTarget:self action:@selector(selectFromLibraryWasPressed) forControlEvents:UIControlEventTouchUpInside]; + + self.cameraBtn = [[UIButton alloc] initWithFrame:cameraBtnFrame]; + [self.cameraBtn setTitle:@"Take Photo" forState:UIControlStateNormal]; + self.cameraBtn.titleLabel.font = btnFont; + [self.cameraBtn addTarget:self action:@selector(takePhotoWasPressed) forControlEvents:UIControlEventTouchUpInside]; + self.cameraBtn.hidden = !self.haveCamera; + + self.cancelBtn = [[UIButton alloc] initWithFrame:cancelBtnFrame]; + [self.cancelBtn setTitle:@"Cancel" forState:UIControlStateNormal]; + self.cancelBtn.titleLabel.font = btnFont; + [self.cancelBtn addTarget:self action:@selector(dismiss) forControlEvents:UIControlEventTouchUpInside]; + + for (UIButton *btn in @[self.photoLibraryBtn, self.cameraBtn, self.cancelBtn]) { + [btn setTitleColor:[@"0b60fe" colorFromHex] forState:UIControlStateNormal]; + [btn setTitleColor:[@"70b3fd" colorFromHex] forState:UIControlStateHighlighted]; + } + + UIView *separator1 = [[UIView alloc] initWithFrame:CGRectMake(0, 140, screenWidth, 1)]; + separator1.backgroundColor = [@"cacaca" colorFromHex]; + [self.imagePickerView addSubview:separator1]; + + UIView *separator2 = [[UIView alloc] initWithFrame:CGRectMake(25, 187, screenWidth-25, 1)]; + separator2.backgroundColor = [@"cacaca" colorFromHex]; + [self.imagePickerView addSubview:separator2]; + UIView *separator3 = [[UIView alloc] initWithFrame:CGRectMake(25, 234, screenWidth-25, 1)]; + separator3.backgroundColor = [@"cacaca" colorFromHex]; + [self.imagePickerView addSubview:separator3]; + + [self.imagePickerView addSubview:self.collectionView]; + [self.imagePickerView addSubview:self.photoLibraryBtn]; + [self.imagePickerView addSubview:self.cameraBtn]; + [self.imagePickerView addSubview:self.cancelBtn]; +} + +#pragma mark - Collection view + +- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView { + return 1; +} + +- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section { + return MIN(20, self.assets.count); +} + +- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath { + PNCollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:[PNCollectionViewCell cellIdentifier] forIndexPath:indexPath]; + + PHAsset *asset = self.assets[self.assets.count-1 - indexPath.row]; + + PHImageRequestOptions *options = [[PHImageRequestOptions alloc] init]; + options.deliveryMode = PHImageRequestOptionsDeliveryModeHighQualityFormat; + options.networkAccessAllowed = YES; + options.progressHandler = ^(double progress, NSError *error, BOOL *stop, NSDictionary *info) { + /* + Progress callbacks may not be on the main thread. Since we're updating + the UI, dispatch to the main queue. + */ + dispatch_async(dispatch_get_main_queue(), ^{ + if ([delegate respondsToSelector:@selector(imagePicker:donwloadImageWithProgress:)]) { + [delegate imagePicker:self donwloadImageWithProgress:progress]; + } + }); + }; + + [[PHImageManager defaultManager] requestImageForAsset:asset targetSize:CGSizeMake(300, 300) contentMode:PHImageContentModeAspectFit options:options resultHandler:^(UIImage *result, NSDictionary *info) { + // Check if the request was successful. + if (!result) { + return; + } + dispatch_async(dispatch_get_main_queue(), ^{ + [cell setPhotoImage:result]; + [cell setNeedsUpdateConstraints]; + }); + }]; + + + return cell; +} + +- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath { + [collectionView deselectItemAtIndexPath:indexPath animated:YES]; + + PHAsset *asset = self.assets[self.assets.count-1 - indexPath.row]; + PHImageRequestOptions *options = [[PHImageRequestOptions alloc] init]; + options.deliveryMode = PHImageRequestOptionsDeliveryModeHighQualityFormat; + options.networkAccessAllowed = YES; + options.progressHandler = ^(double progress, NSError *error, BOOL *stop, NSDictionary *info) { + /* + Progress callbacks may not be on the main thread. Since we're updating + the UI, dispatch to the main queue. + */ + dispatch_async(dispatch_get_main_queue(), ^{ + if ([delegate respondsToSelector:@selector(imagePicker:donwloadImageWithProgress:)]) { + [delegate imagePicker:self donwloadImageWithProgress:progress]; + } + }); + }; + + [[PHImageManager defaultManager] requestImageForAsset:asset targetSize:_targetSize contentMode:PHImageContentModeAspectFit options:options resultHandler:^(UIImage *result, NSDictionary *info) { + // Hide the progress view now the request has completed. + + + // Check if the request was successful. + if (!result) { + return; + } + + // Show the UIImageView and use it to display the requested image. + if ([delegate respondsToSelector:@selector(imagePicker:didSelectImage:)]) { + [delegate imagePicker:self didSelectImage:result]; + } + + [self dismissAnimated:YES]; + }]; + +} + +- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath { + return CGSizeMake(170, 114); +} + +- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout minimumInteritemSpacingForSectionAtIndex:(NSInteger)section { + return 10.0f; +} + +#pragma mark - Image library + + +- (void)getCameraRollImages { + _assets = [@[] mutableCopy]; + dispatch_async(dispatch_get_main_queue(), ^{ + + PHFetchOptions *allPhotosOptions = [PHFetchOptions new]; + allPhotosOptions.sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:@"creationDate" ascending:YES]]; + + PHFetchResult *allPhotosResult = [PHAsset fetchAssetsWithMediaType:PHAssetMediaTypeImage options:allPhotosOptions]; + [allPhotosResult enumerateObjectsUsingBlock:^(PHAsset *asset, NSUInteger idx, BOOL *stop) { + NSLog(@"asset %@", asset); + if(asset) { + [self.assets addObject:asset]; + } + }]; + + [self.collectionView reloadData]; + }); +} + +#pragma mark - Image picker + +- (void)takePhotoWasPressed { + if (![UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) { + + UIAlertView *myAlertView = [[UIAlertView alloc] initWithTitle:@"Error" + message:@"Device has no camera" + delegate:nil + cancelButtonTitle:@"OK" + otherButtonTitles: nil]; + + [myAlertView show]; + + } else { + UIImagePickerController *picker = [[UIImagePickerController alloc] init]; + picker.delegate = self; + picker.sourceType = UIImagePickerControllerSourceTypeCamera; + picker.mediaTypes = [[NSArray alloc] initWithObjects: (NSString *) kUTTypeImage, nil]; + + [self presentViewController:picker animated:YES completion:nil]; + } +} + +- (void)selectFromLibraryWasPressed { + UIImagePickerController *picker = [[UIImagePickerController alloc] init]; + picker.delegate = self; + picker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary; + picker.mediaTypes = [[NSArray alloc] initWithObjects: (NSString *) kUTTypeImage, nil]; + + [self presentViewController:picker animated:YES completion:nil]; +} + +- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info { + UIImage *chosenImage = info[UIImagePickerControllerOriginalImage]; + + [picker dismissViewControllerAnimated:YES completion:^{ + if ([delegate respondsToSelector:@selector(imagePicker:didSelectImage:)]) { + [delegate imagePicker:self didSelectImage:chosenImage]; + } + [self dismissAnimated:YES]; + }]; +} + +- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker { + [picker dismissViewControllerAnimated:YES completion:nil]; +} + +#pragma mark - Show + +- (void)showImagePickerInController:(UIViewController *)controller { + [self showImagePickerInController:controller animated:YES]; +} + +- (void)showImagePickerInController:(UIViewController *)controller animated:(BOOL)animated { + if (self.isVisible != YES) { + if ([delegate respondsToSelector:@selector(imagePickerWillOpen)]) { + [delegate imagePickerWillOpen]; + } + self.isVisible = YES; + + [self setTransitioningDelegate:transitionController]; + self.modalPresentationStyle = UIModalPresentationOverCurrentContext; + + [controller presentViewController:self animated:NO completion:nil]; + + if (animated) { + [UIView animateWithDuration:self.animationTime + delay:0 + options:UIViewAnimationOptionCurveLinear + animations:^{ + [self.imagePickerView setFrame:self.imagePickerFrame]; + [self.backgroundView setAlpha:1]; + } + completion:^(BOOL finished) { + if ([delegate respondsToSelector:@selector(imagePickerDidOpen)]) { + [delegate imagePickerDidOpen]; + } + }]; + } else { + [self.imagePickerView setFrame:self.imagePickerFrame]; + [self.backgroundView setAlpha:0]; + } + } +} + +#pragma mark - Dismiss + +- (void)dismiss { + [self dismissAnimated:YES]; +} + +- (void)dismissAnimated:(BOOL)animated { + if (self.isVisible == YES) { + if ([delegate respondsToSelector:@selector(imagePickerWillClose)]) { + [delegate imagePickerWillClose]; + } + if (animated) { + [UIView animateWithDuration:self.animationTime + delay:0 + options:UIViewAnimationOptionCurveEaseIn + animations:^{ + [self.imagePickerView setFrame:self.hiddenFrame]; + [self.backgroundView setAlpha:0]; + } + completion:^(BOOL finished) { + [self.imagePickerView removeFromSuperview]; + [self.backgroundView removeFromSuperview]; + [self dismissViewControllerAnimated:NO completion:nil]; + if ([delegate respondsToSelector:@selector(imagePickerDidClose)]) { + [delegate imagePickerDidClose]; + } + }]; + } else { + [self.imagePickerView setFrame:self.imagePickerFrame]; + [self.backgroundView setAlpha:0]; + } + + // Set everything to nil + } +} + +@end + + + +#pragma mark - TransitionDelegate - +@implementation TransitionDelegate + +- (id )animationControllerForPresentedController:(UIViewController *)presented presentingController:(UIViewController *)presenting sourceController:(UIViewController *)source { + AnimatedTransitioning *controller = [[AnimatedTransitioning alloc] init]; + controller.isPresenting = YES; + return controller; +} + +@end + + + + +#pragma mark - AnimatedTransitioning - +@implementation AnimatedTransitioning + +- (NSTimeInterval)transitionDuration:(id )transitionContext { + return 0.25f; +} + +- (void)animateTransition:(id )transitionContext { + UIView *inView = [transitionContext containerView]; + UIViewController *toVC = (UIViewController *)[transitionContext viewControllerForKey:UITransitionContextToViewControllerKey]; + UIViewController *fromVC = (UIViewController *)[transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey]; + + [inView addSubview:toVC.view]; + + CGRect screenRect = [[UIScreen mainScreen] bounds]; + [toVC.view setFrame:CGRectMake(0, screenRect.size.height, fromVC.view.frame.size.width, fromVC.view.frame.size.height)]; + + [UIView animateWithDuration:0.25f + animations:^{ + [toVC.view setFrame:CGRectMake(0, 0, fromVC.view.frame.size.width, fromVC.view.frame.size.height)]; + } + completion:^(BOOL finished) { + [transitionContext completeTransition:YES]; + }]; +} + + +@end \ No newline at end of file diff --git a/Pod/Classes/ReplaceMe.m b/Pod/Classes/ReplaceMe.m deleted file mode 100644 index e69de29..0000000