Compare commits

..

7 Commits

Author SHA1 Message Date
5d3900b868 Commit automatico: Aggiornamento dei file 2023-12-17 10:30:11 +01:00
703192e9cf - Fix isValidUrl 2020-11-11 10:20:40 +01:00
6a377b7d20 - upgrade libraries
- add - (NSString*) stringByStrippingHTML
2018-05-02 14:08:51 +02:00
b5fe27627e - add firstname or lastname validation regex 2018-04-24 12:37:28 +02:00
0d514c7ca3 - upgrade libraries
- increase isValidUrl matching regEx
2018-01-18 15:17:45 +01:00
114f16ac1c - Add md5
- Add Sha1
- Add Sha256
- Add Sha512
2016-04-07 17:26:34 +02:00
3a914b99d1 - Update Pod 2016-03-15 20:16:08 +01:00
57 changed files with 3360 additions and 2689 deletions

4
.gitattributes vendored Normal file
View File

@ -0,0 +1,4 @@
*.framework filter=lfs diff=lfs merge=lfs -text
libavcodec.a filter=lfs diff=lfs merge=lfs -text
GoogleMapsBase filter=lfs diff=lfs merge=lfs -text
GoogleMapsCore filter=lfs diff=lfs merge=lfs -text

View File

@ -7,7 +7,7 @@
objects = {
/* Begin PBXBuildFile section */
0D223AB6F02150A9ACBDBD94 /* Pods_NSString_Helper_Example.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FE00DDFA05C08065E8026237 /* Pods_NSString_Helper_Example.framework */; };
4A49F81094ED2A986C0844A0 /* libPods-NSString-Helper_Tests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = CBB752CF9494348EA94E9890 /* libPods-NSString-Helper_Tests.a */; };
6003F58E195388D20070C39A /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6003F58D195388D20070C39A /* Foundation.framework */; };
6003F590195388D20070C39A /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6003F58F195388D20070C39A /* CoreGraphics.framework */; };
6003F592195388D20070C39A /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6003F591195388D20070C39A /* UIKit.framework */; };
@ -22,7 +22,7 @@
6003F5BA195388D20070C39A /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 6003F5B8195388D20070C39A /* InfoPlist.strings */; };
6003F5BC195388D20070C39A /* Tests.m in Sources */ = {isa = PBXBuildFile; fileRef = 6003F5BB195388D20070C39A /* Tests.m */; };
873B8AEB1B1F5CCA007FD442 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 873B8AEA1B1F5CCA007FD442 /* Main.storyboard */; };
FD5F03BF16688F5F84D6B2B4 /* Pods_NSString_Helper_Tests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EEC7D25FF692DF5273E9910A /* Pods_NSString_Helper_Tests.framework */; };
AD14227E5A28C25F00899FB3 /* libPods-NSString-Helper_Example.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 9D42F12F37BCA0ACFD8622CD /* libPods-NSString-Helper_Example.a */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
@ -36,8 +36,7 @@
/* End PBXContainerItemProxy section */
/* Begin PBXFileReference section */
2E9CEE81BD53F89DFA0781BE /* Pods-NSString-Helper_Tests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-NSString-Helper_Tests.release.xcconfig"; path = "Pods/Target Support Files/Pods-NSString-Helper_Tests/Pods-NSString-Helper_Tests.release.xcconfig"; sourceTree = "<group>"; };
412D7B9D1CA8644EED05E876 /* Pods-NSString-Helper_Tests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-NSString-Helper_Tests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-NSString-Helper_Tests/Pods-NSString-Helper_Tests.debug.xcconfig"; sourceTree = "<group>"; };
43F47E058F038E85AB51AF26 /* Pods-NSString-Helper_Tests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-NSString-Helper_Tests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-NSString-Helper_Tests/Pods-NSString-Helper_Tests.debug.xcconfig"; sourceTree = "<group>"; };
6003F58A195388D20070C39A /* NSString-Helper_Example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "NSString-Helper_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; };
@ -57,14 +56,15 @@
6003F5B9195388D20070C39A /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = "<group>"; };
6003F5BB195388D20070C39A /* Tests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = Tests.m; sourceTree = "<group>"; };
606FC2411953D9B200FFA9A0 /* Tests-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Tests-Prefix.pch"; sourceTree = "<group>"; };
623B075D9ED7EFC53DD9D0FD /* Pods-NSString-Helper_Tests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-NSString-Helper_Tests.release.xcconfig"; path = "Pods/Target Support Files/Pods-NSString-Helper_Tests/Pods-NSString-Helper_Tests.release.xcconfig"; sourceTree = "<group>"; };
65AD924A02921B023EB2F1BC /* LICENSE */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = LICENSE; path = ../LICENSE; sourceTree = "<group>"; };
6831E237E4E7BCC8307EA49A /* Pods-NSString-Helper_Example.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-NSString-Helper_Example.release.xcconfig"; path = "Pods/Target Support Files/Pods-NSString-Helper_Example/Pods-NSString-Helper_Example.release.xcconfig"; sourceTree = "<group>"; };
7A02A0538ECFE76907B78514 /* Pods-NSString-Helper_Example.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-NSString-Helper_Example.debug.xcconfig"; path = "Pods/Target Support Files/Pods-NSString-Helper_Example/Pods-NSString-Helper_Example.debug.xcconfig"; sourceTree = "<group>"; };
873B8AEA1B1F5CCA007FD442 /* Main.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = Main.storyboard; sourceTree = "<group>"; };
8F02B3F6151E5B6CD342FFDA /* README.md */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = net.daringfireball.markdown; name = README.md; path = ../README.md; sourceTree = "<group>"; };
9D8D4A4795AC3BF9EBAF46B4 /* NSString-Helper.podspec */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = "NSString-Helper.podspec"; path = "../NSString-Helper.podspec"; sourceTree = "<group>"; };
EEC7D25FF692DF5273E9910A /* Pods_NSString_Helper_Tests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_NSString_Helper_Tests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
FE00DDFA05C08065E8026237 /* Pods_NSString_Helper_Example.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_NSString_Helper_Example.framework; sourceTree = BUILT_PRODUCTS_DIR; };
9D42F12F37BCA0ACFD8622CD /* libPods-NSString-Helper_Example.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-NSString-Helper_Example.a"; sourceTree = BUILT_PRODUCTS_DIR; };
9D8D4A4795AC3BF9EBAF46B4 /* NSString-Helper.podspec */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = "NSString-Helper.podspec"; path = "../NSString-Helper.podspec"; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.ruby; };
A066422FE7F9F7A309C05FA6 /* Pods-NSString-Helper_Example.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-NSString-Helper_Example.release.xcconfig"; path = "Pods/Target Support Files/Pods-NSString-Helper_Example/Pods-NSString-Helper_Example.release.xcconfig"; sourceTree = "<group>"; };
CBB752CF9494348EA94E9890 /* libPods-NSString-Helper_Tests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-NSString-Helper_Tests.a"; sourceTree = BUILT_PRODUCTS_DIR; };
F8D0C102DC63F7EEE95D0F2F /* Pods-NSString-Helper_Example.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-NSString-Helper_Example.debug.xcconfig"; path = "Pods/Target Support Files/Pods-NSString-Helper_Example/Pods-NSString-Helper_Example.debug.xcconfig"; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@ -75,7 +75,7 @@
6003F590195388D20070C39A /* CoreGraphics.framework in Frameworks */,
6003F592195388D20070C39A /* UIKit.framework in Frameworks */,
6003F58E195388D20070C39A /* Foundation.framework in Frameworks */,
0D223AB6F02150A9ACBDBD94 /* Pods_NSString_Helper_Example.framework in Frameworks */,
AD14227E5A28C25F00899FB3 /* libPods-NSString-Helper_Example.a in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -86,7 +86,7 @@
6003F5B0195388D20070C39A /* XCTest.framework in Frameworks */,
6003F5B2195388D20070C39A /* UIKit.framework in Frameworks */,
6003F5B1195388D20070C39A /* Foundation.framework in Frameworks */,
FD5F03BF16688F5F84D6B2B4 /* Pods_NSString_Helper_Tests.framework in Frameworks */,
4A49F81094ED2A986C0844A0 /* libPods-NSString-Helper_Tests.a in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -101,7 +101,7 @@
6003F5B5195388D20070C39A /* Tests */,
6003F58C195388D20070C39A /* Frameworks */,
6003F58B195388D20070C39A /* Products */,
BA7A5012B36E3C927058F0FC /* Pods */,
BBE4504745A5B8690B19EF46 /* Pods */,
);
sourceTree = "<group>";
};
@ -121,8 +121,8 @@
6003F58F195388D20070C39A /* CoreGraphics.framework */,
6003F591195388D20070C39A /* UIKit.framework */,
6003F5AF195388D20070C39A /* XCTest.framework */,
FE00DDFA05C08065E8026237 /* Pods_NSString_Helper_Example.framework */,
EEC7D25FF692DF5273E9910A /* Pods_NSString_Helper_Tests.framework */,
9D42F12F37BCA0ACFD8622CD /* libPods-NSString-Helper_Example.a */,
CBB752CF9494348EA94E9890 /* libPods-NSString-Helper_Tests.a */,
);
name = Frameworks;
sourceTree = "<group>";
@ -182,13 +182,13 @@
name = "Podspec Metadata";
sourceTree = "<group>";
};
BA7A5012B36E3C927058F0FC /* Pods */ = {
BBE4504745A5B8690B19EF46 /* Pods */ = {
isa = PBXGroup;
children = (
7A02A0538ECFE76907B78514 /* Pods-NSString-Helper_Example.debug.xcconfig */,
6831E237E4E7BCC8307EA49A /* Pods-NSString-Helper_Example.release.xcconfig */,
412D7B9D1CA8644EED05E876 /* Pods-NSString-Helper_Tests.debug.xcconfig */,
2E9CEE81BD53F89DFA0781BE /* Pods-NSString-Helper_Tests.release.xcconfig */,
F8D0C102DC63F7EEE95D0F2F /* Pods-NSString-Helper_Example.debug.xcconfig */,
A066422FE7F9F7A309C05FA6 /* Pods-NSString-Helper_Example.release.xcconfig */,
43F47E058F038E85AB51AF26 /* Pods-NSString-Helper_Tests.debug.xcconfig */,
623B075D9ED7EFC53DD9D0FD /* Pods-NSString-Helper_Tests.release.xcconfig */,
);
name = Pods;
sourceTree = "<group>";
@ -200,12 +200,10 @@
isa = PBXNativeTarget;
buildConfigurationList = 6003F5BF195388D20070C39A /* Build configuration list for PBXNativeTarget "NSString-Helper_Example" */;
buildPhases = (
C4D5E64415C6E6C3B486D1D2 /* Check Pods Manifest.lock */,
9B592AE96165CD0F99340ACC /* [CP] Check Pods Manifest.lock */,
6003F586195388D20070C39A /* Sources */,
6003F587195388D20070C39A /* Frameworks */,
6003F588195388D20070C39A /* Resources */,
F4BFB45F0477AADDB169FF4A /* Embed Pods Frameworks */,
2FB602919CD9E6B1CC8177FF /* Copy Pods Resources */,
);
buildRules = (
);
@ -220,12 +218,10 @@
isa = PBXNativeTarget;
buildConfigurationList = 6003F5C2195388D20070C39A /* Build configuration list for PBXNativeTarget "NSString-Helper_Tests" */;
buildPhases = (
3BAC6FE5CC3CFD00D5F15DAA /* Check Pods Manifest.lock */,
D3CD38E80167F24BD9D8D1F7 /* [CP] Check Pods Manifest.lock */,
6003F5AA195388D20070C39A /* Sources */,
6003F5AB195388D20070C39A /* Frameworks */,
6003F5AC195388D20070C39A /* Resources */,
14C3CEC3CFF93DAD514DA1A7 /* Embed Pods Frameworks */,
8C67E10569176F8352202CC1 /* Copy Pods Resources */,
);
buildRules = (
);
@ -257,6 +253,7 @@
developmentRegion = English;
hasScannedForEncodings = 0;
knownRegions = (
English,
en,
Base,
);
@ -293,94 +290,40 @@
/* End PBXResourcesBuildPhase section */
/* Begin PBXShellScriptBuildPhase section */
14C3CEC3CFF93DAD514DA1A7 /* Embed Pods Frameworks */ = {
9B592AE96165CD0F99340ACC /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
"${PODS_ROOT}/Manifest.lock",
);
name = "Embed Pods Frameworks";
name = "[CP] Check Pods Manifest.lock";
outputPaths = (
"$(DERIVED_FILE_DIR)/Pods-NSString-Helper_Example-checkManifestLockResult.txt",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-NSString-Helper_Tests/Pods-NSString-Helper_Tests-frameworks.sh\"\n";
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0;
};
2FB602919CD9E6B1CC8177FF /* Copy Pods Resources */ = {
D3CD38E80167F24BD9D8D1F7 /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
"${PODS_ROOT}/Manifest.lock",
);
name = "Copy Pods Resources";
name = "[CP] Check Pods Manifest.lock";
outputPaths = (
"$(DERIVED_FILE_DIR)/Pods-NSString-Helper_Tests-checkManifestLockResult.txt",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-NSString-Helper_Example/Pods-NSString-Helper_Example-resources.sh\"\n";
showEnvVarsInLog = 0;
};
3BAC6FE5CC3CFD00D5F15DAA /* 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;
};
8C67E10569176F8352202CC1 /* 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-NSString-Helper_Tests/Pods-NSString-Helper_Tests-resources.sh\"\n";
showEnvVarsInLog = 0;
};
C4D5E64415C6E6C3B486D1D2 /* 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;
};
F4BFB45F0477AADDB169FF4A /* 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-NSString-Helper_Example/Pods-NSString-Helper_Example-frameworks.sh\"\n";
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0;
};
/* End PBXShellScriptBuildPhase section */
@ -466,7 +409,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
IPHONEOS_DEPLOYMENT_TARGET = 10.0;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
TARGETED_DEVICE_FAMILY = "1,2";
@ -499,7 +442,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
IPHONEOS_DEPLOYMENT_TARGET = 10.0;
SDKROOT = iphoneos;
TARGETED_DEVICE_FAMILY = "1,2";
VALIDATE_PRODUCT = YES;
@ -508,7 +451,7 @@
};
6003F5C0195388D20070C39A /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 7A02A0538ECFE76907B78514 /* Pods-NSString-Helper_Example.debug.xcconfig */;
baseConfigurationReference = F8D0C102DC63F7EEE95D0F2F /* Pods-NSString-Helper_Example.debug.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
@ -523,7 +466,7 @@
};
6003F5C1195388D20070C39A /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 6831E237E4E7BCC8307EA49A /* Pods-NSString-Helper_Example.release.xcconfig */;
baseConfigurationReference = A066422FE7F9F7A309C05FA6 /* Pods-NSString-Helper_Example.release.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
@ -538,7 +481,7 @@
};
6003F5C3195388D20070C39A /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 412D7B9D1CA8644EED05E876 /* Pods-NSString-Helper_Tests.debug.xcconfig */;
baseConfigurationReference = 43F47E058F038E85AB51AF26 /* Pods-NSString-Helper_Tests.debug.xcconfig */;
buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)";
FRAMEWORK_SEARCH_PATHS = (
@ -561,7 +504,7 @@
};
6003F5C4195388D20070C39A /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 2E9CEE81BD53F89DFA0781BE /* Pods-NSString-Helper_Tests.release.xcconfig */;
baseConfigurationReference = 623B075D9ED7EFC53DD9D0FD /* Pods-NSString-Helper_Tests.release.xcconfig */;
buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)";
FRAMEWORK_SEARCH_PATHS = (

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>

View File

@ -1,5 +1,4 @@
source 'https://github.com/CocoaPods/Specs.git'
use_frameworks!
platform :ios, '10.0'
target 'NSString-Helper_Example' do
pod "NSString-Helper", :path => "../"
@ -7,6 +6,4 @@ end
target 'NSString-Helper_Tests' do
pod "NSString-Helper", :path => "../"
pod 'FBSnapshotTestCase'
end

View File

@ -1,13 +1,7 @@
PODS:
- FBSnapshotTestCase (2.0.7):
- FBSnapshotTestCase/SwiftSupport (= 2.0.7)
- FBSnapshotTestCase/Core (2.0.7)
- FBSnapshotTestCase/SwiftSupport (2.0.7):
- FBSnapshotTestCase/Core
- NSString-Helper (1.0.2)
- NSString-Helper (1.2.1)
DEPENDENCIES:
- FBSnapshotTestCase
- NSString-Helper (from `../`)
EXTERNAL SOURCES:
@ -15,9 +9,8 @@ EXTERNAL SOURCES:
:path: "../"
SPEC CHECKSUMS:
FBSnapshotTestCase: 7e85180d0d141a0cf472352edda7e80d7eaeb547
NSString-Helper: 0ee74919829a332f9838fa87b28cb2d1d991e92c
NSString-Helper: dcbf45d121c0c9d6612acfe131e554cf5538b560
PODFILE CHECKSUM: a88b2ea7b96d7de499d212328481d74fcf022692
PODFILE CHECKSUM: 9a62d5a7de52ffc40c1a1c843b9a7798cf5e4993
COCOAPODS: 1.0.0.beta.2
COCOAPODS: 1.10.0

View File

@ -1,15 +0,0 @@
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"
}

