Compare commits
7 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 5d3900b868 | |||
| 703192e9cf | |||
| 6a377b7d20 | |||
| b5fe27627e | |||
| 0d514c7ca3 | |||
| 114f16ac1c | |||
| 3a914b99d1 |
4
.gitattributes
vendored
Normal file
4
.gitattributes
vendored
Normal 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
|
||||||
@ -7,7 +7,7 @@
|
|||||||
objects = {
|
objects = {
|
||||||
|
|
||||||
/* Begin PBXBuildFile section */
|
/* 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 */; };
|
6003F58E195388D20070C39A /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6003F58D195388D20070C39A /* Foundation.framework */; };
|
||||||
6003F590195388D20070C39A /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6003F58F195388D20070C39A /* CoreGraphics.framework */; };
|
6003F590195388D20070C39A /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6003F58F195388D20070C39A /* CoreGraphics.framework */; };
|
||||||
6003F592195388D20070C39A /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6003F591195388D20070C39A /* UIKit.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 */; };
|
6003F5BA195388D20070C39A /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 6003F5B8195388D20070C39A /* InfoPlist.strings */; };
|
||||||
6003F5BC195388D20070C39A /* Tests.m in Sources */ = {isa = PBXBuildFile; fileRef = 6003F5BB195388D20070C39A /* Tests.m */; };
|
6003F5BC195388D20070C39A /* Tests.m in Sources */ = {isa = PBXBuildFile; fileRef = 6003F5BB195388D20070C39A /* Tests.m */; };
|
||||||
873B8AEB1B1F5CCA007FD442 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 873B8AEA1B1F5CCA007FD442 /* Main.storyboard */; };
|
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 */
|
/* End PBXBuildFile section */
|
||||||
|
|
||||||
/* Begin PBXContainerItemProxy section */
|
/* Begin PBXContainerItemProxy section */
|
||||||
@ -36,8 +36,7 @@
|
|||||||
/* End PBXContainerItemProxy section */
|
/* End PBXContainerItemProxy section */
|
||||||
|
|
||||||
/* Begin PBXFileReference 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>"; };
|
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>"; };
|
||||||
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>"; };
|
|
||||||
6003F58A195388D20070C39A /* NSString-Helper_Example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "NSString-Helper_Example.app"; sourceTree = BUILT_PRODUCTS_DIR; };
|
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; };
|
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; };
|
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>"; };
|
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>"; };
|
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>"; };
|
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>"; };
|
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>"; };
|
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>"; };
|
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>"; };
|
9D42F12F37BCA0ACFD8622CD /* libPods-NSString-Helper_Example.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-NSString-Helper_Example.a"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
EEC7D25FF692DF5273E9910A /* Pods_NSString_Helper_Tests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_NSString_Helper_Tests.framework; 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; };
|
||||||
FE00DDFA05C08065E8026237 /* Pods_NSString_Helper_Example.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_NSString_Helper_Example.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
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 */
|
/* End PBXFileReference section */
|
||||||
|
|
||||||
/* Begin PBXFrameworksBuildPhase section */
|
/* Begin PBXFrameworksBuildPhase section */
|
||||||
@ -75,7 +75,7 @@
|
|||||||
6003F590195388D20070C39A /* CoreGraphics.framework in Frameworks */,
|
6003F590195388D20070C39A /* CoreGraphics.framework in Frameworks */,
|
||||||
6003F592195388D20070C39A /* UIKit.framework in Frameworks */,
|
6003F592195388D20070C39A /* UIKit.framework in Frameworks */,
|
||||||
6003F58E195388D20070C39A /* Foundation.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;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
@ -86,7 +86,7 @@
|
|||||||
6003F5B0195388D20070C39A /* XCTest.framework in Frameworks */,
|
6003F5B0195388D20070C39A /* XCTest.framework in Frameworks */,
|
||||||
6003F5B2195388D20070C39A /* UIKit.framework in Frameworks */,
|
6003F5B2195388D20070C39A /* UIKit.framework in Frameworks */,
|
||||||
6003F5B1195388D20070C39A /* Foundation.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;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
@ -101,7 +101,7 @@
|
|||||||
6003F5B5195388D20070C39A /* Tests */,
|
6003F5B5195388D20070C39A /* Tests */,
|
||||||
6003F58C195388D20070C39A /* Frameworks */,
|
6003F58C195388D20070C39A /* Frameworks */,
|
||||||
6003F58B195388D20070C39A /* Products */,
|
6003F58B195388D20070C39A /* Products */,
|
||||||
BA7A5012B36E3C927058F0FC /* Pods */,
|
BBE4504745A5B8690B19EF46 /* Pods */,
|
||||||
);
|
);
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
@ -121,8 +121,8 @@
|
|||||||
6003F58F195388D20070C39A /* CoreGraphics.framework */,
|
6003F58F195388D20070C39A /* CoreGraphics.framework */,
|
||||||
6003F591195388D20070C39A /* UIKit.framework */,
|
6003F591195388D20070C39A /* UIKit.framework */,
|
||||||
6003F5AF195388D20070C39A /* XCTest.framework */,
|
6003F5AF195388D20070C39A /* XCTest.framework */,
|
||||||
FE00DDFA05C08065E8026237 /* Pods_NSString_Helper_Example.framework */,
|
9D42F12F37BCA0ACFD8622CD /* libPods-NSString-Helper_Example.a */,
|
||||||
EEC7D25FF692DF5273E9910A /* Pods_NSString_Helper_Tests.framework */,
|
CBB752CF9494348EA94E9890 /* libPods-NSString-Helper_Tests.a */,
|
||||||
);
|
);
|
||||||
name = Frameworks;
|
name = Frameworks;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@ -182,13 +182,13 @@
|
|||||||
name = "Podspec Metadata";
|
name = "Podspec Metadata";
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
BA7A5012B36E3C927058F0FC /* Pods */ = {
|
BBE4504745A5B8690B19EF46 /* Pods */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
7A02A0538ECFE76907B78514 /* Pods-NSString-Helper_Example.debug.xcconfig */,
|
F8D0C102DC63F7EEE95D0F2F /* Pods-NSString-Helper_Example.debug.xcconfig */,
|
||||||
6831E237E4E7BCC8307EA49A /* Pods-NSString-Helper_Example.release.xcconfig */,
|
A066422FE7F9F7A309C05FA6 /* Pods-NSString-Helper_Example.release.xcconfig */,
|
||||||
412D7B9D1CA8644EED05E876 /* Pods-NSString-Helper_Tests.debug.xcconfig */,
|
43F47E058F038E85AB51AF26 /* Pods-NSString-Helper_Tests.debug.xcconfig */,
|
||||||
2E9CEE81BD53F89DFA0781BE /* Pods-NSString-Helper_Tests.release.xcconfig */,
|
623B075D9ED7EFC53DD9D0FD /* Pods-NSString-Helper_Tests.release.xcconfig */,
|
||||||
);
|
);
|
||||||
name = Pods;
|
name = Pods;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@ -200,12 +200,10 @@
|
|||||||
isa = PBXNativeTarget;
|
isa = PBXNativeTarget;
|
||||||
buildConfigurationList = 6003F5BF195388D20070C39A /* Build configuration list for PBXNativeTarget "NSString-Helper_Example" */;
|
buildConfigurationList = 6003F5BF195388D20070C39A /* Build configuration list for PBXNativeTarget "NSString-Helper_Example" */;
|
||||||
buildPhases = (
|
buildPhases = (
|
||||||
C4D5E64415C6E6C3B486D1D2 /* Check Pods Manifest.lock */,
|
9B592AE96165CD0F99340ACC /* [CP] Check Pods Manifest.lock */,
|
||||||
6003F586195388D20070C39A /* Sources */,
|
6003F586195388D20070C39A /* Sources */,
|
||||||
6003F587195388D20070C39A /* Frameworks */,
|
6003F587195388D20070C39A /* Frameworks */,
|
||||||
6003F588195388D20070C39A /* Resources */,
|
6003F588195388D20070C39A /* Resources */,
|
||||||
F4BFB45F0477AADDB169FF4A /* Embed Pods Frameworks */,
|
|
||||||
2FB602919CD9E6B1CC8177FF /* Copy Pods Resources */,
|
|
||||||
);
|
);
|
||||||
buildRules = (
|
buildRules = (
|
||||||
);
|
);
|
||||||
@ -220,12 +218,10 @@
|
|||||||
isa = PBXNativeTarget;
|
isa = PBXNativeTarget;
|
||||||
buildConfigurationList = 6003F5C2195388D20070C39A /* Build configuration list for PBXNativeTarget "NSString-Helper_Tests" */;
|
buildConfigurationList = 6003F5C2195388D20070C39A /* Build configuration list for PBXNativeTarget "NSString-Helper_Tests" */;
|
||||||
buildPhases = (
|
buildPhases = (
|
||||||
3BAC6FE5CC3CFD00D5F15DAA /* Check Pods Manifest.lock */,
|
D3CD38E80167F24BD9D8D1F7 /* [CP] Check Pods Manifest.lock */,
|
||||||
6003F5AA195388D20070C39A /* Sources */,
|
6003F5AA195388D20070C39A /* Sources */,
|
||||||
6003F5AB195388D20070C39A /* Frameworks */,
|
6003F5AB195388D20070C39A /* Frameworks */,
|
||||||
6003F5AC195388D20070C39A /* Resources */,
|
6003F5AC195388D20070C39A /* Resources */,
|
||||||
14C3CEC3CFF93DAD514DA1A7 /* Embed Pods Frameworks */,
|
|
||||||
8C67E10569176F8352202CC1 /* Copy Pods Resources */,
|
|
||||||
);
|
);
|
||||||
buildRules = (
|
buildRules = (
|
||||||
);
|
);
|
||||||
@ -257,6 +253,7 @@
|
|||||||
developmentRegion = English;
|
developmentRegion = English;
|
||||||
hasScannedForEncodings = 0;
|
hasScannedForEncodings = 0;
|
||||||
knownRegions = (
|
knownRegions = (
|
||||||
|
English,
|
||||||
en,
|
en,
|
||||||
Base,
|
Base,
|
||||||
);
|
);
|
||||||
@ -293,94 +290,40 @@
|
|||||||
/* End PBXResourcesBuildPhase section */
|
/* End PBXResourcesBuildPhase section */
|
||||||
|
|
||||||
/* Begin PBXShellScriptBuildPhase section */
|
/* Begin PBXShellScriptBuildPhase section */
|
||||||
14C3CEC3CFF93DAD514DA1A7 /* Embed Pods Frameworks */ = {
|
9B592AE96165CD0F99340ACC /* [CP] Check Pods Manifest.lock */ = {
|
||||||
isa = PBXShellScriptBuildPhase;
|
isa = PBXShellScriptBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
);
|
);
|
||||||
inputPaths = (
|
inputPaths = (
|
||||||
|
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
|
||||||
|
"${PODS_ROOT}/Manifest.lock",
|
||||||
);
|
);
|
||||||
name = "Embed Pods Frameworks";
|
name = "[CP] Check Pods Manifest.lock";
|
||||||
outputPaths = (
|
outputPaths = (
|
||||||
|
"$(DERIVED_FILE_DIR)/Pods-NSString-Helper_Example-checkManifestLockResult.txt",
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
shellPath = /bin/sh;
|
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;
|
showEnvVarsInLog = 0;
|
||||||
};
|
};
|
||||||
2FB602919CD9E6B1CC8177FF /* Copy Pods Resources */ = {
|
D3CD38E80167F24BD9D8D1F7 /* [CP] Check Pods Manifest.lock */ = {
|
||||||
isa = PBXShellScriptBuildPhase;
|
isa = PBXShellScriptBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
);
|
);
|
||||||
inputPaths = (
|
inputPaths = (
|
||||||
|
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
|
||||||
|
"${PODS_ROOT}/Manifest.lock",
|
||||||
);
|
);
|
||||||
name = "Copy Pods Resources";
|
name = "[CP] Check Pods Manifest.lock";
|
||||||
outputPaths = (
|
outputPaths = (
|
||||||
|
"$(DERIVED_FILE_DIR)/Pods-NSString-Helper_Tests-checkManifestLockResult.txt",
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
shellPath = /bin/sh;
|
shellPath = /bin/sh;
|
||||||
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-NSString-Helper_Example/Pods-NSString-Helper_Example-resources.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;
|
|
||||||
};
|
|
||||||
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";
|
|
||||||
showEnvVarsInLog = 0;
|
showEnvVarsInLog = 0;
|
||||||
};
|
};
|
||||||
/* End PBXShellScriptBuildPhase section */
|
/* End PBXShellScriptBuildPhase section */
|
||||||
@ -466,7 +409,7 @@
|
|||||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
|
IPHONEOS_DEPLOYMENT_TARGET = 10.0;
|
||||||
ONLY_ACTIVE_ARCH = YES;
|
ONLY_ACTIVE_ARCH = YES;
|
||||||
SDKROOT = iphoneos;
|
SDKROOT = iphoneos;
|
||||||
TARGETED_DEVICE_FAMILY = "1,2";
|
TARGETED_DEVICE_FAMILY = "1,2";
|
||||||
@ -499,7 +442,7 @@
|
|||||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
|
IPHONEOS_DEPLOYMENT_TARGET = 10.0;
|
||||||
SDKROOT = iphoneos;
|
SDKROOT = iphoneos;
|
||||||
TARGETED_DEVICE_FAMILY = "1,2";
|
TARGETED_DEVICE_FAMILY = "1,2";
|
||||||
VALIDATE_PRODUCT = YES;
|
VALIDATE_PRODUCT = YES;
|
||||||
@ -508,7 +451,7 @@
|
|||||||
};
|
};
|
||||||
6003F5C0195388D20070C39A /* Debug */ = {
|
6003F5C0195388D20070C39A /* Debug */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
baseConfigurationReference = 7A02A0538ECFE76907B78514 /* Pods-NSString-Helper_Example.debug.xcconfig */;
|
baseConfigurationReference = F8D0C102DC63F7EEE95D0F2F /* Pods-NSString-Helper_Example.debug.xcconfig */;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
|
ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
|
||||||
@ -523,7 +466,7 @@
|
|||||||
};
|
};
|
||||||
6003F5C1195388D20070C39A /* Release */ = {
|
6003F5C1195388D20070C39A /* Release */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
baseConfigurationReference = 6831E237E4E7BCC8307EA49A /* Pods-NSString-Helper_Example.release.xcconfig */;
|
baseConfigurationReference = A066422FE7F9F7A309C05FA6 /* Pods-NSString-Helper_Example.release.xcconfig */;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
|
ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
|
||||||
@ -538,7 +481,7 @@
|
|||||||
};
|
};
|
||||||
6003F5C3195388D20070C39A /* Debug */ = {
|
6003F5C3195388D20070C39A /* Debug */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
baseConfigurationReference = 412D7B9D1CA8644EED05E876 /* Pods-NSString-Helper_Tests.debug.xcconfig */;
|
baseConfigurationReference = 43F47E058F038E85AB51AF26 /* Pods-NSString-Helper_Tests.debug.xcconfig */;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
BUNDLE_LOADER = "$(TEST_HOST)";
|
BUNDLE_LOADER = "$(TEST_HOST)";
|
||||||
FRAMEWORK_SEARCH_PATHS = (
|
FRAMEWORK_SEARCH_PATHS = (
|
||||||
@ -561,7 +504,7 @@
|
|||||||
};
|
};
|
||||||
6003F5C4195388D20070C39A /* Release */ = {
|
6003F5C4195388D20070C39A /* Release */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
baseConfigurationReference = 2E9CEE81BD53F89DFA0781BE /* Pods-NSString-Helper_Tests.release.xcconfig */;
|
baseConfigurationReference = 623B075D9ED7EFC53DD9D0FD /* Pods-NSString-Helper_Tests.release.xcconfig */;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
BUNDLE_LOADER = "$(TEST_HOST)";
|
BUNDLE_LOADER = "$(TEST_HOST)";
|
||||||
FRAMEWORK_SEARCH_PATHS = (
|
FRAMEWORK_SEARCH_PATHS = (
|
||||||
|
|||||||
@ -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>
|
||||||
@ -1,5 +1,4 @@
|
|||||||
source 'https://github.com/CocoaPods/Specs.git'
|
platform :ios, '10.0'
|
||||||
use_frameworks!
|
|
||||||
|
|
||||||
target 'NSString-Helper_Example' do
|
target 'NSString-Helper_Example' do
|
||||||
pod "NSString-Helper", :path => "../"
|
pod "NSString-Helper", :path => "../"
|
||||||
@ -7,6 +6,4 @@ end
|
|||||||
|
|
||||||
target 'NSString-Helper_Tests' do
|
target 'NSString-Helper_Tests' do
|
||||||
pod "NSString-Helper", :path => "../"
|
pod "NSString-Helper", :path => "../"
|
||||||
|
|
||||||
pod 'FBSnapshotTestCase'
|
|
||||||
end
|
end
|
||||||
|
|||||||
@ -1,13 +1,7 @@
|
|||||||
PODS:
|
PODS:
|
||||||
- FBSnapshotTestCase (2.0.7):
|
- NSString-Helper (1.2.1)
|
||||||
- FBSnapshotTestCase/SwiftSupport (= 2.0.7)
|
|
||||||
- FBSnapshotTestCase/Core (2.0.7)
|
|
||||||
- FBSnapshotTestCase/SwiftSupport (2.0.7):
|
|
||||||
- FBSnapshotTestCase/Core
|
|
||||||
- NSString-Helper (1.0.2)
|
|
||||||
|
|
||||||
DEPENDENCIES:
|
DEPENDENCIES:
|
||||||
- FBSnapshotTestCase
|
|
||||||
- NSString-Helper (from `../`)
|
- NSString-Helper (from `../`)
|
||||||
|
|
||||||
EXTERNAL SOURCES:
|
EXTERNAL SOURCES:
|
||||||
@ -15,9 +9,8 @@ EXTERNAL SOURCES:
|
|||||||
:path: "../"
|
:path: "../"
|
||||||
|
|
||||||
SPEC CHECKSUMS:
|
SPEC CHECKSUMS:
|
||||||
FBSnapshotTestCase: 7e85180d0d141a0cf472352edda7e80d7eaeb547
|
NSString-Helper: dcbf45d121c0c9d6612acfe131e554cf5538b560
|
||||||
NSString-Helper: 0ee74919829a332f9838fa87b28cb2d1d991e92c
|
|
||||||
|
|
||||||
PODFILE CHECKSUM: a88b2ea7b96d7de499d212328481d74fcf022692
|
PODFILE CHECKSUM: 9a62d5a7de52ffc40c1a1c843b9a7798cf5e4993
|
||||||
|
|
||||||
COCOAPODS: 1.0.0.beta.2
|
COCOAPODS: 1.10.0
|
||||||
|
|||||||
@ -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"
|
|
||||||
}
|
|
||||||
|
|
||||||
@ -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
|
|
||||||
@ -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
|
|
||||||
@ -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
|
|
||||||
@ -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
|
|
||||||
@ -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
|
|
||||||
@ -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
|
|
||||||
@ -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
|
|
||||||
@ -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
|
|
||||||
@ -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
|
|
||||||
@ -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;
|
|
||||||
}
|
|
||||||
@ -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
|
|
||||||
@ -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
|
|
||||||
@ -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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
29
Example/Pods/FBSnapshotTestCase/LICENSE
generated
29
Example/Pods/FBSnapshotTestCase/LICENSE
generated
@ -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.
|
|
||||||
97
Example/Pods/FBSnapshotTestCase/README.md
generated
97
Example/Pods/FBSnapshotTestCase/README.md
generated
@ -1,97 +0,0 @@
|
|||||||
FBSnapshotTestCase
|
|
||||||
======================
|
|
||||||
|
|
||||||
[](https://travis-ci.org/facebook/ios-snapshot-test-case) [](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`|
|
|
||||||
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
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`.
|
|
||||||
1
Example/Pods/Headers/Private/NSString-Helper/NSString+Helper.h
generated
Symbolic link
1
Example/Pods/Headers/Private/NSString-Helper/NSString+Helper.h
generated
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../../../../../NSString-Helper/NSString+Helper.h
|
||||||
1
Example/Pods/Headers/Public/NSString-Helper/NSString+Helper.h
generated
Symbolic link
1
Example/Pods/Headers/Public/NSString-Helper/NSString+Helper.h
generated
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../../../../../NSString-Helper/NSString+Helper.h
|
||||||
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "NSString-Helper",
|
"name": "NSString-Helper",
|
||||||
"version": "1.0.2",
|
"version": "1.2.1",
|
||||||
"summary": "NSString-Helper is usefull helper to validate email NSString",
|
"summary": "NSString-Helper is usefull helper to validate email NSString",
|
||||||
"homepage": "https://github.com/giuseppenucifora/NSString-Helper",
|
"homepage": "https://github.com/giuseppenucifora/NSString-Helper",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
@ -9,17 +9,12 @@
|
|||||||
},
|
},
|
||||||
"source": {
|
"source": {
|
||||||
"git": "https://github.com/giuseppenucifora/NSString-Helper.git",
|
"git": "https://github.com/giuseppenucifora/NSString-Helper.git",
|
||||||
"tag": "1.0.2"
|
"tag": "1.2.1"
|
||||||
},
|
},
|
||||||
"social_media_url": "https://twitter.com/giuseppenuc",
|
"social_media_url": "https://twitter.com/giuseppenuc",
|
||||||
"requires_arc": true,
|
"requires_arc": true,
|
||||||
"platforms": {
|
"platforms": {
|
||||||
"ios": "8.0"
|
"ios": "10.0"
|
||||||
},
|
},
|
||||||
"source_files": "NSString-Helper/*.{h,m}",
|
"source_files": "NSString-Helper/*.{h,m}"
|
||||||
"resource_bundles": {
|
|
||||||
"NSString-Helper": [
|
|
||||||
"Pod/Assets/*.png"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
15
Example/Pods/Manifest.lock
generated
15
Example/Pods/Manifest.lock
generated
@ -1,13 +1,7 @@
|
|||||||
PODS:
|
PODS:
|
||||||
- FBSnapshotTestCase (2.0.7):
|
- NSString-Helper (1.2.1)
|
||||||
- FBSnapshotTestCase/SwiftSupport (= 2.0.7)
|
|
||||||
- FBSnapshotTestCase/Core (2.0.7)
|
|
||||||
- FBSnapshotTestCase/SwiftSupport (2.0.7):
|
|
||||||
- FBSnapshotTestCase/Core
|
|
||||||
- NSString-Helper (1.0.2)
|
|
||||||
|
|
||||||
DEPENDENCIES:
|
DEPENDENCIES:
|
||||||
- FBSnapshotTestCase
|
|
||||||
- NSString-Helper (from `../`)
|
- NSString-Helper (from `../`)
|
||||||
|
|
||||||
EXTERNAL SOURCES:
|
EXTERNAL SOURCES:
|
||||||
@ -15,9 +9,8 @@ EXTERNAL SOURCES:
|
|||||||
:path: "../"
|
:path: "../"
|
||||||
|
|
||||||
SPEC CHECKSUMS:
|
SPEC CHECKSUMS:
|
||||||
FBSnapshotTestCase: 7e85180d0d141a0cf472352edda7e80d7eaeb547
|
NSString-Helper: dcbf45d121c0c9d6612acfe131e554cf5538b560
|
||||||
NSString-Helper: 0ee74919829a332f9838fa87b28cb2d1d991e92c
|
|
||||||
|
|
||||||
PODFILE CHECKSUM: a88b2ea7b96d7de499d212328481d74fcf022692
|
PODFILE CHECKSUM: 9a62d5a7de52ffc40c1a1c843b9a7798cf5e4993
|
||||||
|
|
||||||
COCOAPODS: 1.0.0.beta.2
|
COCOAPODS: 1.10.0
|
||||||
|
|||||||
1084
Example/Pods/Pods.xcodeproj/project.pbxproj
generated
1084
Example/Pods/Pods.xcodeproj/project.pbxproj
generated
File diff suppressed because it is too large
Load Diff
@ -1,5 +0,0 @@
|
|||||||
#import <Foundation/Foundation.h>
|
|
||||||
@interface PodsDummy_FBSnapshotTestCase : NSObject
|
|
||||||
@end
|
|
||||||
@implementation PodsDummy_FBSnapshotTestCase
|
|
||||||
@end
|
|
||||||
@ -1,4 +0,0 @@
|
|||||||
#ifdef __OBJC__
|
|
||||||
#import <UIKit/UIKit.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
@ -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"
|
|
||||||
}
|
|
||||||
|
|
||||||
@ -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
|
|
||||||
@ -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>
|
|
||||||
@ -15,7 +15,7 @@
|
|||||||
<key>CFBundlePackageType</key>
|
<key>CFBundlePackageType</key>
|
||||||
<string>FMWK</string>
|
<string>FMWK</string>
|
||||||
<key>CFBundleShortVersionString</key>
|
<key>CFBundleShortVersionString</key>
|
||||||
<string>1.0.2</string>
|
<string>1.2.0</string>
|
||||||
<key>CFBundleSignature</key>
|
<key>CFBundleSignature</key>
|
||||||
<string>????</string>
|
<string>????</string>
|
||||||
<key>CFBundleVersion</key>
|
<key>CFBundleVersion</key>
|
||||||
|
|||||||
@ -1,4 +1,12 @@
|
|||||||
#ifdef __OBJC__
|
#ifdef __OBJC__
|
||||||
#import <UIKit/UIKit.h>
|
#import <UIKit/UIKit.h>
|
||||||
|
#else
|
||||||
|
#ifndef FOUNDATION_EXPORT
|
||||||
|
#if defined(__cplusplus)
|
||||||
|
#define FOUNDATION_EXPORT extern "C"
|
||||||
|
#else
|
||||||
|
#define FOUNDATION_EXPORT extern
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@ -1,4 +1,14 @@
|
|||||||
|
#ifdef __OBJC__
|
||||||
#import <UIKit/UIKit.h>
|
#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"
|
#import "NSString+Helper.h"
|
||||||
|
|
||||||
|
|||||||
12
Example/Pods/Target Support Files/NSString-Helper/NSString-Helper.debug.xcconfig
generated
Normal file
12
Example/Pods/Target Support Files/NSString-Helper/NSString-Helper.debug.xcconfig
generated
Normal 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
|
||||||
12
Example/Pods/Target Support Files/NSString-Helper/NSString-Helper.release.xcconfig
generated
Normal file
12
Example/Pods/Target Support Files/NSString-Helper/NSString-Helper.release.xcconfig
generated
Normal 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
|
||||||
@ -1,5 +1,8 @@
|
|||||||
|
CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/NSString-Helper
|
||||||
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
|
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_ROOT = ${SRCROOT}
|
||||||
|
PODS_TARGET_SRCROOT = ${PODS_ROOT}/../..
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier}
|
PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier}
|
||||||
SKIP_INSTALL = YES
|
SKIP_INSTALL = YES
|
||||||
|
|||||||
@ -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>
|
|
||||||
@ -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
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
THE SOFTWARE.
|
THE SOFTWARE.
|
||||||
</string>
|
</string>
|
||||||
|
<key>License</key>
|
||||||
|
<string>MIT</string>
|
||||||
<key>Title</key>
|
<key>Title</key>
|
||||||
<string>NSString-Helper</string>
|
<string>NSString-Helper</string>
|
||||||
<key>Type</key>
|
<key>Type</key>
|
||||||
|
|||||||
@ -1,11 +1,28 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
set -e
|
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}"
|
echo "mkdir -p ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
|
||||||
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}"
|
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()
|
install_framework()
|
||||||
{
|
{
|
||||||
if [ -r "${BUILT_PRODUCTS_DIR}/$1" ]; then
|
if [ -r "${BUILT_PRODUCTS_DIR}/$1" ]; then
|
||||||
@ -16,16 +33,16 @@ install_framework()
|
|||||||
local source="$1"
|
local source="$1"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
local destination="${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
|
local destination="${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
|
||||||
|
|
||||||
if [ -L "${source}" ]; then
|
if [ -L "${source}" ]; then
|
||||||
echo "Symlinked..."
|
echo "Symlinked..."
|
||||||
source="$(readlink "${source}")"
|
source="$(readlink "${source}")"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# use filter instead of exclude so missing patterns dont' throw errors
|
# Use filter instead of exclude so missing patterns don't throw errors.
|
||||||
echo "rsync -av --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${destination}\""
|
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 -av --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
|
local basename
|
||||||
basename="$(basename -s .framework "$1")"
|
basename="$(basename -s .framework "$1")"
|
||||||
@ -54,24 +71,65 @@ install_framework()
|
|||||||
fi
|
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
|
# Signs a framework with the provided identity
|
||||||
code_sign_if_enabled() {
|
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
|
# Use the current code_sign_identitiy
|
||||||
echo "Code Signing $1 with Identity ${EXPANDED_CODE_SIGN_IDENTITY_NAME}"
|
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\""
|
local code_sign_cmd="/usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} ${OTHER_CODE_SIGN_FLAGS:-} --preserve-metadata=identifier,entitlements '$1'"
|
||||||
/usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} --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
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
# Strip invalid architectures
|
# Strip invalid architectures
|
||||||
strip_invalid_archs() {
|
strip_invalid_archs() {
|
||||||
binary="$1"
|
binary="$1"
|
||||||
# Get architectures for current file
|
# Get architectures for current target binary
|
||||||
archs="$(lipo -info "$binary" | rev | cut -d ':' -f1 | rev)"
|
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=""
|
stripped=""
|
||||||
for arch in $archs; do
|
for arch in $binary_archs; do
|
||||||
if ! [[ "${VALID_ARCHS}" == *"$arch"* ]]; then
|
if ! [[ "${ARCHS}" == *"$arch"* ]]; then
|
||||||
# Strip non-valid architectures in-place
|
# Strip non-valid architectures in-place
|
||||||
lipo -remove "$arch" -output "$binary" "$binary" || exit 1
|
lipo -remove "$arch" -output "$binary" "$binary" || exit 1
|
||||||
stripped="$stripped $arch"
|
stripped="$stripped $arch"
|
||||||
@ -80,12 +138,16 @@ strip_invalid_archs() {
|
|||||||
if [[ "$stripped" ]]; then
|
if [[ "$stripped" ]]; then
|
||||||
echo "Stripped $binary of architectures:$stripped"
|
echo "Stripped $binary of architectures:$stripped"
|
||||||
fi
|
fi
|
||||||
|
STRIP_BINARY_RETVAL=1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if [[ "$CONFIGURATION" == "Debug" ]]; then
|
if [[ "$CONFIGURATION" == "Debug" ]]; then
|
||||||
install_framework "Pods-NSString-Helper_Example/NSString_Helper.framework"
|
install_framework "${BUILT_PRODUCTS_DIR}/NSString-Helper/NSString_Helper.framework"
|
||||||
fi
|
fi
|
||||||
if [[ "$CONFIGURATION" == "Release" ]]; then
|
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
|
fi
|
||||||
|
|||||||
@ -1,18 +1,45 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
set -e
|
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=${PODS_ROOT}/resources-to-copy-${TARGETNAME}.txt
|
||||||
> "$RESOURCES_TO_COPY"
|
> "$RESOURCES_TO_COPY"
|
||||||
|
|
||||||
XCASSET_FILES=()
|
XCASSET_FILES=()
|
||||||
|
|
||||||
realpath() {
|
# This protects against multiple targets copying the same framework dependency at the same time. The solution
|
||||||
DIRECTORY="$(cd "${1%/*}" && pwd)"
|
# was originally proposed here: https://lists.samba.org/archive/rsync/2008-February/020158.html
|
||||||
FILENAME="${1##*/}"
|
RSYNC_PROTECT_TMP_FILES=(--filter "P .*.??????")
|
||||||
echo "$DIRECTORY/$FILENAME"
|
|
||||||
}
|
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()
|
install_resource()
|
||||||
{
|
{
|
||||||
@ -29,74 +56,63 @@ EOM
|
|||||||
fi
|
fi
|
||||||
case $RESOURCE_PATH in
|
case $RESOURCE_PATH in
|
||||||
*.storyboard)
|
*.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}"
|
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 "${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 "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .storyboard`.storyboardc" "$RESOURCE_PATH" --sdk "${SDKROOT}" ${TARGET_DEVICE_ARGS}
|
||||||
;;
|
;;
|
||||||
*.xib)
|
*.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}"
|
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 "${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 "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .xib`.nib" "$RESOURCE_PATH" --sdk "${SDKROOT}" ${TARGET_DEVICE_ARGS}
|
||||||
;;
|
;;
|
||||||
*.framework)
|
*.framework)
|
||||||
echo "mkdir -p ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
|
echo "mkdir -p ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" || true
|
||||||
mkdir -p "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
|
mkdir -p "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
|
||||||
echo "rsync -av $RESOURCE_PATH ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
|
echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" $RESOURCE_PATH ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" || true
|
||||||
rsync -av "$RESOURCE_PATH" "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
|
rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
|
||||||
;;
|
;;
|
||||||
*.xcdatamodel)
|
*.xcdatamodel)
|
||||||
echo "xcrun momc \"$RESOURCE_PATH\" \"${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH"`.mom\""
|
echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH"`.mom\"" || true
|
||||||
xcrun momc "$RESOURCE_PATH" "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodel`.mom"
|
xcrun momc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodel`.mom"
|
||||||
;;
|
;;
|
||||||
*.xcdatamodeld)
|
*.xcdatamodeld)
|
||||||
echo "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" "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd"
|
xcrun momc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd"
|
||||||
;;
|
;;
|
||||||
*.xcmappingmodel)
|
*.xcmappingmodel)
|
||||||
echo "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" "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm"
|
xcrun mapc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm"
|
||||||
;;
|
;;
|
||||||
*.xcassets)
|
*.xcassets)
|
||||||
ABSOLUTE_XCASSET_FILE=$(realpath "$RESOURCE_PATH")
|
ABSOLUTE_XCASSET_FILE="$RESOURCE_PATH"
|
||||||
XCASSET_FILES+=("$ABSOLUTE_XCASSET_FILE")
|
XCASSET_FILES+=("$ABSOLUTE_XCASSET_FILE")
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
echo "$RESOURCE_PATH"
|
echo "$RESOURCE_PATH" || true
|
||||||
echo "$RESOURCE_PATH" >> "$RESOURCES_TO_COPY"
|
echo "$RESOURCE_PATH" >> "$RESOURCES_TO_COPY"
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
}
|
}
|
||||||
|
|
||||||
mkdir -p "${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" / "${CONFIGURATION_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
|
if [[ "${ACTION}" == "install" ]] && [[ "${SKIP_INSTALL}" == "NO" ]]; then
|
||||||
mkdir -p "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}"
|
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}"
|
rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}"
|
||||||
fi
|
fi
|
||||||
rm -f "$RESOURCES_TO_COPY"
|
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
|
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).
|
# Find all other xcassets (this unfortunately includes those of path pods and other targets).
|
||||||
OTHER_XCASSETS=$(find "$PWD" -iname "*.xcassets" -type d)
|
OTHER_XCASSETS=$(find "$PWD" -iname "*.xcassets" -type d)
|
||||||
while read line; do
|
while read line; do
|
||||||
if [[ $line != "`realpath $PODS_ROOT`*" ]]; then
|
if [[ $line != "${PODS_ROOT}*" ]]; then
|
||||||
XCASSET_FILES+=("$line")
|
XCASSET_FILES+=("$line")
|
||||||
fi
|
fi
|
||||||
done <<<"$OTHER_XCASSETS"
|
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
|
fi
|
||||||
|
|||||||
@ -1,4 +1,14 @@
|
|||||||
|
#ifdef __OBJC__
|
||||||
#import <UIKit/UIKit.h>
|
#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;
|
FOUNDATION_EXPORT double Pods_NSString_Helper_ExampleVersionNumber;
|
||||||
|
|||||||
@ -1,6 +1,11 @@
|
|||||||
|
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO
|
||||||
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
|
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
|
||||||
LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks'
|
HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/NSString-Helper"
|
||||||
OTHER_CFLAGS = $(inherited) -iquote "$CONFIGURATION_BUILD_DIR/NSString_Helper.framework/Headers"
|
LIBRARY_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/NSString-Helper"
|
||||||
OTHER_LDFLAGS = $(inherited) -framework "NSString_Helper"
|
OTHER_LDFLAGS = $(inherited) -ObjC -l"NSString-Helper"
|
||||||
PODS_FRAMEWORK_BUILD_PATH = $(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/Pods-NSString-Helper_Example
|
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_ROOT = ${SRCROOT}/Pods
|
||||||
|
PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates
|
||||||
|
USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES
|
||||||
|
|||||||
@ -1,6 +1,11 @@
|
|||||||
|
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO
|
||||||
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
|
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
|
||||||
LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks'
|
HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/NSString-Helper"
|
||||||
OTHER_CFLAGS = $(inherited) -iquote "$CONFIGURATION_BUILD_DIR/NSString_Helper.framework/Headers"
|
LIBRARY_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/NSString-Helper"
|
||||||
OTHER_LDFLAGS = $(inherited) -framework "NSString_Helper"
|
OTHER_LDFLAGS = $(inherited) -ObjC -l"NSString-Helper"
|
||||||
PODS_FRAMEWORK_BUILD_PATH = $(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/Pods-NSString-Helper_Example
|
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_ROOT = ${SRCROOT}/Pods
|
||||||
|
PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates
|
||||||
|
USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES
|
||||||
|
|||||||
@ -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
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
THE SOFTWARE.
|
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
|
Generated by CocoaPods - https://cocoapods.org
|
||||||
|
|||||||
@ -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
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
THE SOFTWARE.
|
THE SOFTWARE.
|
||||||
</string>
|
</string>
|
||||||
|
<key>License</key>
|
||||||
|
<string>MIT</string>
|
||||||
<key>Title</key>
|
<key>Title</key>
|
||||||
<string>NSString-Helper</string>
|
<string>NSString-Helper</string>
|
||||||
<key>Type</key>
|
<key>Type</key>
|
||||||
<string>PSGroupSpecifier</string>
|
<string>PSGroupSpecifier</string>
|
||||||
</dict>
|
</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>
|
<dict>
|
||||||
<key>FooterText</key>
|
<key>FooterText</key>
|
||||||
<string>Generated by CocoaPods - https://cocoapods.org</string>
|
<string>Generated by CocoaPods - https://cocoapods.org</string>
|
||||||
|
|||||||
@ -1,11 +1,28 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
set -e
|
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}"
|
echo "mkdir -p ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
|
||||||
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}"
|
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()
|
install_framework()
|
||||||
{
|
{
|
||||||
if [ -r "${BUILT_PRODUCTS_DIR}/$1" ]; then
|
if [ -r "${BUILT_PRODUCTS_DIR}/$1" ]; then
|
||||||
@ -16,16 +33,16 @@ install_framework()
|
|||||||
local source="$1"
|
local source="$1"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
local destination="${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
|
local destination="${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
|
||||||
|
|
||||||
if [ -L "${source}" ]; then
|
if [ -L "${source}" ]; then
|
||||||
echo "Symlinked..."
|
echo "Symlinked..."
|
||||||
source="$(readlink "${source}")"
|
source="$(readlink "${source}")"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# use filter instead of exclude so missing patterns dont' throw errors
|
# Use filter instead of exclude so missing patterns don't throw errors.
|
||||||
echo "rsync -av --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${destination}\""
|
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 -av --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
|
local basename
|
||||||
basename="$(basename -s .framework "$1")"
|
basename="$(basename -s .framework "$1")"
|
||||||
@ -54,24 +71,65 @@ install_framework()
|
|||||||
fi
|
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
|
# Signs a framework with the provided identity
|
||||||
code_sign_if_enabled() {
|
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
|
# Use the current code_sign_identitiy
|
||||||
echo "Code Signing $1 with Identity ${EXPANDED_CODE_SIGN_IDENTITY_NAME}"
|
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\""
|
local code_sign_cmd="/usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} ${OTHER_CODE_SIGN_FLAGS:-} --preserve-metadata=identifier,entitlements '$1'"
|
||||||
/usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} --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
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
# Strip invalid architectures
|
# Strip invalid architectures
|
||||||
strip_invalid_archs() {
|
strip_invalid_archs() {
|
||||||
binary="$1"
|
binary="$1"
|
||||||
# Get architectures for current file
|
# Get architectures for current target binary
|
||||||
archs="$(lipo -info "$binary" | rev | cut -d ':' -f1 | rev)"
|
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=""
|
stripped=""
|
||||||
for arch in $archs; do
|
for arch in $binary_archs; do
|
||||||
if ! [[ "${VALID_ARCHS}" == *"$arch"* ]]; then
|
if ! [[ "${ARCHS}" == *"$arch"* ]]; then
|
||||||
# Strip non-valid architectures in-place
|
# Strip non-valid architectures in-place
|
||||||
lipo -remove "$arch" -output "$binary" "$binary" || exit 1
|
lipo -remove "$arch" -output "$binary" "$binary" || exit 1
|
||||||
stripped="$stripped $arch"
|
stripped="$stripped $arch"
|
||||||
@ -80,14 +138,18 @@ strip_invalid_archs() {
|
|||||||
if [[ "$stripped" ]]; then
|
if [[ "$stripped" ]]; then
|
||||||
echo "Stripped $binary of architectures:$stripped"
|
echo "Stripped $binary of architectures:$stripped"
|
||||||
fi
|
fi
|
||||||
|
STRIP_BINARY_RETVAL=1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if [[ "$CONFIGURATION" == "Debug" ]]; then
|
if [[ "$CONFIGURATION" == "Debug" ]]; then
|
||||||
install_framework "Pods-NSString-Helper_Tests/NSString_Helper.framework"
|
install_framework "${BUILT_PRODUCTS_DIR}/NSString-Helper/NSString_Helper.framework"
|
||||||
install_framework "Pods-NSString-Helper_Tests/FBSnapshotTestCase.framework"
|
install_framework "${BUILT_PRODUCTS_DIR}/FBSnapshotTestCase/FBSnapshotTestCase.framework"
|
||||||
fi
|
fi
|
||||||
if [[ "$CONFIGURATION" == "Release" ]]; then
|
if [[ "$CONFIGURATION" == "Release" ]]; then
|
||||||
install_framework "Pods-NSString-Helper_Tests/NSString_Helper.framework"
|
install_framework "${BUILT_PRODUCTS_DIR}/NSString-Helper/NSString_Helper.framework"
|
||||||
install_framework "Pods-NSString-Helper_Tests/FBSnapshotTestCase.framework"
|
install_framework "${BUILT_PRODUCTS_DIR}/FBSnapshotTestCase/FBSnapshotTestCase.framework"
|
||||||
|
fi
|
||||||
|
if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then
|
||||||
|
wait
|
||||||
fi
|
fi
|
||||||
|
|||||||
@ -1,18 +1,45 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
set -e
|
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=${PODS_ROOT}/resources-to-copy-${TARGETNAME}.txt
|
||||||
> "$RESOURCES_TO_COPY"
|
> "$RESOURCES_TO_COPY"
|
||||||
|
|
||||||
XCASSET_FILES=()
|
XCASSET_FILES=()
|
||||||
|
|
||||||
realpath() {
|
# This protects against multiple targets copying the same framework dependency at the same time. The solution
|
||||||
DIRECTORY="$(cd "${1%/*}" && pwd)"
|
# was originally proposed here: https://lists.samba.org/archive/rsync/2008-February/020158.html
|
||||||
FILENAME="${1##*/}"
|
RSYNC_PROTECT_TMP_FILES=(--filter "P .*.??????")
|
||||||
echo "$DIRECTORY/$FILENAME"
|
|
||||||
}
|
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()
|
install_resource()
|
||||||
{
|
{
|
||||||
@ -29,74 +56,63 @@ EOM
|
|||||||
fi
|
fi
|
||||||
case $RESOURCE_PATH in
|
case $RESOURCE_PATH in
|
||||||
*.storyboard)
|
*.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}"
|
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 "${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 "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .storyboard`.storyboardc" "$RESOURCE_PATH" --sdk "${SDKROOT}" ${TARGET_DEVICE_ARGS}
|
||||||
;;
|
;;
|
||||||
*.xib)
|
*.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}"
|
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 "${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 "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .xib`.nib" "$RESOURCE_PATH" --sdk "${SDKROOT}" ${TARGET_DEVICE_ARGS}
|
||||||
;;
|
;;
|
||||||
*.framework)
|
*.framework)
|
||||||
echo "mkdir -p ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
|
echo "mkdir -p ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" || true
|
||||||
mkdir -p "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
|
mkdir -p "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
|
||||||
echo "rsync -av $RESOURCE_PATH ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
|
echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" $RESOURCE_PATH ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" || true
|
||||||
rsync -av "$RESOURCE_PATH" "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
|
rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
|
||||||
;;
|
;;
|
||||||
*.xcdatamodel)
|
*.xcdatamodel)
|
||||||
echo "xcrun momc \"$RESOURCE_PATH\" \"${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH"`.mom\""
|
echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH"`.mom\"" || true
|
||||||
xcrun momc "$RESOURCE_PATH" "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodel`.mom"
|
xcrun momc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodel`.mom"
|
||||||
;;
|
;;
|
||||||
*.xcdatamodeld)
|
*.xcdatamodeld)
|
||||||
echo "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" "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd"
|
xcrun momc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd"
|
||||||
;;
|
;;
|
||||||
*.xcmappingmodel)
|
*.xcmappingmodel)
|
||||||
echo "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" "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm"
|
xcrun mapc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm"
|
||||||
;;
|
;;
|
||||||
*.xcassets)
|
*.xcassets)
|
||||||
ABSOLUTE_XCASSET_FILE=$(realpath "$RESOURCE_PATH")
|
ABSOLUTE_XCASSET_FILE="$RESOURCE_PATH"
|
||||||
XCASSET_FILES+=("$ABSOLUTE_XCASSET_FILE")
|
XCASSET_FILES+=("$ABSOLUTE_XCASSET_FILE")
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
echo "$RESOURCE_PATH"
|
echo "$RESOURCE_PATH" || true
|
||||||
echo "$RESOURCE_PATH" >> "$RESOURCES_TO_COPY"
|
echo "$RESOURCE_PATH" >> "$RESOURCES_TO_COPY"
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
}
|
}
|
||||||
|
|
||||||
mkdir -p "${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" / "${CONFIGURATION_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
|
if [[ "${ACTION}" == "install" ]] && [[ "${SKIP_INSTALL}" == "NO" ]]; then
|
||||||
mkdir -p "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}"
|
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}"
|
rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}"
|
||||||
fi
|
fi
|
||||||
rm -f "$RESOURCES_TO_COPY"
|
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
|
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).
|
# Find all other xcassets (this unfortunately includes those of path pods and other targets).
|
||||||
OTHER_XCASSETS=$(find "$PWD" -iname "*.xcassets" -type d)
|
OTHER_XCASSETS=$(find "$PWD" -iname "*.xcassets" -type d)
|
||||||
while read line; do
|
while read line; do
|
||||||
if [[ $line != "`realpath $PODS_ROOT`*" ]]; then
|
if [[ $line != "${PODS_ROOT}*" ]]; then
|
||||||
XCASSET_FILES+=("$line")
|
XCASSET_FILES+=("$line")
|
||||||
fi
|
fi
|
||||||
done <<<"$OTHER_XCASSETS"
|
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
|
fi
|
||||||
|
|||||||
@ -1,4 +1,14 @@
|
|||||||
|
#ifdef __OBJC__
|
||||||
#import <UIKit/UIKit.h>
|
#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;
|
FOUNDATION_EXPORT double Pods_NSString_Helper_TestsVersionNumber;
|
||||||
|
|||||||
@ -1,8 +1,11 @@
|
|||||||
EMBEDDED_CONTENT_CONTAINS_SWIFT = YES
|
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO
|
||||||
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
|
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
|
||||||
LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks'
|
HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/NSString-Helper"
|
||||||
OTHER_CFLAGS = $(inherited) -iquote "$CONFIGURATION_BUILD_DIR/FBSnapshotTestCase.framework/Headers" -iquote "$CONFIGURATION_BUILD_DIR/NSString_Helper.framework/Headers"
|
LIBRARY_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/NSString-Helper"
|
||||||
OTHER_LDFLAGS = $(inherited) -framework "FBSnapshotTestCase" -framework "NSString_Helper"
|
OTHER_LDFLAGS = $(inherited) -ObjC -l"NSString-Helper"
|
||||||
OTHER_SWIFT_FLAGS = $(inherited) "-D" "COCOAPODS"
|
PODS_BUILD_DIR = ${BUILD_DIR}
|
||||||
PODS_FRAMEWORK_BUILD_PATH = $(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/Pods-NSString-Helper_Tests
|
PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
|
||||||
|
PODS_PODFILE_DIR_PATH = ${SRCROOT}/.
|
||||||
PODS_ROOT = ${SRCROOT}/Pods
|
PODS_ROOT = ${SRCROOT}/Pods
|
||||||
|
PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates
|
||||||
|
USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES
|
||||||
|
|||||||
@ -1,8 +1,11 @@
|
|||||||
EMBEDDED_CONTENT_CONTAINS_SWIFT = YES
|
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO
|
||||||
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
|
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
|
||||||
LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks'
|
HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/NSString-Helper"
|
||||||
OTHER_CFLAGS = $(inherited) -iquote "$CONFIGURATION_BUILD_DIR/FBSnapshotTestCase.framework/Headers" -iquote "$CONFIGURATION_BUILD_DIR/NSString_Helper.framework/Headers"
|
LIBRARY_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/NSString-Helper"
|
||||||
OTHER_LDFLAGS = $(inherited) -framework "FBSnapshotTestCase" -framework "NSString_Helper"
|
OTHER_LDFLAGS = $(inherited) -ObjC -l"NSString-Helper"
|
||||||
OTHER_SWIFT_FLAGS = $(inherited) "-D" "COCOAPODS"
|
PODS_BUILD_DIR = ${BUILD_DIR}
|
||||||
PODS_FRAMEWORK_BUILD_PATH = $(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/Pods-NSString-Helper_Tests
|
PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
|
||||||
|
PODS_PODFILE_DIR_PATH = ${SRCROOT}/.
|
||||||
PODS_ROOT = ${SRCROOT}/Pods
|
PODS_ROOT = ${SRCROOT}/Pods
|
||||||
|
PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates
|
||||||
|
USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES
|
||||||
|
|||||||
@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
Pod::Spec.new do |s|
|
Pod::Spec.new do |s|
|
||||||
s.name = "NSString-Helper"
|
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.summary = "NSString-Helper is usefull helper to validate email NSString"
|
||||||
s.homepage = "https://github.com/giuseppenucifora/NSString-Helper"
|
s.homepage = "https://github.com/giuseppenucifora/NSString-Helper"
|
||||||
s.license = 'MIT'
|
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.social_media_url = 'https://twitter.com/giuseppenuc'
|
||||||
s.requires_arc = true
|
s.requires_arc = true
|
||||||
|
|
||||||
|
s.ios.deployment_target = '10.0'
|
||||||
s.platform = :ios, '8.0'
|
s.platform = :ios, '10.0'
|
||||||
s.requires_arc = true
|
s.requires_arc = true
|
||||||
|
|
||||||
s.source_files = 'NSString-Helper/*.{h,m}'
|
s.source_files = 'NSString-Helper/*.{h,m}'
|
||||||
s.resource_bundles = {
|
end
|
||||||
'NSString-Helper' => ['Pod/Assets/*.png']
|
|
||||||
}
|
|
||||||
end
|
|
||||||
|
|||||||
@ -10,6 +10,8 @@
|
|||||||
|
|
||||||
@interface NSString (Helper)
|
@interface NSString (Helper)
|
||||||
|
|
||||||
|
+ (NSString *) getRandString: (int) length;
|
||||||
|
|
||||||
- (BOOL) isValidEmail;
|
- (BOOL) isValidEmail;
|
||||||
|
|
||||||
- (BOOL) isNumeric;
|
- (BOOL) isNumeric;
|
||||||
@ -20,4 +22,17 @@
|
|||||||
|
|
||||||
- (BOOL) isValidTaxCode;
|
- (BOOL) isValidTaxCode;
|
||||||
|
|
||||||
|
- (BOOL) isValidFirstnameOrLastname;
|
||||||
|
|
||||||
|
- (NSString *) md5;
|
||||||
|
|
||||||
|
- (NSString*) sha1;
|
||||||
|
|
||||||
|
- (NSString*) sha256;
|
||||||
|
|
||||||
|
- (NSString*) sha512;
|
||||||
|
|
||||||
|
- (NSString*) stringByStrippingHTML;
|
||||||
|
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|||||||
@ -7,6 +7,7 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
#import "NSString+Helper.h"
|
#import "NSString+Helper.h"
|
||||||
|
#import <CommonCrypto/CommonDigest.h>
|
||||||
|
|
||||||
@implementation NSString (Helper)
|
@implementation NSString (Helper)
|
||||||
|
|
||||||
@ -45,10 +46,9 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
- (BOOL) isValidUrl {
|
- (BOOL) isValidUrl {
|
||||||
NSString *urlRegEx =
|
|
||||||
@"(http|https)://((\\w)*|([0-9]*)|([-|_])*)+([\\.|/]((\\w)*|([0-9]*)|([-|_])*))+";
|
NSURLRequest *req = [NSURLRequest requestWithURL:[NSURL URLWithString:self]];
|
||||||
NSPredicate *urlTest = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", urlRegEx];
|
return [NSURLConnection canHandleRequest:req];
|
||||||
return [urlTest evaluateWithObject:self];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (BOOL) isValidTaxCode {
|
- (BOOL) isValidTaxCode {
|
||||||
@ -58,4 +58,101 @@
|
|||||||
return [urlTest evaluateWithObject:self];
|
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
|
@end
|
||||||
|
|||||||
@ -1 +0,0 @@
|
|||||||
Example/Pods/Pods.xcodeproj
|
|
||||||
2442
_Pods.xcodeproj/project.pbxproj
Normal file
2442
_Pods.xcodeproj/project.pbxproj
Normal file
File diff suppressed because it is too large
Load Diff
@ -7,33 +7,30 @@
|
|||||||
buildImplicitDependencies = "YES">
|
buildImplicitDependencies = "YES">
|
||||||
<BuildActionEntries>
|
<BuildActionEntries>
|
||||||
<BuildActionEntry
|
<BuildActionEntry
|
||||||
|
buildForAnalyzing = "YES"
|
||||||
buildForTesting = "YES"
|
buildForTesting = "YES"
|
||||||
buildForRunning = "YES"
|
buildForRunning = "YES"
|
||||||
buildForProfiling = "YES"
|
buildForProfiling = "YES"
|
||||||
buildForArchiving = "YES"
|
buildForArchiving = "YES">
|
||||||
buildForAnalyzing = "YES">
|
|
||||||
<BuildableReference
|
<BuildableReference
|
||||||
BuildableIdentifier = "primary"
|
BuildableIdentifier = 'primary'
|
||||||
BlueprintIdentifier = "6F621F2F34EEA2E2A05B25FA44939F5D"
|
BlueprintIdentifier = '396F09A7332B19101DE9B640'
|
||||||
BuildableName = "NSString_Helper.framework"
|
BlueprintName = 'NSString-Helper'
|
||||||
BlueprintName = "NSString-Helper"
|
ReferencedContainer = 'container:Pods.xcodeproj'
|
||||||
ReferencedContainer = "container:Pods.xcodeproj">
|
BuildableName = 'NSString_Helper.framework'>
|
||||||
</BuildableReference>
|
</BuildableReference>
|
||||||
</BuildActionEntry>
|
</BuildActionEntry>
|
||||||
</BuildActionEntries>
|
</BuildActionEntries>
|
||||||
</BuildAction>
|
</BuildAction>
|
||||||
<TestAction
|
<TestAction
|
||||||
buildConfiguration = "Debug"
|
|
||||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||||
<Testables>
|
buildConfiguration = "Debug">
|
||||||
</Testables>
|
|
||||||
<AdditionalOptions>
|
<AdditionalOptions>
|
||||||
</AdditionalOptions>
|
</AdditionalOptions>
|
||||||
</TestAction>
|
</TestAction>
|
||||||
<LaunchAction
|
<LaunchAction
|
||||||
buildConfiguration = "Debug"
|
|
||||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||||
launchStyle = "0"
|
launchStyle = "0"
|
||||||
@ -41,25 +38,17 @@
|
|||||||
ignoresPersistentStateOnLaunch = "NO"
|
ignoresPersistentStateOnLaunch = "NO"
|
||||||
debugDocumentVersioning = "YES"
|
debugDocumentVersioning = "YES"
|
||||||
debugServiceExtension = "internal"
|
debugServiceExtension = "internal"
|
||||||
|
buildConfiguration = "Debug"
|
||||||
allowLocationSimulation = "YES">
|
allowLocationSimulation = "YES">
|
||||||
<MacroExpansion>
|
|
||||||
<BuildableReference
|
|
||||||
BuildableIdentifier = "primary"
|
|
||||||
BlueprintIdentifier = "6F621F2F34EEA2E2A05B25FA44939F5D"
|
|
||||||
BuildableName = "NSString_Helper.framework"
|
|
||||||
BlueprintName = "NSString-Helper"
|
|
||||||
ReferencedContainer = "container:Pods.xcodeproj">
|
|
||||||
</BuildableReference>
|
|
||||||
</MacroExpansion>
|
|
||||||
<AdditionalOptions>
|
<AdditionalOptions>
|
||||||
</AdditionalOptions>
|
</AdditionalOptions>
|
||||||
</LaunchAction>
|
</LaunchAction>
|
||||||
<ProfileAction
|
<ProfileAction
|
||||||
buildConfiguration = "Release"
|
|
||||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
|
||||||
savedToolIdentifier = ""
|
savedToolIdentifier = ""
|
||||||
useCustomWorkingDirectory = "NO"
|
useCustomWorkingDirectory = "NO"
|
||||||
debugDocumentVersioning = "YES">
|
debugDocumentVersioning = "YES"
|
||||||
|
buildConfiguration = "Release"
|
||||||
|
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||||
</ProfileAction>
|
</ProfileAction>
|
||||||
<AnalyzeAction
|
<AnalyzeAction
|
||||||
buildConfiguration = "Debug">
|
buildConfiguration = "Debug">
|
||||||
Loading…
x
Reference in New Issue
Block a user