View File

@ -1,37 +0,0 @@
//
// 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 <UIKit/UIKit.h>
@interface UIImage (Compare)
- (BOOL)fb_compareWithImage:(UIImage *)image tolerance:(CGFloat)tolerance;
@end

View File

@ -1,134 +0,0 @@
//
// 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 <FBSnapshotTestCase/UIImage+Compare.h>
// 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

View File

@ -1,37 +0,0 @@
//
// 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 <UIKit/UIKit.h>
@interface UIImage (Diff)
- (UIImage *)fb_diffWithImage:(UIImage *)image;
@end

View File

@ -1,56 +0,0 @@
//
// 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 <FBSnapshotTestCase/UIImage+Diff.h>
@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

View File

@ -1,24 +0,0 @@
/*
* 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 <UIKit/UIKit.h>
@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

View File

@ -1,62 +0,0 @@
/*
* 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 <FBSnapshotTestCase/UIImage+Snapshot.h>
@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

View File

@ -1,200 +0,0 @@
/*
* 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 <FBSnapshotTestCase/FBSnapshotTestCasePlatform.h>
#import <QuartzCore/QuartzCore.h>
#import <UIKit/UIKit.h>
#import <XCTest/XCTest.h>
/*
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

View File

@ -1,136 +0,0 @@
/*
* 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 <FBSnapshotTestCase/FBSnapshotTestCase.h>
#import <FBSnapshotTestCase/FBSnapshotTestController.h>
@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

View File

@ -1,44 +0,0 @@
/*
* 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 <Foundation/Foundation.h>
#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

View File

@ -1,49 +0,0 @@
/*
* 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 <FBSnapshotTestCase/FBSnapshotTestCasePlatform.h>
#import <UIKit/UIKit.h>
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;
}

View File

@ -1,151 +0,0 @@
/*
* 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 <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
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

View File

@ -1,356 +0,0 @@
/*
* 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 <FBSnapshotTestCase/FBSnapshotTestController.h>
#import <FBSnapshotTestCase/FBSnapshotTestCasePlatform.h>
#import <FBSnapshotTestCase/UIImage+Compare.h>
#import <FBSnapshotTestCase/UIImage+Diff.h>
#import <FBSnapshotTestCase/UIImage+Snapshot.h>
#import <UIKit/UIKit.h>
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

View File

@ -1,66 +0,0 @@
/*
* 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)
}
}
}

View File

@ -1,29 +0,0 @@
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.

View File

@ -1,97 +0,0 @@
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`.

View File

@ -0,0 +1 @@
../../../../../NSString-Helper/NSString+Helper.h

View File

@ -0,0 +1 @@
../../../../../NSString-Helper/NSString+Helper.h

View File

@ -1,6 +1,6 @@
{
"name": "NSString-Helper",
"version": "1.0.2",
"version": "1.2.1",
"summary": "NSString-Helper is usefull helper to validate email NSString",
"homepage": "https://github.com/giuseppenucifora/NSString-Helper",
"license": "MIT",
@ -9,17 +9,12 @@
},
"source": {
"git": "https://github.com/giuseppenucifora/NSString-Helper.git",
"tag": "1.0.2"
"tag": "1.2.1"
},
"social_media_url": "https://twitter.com/giuseppenuc",
"requires_arc": true,
"platforms": {
"ios": "8.0"
"ios": "10.0"
},
"source_files": "NSString-Helper/*.{h,m}",
"resource_bundles": {
"NSString-Helper": [
"Pod/Assets/*.png"
]
}
"source_files": "NSString-Helper/*.{h,m}"
}

View File

@ -1,13 +1,7 @@
PODS:
- FBSnapshotTestCase (2.0.7):
- FBSnapshotTestCase/SwiftSupport (= 2.0.7)
- FBSnapshotTestCase/Core (2.0.7)
- FBSnapshotTestCase/SwiftSupport (2.0.7):
- FBSnapshotTestCase/Core
- NSString-Helper (1.0.2)
- NSString-Helper (1.2.1)
DEPENDENCIES:
- FBSnapshotTestCase
- NSString-Helper (from `../`)
EXTERNAL SOURCES:
@ -15,9 +9,8 @@ EXTERNAL SOURCES:
:path: "../"
SPEC CHECKSUMS:
FBSnapshotTestCase: 7e85180d0d141a0cf472352edda7e80d7eaeb547
NSString-Helper: 0ee74919829a332f9838fa87b28cb2d1d991e92c
NSString-Helper: dcbf45d121c0c9d6612acfe131e554cf5538b560
PODFILE CHECKSUM: a88b2ea7b96d7de499d212328481d74fcf022692
PODFILE CHECKSUM: 9a62d5a7de52ffc40c1a1c843b9a7798cf5e4993
COCOAPODS: 1.0.0.beta.2
COCOAPODS: 1.10.0

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +0,0 @@
#import <Foundation/Foundation.h>
@interface PodsDummy_FBSnapshotTestCase : NSObject
@end
@implementation PodsDummy_FBSnapshotTestCase
@end

View File

@ -1,4 +0,0 @@
#ifdef __OBJC__
#import <UIKit/UIKit.h>
#endif

View File

@ -1,15 +0,0 @@
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"
}

View File

@ -1,9 +0,0 @@
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

View File

@ -1,26 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>${EXECUTABLE_NAME}</string>
<key>CFBundleIdentifier</key>
<string>${PRODUCT_BUNDLE_IDENTIFIER}</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>${PRODUCT_NAME}</string>
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>2.0.7</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>${CURRENT_PROJECT_VERSION}</string>
<key>NSPrincipalClass</key>
<string></string>
</dict>
</plist>

View File

@ -15,7 +15,7 @@
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>1.0.2</string>
<string>1.2.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>

View File

@ -1,4 +1,12 @@
#ifdef __OBJC__
#import <UIKit/UIKit.h>
#else
#ifndef FOUNDATION_EXPORT
#if defined(__cplusplus)
#define FOUNDATION_EXPORT extern "C"
#else
#define FOUNDATION_EXPORT extern
#endif
#endif
#endif

View File

@ -1,4 +1,14 @@
#ifdef __OBJC__
#import <UIKit/UIKit.h>
#else
#ifndef FOUNDATION_EXPORT
#if defined(__cplusplus)
#define FOUNDATION_EXPORT extern "C"
#else
#define FOUNDATION_EXPORT extern
#endif
#endif
#endif
#import "NSString+Helper.h"

View File

@ -0,0 +1,12 @@
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO
CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/NSString-Helper
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Private/NSString-Helper" "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/NSString-Helper"
PODS_BUILD_DIR = ${BUILD_DIR}
PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
PODS_ROOT = ${SRCROOT}
PODS_TARGET_SRCROOT = ${PODS_ROOT}/../..
PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates
PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier}
SKIP_INSTALL = YES
USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES

View File

@ -0,0 +1,12 @@
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO
CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/NSString-Helper
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Private/NSString-Helper" "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/NSString-Helper"
PODS_BUILD_DIR = ${BUILD_DIR}
PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
PODS_ROOT = ${SRCROOT}
PODS_TARGET_SRCROOT = ${PODS_ROOT}/../..
PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates
PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier}
SKIP_INSTALL = YES
USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES

View File

@ -1,5 +1,8 @@
CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/NSString-Helper
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
HEADER_SEARCH_PATHS = "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Public"
PODS_BUILD_DIR = ${BUILD_DIR}
PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
PODS_ROOT = ${SRCROOT}
PODS_TARGET_SRCROOT = ${PODS_ROOT}/../..
PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier}
SKIP_INSTALL = YES

View File

@ -1,24 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleIdentifier</key>
<string>${PRODUCT_BUNDLE_IDENTIFIER}</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>${PRODUCT_NAME}</string>
<key>CFBundlePackageType</key>
<string>BNDL</string>
<key>CFBundleShortVersionString</key>
<string>1.0.2</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>${CURRENT_PROJECT_VERSION}</string>
<key>NSPrincipalClass</key>
<string></string>
</dict>
</plist>

View File

@ -34,6 +34,8 @@ 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.
</string>
<key>License</key>
<string>MIT</string>
<key>Title</key>
<string>NSString-Helper</string>
<key>Type</key>

View File

@ -1,11 +1,28 @@
#!/bin/sh
set -e
set -u
set -o pipefail
if [ -z ${FRAMEWORKS_FOLDER_PATH+x} ]; then
# If FRAMEWORKS_FOLDER_PATH is not set, then there's nowhere for us to copy
# frameworks to, so exit 0 (signalling the script phase was successful).
exit 0
fi
echo "mkdir -p ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
mkdir -p "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
COCOAPODS_PARALLEL_CODE_SIGN="${COCOAPODS_PARALLEL_CODE_SIGN:-false}"
SWIFT_STDLIB_PATH="${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}"
# Used as a return value for each invocation of `strip_invalid_archs` function.
STRIP_BINARY_RETVAL=0
# This protects against multiple targets copying the same framework dependency at the same time. The solution
# was originally proposed here: https://lists.samba.org/archive/rsync/2008-February/020158.html
RSYNC_PROTECT_TMP_FILES=(--filter "P .*.??????")
# Copies and strips a vendored framework
install_framework()
{
if [ -r "${BUILT_PRODUCTS_DIR}/$1" ]; then
@ -16,16 +33,16 @@ install_framework()
local source="$1"
fi
local destination="${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
local destination="${TARGET_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}"
# Use filter instead of exclude so missing patterns don't throw errors.
echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${destination}\""
rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${destination}"
local basename
basename="$(basename -s .framework "$1")"
@ -54,24 +71,65 @@ install_framework()
fi
}
# Copies and strips a vendored dSYM
install_dsym() {
local source="$1"
if [ -r "$source" ]; then
# Copy the dSYM into a the targets temp dir.
echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${DERIVED_FILES_DIR}\""
rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${DERIVED_FILES_DIR}"
local basename
basename="$(basename -s .framework.dSYM "$source")"
binary="${DERIVED_FILES_DIR}/${basename}.framework.dSYM/Contents/Resources/DWARF/${basename}"
# Strip invalid architectures so "fat" simulator / device frameworks work on device
if [[ "$(file "$binary")" == *"Mach-O dSYM companion"* ]]; then
strip_invalid_archs "$binary"
fi
if [[ $STRIP_BINARY_RETVAL == 1 ]]; then
# Move the stripped file into its final destination.
echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${DERIVED_FILES_DIR}/${basename}.framework.dSYM\" \"${DWARF_DSYM_FOLDER_PATH}\""
rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${DERIVED_FILES_DIR}/${basename}.framework.dSYM" "${DWARF_DSYM_FOLDER_PATH}"
else
# The dSYM was not stripped at all, in this case touch a fake folder so the input/output paths from Xcode do not reexecute this script because the file is missing.
touch "${DWARF_DSYM_FOLDER_PATH}/${basename}.framework.dSYM"
fi
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
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"
local code_sign_cmd="/usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} ${OTHER_CODE_SIGN_FLAGS:-} --preserve-metadata=identifier,entitlements '$1'"
if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then
code_sign_cmd="$code_sign_cmd &"
fi
echo "$code_sign_cmd"
eval "$code_sign_cmd"
fi
}
# Strip invalid architectures
strip_invalid_archs() {
binary="$1"
# Get architectures for current file
archs="$(lipo -info "$binary" | rev | cut -d ':' -f1 | rev)"
# Get architectures for current target binary
binary_archs="$(lipo -info "$binary" | rev | cut -d ':' -f1 | awk '{$1=$1;print}' | rev)"
# Intersect them with the architectures we are building for
intersected_archs="$(echo ${ARCHS[@]} ${binary_archs[@]} | tr ' ' '\n' | sort | uniq -d)"
# If there are no archs supported by this binary then warn the user
if [[ -z "$intersected_archs" ]]; then
echo "warning: [CP] Vendored binary '$binary' contains architectures ($binary_archs) none of which match the current build architectures ($ARCHS)."
STRIP_BINARY_RETVAL=0
return
fi
stripped=""
for arch in $archs; do
if ! [[ "${VALID_ARCHS}" == *"$arch"* ]]; then
for arch in $binary_archs; do
if ! [[ "${ARCHS}" == *"$arch"* ]]; then
# Strip non-valid architectures in-place
lipo -remove "$arch" -output "$binary" "$binary" || exit 1
stripped="$stripped $arch"
@ -80,12 +138,16 @@ strip_invalid_archs() {
if [[ "$stripped" ]]; then
echo "Stripped $binary of architectures:$stripped"
fi
STRIP_BINARY_RETVAL=1
}
if [[ "$CONFIGURATION" == "Debug" ]]; then
install_framework "Pods-NSString-Helper_Example/NSString_Helper.framework"
install_framework "${BUILT_PRODUCTS_DIR}/NSString-Helper/NSString_Helper.framework"
fi
if [[ "$CONFIGURATION" == "Release" ]]; then
install_framework "Pods-NSString-Helper_Example/NSString_Helper.framework"
install_framework "${BUILT_PRODUCTS_DIR}/NSString-Helper/NSString_Helper.framework"
fi
if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then
wait
fi

View File

@ -1,18 +1,45 @@
#!/bin/sh
set -e
set -u
set -o pipefail
mkdir -p "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}"
if [ -z ${UNLOCALIZED_RESOURCES_FOLDER_PATH+x} ]; then
# If UNLOCALIZED_RESOURCES_FOLDER_PATH is not set, then there's nowhere for us to copy
# resources to, so exit 0 (signalling the script phase was successful).
exit 0
fi
mkdir -p "${TARGET_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"
}
# This protects against multiple targets copying the same framework dependency at the same time. The solution
# was originally proposed here: https://lists.samba.org/archive/rsync/2008-February/020158.html
RSYNC_PROTECT_TMP_FILES=(--filter "P .*.??????")
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"
;;
3)
TARGET_DEVICE_ARGS="--target-device tv"
;;
4)
TARGET_DEVICE_ARGS="--target-device watch"
;;
*)
TARGET_DEVICE_ARGS="--target-device mac"
;;
esac
install_resource()
{
@ -29,74 +56,63 @@ EOM
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}"
echo "ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile ${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .storyboard`.storyboardc $RESOURCE_PATH --sdk ${SDKROOT} ${TARGET_DEVICE_ARGS}" || true
ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .storyboard`.storyboardc" "$RESOURCE_PATH" --sdk "${SDKROOT}" ${TARGET_DEVICE_ARGS}
;;
*.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}"
echo "ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile ${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .xib`.nib $RESOURCE_PATH --sdk ${SDKROOT} ${TARGET_DEVICE_ARGS}" || true
ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .xib`.nib" "$RESOURCE_PATH" --sdk "${SDKROOT}" ${TARGET_DEVICE_ARGS}
;;
*.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}"
echo "mkdir -p ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" || true
mkdir -p "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" $RESOURCE_PATH ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" || true
rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" "$RESOURCE_PATH" "${TARGET_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"
echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH"`.mom\"" || true
xcrun momc "$RESOURCE_PATH" "${TARGET_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"
echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd\"" || true
xcrun momc "$RESOURCE_PATH" "${TARGET_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"
echo "xcrun mapc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm\"" || true
xcrun mapc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm"
;;
*.xcassets)
ABSOLUTE_XCASSET_FILE=$(realpath "$RESOURCE_PATH")
ABSOLUTE_XCASSET_FILE="$RESOURCE_PATH"
XCASSET_FILES+=("$ABSOLUTE_XCASSET_FILE")
;;
*)
echo "$RESOURCE_PATH"
echo "$RESOURCE_PATH" || true
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}"
mkdir -p "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}"
rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${TARGET_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" ]
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
if [[ $line != "${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}"
if [ -z ${ASSETCATALOG_COMPILER_APPICON_NAME+x} ]; then
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}"
else
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}" --app-icon "${ASSETCATALOG_COMPILER_APPICON_NAME}" --output-partial-info-plist "${TARGET_BUILD_DIR}/assetcatalog_generated_info.plist"
fi
fi

View File

@ -1,4 +1,14 @@
#ifdef __OBJC__
#import <UIKit/UIKit.h>
#else
#ifndef FOUNDATION_EXPORT
#if defined(__cplusplus)
#define FOUNDATION_EXPORT extern "C"
#else
#define FOUNDATION_EXPORT extern
#endif
#endif
#endif
FOUNDATION_EXPORT double Pods_NSString_Helper_ExampleVersionNumber;

View File

@ -1,6 +1,11 @@
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks'
OTHER_CFLAGS = $(inherited) -iquote "$CONFIGURATION_BUILD_DIR/NSString_Helper.framework/Headers"
OTHER_LDFLAGS = $(inherited) -framework "NSString_Helper"
PODS_FRAMEWORK_BUILD_PATH = $(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/Pods-NSString-Helper_Example
HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/NSString-Helper"
LIBRARY_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/NSString-Helper"
OTHER_LDFLAGS = $(inherited) -ObjC -l"NSString-Helper"
PODS_BUILD_DIR = ${BUILD_DIR}
PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
PODS_PODFILE_DIR_PATH = ${SRCROOT}/.
PODS_ROOT = ${SRCROOT}/Pods
PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates
USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES

View File

@ -1,6 +1,11 @@
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks'
OTHER_CFLAGS = $(inherited) -iquote "$CONFIGURATION_BUILD_DIR/NSString_Helper.framework/Headers"
OTHER_LDFLAGS = $(inherited) -framework "NSString_Helper"
PODS_FRAMEWORK_BUILD_PATH = $(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/Pods-NSString-Helper_Example
HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/NSString-Helper"
LIBRARY_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/NSString-Helper"
OTHER_LDFLAGS = $(inherited) -ObjC -l"NSString-Helper"
PODS_BUILD_DIR = ${BUILD_DIR}
PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
PODS_PODFILE_DIR_PATH = ${SRCROOT}/.
PODS_ROOT = ${SRCROOT}/Pods
PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates
USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES

View File

@ -23,37 +23,4 @@ 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.
Generated by CocoaPods - https://cocoapods.org

View File

@ -34,48 +34,13 @@ 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.
</string>
<key>License</key>
<string>MIT</string>
<key>Title</key>
<string>NSString-Helper</string>
<key>Type</key>
<string>PSGroupSpecifier</string>
</dict>
<dict>
<key>FooterText</key>
<string>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.
</string>
<key>Title</key>
<string>FBSnapshotTestCase</string>
<key>Type</key>
<string>PSGroupSpecifier</string>
</dict>
<dict>
<key>FooterText</key>
<string>Generated by CocoaPods - https://cocoapods.org</string>

View File

@ -1,11 +1,28 @@
#!/bin/sh
set -e
set -u
set -o pipefail
if [ -z ${FRAMEWORKS_FOLDER_PATH+x} ]; then
# If FRAMEWORKS_FOLDER_PATH is not set, then there's nowhere for us to copy
# frameworks to, so exit 0 (signalling the script phase was successful).
exit 0
fi
echo "mkdir -p ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
mkdir -p "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
COCOAPODS_PARALLEL_CODE_SIGN="${COCOAPODS_PARALLEL_CODE_SIGN:-false}"
SWIFT_STDLIB_PATH="${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}"
# Used as a return value for each invocation of `strip_invalid_archs` function.
STRIP_BINARY_RETVAL=0
# This protects against multiple targets copying the same framework dependency at the same time. The solution
# was originally proposed here: https://lists.samba.org/archive/rsync/2008-February/020158.html
RSYNC_PROTECT_TMP_FILES=(--filter "P .*.??????")
# Copies and strips a vendored framework
install_framework()
{
if [ -r "${BUILT_PRODUCTS_DIR}/$1" ]; then
@ -16,16 +33,16 @@ install_framework()
local source="$1"
fi
local destination="${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
local destination="${TARGET_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}"
# Use filter instead of exclude so missing patterns don't throw errors.
echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${destination}\""
rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${destination}"
local basename
basename="$(basename -s .framework "$1")"
@ -54,24 +71,65 @@ install_framework()
fi
}
# Copies and strips a vendored dSYM
install_dsym() {
local source="$1"
if [ -r "$source" ]; then
# Copy the dSYM into a the targets temp dir.
echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${DERIVED_FILES_DIR}\""
rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${DERIVED_FILES_DIR}"
local basename
basename="$(basename -s .framework.dSYM "$source")"
binary="${DERIVED_FILES_DIR}/${basename}.framework.dSYM/Contents/Resources/DWARF/${basename}"
# Strip invalid architectures so "fat" simulator / device frameworks work on device
if [[ "$(file "$binary")" == *"Mach-O dSYM companion"* ]]; then
strip_invalid_archs "$binary"
fi
if [[ $STRIP_BINARY_RETVAL == 1 ]]; then
# Move the stripped file into its final destination.
echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${DERIVED_FILES_DIR}/${basename}.framework.dSYM\" \"${DWARF_DSYM_FOLDER_PATH}\""
rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${DERIVED_FILES_DIR}/${basename}.framework.dSYM" "${DWARF_DSYM_FOLDER_PATH}"
else
# The dSYM was not stripped at all, in this case touch a fake folder so the input/output paths from Xcode do not reexecute this script because the file is missing.
touch "${DWARF_DSYM_FOLDER_PATH}/${basename}.framework.dSYM"
fi
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
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"
local code_sign_cmd="/usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} ${OTHER_CODE_SIGN_FLAGS:-} --preserve-metadata=identifier,entitlements '$1'"
if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then
code_sign_cmd="$code_sign_cmd &"
fi
echo "$code_sign_cmd"
eval "$code_sign_cmd"
fi
}
# Strip invalid architectures
strip_invalid_archs() {
binary="$1"
# Get architectures for current file
archs="$(lipo -info "$binary" | rev | cut -d ':' -f1 | rev)"
# Get architectures for current target binary
binary_archs="$(lipo -info "$binary" | rev | cut -d ':' -f1 | awk '{$1=$1;print}' | rev)"
# Intersect them with the architectures we are building for
intersected_archs="$(echo ${ARCHS[@]} ${binary_archs[@]} | tr ' ' '\n' | sort | uniq -d)"
# If there are no archs supported by this binary then warn the user
if [[ -z "$intersected_archs" ]]; then
echo "warning: [CP] Vendored binary '$binary' contains architectures ($binary_archs) none of which match the current build architectures ($ARCHS)."
STRIP_BINARY_RETVAL=0
return
fi
stripped=""
for arch in $archs; do
if ! [[ "${VALID_ARCHS}" == *"$arch"* ]]; then
for arch in $binary_archs; do
if ! [[ "${ARCHS}" == *"$arch"* ]]; then
# Strip non-valid architectures in-place
lipo -remove "$arch" -output "$binary" "$binary" || exit 1
stripped="$stripped $arch"
@ -80,14 +138,18 @@ strip_invalid_archs() {
if [[ "$stripped" ]]; then
echo "Stripped $binary of architectures:$stripped"
fi
STRIP_BINARY_RETVAL=1
}
if [[ "$CONFIGURATION" == "Debug" ]]; then
install_framework "Pods-NSString-Helper_Tests/NSString_Helper.framework"
install_framework "Pods-NSString-Helper_Tests/FBSnapshotTestCase.framework"
install_framework "${BUILT_PRODUCTS_DIR}/NSString-Helper/NSString_Helper.framework"
install_framework "${BUILT_PRODUCTS_DIR}/FBSnapshotTestCase/FBSnapshotTestCase.framework"
fi
if [[ "$CONFIGURATION" == "Release" ]]; then
install_framework "Pods-NSString-Helper_Tests/NSString_Helper.framework"
install_framework "Pods-NSString-Helper_Tests/FBSnapshotTestCase.framework"
install_framework "${BUILT_PRODUCTS_DIR}/NSString-Helper/NSString_Helper.framework"
install_framework "${BUILT_PRODUCTS_DIR}/FBSnapshotTestCase/FBSnapshotTestCase.framework"
fi
if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then
wait
fi

View File

@ -1,18 +1,45 @@
#!/bin/sh
set -e
set -u
set -o pipefail
mkdir -p "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}"
if [ -z ${UNLOCALIZED_RESOURCES_FOLDER_PATH+x} ]; then
# If UNLOCALIZED_RESOURCES_FOLDER_PATH is not set, then there's nowhere for us to copy
# resources to, so exit 0 (signalling the script phase was successful).
exit 0
fi
mkdir -p "${TARGET_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"
}
# This protects against multiple targets copying the same framework dependency at the same time. The solution
# was originally proposed here: https://lists.samba.org/archive/rsync/2008-February/020158.html
RSYNC_PROTECT_TMP_FILES=(--filter "P .*.??????")
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"
;;
3)
TARGET_DEVICE_ARGS="--target-device tv"
;;
4)
TARGET_DEVICE_ARGS="--target-device watch"
;;
*)
TARGET_DEVICE_ARGS="--target-device mac"
;;
esac
install_resource()
{
@ -29,74 +56,63 @@ EOM
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}"
echo "ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile ${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .storyboard`.storyboardc $RESOURCE_PATH --sdk ${SDKROOT} ${TARGET_DEVICE_ARGS}" || true
ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .storyboard`.storyboardc" "$RESOURCE_PATH" --sdk "${SDKROOT}" ${TARGET_DEVICE_ARGS}
;;
*.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}"
echo "ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile ${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .xib`.nib $RESOURCE_PATH --sdk ${SDKROOT} ${TARGET_DEVICE_ARGS}" || true
ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .xib`.nib" "$RESOURCE_PATH" --sdk "${SDKROOT}" ${TARGET_DEVICE_ARGS}
;;
*.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}"
echo "mkdir -p ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" || true
mkdir -p "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" $RESOURCE_PATH ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" || true
rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" "$RESOURCE_PATH" "${TARGET_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"
echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH"`.mom\"" || true
xcrun momc "$RESOURCE_PATH" "${TARGET_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"
echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd\"" || true
xcrun momc "$RESOURCE_PATH" "${TARGET_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"
echo "xcrun mapc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm\"" || true
xcrun mapc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm"
;;
*.xcassets)
ABSOLUTE_XCASSET_FILE=$(realpath "$RESOURCE_PATH")
ABSOLUTE_XCASSET_FILE="$RESOURCE_PATH"
XCASSET_FILES+=("$ABSOLUTE_XCASSET_FILE")
;;
*)
echo "$RESOURCE_PATH"
echo "$RESOURCE_PATH" || true
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}"
mkdir -p "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}"
rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${TARGET_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" ]
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
if [[ $line != "${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}"
if [ -z ${ASSETCATALOG_COMPILER_APPICON_NAME+x} ]; then
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}"
else
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}" --app-icon "${ASSETCATALOG_COMPILER_APPICON_NAME}" --output-partial-info-plist "${TARGET_BUILD_DIR}/assetcatalog_generated_info.plist"
fi
fi

View File

@ -1,4 +1,14 @@
#ifdef __OBJC__
#import <UIKit/UIKit.h>
#else
#ifndef FOUNDATION_EXPORT
#if defined(__cplusplus)
#define FOUNDATION_EXPORT extern "C"
#else
#define FOUNDATION_EXPORT extern
#endif
#endif
#endif
FOUNDATION_EXPORT double Pods_NSString_Helper_TestsVersionNumber;

View File

@ -1,8 +1,11 @@
EMBEDDED_CONTENT_CONTAINS_SWIFT = YES
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks'
OTHER_CFLAGS = $(inherited) -iquote "$CONFIGURATION_BUILD_DIR/FBSnapshotTestCase.framework/Headers" -iquote "$CONFIGURATION_BUILD_DIR/NSString_Helper.framework/Headers"
OTHER_LDFLAGS = $(inherited) -framework "FBSnapshotTestCase" -framework "NSString_Helper"
OTHER_SWIFT_FLAGS = $(inherited) "-D" "COCOAPODS"
PODS_FRAMEWORK_BUILD_PATH = $(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/Pods-NSString-Helper_Tests
HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/NSString-Helper"
LIBRARY_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/NSString-Helper"
OTHER_LDFLAGS = $(inherited) -ObjC -l"NSString-Helper"
PODS_BUILD_DIR = ${BUILD_DIR}
PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
PODS_PODFILE_DIR_PATH = ${SRCROOT}/.
PODS_ROOT = ${SRCROOT}/Pods
PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates
USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES

View File

@ -1,8 +1,11 @@
EMBEDDED_CONTENT_CONTAINS_SWIFT = YES
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks'
OTHER_CFLAGS = $(inherited) -iquote "$CONFIGURATION_BUILD_DIR/FBSnapshotTestCase.framework/Headers" -iquote "$CONFIGURATION_BUILD_DIR/NSString_Helper.framework/Headers"
OTHER_LDFLAGS = $(inherited) -framework "FBSnapshotTestCase" -framework "NSString_Helper"
OTHER_SWIFT_FLAGS = $(inherited) "-D" "COCOAPODS"
PODS_FRAMEWORK_BUILD_PATH = $(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/Pods-NSString-Helper_Tests
HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/NSString-Helper"
LIBRARY_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/NSString-Helper"
OTHER_LDFLAGS = $(inherited) -ObjC -l"NSString-Helper"
PODS_BUILD_DIR = ${BUILD_DIR}
PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
PODS_PODFILE_DIR_PATH = ${SRCROOT}/.
PODS_ROOT = ${SRCROOT}/Pods
PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates
USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES

View File

@ -8,7 +8,7 @@
Pod::Spec.new do |s|
s.name = "NSString-Helper"
s.version = "1.0.3"
s.version = "1.2.1"
s.summary = "NSString-Helper is usefull helper to validate email NSString"
s.homepage = "https://github.com/giuseppenucifora/NSString-Helper"
s.license = 'MIT'
@ -17,12 +17,9 @@ s.source = { :git => "https://github.com/giuseppenucifora/NSString-Hel
s.social_media_url = 'https://twitter.com/giuseppenuc'
s.requires_arc = true
s.platform = :ios, '8.0'
s.ios.deployment_target = '10.0'
s.platform = :ios, '10.0'
s.requires_arc = true
s.source_files = 'NSString-Helper/*.{h,m}'
s.resource_bundles = {
'NSString-Helper' => ['Pod/Assets/*.png']
}
end
end

View File

@ -10,6 +10,8 @@
@interface NSString (Helper)
+ (NSString *) getRandString: (int) length;
- (BOOL) isValidEmail;
- (BOOL) isNumeric;
@ -20,4 +22,17 @@
- (BOOL) isValidTaxCode;
- (BOOL) isValidFirstnameOrLastname;
- (NSString *) md5;
- (NSString*) sha1;
- (NSString*) sha256;
- (NSString*) sha512;
- (NSString*) stringByStrippingHTML;
@end

View File

@ -7,6 +7,7 @@
//
#import "NSString+Helper.h"
#import <CommonCrypto/CommonDigest.h>
@implementation NSString (Helper)
@ -45,10 +46,9 @@
}
- (BOOL) isValidUrl {
NSString *urlRegEx =
@"(http|https)://((\\w)*|([0-9]*)|([-|_])*)+([\\.|/]((\\w)*|([0-9]*)|([-|_])*))+";
NSPredicate *urlTest = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", urlRegEx];
return [urlTest evaluateWithObject:self];
NSURLRequest *req = [NSURLRequest requestWithURL:[NSURL URLWithString:self]];
return [NSURLConnection canHandleRequest:req];
}
- (BOOL) isValidTaxCode {
@ -58,4 +58,101 @@
return [urlTest evaluateWithObject:self];
}
- (BOOL) isValidFirstnameOrLastname {
NSString *firstNameRegEx = @"^[a-zA-Z][ a-zA-Z\\s]+$";
NSPredicate *nameTest = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", firstNameRegEx];
return [nameTest evaluateWithObject:self];
}
#pragma mark - Random String Method
+ (NSString *) getRandString: (int) length {
NSString *letters = @"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
NSMutableString *randomString = [NSMutableString stringWithCapacity: length];
for (int i=0; i<length; i++) {
[randomString appendFormat: @"%C", [letters characterAtIndex: arc4random() % [letters length]]];
}
return randomString;
}
- (NSString *) md5 {
const char *cStr = [self UTF8String];
unsigned char digest[16];
CC_MD5( cStr, (CC_LONG)strlen(cStr), digest ); // This is the md5 call
NSMutableString *output = [NSMutableString stringWithCapacity:CC_MD5_DIGEST_LENGTH * 2];
for(int i = 0; i < CC_MD5_DIGEST_LENGTH; i++)
[output appendFormat:@"%02x", digest[i]];
return output;
}
- (NSString*) sha1 {
const char *cstr = [self cStringUsingEncoding:NSUTF8StringEncoding];
NSData *data = [NSData dataWithBytes:cstr length:self.length];
uint8_t digest[CC_SHA1_DIGEST_LENGTH];
CC_SHA1(data.bytes, (CC_LONG)data.length, digest);
NSMutableString* output = [NSMutableString stringWithCapacity:CC_SHA1_DIGEST_LENGTH * 2];
for(int i = 0; i < CC_SHA1_DIGEST_LENGTH; i++)
[output appendFormat:@"%02x", digest[i]];
return output;
}
- (NSString*) sha256 {
const char *s=[self cStringUsingEncoding:NSASCIIStringEncoding];
NSData *keyData=[NSData dataWithBytes:s length:strlen(s)];
uint8_t digest[CC_SHA256_DIGEST_LENGTH]={0};
CC_SHA256(keyData.bytes, (CC_LONG)keyData.length, digest);
NSData *out=[NSData dataWithBytes:digest length:CC_SHA256_DIGEST_LENGTH];
NSString *hash=[out description];
hash = [hash stringByReplacingOccurrencesOfString:@" " withString:@""];
hash = [hash stringByReplacingOccurrencesOfString:@"<" withString:@""];
hash = [hash stringByReplacingOccurrencesOfString:@">" withString:@""];
return hash;
}
- (NSString*) sha512 {
const char *s=[self cStringUsingEncoding:NSASCIIStringEncoding];
NSData *keyData=[NSData dataWithBytes:s length:strlen(s)];
uint8_t digest[CC_SHA512_DIGEST_LENGTH]={0};
CC_SHA512(keyData.bytes, (CC_LONG)keyData.length, digest);
NSData *out=[NSData dataWithBytes:digest length:CC_SHA512_DIGEST_LENGTH];
NSString *hash=[out description];
hash = [hash stringByReplacingOccurrencesOfString:@" " withString:@""];
hash = [hash stringByReplacingOccurrencesOfString:@"<" withString:@""];
hash = [hash stringByReplacingOccurrencesOfString:@">" withString:@""];
return hash;
}
- (NSString*) stringByStrippingHTML {
NSRange r;
NSString *s = [self copy];
while ((r = [s rangeOfString:@"<[^>]+>" options:NSRegularExpressionSearch]).location != NSNotFound)
s = [s stringByReplacingCharactersInRange:r withString:@""];
return s;
}
@end

View File

@ -1 +0,0 @@
Example/Pods/Pods.xcodeproj

File diff suppressed because it is too large Load Diff

View File

@ -7,33 +7,30 @@
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForAnalyzing = "YES"
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
buildForArchiving = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "6F621F2F34EEA2E2A05B25FA44939F5D"
BuildableName = "NSString_Helper.framework"
BlueprintName = "NSString-Helper"
ReferencedContainer = "container:Pods.xcodeproj">
BuildableIdentifier = 'primary'
BlueprintIdentifier = '396F09A7332B19101DE9B640'
BlueprintName = 'NSString-Helper'
ReferencedContainer = 'container:Pods.xcodeproj'
BuildableName = 'NSString_Helper.framework'>
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
shouldUseLaunchSchemeArgsEnv = "YES"
buildConfiguration = "Debug">
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
@ -41,25 +38,17 @@
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
buildConfiguration = "Debug"
allowLocationSimulation = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "6F621F2F34EEA2E2A05B25FA44939F5D"
BuildableName = "NSString_Helper.framework"
BlueprintName = "NSString-Helper"
ReferencedContainer = "container:Pods.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
debugDocumentVersioning = "YES"
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES">
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">