├── .gitignore ├── .swiftpm └── xcode │ └── package.xcworkspace │ └── contents.xcworkspacedata ├── Example ├── Example.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ ├── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ │ └── xcuserdata │ │ │ └── mehran.xcuserdatad │ │ │ └── UserInterfaceState.xcuserstate │ └── xcuserdata │ │ └── mehran.xcuserdatad │ │ └── xcschemes │ │ └── xcschememanagement.plist ├── Example.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist ├── Example │ ├── AppDelegate.swift │ ├── Assets.xcassets │ │ ├── AccentColor.colorset │ │ │ └── Contents.json │ │ ├── AppIcon.appiconset │ │ │ └── Contents.json │ │ ├── Contents.json │ │ └── Placeholder.imageset │ │ │ ├── Contents.json │ │ │ └── Placeholder.png │ ├── Base.lproj │ │ ├── LaunchScreen.storyboard │ │ └── Main.storyboard │ ├── BaseViewController.swift │ ├── Info.plist │ ├── SceneDelegate.swift │ └── ViewController.swift ├── ExampleTests │ └── ExampleTests.swift ├── ExampleUITests │ ├── ExampleUITests.swift │ └── ExampleUITestsLaunchTests.swift ├── Podfile └── Podfile.lock ├── LICENSE ├── LICENSE.md ├── Package.swift ├── README.md ├── Resource └── TopImage.png ├── SecurityKit.podspec └── SecurityKit ├── SecurityKit.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ ├── xcshareddata │ │ └── IDEWorkspaceChecks.plist │ └── xcuserdata │ │ └── mehran.xcuserdatad │ │ └── UserInterfaceState.xcuserstate └── xcuserdata │ └── mehran.xcuserdatad │ └── xcschemes │ └── xcschememanagement.plist ├── SecurityKit ├── BackgroundLayer.swift ├── JailBrokenDetection.swift ├── ReverseEngineering.swift ├── ScreenCaptureProtection.swift ├── SecurityKit.docc │ └── SecurityKit.md ├── SecurityKit.h ├── SecurityKit.swift ├── SimulatorDetection.swift ├── StringEncryption.swift ├── TestableStringEncryption.swift └── VPNChecker.swift └── SecurityKitTests └── StringEncryptionTest.swift /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by https://www.toptal.com/developers/gitignore/api/xcode,swift,cocoapods 2 | # Edit at https://www.toptal.com/developers/gitignore?templates=xcode,swift,cocoapods 3 | 4 | ### CocoaPods ### 5 | ## CocoaPods GitIgnore Template 6 | 7 | # CocoaPods - Only use to conserve bandwidth / Save time on Pushing 8 | # - Also handy if you have a large number of dependant pods 9 | # - AS PER https://guides.cocoapods.org/using/using-cocoapods.html NEVER IGNORE THE LOCK FILE 10 | Pods/ 11 | 12 | ### Swift ### 13 | # Xcode 14 | # 15 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 16 | 17 | ## User settings 18 | xcuserdata/ 19 | 20 | # OS generated files # 21 | ###################### 22 | .DS_Store 23 | .DS_Store? 24 | ._* 25 | .Spotlight-V100 26 | .Trashes 27 | ehthumbs.db 28 | Thumbs.db 29 | 30 | ## compatibility with Xcode 8 and earlier (ignoring not required starting Xcode 9) 31 | *.xcscmblueprint 32 | *.xccheckout 33 | 34 | ## compatibility with Xcode 3 and earlier (ignoring not required starting Xcode 4) 35 | build/ 36 | DerivedData/ 37 | *.moved-aside 38 | *.pbxuser 39 | !default.pbxuser 40 | *.mode1v3 41 | !default.mode1v3 42 | *.mode2v3 43 | !default.mode2v3 44 | *.perspectivev3 45 | !default.perspectivev3 46 | 47 | ## Obj-C/Swift specific 48 | *.hmap 49 | 50 | ## App packaging 51 | *.ipa 52 | *.dSYM.zip 53 | *.dSYM 54 | 55 | ## Playgrounds 56 | timeline.xctimeline 57 | playground.xcworkspace 58 | 59 | # Swift Package Manager 60 | # Add this line if you want to avoid checking in source code from Swift Package Manager dependencies. 61 | # Packages/ 62 | # Package.pins 63 | # Package.resolved 64 | # *.xcodeproj 65 | # Xcode automatically generates this directory with a .xcworkspacedata file and xcuserdata 66 | # hence it is not needed unless you have added a package configuration file to your project 67 | # .swiftpm 68 | 69 | .build/ 70 | 71 | # CocoaPods 72 | # We recommend against adding the Pods directory to your .gitignore. However 73 | # you should judge for yourself, the pros and cons are mentioned at: 74 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 75 | # Pods/ 76 | # Add this line if you want to avoid checking in source code from the Xcode workspace 77 | # *.xcworkspace 78 | 79 | # Carthage 80 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 81 | # Carthage/Checkouts 82 | 83 | Carthage/Build/ 84 | 85 | # Accio dependency management 86 | Dependencies/ 87 | .accio/ 88 | 89 | # fastlane 90 | # It is recommended to not store the screenshots in the git repo. 91 | # Instead, use fastlane to re-generate the screenshots whenever they are needed. 92 | # For more information about the recommended setup visit: 93 | # https://docs.fastlane.tools/best-practices/source-control/#source-control 94 | 95 | fastlane/report.xml 96 | fastlane/Preview.html 97 | fastlane/screenshots/**/*.png 98 | fastlane/test_output 99 | 100 | # Code Injection 101 | # After new code Injection tools there's a generated folder /iOSInjectionProject 102 | # https://github.com/johnno1962/injectionforxcode 103 | 104 | iOSInjectionProject/ 105 | 106 | ### Xcode ### 107 | 108 | ## Xcode 8 and earlier 109 | 110 | ### Xcode Patch ### 111 | *.xcodeproj/* 112 | !*.xcodeproj/project.pbxproj 113 | !*.xcodeproj/xcshareddata/ 114 | !*.xcworkspace/contents.xcworkspacedata 115 | /*.gcno 116 | **/xcshareddata/WorkspaceSettings.xcsettings 117 | 118 | # End of https://www.toptal.com/developers/gitignore/api/xcode,swift,cocoapods 119 | -------------------------------------------------------------------------------- /.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Example/Example.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 55; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 0289DE1E2881DD0300792814 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0289DE1D2881DD0300792814 /* AppDelegate.swift */; }; 11 | 0289DE202881DD0300792814 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0289DE1F2881DD0300792814 /* SceneDelegate.swift */; }; 12 | 0289DE222881DD0300792814 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0289DE212881DD0300792814 /* ViewController.swift */; }; 13 | 0289DE252881DD0300792814 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 0289DE232881DD0300792814 /* Main.storyboard */; }; 14 | 0289DE272881DD0400792814 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 0289DE262881DD0400792814 /* Assets.xcassets */; }; 15 | 0289DE2A2881DD0400792814 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 0289DE282881DD0400792814 /* LaunchScreen.storyboard */; }; 16 | 0289DE352881DD0400792814 /* ExampleTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0289DE342881DD0400792814 /* ExampleTests.swift */; }; 17 | 0289DE3F2881DD0400792814 /* ExampleUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0289DE3E2881DD0400792814 /* ExampleUITests.swift */; }; 18 | 0289DE412881DD0400792814 /* ExampleUITestsLaunchTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0289DE402881DD0400792814 /* ExampleUITestsLaunchTests.swift */; }; 19 | 02DEB9A9289267720056A67D /* BaseViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 02DEB9A8289267720056A67D /* BaseViewController.swift */; }; 20 | 6A10D1BF07FE18157AF2A2D5 /* Pods_Example_ExampleUITests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 21B3A895BAB9849D59A379DF /* Pods_Example_ExampleUITests.framework */; }; 21 | E1BBA2C38D61AB649235627C /* Pods_ExampleTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7F98F53E1CAB7FEFBD440CB6 /* Pods_ExampleTests.framework */; }; 22 | FF4207AFCD8073F72AD7E172 /* Pods_Example.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F78592B945FB0D80534ACFD7 /* Pods_Example.framework */; }; 23 | /* End PBXBuildFile section */ 24 | 25 | /* Begin PBXContainerItemProxy section */ 26 | 0289DE312881DD0400792814 /* PBXContainerItemProxy */ = { 27 | isa = PBXContainerItemProxy; 28 | containerPortal = 0289DE122881DD0300792814 /* Project object */; 29 | proxyType = 1; 30 | remoteGlobalIDString = 0289DE192881DD0300792814; 31 | remoteInfo = Example; 32 | }; 33 | 0289DE3B2881DD0400792814 /* PBXContainerItemProxy */ = { 34 | isa = PBXContainerItemProxy; 35 | containerPortal = 0289DE122881DD0300792814 /* Project object */; 36 | proxyType = 1; 37 | remoteGlobalIDString = 0289DE192881DD0300792814; 38 | remoteInfo = Example; 39 | }; 40 | /* End PBXContainerItemProxy section */ 41 | 42 | /* Begin PBXFileReference section */ 43 | 0289DE1A2881DD0300792814 /* Example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Example.app; sourceTree = BUILT_PRODUCTS_DIR; }; 44 | 0289DE1D2881DD0300792814 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 45 | 0289DE1F2881DD0300792814 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; }; 46 | 0289DE212881DD0300792814 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; 47 | 0289DE242881DD0300792814 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 48 | 0289DE262881DD0400792814 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 49 | 0289DE292881DD0400792814 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 50 | 0289DE2B2881DD0400792814 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 51 | 0289DE302881DD0400792814 /* ExampleTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = ExampleTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 52 | 0289DE342881DD0400792814 /* ExampleTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExampleTests.swift; sourceTree = ""; }; 53 | 0289DE3A2881DD0400792814 /* ExampleUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = ExampleUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 54 | 0289DE3E2881DD0400792814 /* ExampleUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExampleUITests.swift; sourceTree = ""; }; 55 | 0289DE402881DD0400792814 /* ExampleUITestsLaunchTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExampleUITestsLaunchTests.swift; sourceTree = ""; }; 56 | 02DEB9A8289267720056A67D /* BaseViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BaseViewController.swift; sourceTree = ""; }; 57 | 0A5150A0A69C20EB0A07165D /* Pods-ExampleTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ExampleTests.release.xcconfig"; path = "Target Support Files/Pods-ExampleTests/Pods-ExampleTests.release.xcconfig"; sourceTree = ""; }; 58 | 21B3A895BAB9849D59A379DF /* Pods_Example_ExampleUITests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Example_ExampleUITests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 59 | 7C75B1F0297AAD67D2D5E327 /* Pods-Example-ExampleUITests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Example-ExampleUITests.debug.xcconfig"; path = "Target Support Files/Pods-Example-ExampleUITests/Pods-Example-ExampleUITests.debug.xcconfig"; sourceTree = ""; }; 60 | 7F98F53E1CAB7FEFBD440CB6 /* Pods_ExampleTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_ExampleTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 61 | BC5A0D467B2015D8E1D2C1A0 /* Pods-ExampleTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ExampleTests.debug.xcconfig"; path = "Target Support Files/Pods-ExampleTests/Pods-ExampleTests.debug.xcconfig"; sourceTree = ""; }; 62 | CFED83672792520D6E74A09C /* Pods-Example.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Example.debug.xcconfig"; path = "Target Support Files/Pods-Example/Pods-Example.debug.xcconfig"; sourceTree = ""; }; 63 | D75A18523C6361F9E8D4B140 /* Pods-Example.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Example.release.xcconfig"; path = "Target Support Files/Pods-Example/Pods-Example.release.xcconfig"; sourceTree = ""; }; 64 | F431F3C8B35BB3B6B48C08F7 /* Pods-Example-ExampleUITests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Example-ExampleUITests.release.xcconfig"; path = "Target Support Files/Pods-Example-ExampleUITests/Pods-Example-ExampleUITests.release.xcconfig"; sourceTree = ""; }; 65 | F78592B945FB0D80534ACFD7 /* Pods_Example.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Example.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 66 | /* End PBXFileReference section */ 67 | 68 | /* Begin PBXFrameworksBuildPhase section */ 69 | 0289DE172881DD0300792814 /* Frameworks */ = { 70 | isa = PBXFrameworksBuildPhase; 71 | buildActionMask = 2147483647; 72 | files = ( 73 | FF4207AFCD8073F72AD7E172 /* Pods_Example.framework in Frameworks */, 74 | ); 75 | runOnlyForDeploymentPostprocessing = 0; 76 | }; 77 | 0289DE2D2881DD0400792814 /* Frameworks */ = { 78 | isa = PBXFrameworksBuildPhase; 79 | buildActionMask = 2147483647; 80 | files = ( 81 | E1BBA2C38D61AB649235627C /* Pods_ExampleTests.framework in Frameworks */, 82 | ); 83 | runOnlyForDeploymentPostprocessing = 0; 84 | }; 85 | 0289DE372881DD0400792814 /* Frameworks */ = { 86 | isa = PBXFrameworksBuildPhase; 87 | buildActionMask = 2147483647; 88 | files = ( 89 | 6A10D1BF07FE18157AF2A2D5 /* Pods_Example_ExampleUITests.framework in Frameworks */, 90 | ); 91 | runOnlyForDeploymentPostprocessing = 0; 92 | }; 93 | /* End PBXFrameworksBuildPhase section */ 94 | 95 | /* Begin PBXGroup section */ 96 | 0289DE112881DD0300792814 = { 97 | isa = PBXGroup; 98 | children = ( 99 | 0289DE1C2881DD0300792814 /* Example */, 100 | 0289DE332881DD0400792814 /* ExampleTests */, 101 | 0289DE3D2881DD0400792814 /* ExampleUITests */, 102 | 0289DE1B2881DD0300792814 /* Products */, 103 | E494DC055BFA568E84D9C523 /* Pods */, 104 | E5E948E22DAC42EE1C50D8DC /* Frameworks */, 105 | ); 106 | sourceTree = ""; 107 | }; 108 | 0289DE1B2881DD0300792814 /* Products */ = { 109 | isa = PBXGroup; 110 | children = ( 111 | 0289DE1A2881DD0300792814 /* Example.app */, 112 | 0289DE302881DD0400792814 /* ExampleTests.xctest */, 113 | 0289DE3A2881DD0400792814 /* ExampleUITests.xctest */, 114 | ); 115 | name = Products; 116 | sourceTree = ""; 117 | }; 118 | 0289DE1C2881DD0300792814 /* Example */ = { 119 | isa = PBXGroup; 120 | children = ( 121 | 0289DE1D2881DD0300792814 /* AppDelegate.swift */, 122 | 0289DE1F2881DD0300792814 /* SceneDelegate.swift */, 123 | 02DEB9A8289267720056A67D /* BaseViewController.swift */, 124 | 0289DE212881DD0300792814 /* ViewController.swift */, 125 | 0289DE232881DD0300792814 /* Main.storyboard */, 126 | 0289DE262881DD0400792814 /* Assets.xcassets */, 127 | 0289DE282881DD0400792814 /* LaunchScreen.storyboard */, 128 | 0289DE2B2881DD0400792814 /* Info.plist */, 129 | ); 130 | path = Example; 131 | sourceTree = ""; 132 | }; 133 | 0289DE332881DD0400792814 /* ExampleTests */ = { 134 | isa = PBXGroup; 135 | children = ( 136 | 0289DE342881DD0400792814 /* ExampleTests.swift */, 137 | ); 138 | path = ExampleTests; 139 | sourceTree = ""; 140 | }; 141 | 0289DE3D2881DD0400792814 /* ExampleUITests */ = { 142 | isa = PBXGroup; 143 | children = ( 144 | 0289DE3E2881DD0400792814 /* ExampleUITests.swift */, 145 | 0289DE402881DD0400792814 /* ExampleUITestsLaunchTests.swift */, 146 | ); 147 | path = ExampleUITests; 148 | sourceTree = ""; 149 | }; 150 | E494DC055BFA568E84D9C523 /* Pods */ = { 151 | isa = PBXGroup; 152 | children = ( 153 | CFED83672792520D6E74A09C /* Pods-Example.debug.xcconfig */, 154 | D75A18523C6361F9E8D4B140 /* Pods-Example.release.xcconfig */, 155 | 7C75B1F0297AAD67D2D5E327 /* Pods-Example-ExampleUITests.debug.xcconfig */, 156 | F431F3C8B35BB3B6B48C08F7 /* Pods-Example-ExampleUITests.release.xcconfig */, 157 | BC5A0D467B2015D8E1D2C1A0 /* Pods-ExampleTests.debug.xcconfig */, 158 | 0A5150A0A69C20EB0A07165D /* Pods-ExampleTests.release.xcconfig */, 159 | ); 160 | path = Pods; 161 | sourceTree = ""; 162 | }; 163 | E5E948E22DAC42EE1C50D8DC /* Frameworks */ = { 164 | isa = PBXGroup; 165 | children = ( 166 | F78592B945FB0D80534ACFD7 /* Pods_Example.framework */, 167 | 21B3A895BAB9849D59A379DF /* Pods_Example_ExampleUITests.framework */, 168 | 7F98F53E1CAB7FEFBD440CB6 /* Pods_ExampleTests.framework */, 169 | ); 170 | name = Frameworks; 171 | sourceTree = ""; 172 | }; 173 | /* End PBXGroup section */ 174 | 175 | /* Begin PBXNativeTarget section */ 176 | 0289DE192881DD0300792814 /* Example */ = { 177 | isa = PBXNativeTarget; 178 | buildConfigurationList = 0289DE442881DD0400792814 /* Build configuration list for PBXNativeTarget "Example" */; 179 | buildPhases = ( 180 | 1649CF15A6B3AB3B0079C6C8 /* [CP] Check Pods Manifest.lock */, 181 | 0289DE162881DD0300792814 /* Sources */, 182 | 0289DE172881DD0300792814 /* Frameworks */, 183 | 0289DE182881DD0300792814 /* Resources */, 184 | D5AF23FBF20F4E69DF00E1A8 /* [CP] Embed Pods Frameworks */, 185 | ); 186 | buildRules = ( 187 | ); 188 | dependencies = ( 189 | ); 190 | name = Example; 191 | productName = Example; 192 | productReference = 0289DE1A2881DD0300792814 /* Example.app */; 193 | productType = "com.apple.product-type.application"; 194 | }; 195 | 0289DE2F2881DD0400792814 /* ExampleTests */ = { 196 | isa = PBXNativeTarget; 197 | buildConfigurationList = 0289DE472881DD0400792814 /* Build configuration list for PBXNativeTarget "ExampleTests" */; 198 | buildPhases = ( 199 | 47DE39717B4D1EF7BDD69CB7 /* [CP] Check Pods Manifest.lock */, 200 | 0289DE2C2881DD0400792814 /* Sources */, 201 | 0289DE2D2881DD0400792814 /* Frameworks */, 202 | 0289DE2E2881DD0400792814 /* Resources */, 203 | ); 204 | buildRules = ( 205 | ); 206 | dependencies = ( 207 | 0289DE322881DD0400792814 /* PBXTargetDependency */, 208 | ); 209 | name = ExampleTests; 210 | productName = ExampleTests; 211 | productReference = 0289DE302881DD0400792814 /* ExampleTests.xctest */; 212 | productType = "com.apple.product-type.bundle.unit-test"; 213 | }; 214 | 0289DE392881DD0400792814 /* ExampleUITests */ = { 215 | isa = PBXNativeTarget; 216 | buildConfigurationList = 0289DE4A2881DD0400792814 /* Build configuration list for PBXNativeTarget "ExampleUITests" */; 217 | buildPhases = ( 218 | 7099A57A5595A7CF63419E6D /* [CP] Check Pods Manifest.lock */, 219 | 0289DE362881DD0400792814 /* Sources */, 220 | 0289DE372881DD0400792814 /* Frameworks */, 221 | 0289DE382881DD0400792814 /* Resources */, 222 | 8A5CCF52A5036C67D97BD3F8 /* [CP] Embed Pods Frameworks */, 223 | ); 224 | buildRules = ( 225 | ); 226 | dependencies = ( 227 | 0289DE3C2881DD0400792814 /* PBXTargetDependency */, 228 | ); 229 | name = ExampleUITests; 230 | productName = ExampleUITests; 231 | productReference = 0289DE3A2881DD0400792814 /* ExampleUITests.xctest */; 232 | productType = "com.apple.product-type.bundle.ui-testing"; 233 | }; 234 | /* End PBXNativeTarget section */ 235 | 236 | /* Begin PBXProject section */ 237 | 0289DE122881DD0300792814 /* Project object */ = { 238 | isa = PBXProject; 239 | attributes = { 240 | BuildIndependentTargetsInParallel = 1; 241 | LastSwiftUpdateCheck = 1330; 242 | LastUpgradeCheck = 1330; 243 | TargetAttributes = { 244 | 0289DE192881DD0300792814 = { 245 | CreatedOnToolsVersion = 13.3; 246 | LastSwiftMigration = 1330; 247 | }; 248 | 0289DE2F2881DD0400792814 = { 249 | CreatedOnToolsVersion = 13.3; 250 | TestTargetID = 0289DE192881DD0300792814; 251 | }; 252 | 0289DE392881DD0400792814 = { 253 | CreatedOnToolsVersion = 13.3; 254 | TestTargetID = 0289DE192881DD0300792814; 255 | }; 256 | }; 257 | }; 258 | buildConfigurationList = 0289DE152881DD0300792814 /* Build configuration list for PBXProject "Example" */; 259 | compatibilityVersion = "Xcode 13.0"; 260 | developmentRegion = en; 261 | hasScannedForEncodings = 0; 262 | knownRegions = ( 263 | en, 264 | Base, 265 | ); 266 | mainGroup = 0289DE112881DD0300792814; 267 | productRefGroup = 0289DE1B2881DD0300792814 /* Products */; 268 | projectDirPath = ""; 269 | projectRoot = ""; 270 | targets = ( 271 | 0289DE192881DD0300792814 /* Example */, 272 | 0289DE2F2881DD0400792814 /* ExampleTests */, 273 | 0289DE392881DD0400792814 /* ExampleUITests */, 274 | ); 275 | }; 276 | /* End PBXProject section */ 277 | 278 | /* Begin PBXResourcesBuildPhase section */ 279 | 0289DE182881DD0300792814 /* Resources */ = { 280 | isa = PBXResourcesBuildPhase; 281 | buildActionMask = 2147483647; 282 | files = ( 283 | 0289DE2A2881DD0400792814 /* LaunchScreen.storyboard in Resources */, 284 | 0289DE272881DD0400792814 /* Assets.xcassets in Resources */, 285 | 0289DE252881DD0300792814 /* Main.storyboard in Resources */, 286 | ); 287 | runOnlyForDeploymentPostprocessing = 0; 288 | }; 289 | 0289DE2E2881DD0400792814 /* Resources */ = { 290 | isa = PBXResourcesBuildPhase; 291 | buildActionMask = 2147483647; 292 | files = ( 293 | ); 294 | runOnlyForDeploymentPostprocessing = 0; 295 | }; 296 | 0289DE382881DD0400792814 /* Resources */ = { 297 | isa = PBXResourcesBuildPhase; 298 | buildActionMask = 2147483647; 299 | files = ( 300 | ); 301 | runOnlyForDeploymentPostprocessing = 0; 302 | }; 303 | /* End PBXResourcesBuildPhase section */ 304 | 305 | /* Begin PBXShellScriptBuildPhase section */ 306 | 1649CF15A6B3AB3B0079C6C8 /* [CP] Check Pods Manifest.lock */ = { 307 | isa = PBXShellScriptBuildPhase; 308 | buildActionMask = 2147483647; 309 | files = ( 310 | ); 311 | inputFileListPaths = ( 312 | ); 313 | inputPaths = ( 314 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock", 315 | "${PODS_ROOT}/Manifest.lock", 316 | ); 317 | name = "[CP] Check Pods Manifest.lock"; 318 | outputFileListPaths = ( 319 | ); 320 | outputPaths = ( 321 | "$(DERIVED_FILE_DIR)/Pods-Example-checkManifestLockResult.txt", 322 | ); 323 | runOnlyForDeploymentPostprocessing = 0; 324 | shellPath = /bin/sh; 325 | 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"; 326 | showEnvVarsInLog = 0; 327 | }; 328 | 47DE39717B4D1EF7BDD69CB7 /* [CP] Check Pods Manifest.lock */ = { 329 | isa = PBXShellScriptBuildPhase; 330 | buildActionMask = 2147483647; 331 | files = ( 332 | ); 333 | inputFileListPaths = ( 334 | ); 335 | inputPaths = ( 336 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock", 337 | "${PODS_ROOT}/Manifest.lock", 338 | ); 339 | name = "[CP] Check Pods Manifest.lock"; 340 | outputFileListPaths = ( 341 | ); 342 | outputPaths = ( 343 | "$(DERIVED_FILE_DIR)/Pods-ExampleTests-checkManifestLockResult.txt", 344 | ); 345 | runOnlyForDeploymentPostprocessing = 0; 346 | shellPath = /bin/sh; 347 | shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; 348 | showEnvVarsInLog = 0; 349 | }; 350 | 7099A57A5595A7CF63419E6D /* [CP] Check Pods Manifest.lock */ = { 351 | isa = PBXShellScriptBuildPhase; 352 | buildActionMask = 2147483647; 353 | files = ( 354 | ); 355 | inputFileListPaths = ( 356 | ); 357 | inputPaths = ( 358 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock", 359 | "${PODS_ROOT}/Manifest.lock", 360 | ); 361 | name = "[CP] Check Pods Manifest.lock"; 362 | outputFileListPaths = ( 363 | ); 364 | outputPaths = ( 365 | "$(DERIVED_FILE_DIR)/Pods-Example-ExampleUITests-checkManifestLockResult.txt", 366 | ); 367 | runOnlyForDeploymentPostprocessing = 0; 368 | shellPath = /bin/sh; 369 | 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"; 370 | showEnvVarsInLog = 0; 371 | }; 372 | 8A5CCF52A5036C67D97BD3F8 /* [CP] Embed Pods Frameworks */ = { 373 | isa = PBXShellScriptBuildPhase; 374 | buildActionMask = 2147483647; 375 | files = ( 376 | ); 377 | inputFileListPaths = ( 378 | "${PODS_ROOT}/Target Support Files/Pods-Example-ExampleUITests/Pods-Example-ExampleUITests-frameworks-${CONFIGURATION}-input-files.xcfilelist", 379 | ); 380 | name = "[CP] Embed Pods Frameworks"; 381 | outputFileListPaths = ( 382 | "${PODS_ROOT}/Target Support Files/Pods-Example-ExampleUITests/Pods-Example-ExampleUITests-frameworks-${CONFIGURATION}-output-files.xcfilelist", 383 | ); 384 | runOnlyForDeploymentPostprocessing = 0; 385 | shellPath = /bin/sh; 386 | shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Example-ExampleUITests/Pods-Example-ExampleUITests-frameworks.sh\"\n"; 387 | showEnvVarsInLog = 0; 388 | }; 389 | D5AF23FBF20F4E69DF00E1A8 /* [CP] Embed Pods Frameworks */ = { 390 | isa = PBXShellScriptBuildPhase; 391 | buildActionMask = 2147483647; 392 | files = ( 393 | ); 394 | inputFileListPaths = ( 395 | "${PODS_ROOT}/Target Support Files/Pods-Example/Pods-Example-frameworks-${CONFIGURATION}-input-files.xcfilelist", 396 | ); 397 | name = "[CP] Embed Pods Frameworks"; 398 | outputFileListPaths = ( 399 | "${PODS_ROOT}/Target Support Files/Pods-Example/Pods-Example-frameworks-${CONFIGURATION}-output-files.xcfilelist", 400 | ); 401 | runOnlyForDeploymentPostprocessing = 0; 402 | shellPath = /bin/sh; 403 | shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Example/Pods-Example-frameworks.sh\"\n"; 404 | showEnvVarsInLog = 0; 405 | }; 406 | /* End PBXShellScriptBuildPhase section */ 407 | 408 | /* Begin PBXSourcesBuildPhase section */ 409 | 0289DE162881DD0300792814 /* Sources */ = { 410 | isa = PBXSourcesBuildPhase; 411 | buildActionMask = 2147483647; 412 | files = ( 413 | 0289DE222881DD0300792814 /* ViewController.swift in Sources */, 414 | 02DEB9A9289267720056A67D /* BaseViewController.swift in Sources */, 415 | 0289DE1E2881DD0300792814 /* AppDelegate.swift in Sources */, 416 | 0289DE202881DD0300792814 /* SceneDelegate.swift in Sources */, 417 | ); 418 | runOnlyForDeploymentPostprocessing = 0; 419 | }; 420 | 0289DE2C2881DD0400792814 /* Sources */ = { 421 | isa = PBXSourcesBuildPhase; 422 | buildActionMask = 2147483647; 423 | files = ( 424 | 0289DE352881DD0400792814 /* ExampleTests.swift in Sources */, 425 | ); 426 | runOnlyForDeploymentPostprocessing = 0; 427 | }; 428 | 0289DE362881DD0400792814 /* Sources */ = { 429 | isa = PBXSourcesBuildPhase; 430 | buildActionMask = 2147483647; 431 | files = ( 432 | 0289DE3F2881DD0400792814 /* ExampleUITests.swift in Sources */, 433 | 0289DE412881DD0400792814 /* ExampleUITestsLaunchTests.swift in Sources */, 434 | ); 435 | runOnlyForDeploymentPostprocessing = 0; 436 | }; 437 | /* End PBXSourcesBuildPhase section */ 438 | 439 | /* Begin PBXTargetDependency section */ 440 | 0289DE322881DD0400792814 /* PBXTargetDependency */ = { 441 | isa = PBXTargetDependency; 442 | target = 0289DE192881DD0300792814 /* Example */; 443 | targetProxy = 0289DE312881DD0400792814 /* PBXContainerItemProxy */; 444 | }; 445 | 0289DE3C2881DD0400792814 /* PBXTargetDependency */ = { 446 | isa = PBXTargetDependency; 447 | target = 0289DE192881DD0300792814 /* Example */; 448 | targetProxy = 0289DE3B2881DD0400792814 /* PBXContainerItemProxy */; 449 | }; 450 | /* End PBXTargetDependency section */ 451 | 452 | /* Begin PBXVariantGroup section */ 453 | 0289DE232881DD0300792814 /* Main.storyboard */ = { 454 | isa = PBXVariantGroup; 455 | children = ( 456 | 0289DE242881DD0300792814 /* Base */, 457 | ); 458 | name = Main.storyboard; 459 | sourceTree = ""; 460 | }; 461 | 0289DE282881DD0400792814 /* LaunchScreen.storyboard */ = { 462 | isa = PBXVariantGroup; 463 | children = ( 464 | 0289DE292881DD0400792814 /* Base */, 465 | ); 466 | name = LaunchScreen.storyboard; 467 | sourceTree = ""; 468 | }; 469 | /* End PBXVariantGroup section */ 470 | 471 | /* Begin XCBuildConfiguration section */ 472 | 0289DE422881DD0400792814 /* Debug */ = { 473 | isa = XCBuildConfiguration; 474 | buildSettings = { 475 | ALWAYS_SEARCH_USER_PATHS = NO; 476 | CLANG_ANALYZER_NONNULL = YES; 477 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 478 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++17"; 479 | CLANG_ENABLE_MODULES = YES; 480 | CLANG_ENABLE_OBJC_ARC = YES; 481 | CLANG_ENABLE_OBJC_WEAK = YES; 482 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 483 | CLANG_WARN_BOOL_CONVERSION = YES; 484 | CLANG_WARN_COMMA = YES; 485 | CLANG_WARN_CONSTANT_CONVERSION = YES; 486 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 487 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 488 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 489 | CLANG_WARN_EMPTY_BODY = YES; 490 | CLANG_WARN_ENUM_CONVERSION = YES; 491 | CLANG_WARN_INFINITE_RECURSION = YES; 492 | CLANG_WARN_INT_CONVERSION = YES; 493 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 494 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 495 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 496 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 497 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 498 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 499 | CLANG_WARN_STRICT_PROTOTYPES = YES; 500 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 501 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 502 | CLANG_WARN_UNREACHABLE_CODE = YES; 503 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 504 | COPY_PHASE_STRIP = NO; 505 | DEBUG_INFORMATION_FORMAT = dwarf; 506 | ENABLE_STRICT_OBJC_MSGSEND = YES; 507 | ENABLE_TESTABILITY = YES; 508 | GCC_C_LANGUAGE_STANDARD = gnu11; 509 | GCC_DYNAMIC_NO_PIC = NO; 510 | GCC_NO_COMMON_BLOCKS = YES; 511 | GCC_OPTIMIZATION_LEVEL = 0; 512 | GCC_PREPROCESSOR_DEFINITIONS = ( 513 | "DEBUG=1", 514 | "$(inherited)", 515 | ); 516 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 517 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 518 | GCC_WARN_UNDECLARED_SELECTOR = YES; 519 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 520 | GCC_WARN_UNUSED_FUNCTION = YES; 521 | GCC_WARN_UNUSED_VARIABLE = YES; 522 | IPHONEOS_DEPLOYMENT_TARGET = 15.4; 523 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; 524 | MTL_FAST_MATH = YES; 525 | ONLY_ACTIVE_ARCH = YES; 526 | SDKROOT = iphoneos; 527 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 528 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 529 | }; 530 | name = Debug; 531 | }; 532 | 0289DE432881DD0400792814 /* Release */ = { 533 | isa = XCBuildConfiguration; 534 | buildSettings = { 535 | ALWAYS_SEARCH_USER_PATHS = NO; 536 | CLANG_ANALYZER_NONNULL = YES; 537 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 538 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++17"; 539 | CLANG_ENABLE_MODULES = YES; 540 | CLANG_ENABLE_OBJC_ARC = YES; 541 | CLANG_ENABLE_OBJC_WEAK = YES; 542 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 543 | CLANG_WARN_BOOL_CONVERSION = YES; 544 | CLANG_WARN_COMMA = YES; 545 | CLANG_WARN_CONSTANT_CONVERSION = YES; 546 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 547 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 548 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 549 | CLANG_WARN_EMPTY_BODY = YES; 550 | CLANG_WARN_ENUM_CONVERSION = YES; 551 | CLANG_WARN_INFINITE_RECURSION = YES; 552 | CLANG_WARN_INT_CONVERSION = YES; 553 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 554 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 555 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 556 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 557 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 558 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 559 | CLANG_WARN_STRICT_PROTOTYPES = YES; 560 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 561 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 562 | CLANG_WARN_UNREACHABLE_CODE = YES; 563 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 564 | COPY_PHASE_STRIP = NO; 565 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 566 | ENABLE_NS_ASSERTIONS = NO; 567 | ENABLE_STRICT_OBJC_MSGSEND = YES; 568 | GCC_C_LANGUAGE_STANDARD = gnu11; 569 | GCC_NO_COMMON_BLOCKS = YES; 570 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 571 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 572 | GCC_WARN_UNDECLARED_SELECTOR = YES; 573 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 574 | GCC_WARN_UNUSED_FUNCTION = YES; 575 | GCC_WARN_UNUSED_VARIABLE = YES; 576 | IPHONEOS_DEPLOYMENT_TARGET = 15.4; 577 | MTL_ENABLE_DEBUG_INFO = NO; 578 | MTL_FAST_MATH = YES; 579 | SDKROOT = iphoneos; 580 | SWIFT_COMPILATION_MODE = wholemodule; 581 | SWIFT_OPTIMIZATION_LEVEL = "-O"; 582 | VALIDATE_PRODUCT = YES; 583 | }; 584 | name = Release; 585 | }; 586 | 0289DE452881DD0400792814 /* Debug */ = { 587 | isa = XCBuildConfiguration; 588 | baseConfigurationReference = CFED83672792520D6E74A09C /* Pods-Example.debug.xcconfig */; 589 | buildSettings = { 590 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 591 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; 592 | CLANG_ENABLE_MODULES = YES; 593 | CODE_SIGN_STYLE = Automatic; 594 | CURRENT_PROJECT_VERSION = 1; 595 | DEVELOPMENT_TEAM = 3KZWVBAJSN; 596 | GENERATE_INFOPLIST_FILE = YES; 597 | INFOPLIST_FILE = Example/Info.plist; 598 | INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; 599 | INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen; 600 | INFOPLIST_KEY_UIMainStoryboardFile = Main; 601 | INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; 602 | INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; 603 | LD_RUNPATH_SEARCH_PATHS = ( 604 | "$(inherited)", 605 | "@executable_path/Frameworks", 606 | ); 607 | MARKETING_VERSION = 1.0; 608 | PRODUCT_BUNDLE_IDENTIFIER = gravityapp.Example; 609 | PRODUCT_NAME = "$(TARGET_NAME)"; 610 | SWIFT_EMIT_LOC_STRINGS = YES; 611 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 612 | SWIFT_VERSION = 5.0; 613 | TARGETED_DEVICE_FAMILY = "1,2"; 614 | }; 615 | name = Debug; 616 | }; 617 | 0289DE462881DD0400792814 /* Release */ = { 618 | isa = XCBuildConfiguration; 619 | baseConfigurationReference = D75A18523C6361F9E8D4B140 /* Pods-Example.release.xcconfig */; 620 | buildSettings = { 621 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 622 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; 623 | CLANG_ENABLE_MODULES = YES; 624 | CODE_SIGN_STYLE = Automatic; 625 | CURRENT_PROJECT_VERSION = 1; 626 | DEVELOPMENT_TEAM = 3KZWVBAJSN; 627 | GENERATE_INFOPLIST_FILE = YES; 628 | INFOPLIST_FILE = Example/Info.plist; 629 | INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; 630 | INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen; 631 | INFOPLIST_KEY_UIMainStoryboardFile = Main; 632 | INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; 633 | INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; 634 | LD_RUNPATH_SEARCH_PATHS = ( 635 | "$(inherited)", 636 | "@executable_path/Frameworks", 637 | ); 638 | MARKETING_VERSION = 1.0; 639 | PRODUCT_BUNDLE_IDENTIFIER = gravityapp.Example; 640 | PRODUCT_NAME = "$(TARGET_NAME)"; 641 | SWIFT_EMIT_LOC_STRINGS = YES; 642 | SWIFT_VERSION = 5.0; 643 | TARGETED_DEVICE_FAMILY = "1,2"; 644 | }; 645 | name = Release; 646 | }; 647 | 0289DE482881DD0400792814 /* Debug */ = { 648 | isa = XCBuildConfiguration; 649 | baseConfigurationReference = BC5A0D467B2015D8E1D2C1A0 /* Pods-ExampleTests.debug.xcconfig */; 650 | buildSettings = { 651 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 652 | BUNDLE_LOADER = "$(TEST_HOST)"; 653 | CODE_SIGN_STYLE = Automatic; 654 | CURRENT_PROJECT_VERSION = 1; 655 | DEVELOPMENT_TEAM = 3KZWVBAJSN; 656 | GENERATE_INFOPLIST_FILE = YES; 657 | IPHONEOS_DEPLOYMENT_TARGET = 15.4; 658 | MARKETING_VERSION = 1.0; 659 | PRODUCT_BUNDLE_IDENTIFIER = gravityapp.ExampleTests; 660 | PRODUCT_NAME = "$(TARGET_NAME)"; 661 | SWIFT_EMIT_LOC_STRINGS = NO; 662 | SWIFT_VERSION = 5.0; 663 | TARGETED_DEVICE_FAMILY = "1,2"; 664 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Example.app/Example"; 665 | }; 666 | name = Debug; 667 | }; 668 | 0289DE492881DD0400792814 /* Release */ = { 669 | isa = XCBuildConfiguration; 670 | baseConfigurationReference = 0A5150A0A69C20EB0A07165D /* Pods-ExampleTests.release.xcconfig */; 671 | buildSettings = { 672 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 673 | BUNDLE_LOADER = "$(TEST_HOST)"; 674 | CODE_SIGN_STYLE = Automatic; 675 | CURRENT_PROJECT_VERSION = 1; 676 | DEVELOPMENT_TEAM = 3KZWVBAJSN; 677 | GENERATE_INFOPLIST_FILE = YES; 678 | IPHONEOS_DEPLOYMENT_TARGET = 15.4; 679 | MARKETING_VERSION = 1.0; 680 | PRODUCT_BUNDLE_IDENTIFIER = gravityapp.ExampleTests; 681 | PRODUCT_NAME = "$(TARGET_NAME)"; 682 | SWIFT_EMIT_LOC_STRINGS = NO; 683 | SWIFT_VERSION = 5.0; 684 | TARGETED_DEVICE_FAMILY = "1,2"; 685 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Example.app/Example"; 686 | }; 687 | name = Release; 688 | }; 689 | 0289DE4B2881DD0400792814 /* Debug */ = { 690 | isa = XCBuildConfiguration; 691 | baseConfigurationReference = 7C75B1F0297AAD67D2D5E327 /* Pods-Example-ExampleUITests.debug.xcconfig */; 692 | buildSettings = { 693 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 694 | CODE_SIGN_STYLE = Automatic; 695 | CURRENT_PROJECT_VERSION = 1; 696 | DEVELOPMENT_TEAM = 3KZWVBAJSN; 697 | GENERATE_INFOPLIST_FILE = YES; 698 | MARKETING_VERSION = 1.0; 699 | PRODUCT_BUNDLE_IDENTIFIER = gravityapp.ExampleUITests; 700 | PRODUCT_NAME = "$(TARGET_NAME)"; 701 | SWIFT_EMIT_LOC_STRINGS = NO; 702 | SWIFT_VERSION = 5.0; 703 | TARGETED_DEVICE_FAMILY = "1,2"; 704 | TEST_TARGET_NAME = Example; 705 | }; 706 | name = Debug; 707 | }; 708 | 0289DE4C2881DD0400792814 /* Release */ = { 709 | isa = XCBuildConfiguration; 710 | baseConfigurationReference = F431F3C8B35BB3B6B48C08F7 /* Pods-Example-ExampleUITests.release.xcconfig */; 711 | buildSettings = { 712 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 713 | CODE_SIGN_STYLE = Automatic; 714 | CURRENT_PROJECT_VERSION = 1; 715 | DEVELOPMENT_TEAM = 3KZWVBAJSN; 716 | GENERATE_INFOPLIST_FILE = YES; 717 | MARKETING_VERSION = 1.0; 718 | PRODUCT_BUNDLE_IDENTIFIER = gravityapp.ExampleUITests; 719 | PRODUCT_NAME = "$(TARGET_NAME)"; 720 | SWIFT_EMIT_LOC_STRINGS = NO; 721 | SWIFT_VERSION = 5.0; 722 | TARGETED_DEVICE_FAMILY = "1,2"; 723 | TEST_TARGET_NAME = Example; 724 | }; 725 | name = Release; 726 | }; 727 | /* End XCBuildConfiguration section */ 728 | 729 | /* Begin XCConfigurationList section */ 730 | 0289DE152881DD0300792814 /* Build configuration list for PBXProject "Example" */ = { 731 | isa = XCConfigurationList; 732 | buildConfigurations = ( 733 | 0289DE422881DD0400792814 /* Debug */, 734 | 0289DE432881DD0400792814 /* Release */, 735 | ); 736 | defaultConfigurationIsVisible = 0; 737 | defaultConfigurationName = Release; 738 | }; 739 | 0289DE442881DD0400792814 /* Build configuration list for PBXNativeTarget "Example" */ = { 740 | isa = XCConfigurationList; 741 | buildConfigurations = ( 742 | 0289DE452881DD0400792814 /* Debug */, 743 | 0289DE462881DD0400792814 /* Release */, 744 | ); 745 | defaultConfigurationIsVisible = 0; 746 | defaultConfigurationName = Release; 747 | }; 748 | 0289DE472881DD0400792814 /* Build configuration list for PBXNativeTarget "ExampleTests" */ = { 749 | isa = XCConfigurationList; 750 | buildConfigurations = ( 751 | 0289DE482881DD0400792814 /* Debug */, 752 | 0289DE492881DD0400792814 /* Release */, 753 | ); 754 | defaultConfigurationIsVisible = 0; 755 | defaultConfigurationName = Release; 756 | }; 757 | 0289DE4A2881DD0400792814 /* Build configuration list for PBXNativeTarget "ExampleUITests" */ = { 758 | isa = XCConfigurationList; 759 | buildConfigurations = ( 760 | 0289DE4B2881DD0400792814 /* Debug */, 761 | 0289DE4C2881DD0400792814 /* Release */, 762 | ); 763 | defaultConfigurationIsVisible = 0; 764 | defaultConfigurationName = Release; 765 | }; 766 | /* End XCConfigurationList section */ 767 | }; 768 | rootObject = 0289DE122881DD0300792814 /* Project object */; 769 | } 770 | -------------------------------------------------------------------------------- /Example/Example.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Example/Example.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Example/Example.xcodeproj/project.xcworkspace/xcuserdata/mehran.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mehrankmlf/SecurityKit/8c2a2ae2b4f057c3007b667bf9dea65bc3f967ce/Example/Example.xcodeproj/project.xcworkspace/xcuserdata/mehran.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /Example/Example.xcodeproj/xcuserdata/mehran.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | Example.xcscheme_^#shared#^_ 8 | 9 | orderHint 10 | 4 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /Example/Example.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /Example/Example.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Example/Example/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // Example 4 | // 5 | // Created by Mehran on 4/24/1401 AP. 6 | // 7 | 8 | import UIKit 9 | 10 | @main 11 | class AppDelegate: UIResponder, UIApplicationDelegate { 12 | 13 | 14 | 15 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 16 | // Override point for customization after application launch. 17 | return true 18 | } 19 | 20 | // MARK: UISceneSession Lifecycle 21 | 22 | func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration { 23 | // Called when a new scene session is being created. 24 | // Use this method to select a configuration to create the new scene with. 25 | return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role) 26 | } 27 | 28 | func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set) { 29 | // Called when the user discards a scene session. 30 | // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions. 31 | // Use this method to release any resources that were specific to the discarded scenes, as they will not return. 32 | } 33 | 34 | 35 | } 36 | 37 | -------------------------------------------------------------------------------- /Example/Example/Assets.xcassets/AccentColor.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "idiom" : "universal" 5 | } 6 | ], 7 | "info" : { 8 | "author" : "xcode", 9 | "version" : 1 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /Example/Example/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "scale" : "2x", 6 | "size" : "20x20" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "scale" : "3x", 11 | "size" : "20x20" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "scale" : "2x", 16 | "size" : "29x29" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "scale" : "3x", 21 | "size" : "29x29" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "scale" : "2x", 26 | "size" : "40x40" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "scale" : "3x", 31 | "size" : "40x40" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "scale" : "2x", 36 | "size" : "60x60" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "scale" : "3x", 41 | "size" : "60x60" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "scale" : "1x", 46 | "size" : "20x20" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "scale" : "2x", 51 | "size" : "20x20" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "scale" : "1x", 56 | "size" : "29x29" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "scale" : "2x", 61 | "size" : "29x29" 62 | }, 63 | { 64 | "idiom" : "ipad", 65 | "scale" : "1x", 66 | "size" : "40x40" 67 | }, 68 | { 69 | "idiom" : "ipad", 70 | "scale" : "2x", 71 | "size" : "40x40" 72 | }, 73 | { 74 | "idiom" : "ipad", 75 | "scale" : "1x", 76 | "size" : "76x76" 77 | }, 78 | { 79 | "idiom" : "ipad", 80 | "scale" : "2x", 81 | "size" : "76x76" 82 | }, 83 | { 84 | "idiom" : "ipad", 85 | "scale" : "2x", 86 | "size" : "83.5x83.5" 87 | }, 88 | { 89 | "idiom" : "ios-marketing", 90 | "scale" : "1x", 91 | "size" : "1024x1024" 92 | } 93 | ], 94 | "info" : { 95 | "author" : "xcode", 96 | "version" : 1 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /Example/Example/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /Example/Example/Assets.xcassets/Placeholder.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "Placeholder.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "author" : "xcode", 19 | "version" : 1 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Example/Example/Assets.xcassets/Placeholder.imageset/Placeholder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mehrankmlf/SecurityKit/8c2a2ae2b4f057c3007b667bf9dea65bc3f967ce/Example/Example/Assets.xcassets/Placeholder.imageset/Placeholder.png -------------------------------------------------------------------------------- /Example/Example/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /Example/Example/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 36 | 42 | 43 | 44 | 45 | 46 | 47 | 53 | 59 | 60 | 61 | 62 | 63 | 64 | 70 | 76 | 77 | 78 | 79 | 80 | 81 | 87 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | -------------------------------------------------------------------------------- /Example/Example/BaseViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // BaseViewController.swift 3 | // Example 4 | // 5 | // Created by Mehran on 5/6/1401 AP. 6 | // 7 | 8 | import UIKit 9 | 10 | class BaseViewController: UIViewController { 11 | 12 | override func viewDidLoad() { 13 | super.viewDidLoad() 14 | 15 | // Do any additional setup after loading the view. 16 | } 17 | 18 | func showAlert(message : String) { 19 | // create the alert 20 | let alert = UIAlertController(title: "Alert", message: message, preferredStyle: .alert) 21 | 22 | // add an action (button) 23 | alert.addAction(UIAlertAction(title: "OK", style: UIAlertAction.Style.default, handler: nil)) 24 | 25 | // show the alert 26 | self.present(alert, animated: true, completion: nil) 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Example/Example/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | UIApplicationSceneManifest 6 | 7 | UIApplicationSupportsMultipleScenes 8 | 9 | UISceneConfigurations 10 | 11 | UIWindowSceneSessionRoleApplication 12 | 13 | 14 | UISceneConfigurationName 15 | Default Configuration 16 | UISceneDelegateClassName 17 | $(PRODUCT_MODULE_NAME).SceneDelegate 18 | UISceneStoryboardFile 19 | Main 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /Example/Example/SceneDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SceneDelegate.swift 3 | // Example 4 | // 5 | // Created by Mehran on 4/24/1401 AP. 6 | // 7 | 8 | import UIKit 9 | import SecurityKit 10 | 11 | class SceneDelegate: UIResponder, UIWindowSceneDelegate { 12 | 13 | var window: UIWindow? 14 | 15 | 16 | func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { 17 | // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`. 18 | // If using a storyboard, the `window` property will automatically be initialized and attached to the scene. 19 | // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead). 20 | guard let _ = (scene as? UIWindowScene) else { return } 21 | } 22 | 23 | func sceneDidDisconnect(_ scene: UIScene) { 24 | // Called as the scene is being released by the system. 25 | // This occurs shortly after the scene enters the background, or when its session is discarded. 26 | // Release any resources associated with this scene that can be re-created the next time the scene connects. 27 | // The scene may re-connect later, as its session was not necessarily discarded (see `application:didDiscardSceneSessions` instead). 28 | } 29 | 30 | func sceneDidBecomeActive(_ scene: UIScene) { 31 | // Called when the scene has moved from an inactive state to an active state. 32 | // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive. 33 | SecurityKit.removeSecureScreenShot(window: &window) 34 | } 35 | 36 | func sceneWillResignActive(_ scene: UIScene) { 37 | // Called when the scene will move from an active state to an inactive state. 38 | // This may occur due to temporary interruptions (ex. an incoming phone call). 39 | guard let image = UIImage(named: "Placeholder") else {return} 40 | SecurityKit.createSecureScreenShot(window: window, image: image) 41 | } 42 | 43 | func sceneWillEnterForeground(_ scene: UIScene) { 44 | // Called as the scene transitions from the background to the foreground. 45 | // Use this method to undo the changes made on entering the background. 46 | } 47 | 48 | func sceneDidEnterBackground(_ scene: UIScene) { 49 | // Called as the scene transitions from the foreground to the background. 50 | // Use this method to save data, release shared resources, and store enough scene-specific state information 51 | // to restore the scene back to its current state. 52 | } 53 | 54 | 55 | } 56 | 57 | -------------------------------------------------------------------------------- /Example/Example/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // Example 4 | // 5 | // Created by Mehran on 4/24/1401 AP. 6 | // 7 | 8 | import UIKit 9 | import SecurityKit 10 | 11 | class ViewController: BaseViewController { 12 | 13 | @IBOutlet weak var lblJailBroken: UILabel! 14 | @IBOutlet weak var lblReverseEngineering: UILabel! 15 | @IBOutlet weak var lblDeviceisSimulator: UILabel! 16 | @IBOutlet weak var lblVPNActivate: UILabel! 17 | 18 | override func viewDidLoad() { 19 | super.viewDidLoad() 20 | self.checkJailBrokenDevice() 21 | self.checkReverseEngineering() 22 | self.checkSimulator() 23 | self.checkVPNActivate() 24 | 25 | ScreenCaptureProtection.shared.makeProtection(for: self.view) 26 | 27 | self.makaStringObfuscate() 28 | } 29 | 30 | private func checkJailBrokenDevice() { 31 | if SecurityKit.isDeviceJailBroken() { 32 | lblJailBroken.text = "YES" 33 | }else{ 34 | lblJailBroken.text = "NO" 35 | } 36 | } 37 | 38 | private func checkReverseEngineering() { 39 | if SecurityKit.isReverseEngineeringToolsExecuted() { 40 | lblReverseEngineering.text = "YES" 41 | }else{ 42 | lblReverseEngineering.text = "NO" 43 | } 44 | } 45 | 46 | private func checkSimulator() { 47 | if SecurityKit.isDeviceSimulator() { 48 | lblDeviceisSimulator.text = "YES" 49 | }else{ 50 | lblDeviceisSimulator.text = "NO" 51 | } 52 | } 53 | 54 | private func checkVPNActivate() { 55 | if SecurityKit.isVPNConnected() { 56 | lblVPNActivate.text = "YES" 57 | }else{ 58 | lblVPNActivate.text = "NO" 59 | } 60 | } 61 | 62 | private func makaStringObfuscate() { 63 | let plainText = "PlainText" 64 | let key = "key" 65 | 66 | let encrypt = SecurityKit.stringEncryption(plainText: plainText, encryptionKey: key) 67 | 68 | print(encrypt) 69 | 70 | let decrypt = SecurityKit.stringDecryption(cypherText: encrypt, decryptionKey: key) 71 | 72 | print(decrypt) 73 | } 74 | } 75 | 76 | -------------------------------------------------------------------------------- /Example/ExampleTests/ExampleTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ExampleTests.swift 3 | // ExampleTests 4 | // 5 | // Created by Mehran on 4/24/1401 AP. 6 | // 7 | 8 | import XCTest 9 | @testable import Example 10 | 11 | class ExampleTests: XCTestCase { 12 | 13 | override func setUpWithError() throws { 14 | // Put setup code here. This method is called before the invocation of each test method in the class. 15 | } 16 | 17 | override func tearDownWithError() throws { 18 | // Put teardown code here. This method is called after the invocation of each test method in the class. 19 | } 20 | 21 | func testExample() throws { 22 | // This is an example of a functional test case. 23 | // Use XCTAssert and related functions to verify your tests produce the correct results. 24 | // Any test you write for XCTest can be annotated as throws and async. 25 | // Mark your test throws to produce an unexpected failure when your test encounters an uncaught error. 26 | // Mark your test async to allow awaiting for asynchronous code to complete. Check the results with assertions afterwards. 27 | } 28 | 29 | func testPerformanceExample() throws { 30 | // This is an example of a performance test case. 31 | self.measure { 32 | // Put the code you want to measure the time of here. 33 | } 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /Example/ExampleUITests/ExampleUITests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ExampleUITests.swift 3 | // ExampleUITests 4 | // 5 | // Created by Mehran on 4/24/1401 AP. 6 | // 7 | 8 | import XCTest 9 | 10 | class ExampleUITests: XCTestCase { 11 | 12 | override func setUpWithError() throws { 13 | // Put setup code here. This method is called before the invocation of each test method in the class. 14 | 15 | // In UI tests it is usually best to stop immediately when a failure occurs. 16 | continueAfterFailure = false 17 | 18 | // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this. 19 | } 20 | 21 | override func tearDownWithError() throws { 22 | // Put teardown code here. This method is called after the invocation of each test method in the class. 23 | } 24 | 25 | func testExample() throws { 26 | // UI tests must launch the application that they test. 27 | let app = XCUIApplication() 28 | app.launch() 29 | 30 | // Use XCTAssert and related functions to verify your tests produce the correct results. 31 | } 32 | 33 | func testLaunchPerformance() throws { 34 | if #available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 7.0, *) { 35 | // This measures how long it takes to launch your application. 36 | measure(metrics: [XCTApplicationLaunchMetric()]) { 37 | XCUIApplication().launch() 38 | } 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /Example/ExampleUITests/ExampleUITestsLaunchTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ExampleUITestsLaunchTests.swift 3 | // ExampleUITests 4 | // 5 | // Created by Mehran on 4/24/1401 AP. 6 | // 7 | 8 | import XCTest 9 | 10 | class ExampleUITestsLaunchTests: XCTestCase { 11 | 12 | override class var runsForEachTargetApplicationUIConfiguration: Bool { 13 | true 14 | } 15 | 16 | override func setUpWithError() throws { 17 | continueAfterFailure = false 18 | } 19 | 20 | func testLaunch() throws { 21 | let app = XCUIApplication() 22 | app.launch() 23 | 24 | // Insert steps here to perform after app launch but before taking a screenshot, 25 | // such as logging into a test account or navigating somewhere in the app 26 | 27 | let attachment = XCTAttachment(screenshot: app.screenshot()) 28 | attachment.name = "Launch Screen" 29 | attachment.lifetime = .keepAlways 30 | add(attachment) 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /Example/Podfile: -------------------------------------------------------------------------------- 1 | # Uncomment the next line to define a global platform for your project 2 | # platform :ios, '9.0' 3 | 4 | target 'Example' do 5 | # Comment the next line if you don't want to use dynamic frameworks 6 | use_frameworks! 7 | 8 | # Pods for Example 9 | 10 | pod 'SecurityKit', :path => '../' 11 | 12 | target 'ExampleTests' do 13 | inherit! :search_paths 14 | # Pods for testing 15 | end 16 | 17 | target 'ExampleUITests' do 18 | # Pods for testing 19 | end 20 | 21 | end 22 | -------------------------------------------------------------------------------- /Example/Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - SecurityKit (1.0.3) 3 | 4 | DEPENDENCIES: 5 | - SecurityKit (from `../`) 6 | 7 | EXTERNAL SOURCES: 8 | SecurityKit: 9 | :path: "../" 10 | 11 | SPEC CHECKSUMS: 12 | SecurityKit: 85ef0d59759701b5cfe111ed23f3f45071974cc5 13 | 14 | PODFILE CHECKSUM: 1d02dc804be3aff50268d847013a14a3783a604e 15 | 16 | COCOAPODS: 1.12.0 17 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 Mehran Kamalifard 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 Mehran Kamalifard 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Package.swift: -------------------------------------------------------------------------------- 1 | // swift-tools-version:5.7 2 | // The swift-tools-version declares the minimum version of Swift required to build this package. 3 | 4 | // Package.swift 5 | // SecurityKit 6 | // 7 | // Created by Steven Woolgar on 04/02/2023. 8 | // Copyright © 2023 Mehran Kamalifard. All rights reserved. 9 | // 10 | 11 | import PackageDescription 12 | 13 | let package = Package( 14 | name: "SecurityKit", 15 | defaultLocalization: "en", 16 | platforms: [.iOS(.v12)], 17 | 18 | products: [.library(name: "SecurityKit", targets: ["SecurityKit"])], 19 | targets: [ 20 | .target( 21 | name: "SecurityKit", 22 | path: "SecurityKit/SecurityKit", 23 | exclude: ["SecurityKit.docc"] 24 | ) 25 | ], 26 | 27 | swiftLanguageVersions: [.v5] 28 | ) 29 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 | SecurityKit 3 |

4 | 5 | ## Security Kit 6 | 7 |

8 | 9 | Security Kit is a lightweight framework that helps to achieve a security layer 10 | 11 |

12 | 13 |

14 | • Example 15 | • Usage 16 | • Installation 17 | • License 18 |

19 | 20 | ## Example 21 | 22 | To run the example project, run `pod try SecurityKit` 23 | 24 | ## Features 25 | 26 | - [x] JailBroken Device Detection 27 | - [x] Security Background Layer 28 | - [x] Detect Reverse Engineering Tools Executed. 29 | - [x] Check Device is a Simulator or a Real Device. 30 | - [x] Check VPN is running. 31 | - [x] Screen Capture Protection. 32 | - [x] Obfuscate Sensitive String with XOR Data Encryption Algorithm. 33 | 34 | ### Requirements 35 | 36 | | Language | Branch | Pod version | Xcode version | iOS version | 37 | | --------- | ------ | ----------- | ------------- | ----------- | 38 | | Swift 5.0 | [master](https://github.com/mehrankmlf/SecurityKit/tree/master) | >= 1.0.x | Xcode 10+ | iOS 12.0+ | 39 | 40 | ### CocoaPods 41 | 42 | [CocoaPods](http://cocoapods.org) is a dependency manager for Cocoa projects. You can install it with the following command: 43 | 44 | ```bash 45 | $ gem install cocoapods 46 | ``` 47 | 48 | To integrate SecurityKit into your Xcode project using CocoaPods, specify it in your `Podfile`: 49 | 50 | ```ruby 51 | source 'https://github.com/CocoaPods/Specs.git' 52 | platform :ios, '11.0' 53 | use_frameworks! 54 | 55 | target '' do 56 | pod 'SecurityKit' 57 | end 58 | ``` 59 | 60 | Then, run the following command: 61 | 62 | ```bash 63 | $ pod install 64 | ``` 65 | ## Installation 66 | 67 | ### CocoaPods 68 | 69 | ```ruby 70 | pod 'SecurityKit' 71 | ``` 72 | 73 | ## Usage 74 | 75 | ## JailBroken Device Deteaction 76 | 77 | ```swift 78 | 79 | import SecurityKit 80 | 81 | if SecurityKit.isDeviceJailBroken() { 82 | // Do Something 83 | }else{ 84 | // Do Something 85 | } 86 | 87 | ``` 88 | 89 | ### Check Device is Simulator 90 | 91 | ```swift 92 | 93 | import SecurityKit 94 | 95 | if SecurityKit.isDeviceSimulator() { 96 | // Do Something 97 | }else{ 98 | // Do Something 99 | } 100 | 101 | ``` 102 | 103 | ### Reverse Engineering Tools 104 | 105 | ```swift 106 | 107 | import SecurityKit 108 | 109 | if SecurityKit.isRevereseEngineeringToolsExecuted() { 110 | // Do Something 111 | }else{ 112 | // Do Something 113 | } 114 | 115 | ``` 116 | 117 | ### Check VPN Runs 118 | 119 | ```swift 120 | 121 | import SecurityKit 122 | 123 | if SecurityKit.isVPNConnected() { 124 | // Do Something 125 | }else{ 126 | // Do Something 127 | } 128 | 129 | ``` 130 | 131 | ### Security Screen Capture 132 | 133 | ```swift 134 | 135 | import SecurityKit 136 | 137 | override func viewDidLoad() { 138 | super.viewDidLoad() 139 | ScreenCaptureProtection.shared.makeProtection(for: self.view) 140 | } 141 | 142 | override func viewWillAppear(_ animated: Bool) { 143 | super.viewWillAppear(false) 144 | ScreenCaptureProtection.shared.removeScreenProtection(for: self.view) 145 | } 146 | 147 | ``` 148 | 149 | ### Security Background Layer 150 | 151 | ```swift 152 | 153 | import SecurityKit 154 | 155 | var window: UIWindow? 156 | 157 | func sceneWillResignActive(_ scene: UIScene) { 158 | // Called when the scene will move from an active state to an inactive state. 159 | // This may occur due to temporary interruptions (ex. an incoming phone call). 160 | 161 | guard let image = UIImage(named: "Placeholder") else {return} 162 | SecurityKit.createSecureScreenShot(window: window, image: image) 163 | } 164 | 165 | func sceneDidBecomeActive(_ scene: UIScene) { 166 | // Called when the scene has moved from an inactive state to an active state. 167 | // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive. 168 | 169 | SecurityKit.removeSecureScreenShot(window: &window) 170 | } 171 | 172 | ``` 173 | 174 | ### XOR String obfuscation 175 | 176 | ```swift 177 | 178 | import SecurityKit 179 | 180 | // String Encryption 181 | let encrypt = SecurityKit.stringEncryption(plainText: "plainText", encryptionKey: "key") 182 | 183 | // String Decryption 184 | let decrypt = SecurityKit.stringDecryption(cypherText: encrypt, decryptionKey: key) 185 | 186 | ``` 187 | ## License 188 | 189 | SecurityKit is available under the MIT license. See the [LICENSE](LICENSE) file for more info. 190 | -------------------------------------------------------------------------------- /Resource/TopImage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mehrankmlf/SecurityKit/8c2a2ae2b4f057c3007b667bf9dea65bc3f967ce/Resource/TopImage.png -------------------------------------------------------------------------------- /SecurityKit.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |spec| 2 | 3 | spec.name = "SecurityKit" 4 | spec.version = "1.0.3" 5 | spec.summary = "SecurityKit is a security framework for iOS." 6 | # spec.description = "SecurityKit is a security framework for iOS." 7 | 8 | spec.homepage = "https://github.com/mehrankmlf/SecurityKit" 9 | 10 | spec.license = "MIT" 11 | 12 | 13 | spec.author = { "Mehran Kamalifard" => "mehran.kmlf@icloud.com" } 14 | spec.social_media_url = "https://www.linkedin.com/in/mehran-kamalifard/" 15 | 16 | spec.platform = :ios, "12.0" 17 | 18 | spec.source = { :git => "https://github.com/mehrankmlf/SecurityKit.git", :tag => spec.version.to_s } 19 | 20 | spec.source_files = "SecurityKit/SecurityKit/*.{h,m,swift}" 21 | spec.swift_version = "5.0" 22 | 23 | end 24 | -------------------------------------------------------------------------------- /SecurityKit/SecurityKit.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 55; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 0203EAF728661D9300A2E7A2 /* SecurityKit.docc in Sources */ = {isa = PBXBuildFile; fileRef = 0203EAF628661D9300A2E7A2 /* SecurityKit.docc */; }; 11 | 0203EAFD28661D9300A2E7A2 /* SecurityKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0203EAF228661D9300A2E7A2 /* SecurityKit.framework */; }; 12 | 0203EB0328661D9300A2E7A2 /* SecurityKit.h in Headers */ = {isa = PBXBuildFile; fileRef = 0203EAF528661D9300A2E7A2 /* SecurityKit.h */; settings = {ATTRIBUTES = (Public, ); }; }; 13 | 0203EB0D28661F8D00A2E7A2 /* JailBrokenDetection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0203EB0C28661F8D00A2E7A2 /* JailBrokenDetection.swift */; }; 14 | 0219951D286A0F73001830A2 /* BackgroundLayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0219951C286A0F73001830A2 /* BackgroundLayer.swift */; }; 15 | 02341F6F28C7AE94001E05C5 /* StringEncryption.swift in Sources */ = {isa = PBXBuildFile; fileRef = 02341F6E28C7AE94001E05C5 /* StringEncryption.swift */; }; 16 | 0234CA7A28CB744800AC66A3 /* StringEncryptionTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0234CA7928CB744800AC66A3 /* StringEncryptionTest.swift */; }; 17 | 0234CA8128CB8CD500AC66A3 /* TestableStringEncryption.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0234CA7E28CB84F800AC66A3 /* TestableStringEncryption.swift */; }; 18 | 023E1CF0286ED94100061EB4 /* SecurityKit.swift in Sources */ = {isa = PBXBuildFile; fileRef = 023E1CEF286ED94100061EB4 /* SecurityKit.swift */; }; 19 | 0247D85A2868B07200D57EFE /* SimulatorDetection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0247D8592868B07200D57EFE /* SimulatorDetection.swift */; }; 20 | 0247D85C2868BE4100D57EFE /* ReverseEngineering.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0247D85B2868BE4100D57EFE /* ReverseEngineering.swift */; }; 21 | 025683C8289AD7570029BC78 /* ScreenCaptureProtection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 025683C7289AD7570029BC78 /* ScreenCaptureProtection.swift */; }; 22 | 02E953CF2868DD35002929FF /* VPNChecker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 02E953CE2868DD35002929FF /* VPNChecker.swift */; }; 23 | /* End PBXBuildFile section */ 24 | 25 | /* Begin PBXContainerItemProxy section */ 26 | 0203EAFE28661D9300A2E7A2 /* PBXContainerItemProxy */ = { 27 | isa = PBXContainerItemProxy; 28 | containerPortal = 0203EAE928661D9300A2E7A2 /* Project object */; 29 | proxyType = 1; 30 | remoteGlobalIDString = 0203EAF128661D9300A2E7A2; 31 | remoteInfo = SecurityKit; 32 | }; 33 | /* End PBXContainerItemProxy section */ 34 | 35 | /* Begin PBXFileReference section */ 36 | 0203EAF228661D9300A2E7A2 /* SecurityKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SecurityKit.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 37 | 0203EAF528661D9300A2E7A2 /* SecurityKit.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SecurityKit.h; sourceTree = ""; }; 38 | 0203EAF628661D9300A2E7A2 /* SecurityKit.docc */ = {isa = PBXFileReference; lastKnownFileType = folder.documentationcatalog; path = SecurityKit.docc; sourceTree = ""; }; 39 | 0203EAFC28661D9300A2E7A2 /* SecurityKitTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SecurityKitTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 40 | 0203EB0C28661F8D00A2E7A2 /* JailBrokenDetection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JailBrokenDetection.swift; sourceTree = ""; }; 41 | 0219951C286A0F73001830A2 /* BackgroundLayer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BackgroundLayer.swift; sourceTree = ""; }; 42 | 02341F6E28C7AE94001E05C5 /* StringEncryption.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StringEncryption.swift; sourceTree = ""; }; 43 | 0234CA7928CB744800AC66A3 /* StringEncryptionTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StringEncryptionTest.swift; sourceTree = ""; }; 44 | 0234CA7E28CB84F800AC66A3 /* TestableStringEncryption.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TestableStringEncryption.swift; sourceTree = ""; }; 45 | 023E1CEF286ED94100061EB4 /* SecurityKit.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecurityKit.swift; sourceTree = ""; }; 46 | 0247D8592868B07200D57EFE /* SimulatorDetection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SimulatorDetection.swift; sourceTree = ""; }; 47 | 0247D85B2868BE4100D57EFE /* ReverseEngineering.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReverseEngineering.swift; sourceTree = ""; }; 48 | 025683C7289AD7570029BC78 /* ScreenCaptureProtection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScreenCaptureProtection.swift; sourceTree = ""; }; 49 | 02E953CE2868DD35002929FF /* VPNChecker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPNChecker.swift; sourceTree = ""; }; 50 | /* End PBXFileReference section */ 51 | 52 | /* Begin PBXFrameworksBuildPhase section */ 53 | 0203EAEF28661D9300A2E7A2 /* Frameworks */ = { 54 | isa = PBXFrameworksBuildPhase; 55 | buildActionMask = 2147483647; 56 | files = ( 57 | ); 58 | runOnlyForDeploymentPostprocessing = 0; 59 | }; 60 | 0203EAF928661D9300A2E7A2 /* Frameworks */ = { 61 | isa = PBXFrameworksBuildPhase; 62 | buildActionMask = 2147483647; 63 | files = ( 64 | 0203EAFD28661D9300A2E7A2 /* SecurityKit.framework in Frameworks */, 65 | ); 66 | runOnlyForDeploymentPostprocessing = 0; 67 | }; 68 | /* End PBXFrameworksBuildPhase section */ 69 | 70 | /* Begin PBXGroup section */ 71 | 0203EAE828661D9300A2E7A2 = { 72 | isa = PBXGroup; 73 | children = ( 74 | 0203EAF428661D9300A2E7A2 /* SecurityKit */, 75 | 0203EB0028661D9300A2E7A2 /* SecurityKitTests */, 76 | 0203EAF328661D9300A2E7A2 /* Products */, 77 | ); 78 | sourceTree = ""; 79 | }; 80 | 0203EAF328661D9300A2E7A2 /* Products */ = { 81 | isa = PBXGroup; 82 | children = ( 83 | 0203EAF228661D9300A2E7A2 /* SecurityKit.framework */, 84 | 0203EAFC28661D9300A2E7A2 /* SecurityKitTests.xctest */, 85 | ); 86 | name = Products; 87 | sourceTree = ""; 88 | }; 89 | 0203EAF428661D9300A2E7A2 /* SecurityKit */ = { 90 | isa = PBXGroup; 91 | children = ( 92 | 0203EAF528661D9300A2E7A2 /* SecurityKit.h */, 93 | 0203EAF628661D9300A2E7A2 /* SecurityKit.docc */, 94 | 0203EB0C28661F8D00A2E7A2 /* JailBrokenDetection.swift */, 95 | 0247D8592868B07200D57EFE /* SimulatorDetection.swift */, 96 | 0247D85B2868BE4100D57EFE /* ReverseEngineering.swift */, 97 | 02E953CE2868DD35002929FF /* VPNChecker.swift */, 98 | 0219951C286A0F73001830A2 /* BackgroundLayer.swift */, 99 | 023E1CEF286ED94100061EB4 /* SecurityKit.swift */, 100 | 025683C7289AD7570029BC78 /* ScreenCaptureProtection.swift */, 101 | 02341F6E28C7AE94001E05C5 /* StringEncryption.swift */, 102 | 0234CA7E28CB84F800AC66A3 /* TestableStringEncryption.swift */, 103 | ); 104 | path = SecurityKit; 105 | sourceTree = ""; 106 | }; 107 | 0203EB0028661D9300A2E7A2 /* SecurityKitTests */ = { 108 | isa = PBXGroup; 109 | children = ( 110 | 0234CA7928CB744800AC66A3 /* StringEncryptionTest.swift */, 111 | ); 112 | path = SecurityKitTests; 113 | sourceTree = ""; 114 | }; 115 | /* End PBXGroup section */ 116 | 117 | /* Begin PBXHeadersBuildPhase section */ 118 | 0203EAED28661D9300A2E7A2 /* Headers */ = { 119 | isa = PBXHeadersBuildPhase; 120 | buildActionMask = 2147483647; 121 | files = ( 122 | 0203EB0328661D9300A2E7A2 /* SecurityKit.h in Headers */, 123 | ); 124 | runOnlyForDeploymentPostprocessing = 0; 125 | }; 126 | /* End PBXHeadersBuildPhase section */ 127 | 128 | /* Begin PBXNativeTarget section */ 129 | 0203EAF128661D9300A2E7A2 /* SecurityKit */ = { 130 | isa = PBXNativeTarget; 131 | buildConfigurationList = 0203EB0628661D9300A2E7A2 /* Build configuration list for PBXNativeTarget "SecurityKit" */; 132 | buildPhases = ( 133 | 0203EAED28661D9300A2E7A2 /* Headers */, 134 | 0203EAEE28661D9300A2E7A2 /* Sources */, 135 | 0203EAEF28661D9300A2E7A2 /* Frameworks */, 136 | 0203EAF028661D9300A2E7A2 /* Resources */, 137 | ); 138 | buildRules = ( 139 | ); 140 | dependencies = ( 141 | ); 142 | name = SecurityKit; 143 | productName = SecurityKit; 144 | productReference = 0203EAF228661D9300A2E7A2 /* SecurityKit.framework */; 145 | productType = "com.apple.product-type.framework"; 146 | }; 147 | 0203EAFB28661D9300A2E7A2 /* SecurityKitTests */ = { 148 | isa = PBXNativeTarget; 149 | buildConfigurationList = 0203EB0928661D9300A2E7A2 /* Build configuration list for PBXNativeTarget "SecurityKitTests" */; 150 | buildPhases = ( 151 | 0203EAF828661D9300A2E7A2 /* Sources */, 152 | 0203EAF928661D9300A2E7A2 /* Frameworks */, 153 | 0203EAFA28661D9300A2E7A2 /* Resources */, 154 | ); 155 | buildRules = ( 156 | ); 157 | dependencies = ( 158 | 0203EAFF28661D9300A2E7A2 /* PBXTargetDependency */, 159 | ); 160 | name = SecurityKitTests; 161 | productName = SecurityKitTests; 162 | productReference = 0203EAFC28661D9300A2E7A2 /* SecurityKitTests.xctest */; 163 | productType = "com.apple.product-type.bundle.unit-test"; 164 | }; 165 | /* End PBXNativeTarget section */ 166 | 167 | /* Begin PBXProject section */ 168 | 0203EAE928661D9300A2E7A2 /* Project object */ = { 169 | isa = PBXProject; 170 | attributes = { 171 | BuildIndependentTargetsInParallel = 1; 172 | LastSwiftUpdateCheck = 1330; 173 | LastUpgradeCheck = 1330; 174 | TargetAttributes = { 175 | 0203EAF128661D9300A2E7A2 = { 176 | CreatedOnToolsVersion = 13.3; 177 | }; 178 | 0203EAFB28661D9300A2E7A2 = { 179 | CreatedOnToolsVersion = 13.3; 180 | }; 181 | }; 182 | }; 183 | buildConfigurationList = 0203EAEC28661D9300A2E7A2 /* Build configuration list for PBXProject "SecurityKit" */; 184 | compatibilityVersion = "Xcode 13.0"; 185 | developmentRegion = en; 186 | hasScannedForEncodings = 0; 187 | knownRegions = ( 188 | en, 189 | Base, 190 | ); 191 | mainGroup = 0203EAE828661D9300A2E7A2; 192 | productRefGroup = 0203EAF328661D9300A2E7A2 /* Products */; 193 | projectDirPath = ""; 194 | projectRoot = ""; 195 | targets = ( 196 | 0203EAF128661D9300A2E7A2 /* SecurityKit */, 197 | 0203EAFB28661D9300A2E7A2 /* SecurityKitTests */, 198 | ); 199 | }; 200 | /* End PBXProject section */ 201 | 202 | /* Begin PBXResourcesBuildPhase section */ 203 | 0203EAF028661D9300A2E7A2 /* Resources */ = { 204 | isa = PBXResourcesBuildPhase; 205 | buildActionMask = 2147483647; 206 | files = ( 207 | ); 208 | runOnlyForDeploymentPostprocessing = 0; 209 | }; 210 | 0203EAFA28661D9300A2E7A2 /* Resources */ = { 211 | isa = PBXResourcesBuildPhase; 212 | buildActionMask = 2147483647; 213 | files = ( 214 | ); 215 | runOnlyForDeploymentPostprocessing = 0; 216 | }; 217 | /* End PBXResourcesBuildPhase section */ 218 | 219 | /* Begin PBXSourcesBuildPhase section */ 220 | 0203EAEE28661D9300A2E7A2 /* Sources */ = { 221 | isa = PBXSourcesBuildPhase; 222 | buildActionMask = 2147483647; 223 | files = ( 224 | 0247D85A2868B07200D57EFE /* SimulatorDetection.swift in Sources */, 225 | 0219951D286A0F73001830A2 /* BackgroundLayer.swift in Sources */, 226 | 02341F6F28C7AE94001E05C5 /* StringEncryption.swift in Sources */, 227 | 0203EAF728661D9300A2E7A2 /* SecurityKit.docc in Sources */, 228 | 025683C8289AD7570029BC78 /* ScreenCaptureProtection.swift in Sources */, 229 | 0234CA8128CB8CD500AC66A3 /* TestableStringEncryption.swift in Sources */, 230 | 02E953CF2868DD35002929FF /* VPNChecker.swift in Sources */, 231 | 023E1CF0286ED94100061EB4 /* SecurityKit.swift in Sources */, 232 | 0247D85C2868BE4100D57EFE /* ReverseEngineering.swift in Sources */, 233 | 0203EB0D28661F8D00A2E7A2 /* JailBrokenDetection.swift in Sources */, 234 | ); 235 | runOnlyForDeploymentPostprocessing = 0; 236 | }; 237 | 0203EAF828661D9300A2E7A2 /* Sources */ = { 238 | isa = PBXSourcesBuildPhase; 239 | buildActionMask = 2147483647; 240 | files = ( 241 | 0234CA7A28CB744800AC66A3 /* StringEncryptionTest.swift in Sources */, 242 | ); 243 | runOnlyForDeploymentPostprocessing = 0; 244 | }; 245 | /* End PBXSourcesBuildPhase section */ 246 | 247 | /* Begin PBXTargetDependency section */ 248 | 0203EAFF28661D9300A2E7A2 /* PBXTargetDependency */ = { 249 | isa = PBXTargetDependency; 250 | target = 0203EAF128661D9300A2E7A2 /* SecurityKit */; 251 | targetProxy = 0203EAFE28661D9300A2E7A2 /* PBXContainerItemProxy */; 252 | }; 253 | /* End PBXTargetDependency section */ 254 | 255 | /* Begin XCBuildConfiguration section */ 256 | 0203EB0428661D9300A2E7A2 /* Debug */ = { 257 | isa = XCBuildConfiguration; 258 | buildSettings = { 259 | ALWAYS_SEARCH_USER_PATHS = NO; 260 | CLANG_ANALYZER_NONNULL = YES; 261 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 262 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++17"; 263 | CLANG_ENABLE_MODULES = YES; 264 | CLANG_ENABLE_OBJC_ARC = YES; 265 | CLANG_ENABLE_OBJC_WEAK = YES; 266 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 267 | CLANG_WARN_BOOL_CONVERSION = YES; 268 | CLANG_WARN_COMMA = YES; 269 | CLANG_WARN_CONSTANT_CONVERSION = YES; 270 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 271 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 272 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 273 | CLANG_WARN_EMPTY_BODY = YES; 274 | CLANG_WARN_ENUM_CONVERSION = YES; 275 | CLANG_WARN_INFINITE_RECURSION = YES; 276 | CLANG_WARN_INT_CONVERSION = YES; 277 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 278 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 279 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 280 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 281 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 282 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 283 | CLANG_WARN_STRICT_PROTOTYPES = YES; 284 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 285 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 286 | CLANG_WARN_UNREACHABLE_CODE = YES; 287 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 288 | COPY_PHASE_STRIP = NO; 289 | CURRENT_PROJECT_VERSION = 1; 290 | DEBUG_INFORMATION_FORMAT = dwarf; 291 | ENABLE_STRICT_OBJC_MSGSEND = YES; 292 | ENABLE_TESTABILITY = YES; 293 | GCC_C_LANGUAGE_STANDARD = gnu11; 294 | GCC_DYNAMIC_NO_PIC = NO; 295 | GCC_NO_COMMON_BLOCKS = YES; 296 | GCC_OPTIMIZATION_LEVEL = 0; 297 | GCC_PREPROCESSOR_DEFINITIONS = ( 298 | "DEBUG=1", 299 | "$(inherited)", 300 | ); 301 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 302 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 303 | GCC_WARN_UNDECLARED_SELECTOR = YES; 304 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 305 | GCC_WARN_UNUSED_FUNCTION = YES; 306 | GCC_WARN_UNUSED_VARIABLE = YES; 307 | IPHONEOS_DEPLOYMENT_TARGET = 13.0; 308 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; 309 | MTL_FAST_MATH = YES; 310 | ONLY_ACTIVE_ARCH = YES; 311 | SDKROOT = iphoneos; 312 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 313 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 314 | SWIFT_VERSION = 5.0; 315 | VERSIONING_SYSTEM = "apple-generic"; 316 | VERSION_INFO_PREFIX = ""; 317 | }; 318 | name = Debug; 319 | }; 320 | 0203EB0528661D9300A2E7A2 /* Release */ = { 321 | isa = XCBuildConfiguration; 322 | buildSettings = { 323 | ALWAYS_SEARCH_USER_PATHS = NO; 324 | CLANG_ANALYZER_NONNULL = YES; 325 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 326 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++17"; 327 | CLANG_ENABLE_MODULES = YES; 328 | CLANG_ENABLE_OBJC_ARC = YES; 329 | CLANG_ENABLE_OBJC_WEAK = YES; 330 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 331 | CLANG_WARN_BOOL_CONVERSION = YES; 332 | CLANG_WARN_COMMA = YES; 333 | CLANG_WARN_CONSTANT_CONVERSION = YES; 334 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 335 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 336 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 337 | CLANG_WARN_EMPTY_BODY = YES; 338 | CLANG_WARN_ENUM_CONVERSION = YES; 339 | CLANG_WARN_INFINITE_RECURSION = YES; 340 | CLANG_WARN_INT_CONVERSION = YES; 341 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 342 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 343 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 344 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 345 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 346 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 347 | CLANG_WARN_STRICT_PROTOTYPES = YES; 348 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 349 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 350 | CLANG_WARN_UNREACHABLE_CODE = YES; 351 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 352 | COPY_PHASE_STRIP = NO; 353 | CURRENT_PROJECT_VERSION = 1; 354 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 355 | ENABLE_NS_ASSERTIONS = NO; 356 | ENABLE_STRICT_OBJC_MSGSEND = YES; 357 | GCC_C_LANGUAGE_STANDARD = gnu11; 358 | GCC_NO_COMMON_BLOCKS = YES; 359 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 360 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 361 | GCC_WARN_UNDECLARED_SELECTOR = YES; 362 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 363 | GCC_WARN_UNUSED_FUNCTION = YES; 364 | GCC_WARN_UNUSED_VARIABLE = YES; 365 | IPHONEOS_DEPLOYMENT_TARGET = 13.0; 366 | MTL_ENABLE_DEBUG_INFO = NO; 367 | MTL_FAST_MATH = YES; 368 | SDKROOT = iphoneos; 369 | SWIFT_COMPILATION_MODE = wholemodule; 370 | SWIFT_OPTIMIZATION_LEVEL = "-O"; 371 | SWIFT_VERSION = 5.0; 372 | VALIDATE_PRODUCT = YES; 373 | VERSIONING_SYSTEM = "apple-generic"; 374 | VERSION_INFO_PREFIX = ""; 375 | }; 376 | name = Release; 377 | }; 378 | 0203EB0728661D9300A2E7A2 /* Debug */ = { 379 | isa = XCBuildConfiguration; 380 | buildSettings = { 381 | CODE_SIGN_STYLE = Automatic; 382 | CURRENT_PROJECT_VERSION = 1; 383 | DEFINES_MODULE = YES; 384 | DEVELOPMENT_TEAM = 3KZWVBAJSN; 385 | DYLIB_COMPATIBILITY_VERSION = 1; 386 | DYLIB_CURRENT_VERSION = 1; 387 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 388 | GENERATE_INFOPLIST_FILE = YES; 389 | INFOPLIST_KEY_NSHumanReadableCopyright = ""; 390 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 391 | LD_RUNPATH_SEARCH_PATHS = ( 392 | "$(inherited)", 393 | "@executable_path/Frameworks", 394 | "@loader_path/Frameworks", 395 | ); 396 | MARKETING_VERSION = 1.0; 397 | PRODUCT_BUNDLE_IDENTIFIER = gravityapp.SecurityKit; 398 | PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; 399 | SKIP_INSTALL = YES; 400 | SWIFT_EMIT_LOC_STRINGS = YES; 401 | SWIFT_VERSION = 5.0; 402 | TARGETED_DEVICE_FAMILY = "1,2"; 403 | }; 404 | name = Debug; 405 | }; 406 | 0203EB0828661D9300A2E7A2 /* Release */ = { 407 | isa = XCBuildConfiguration; 408 | buildSettings = { 409 | CODE_SIGN_STYLE = Automatic; 410 | CURRENT_PROJECT_VERSION = 1; 411 | DEFINES_MODULE = YES; 412 | DEVELOPMENT_TEAM = 3KZWVBAJSN; 413 | DYLIB_COMPATIBILITY_VERSION = 1; 414 | DYLIB_CURRENT_VERSION = 1; 415 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 416 | GENERATE_INFOPLIST_FILE = YES; 417 | INFOPLIST_KEY_NSHumanReadableCopyright = ""; 418 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 419 | LD_RUNPATH_SEARCH_PATHS = ( 420 | "$(inherited)", 421 | "@executable_path/Frameworks", 422 | "@loader_path/Frameworks", 423 | ); 424 | MARKETING_VERSION = 1.0; 425 | PRODUCT_BUNDLE_IDENTIFIER = gravityapp.SecurityKit; 426 | PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; 427 | SKIP_INSTALL = YES; 428 | SWIFT_EMIT_LOC_STRINGS = YES; 429 | SWIFT_VERSION = 5.0; 430 | TARGETED_DEVICE_FAMILY = "1,2"; 431 | }; 432 | name = Release; 433 | }; 434 | 0203EB0A28661D9300A2E7A2 /* Debug */ = { 435 | isa = XCBuildConfiguration; 436 | buildSettings = { 437 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 438 | CODE_SIGN_STYLE = Automatic; 439 | CURRENT_PROJECT_VERSION = 1; 440 | DEVELOPMENT_TEAM = 3KZWVBAJSN; 441 | GENERATE_INFOPLIST_FILE = YES; 442 | MARKETING_VERSION = 1.0; 443 | PRODUCT_BUNDLE_IDENTIFIER = gravityapp.SecurityKitTests; 444 | PRODUCT_NAME = "$(TARGET_NAME)"; 445 | SWIFT_EMIT_LOC_STRINGS = NO; 446 | SWIFT_VERSION = 5.0; 447 | TARGETED_DEVICE_FAMILY = "1,2"; 448 | }; 449 | name = Debug; 450 | }; 451 | 0203EB0B28661D9300A2E7A2 /* Release */ = { 452 | isa = XCBuildConfiguration; 453 | buildSettings = { 454 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 455 | CODE_SIGN_STYLE = Automatic; 456 | CURRENT_PROJECT_VERSION = 1; 457 | DEVELOPMENT_TEAM = 3KZWVBAJSN; 458 | GENERATE_INFOPLIST_FILE = YES; 459 | MARKETING_VERSION = 1.0; 460 | PRODUCT_BUNDLE_IDENTIFIER = gravityapp.SecurityKitTests; 461 | PRODUCT_NAME = "$(TARGET_NAME)"; 462 | SWIFT_EMIT_LOC_STRINGS = NO; 463 | SWIFT_VERSION = 5.0; 464 | TARGETED_DEVICE_FAMILY = "1,2"; 465 | }; 466 | name = Release; 467 | }; 468 | /* End XCBuildConfiguration section */ 469 | 470 | /* Begin XCConfigurationList section */ 471 | 0203EAEC28661D9300A2E7A2 /* Build configuration list for PBXProject "SecurityKit" */ = { 472 | isa = XCConfigurationList; 473 | buildConfigurations = ( 474 | 0203EB0428661D9300A2E7A2 /* Debug */, 475 | 0203EB0528661D9300A2E7A2 /* Release */, 476 | ); 477 | defaultConfigurationIsVisible = 0; 478 | defaultConfigurationName = Release; 479 | }; 480 | 0203EB0628661D9300A2E7A2 /* Build configuration list for PBXNativeTarget "SecurityKit" */ = { 481 | isa = XCConfigurationList; 482 | buildConfigurations = ( 483 | 0203EB0728661D9300A2E7A2 /* Debug */, 484 | 0203EB0828661D9300A2E7A2 /* Release */, 485 | ); 486 | defaultConfigurationIsVisible = 0; 487 | defaultConfigurationName = Release; 488 | }; 489 | 0203EB0928661D9300A2E7A2 /* Build configuration list for PBXNativeTarget "SecurityKitTests" */ = { 490 | isa = XCConfigurationList; 491 | buildConfigurations = ( 492 | 0203EB0A28661D9300A2E7A2 /* Debug */, 493 | 0203EB0B28661D9300A2E7A2 /* Release */, 494 | ); 495 | defaultConfigurationIsVisible = 0; 496 | defaultConfigurationName = Release; 497 | }; 498 | /* End XCConfigurationList section */ 499 | }; 500 | rootObject = 0203EAE928661D9300A2E7A2 /* Project object */; 501 | } 502 | -------------------------------------------------------------------------------- /SecurityKit/SecurityKit.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /SecurityKit/SecurityKit.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /SecurityKit/SecurityKit.xcodeproj/project.xcworkspace/xcuserdata/mehran.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mehrankmlf/SecurityKit/8c2a2ae2b4f057c3007b667bf9dea65bc3f967ce/SecurityKit/SecurityKit.xcodeproj/project.xcworkspace/xcuserdata/mehran.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /SecurityKit/SecurityKit.xcodeproj/xcuserdata/mehran.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | SecurityKit.xcscheme_^#shared#^_ 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /SecurityKit/SecurityKit/BackgroundLayer.swift: -------------------------------------------------------------------------------- 1 | // 2 | // BackgroundLayer.swift 3 | // SecurityKit 4 | // 5 | // Created by Mehran on 4/6/1401 AP. 6 | // 7 | 8 | import Foundation 9 | import UIKit 10 | 11 | internal class SecureLayer { 12 | 13 | static func showImage(window : UIWindow?, with image : UIImage?) { 14 | guard let window = window,let image = image else{return} 15 | let imageView = UIImageView(image: image) 16 | imageView.backgroundColor = UIColor.white 17 | imageView.isUserInteractionEnabled = false 18 | imageView.contentMode = .scaleAspectFit 19 | imageView.snapshotView(afterScreenUpdates: true) 20 | imageView.frame = window.bounds 21 | window.addSubview(imageView) 22 | } 23 | 24 | static func removeOverlayImage(_ window:inout UIWindow?){ 25 | guard let window = window else{return} 26 | for view in window.subviews{ 27 | if view is UIImageView{ 28 | view.removeFromSuperview() 29 | } 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /SecurityKit/SecurityKit/JailBrokenDetection.swift: -------------------------------------------------------------------------------- 1 | // 2 | // JailBrokenDetection.swift 3 | // SecurityKit 4 | // 5 | // Created by Mehran on 4/3/1401 AP. 6 | // 7 | 8 | import Foundation 9 | import UIKit 10 | 11 | internal class JailBreakDetection { 12 | 13 | internal static func isJailBroken() -> Bool { 14 | let isCydiaInstalled = hasCydiaInstalled() 15 | let fileCheck = isPathsExist() 16 | let directories = isDirectoriesWriteable() 17 | let suspiciousApps = isContainsSuspiciousApps() 18 | 19 | return isCydiaInstalled || 20 | fileCheck || 21 | directories || 22 | suspiciousApps ? true : false 23 | } 24 | 25 | //check if cydia is installed (using URI Scheme) 26 | static func hasCydiaInstalled() -> Bool { 27 | return UIApplication.shared.canOpenURL(URL(string: "cydia://")!) 28 | } 29 | 30 | //suspicious system and app paths to check 31 | private static var suspicousAppandSystemPaths: [String] { 32 | return [ 33 | "/usr/sbin/frida-server", 34 | "/etc/apt/sources.list.d/electra.list", 35 | "/etc/apt/sources.list.d/sileo.sources", 36 | "/.bootstrapped_electra", 37 | "/usr/lib/libjailbreak.dylib", 38 | "/jb/lzma", 39 | "/.cydia_no_stash", 40 | "/.installed_unc0ver", 41 | "/jb/offsets.plist", 42 | "/usr/share/jailbreak/injectme.plist", 43 | "/etc/apt/undecimus/undecimus.list", 44 | "/var/lib/dpkg/info/mobilesubstrate.md5sums", 45 | "/Library/MobileSubstrate/MobileSubstrate.dylib", 46 | "/jb/jailbreakd.plist", 47 | "/jb/amfid_payload.dylib", 48 | "/jb/libjailbreak.dylib", 49 | "/usr/libexec/cydia/firmware.sh", 50 | "/var/lib/cydia", 51 | "/etc/apt", 52 | "/private/var/lib/apt", 53 | "/private/var/Users/", 54 | "/var/log/apt", 55 | "/Applications/Cydia.app", 56 | "/private/var/stash", 57 | "/private/var/lib/apt/", 58 | "/private/var/lib/cydia", 59 | "/private/var/cache/apt/", 60 | "/private/var/log/syslog", 61 | "/private/var/tmp/cydia.log", 62 | "/Applications/Icy.app", 63 | "/Applications/MxTube.app", 64 | "/Applications/RockApp.app", 65 | "/Applications/blackra1n.app", 66 | "/Applications/SBSettings.app", 67 | "/Applications/FakeCarrier.app", 68 | "/Applications/WinterBoard.app", 69 | "/Applications/IntelliScreen.app", 70 | "/private/var/mobile/Library/SBSettings/Themes", 71 | "/Library/MobileSubstrate/CydiaSubstrate.dylib", 72 | "/System/Library/LaunchDaemons/com.ikey.bbot.plist", 73 | "/Library/MobileSubstrate/DynamicLibraries/Veency.plist", 74 | "/Library/MobileSubstrate/DynamicLibraries/LiveClock.plist", 75 | "/System/Library/LaunchDaemons/com.saurik.Cydia.Startup.plist" 76 | ] 77 | } 78 | 79 | private static func isPathsExist() -> Bool { 80 | for path in suspicousAppandSystemPaths { 81 | if FileManager.default.fileExists(atPath: path){ 82 | return true 83 | } 84 | } 85 | return false 86 | } 87 | 88 | private static var directories: [String] { 89 | return [ 90 | "/", 91 | "/root/", 92 | "/private/", 93 | "/jb/" 94 | ] 95 | } 96 | 97 | private static func isDirectoriesWriteable() -> Bool { 98 | // Checks if the restricted directories are writeable. 99 | for path in directories { 100 | do{ 101 | let filePath = path + UUID().uuidString 102 | try "i escaped the Jail".write(toFile: filePath, atomically: true, encoding: .utf8) 103 | try FileManager.default.removeItem(atPath: filePath) 104 | return true 105 | }catch let error{print(error.localizedDescription)} 106 | } 107 | return false 108 | } 109 | 110 | //suspicious apps path to check 111 | private static var suspiciousAppsPathToCheck: [String] { 112 | return ["/Applications/Cydia.app", 113 | "/Applications/blackra1n.app", 114 | "/Applications/FakeCarrier.app", 115 | "/Applications/Icy.app", 116 | "/Applications/IntelliScreen.app", 117 | "/Applications/MxTube.app", 118 | "/Applications/RockApp.app", 119 | "/Applications/SBSettings.app", 120 | "/Applications/WinterBoard.app" 121 | ] 122 | } 123 | 124 | //Check if suspicious apps (Cydia, FakeCarrier, Icy etc.) is installed 125 | private static func isContainsSuspiciousApps() -> Bool { 126 | for path in suspiciousAppsPathToCheck { 127 | if FileManager.default.fileExists(atPath: path) { 128 | return true 129 | } 130 | } 131 | return false 132 | } 133 | } 134 | -------------------------------------------------------------------------------- /SecurityKit/SecurityKit/ReverseEngineering.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ReverseEngineering.swift 3 | // SecurityKit 4 | // 5 | // Created by Mehran on 4/5/1401 AP. 6 | // 7 | 8 | import Foundation 9 | import MachO.dyld 10 | 11 | internal class ReverseEngineering { 12 | 13 | // Detect reverse engineering tools 14 | internal static func isReverseEngineeringTools() -> Bool { 15 | let dyld = checkDYLD() 16 | let frida = isFridaRunning() 17 | return dyld || frida ? true : false 18 | } 19 | 20 | private static func checkDYLD() -> Bool { 21 | let suspiciousLibraries = [ 22 | "FridaGadget", 23 | "frida", 24 | "cynject", 25 | "libcycript" 26 | ] 27 | for libraryIndex in 0..<_dyld_image_count() { 28 | 29 | guard let loadedLibrary = String(validatingUTF8: _dyld_get_image_name(libraryIndex)) else { continue } 30 | for suspiciousLibrary in suspiciousLibraries { 31 | if loadedLibrary.lowercased().contains(suspiciousLibrary.lowercased()) { 32 | return true 33 | } 34 | } 35 | } 36 | return false 37 | } 38 | 39 | private static func isFridaRunning() -> Bool { 40 | func swapBytesIfNeeded(port: in_port_t) -> in_port_t { 41 | let littleEndian = Int(OSHostByteOrder()) == OSLittleEndian 42 | return littleEndian ? _OSSwapInt16(port) : port 43 | } 44 | 45 | var serverAddress = sockaddr_in() 46 | serverAddress.sin_family = sa_family_t(AF_INET) 47 | serverAddress.sin_addr.s_addr = inet_addr("127.0.0.1") 48 | serverAddress.sin_port = swapBytesIfNeeded(port: in_port_t(27042)) 49 | let sock = socket(AF_INET, SOCK_STREAM, 0) 50 | 51 | let result = withUnsafePointer(to: &serverAddress) { 52 | $0.withMemoryRebound(to: sockaddr.self, capacity: 1) { 53 | connect(sock, $0, socklen_t(MemoryLayout.stride)) 54 | } 55 | } 56 | if result != -1 { 57 | return true 58 | } 59 | return false 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /SecurityKit/SecurityKit/ScreenCaptureProtection.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ScreenCaptureProtection.swift 3 | // SecurityKit 4 | // 5 | // Created by Mehran on 5/12/1401 AP. 6 | // 7 | 8 | import Foundation 9 | 10 | import UIKit 11 | 12 | private extension UIView { 13 | 14 | enum Constant { 15 | case textFieldTag 16 | var num : Int { 17 | switch self { 18 | case .textFieldTag: 19 | return Int.max 20 | } 21 | } 22 | } 23 | 24 | // Create a layer on screen to hide sensitive data 25 | func makeSecureTextField() { 26 | 27 | guard superview != nil else { 28 | for subview in subviews { //to avoid layer cyclic crash, when it is a topmost view, adding all its subviews in textfield's layer, TODO: Find a better logic. 29 | subview.makeSecureTextField() 30 | } 31 | return 32 | } 33 | 34 | DispatchQueue.main.async { 35 | let field = UITextField() 36 | field.isSecureTextEntry = true 37 | field.tag = Constant.textFieldTag.num 38 | self.addSubview(field) 39 | field.centerYAnchor.constraint(equalTo: self.centerYAnchor).isActive = true 40 | field.centerXAnchor.constraint(equalTo: self.centerXAnchor).isActive = true 41 | self.layer.superlayer?.addSublayer(field.layer) 42 | field.layer.sublayers?.first?.addSublayer(self.layer) 43 | } 44 | } 45 | 46 | // Remove added layer to the screen 47 | func removeSecureTextField() { 48 | if let guardView = subviews.first(where: { $0.tag == Constant.textFieldTag.num }) { 49 | guardView.removeFromSuperview() 50 | } 51 | } 52 | } 53 | 54 | public class ScreenCaptureProtection { 55 | 56 | public static let shared = ScreenCaptureProtection() 57 | 58 | private init() {} 59 | 60 | public func makeProtection(`for` view: UIView) { 61 | view.makeSecureTextField() 62 | } 63 | 64 | public func removeScreenProtection(`for` view: UIView) { 65 | view.removeSecureTextField() 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /SecurityKit/SecurityKit/SecurityKit.docc/SecurityKit.md: -------------------------------------------------------------------------------- 1 | # ``SecurityKit`` 2 | 3 | Summary 4 | 5 | ## Overview 6 | 7 | Text 8 | 9 | ## Topics 10 | 11 | ### Group 12 | 13 | - ``Symbol`` -------------------------------------------------------------------------------- /SecurityKit/SecurityKit/SecurityKit.h: -------------------------------------------------------------------------------- 1 | // 2 | // SecurityKit.h 3 | // SecurityKit 4 | // 5 | // Created by Mehran on 4/3/1401 AP. 6 | // 7 | 8 | #import 9 | 10 | //! Project version number for SecurityKit. 11 | FOUNDATION_EXPORT double SecurityKitVersionNumber; 12 | 13 | //! Project version string for SecurityKit. 14 | FOUNDATION_EXPORT const unsigned char SecurityKitVersionString[]; 15 | 16 | // In this header, you should import all the public headers of your framework using statements like #import 17 | 18 | 19 | -------------------------------------------------------------------------------- /SecurityKit/SecurityKit/SecurityKit.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SecurityKit.swift 3 | // SecurityKit 4 | // 5 | // Created by Mehran on 4/10/1401 AP. 6 | // 7 | 8 | import Foundation 9 | import UIKit 10 | 11 | public class SecurityKit { 12 | 13 | /** 14 | Detect when device is JAILBROKEN 15 | 16 | - returns: Bool 17 | - warning: none 18 | 19 | # Example # 20 | ``` 21 | let jailBroken = SecurityKit.isDeviceJailBroken() 22 | ``` 23 | */ 24 | public static func isDeviceJailBroken() -> Bool { 25 | return JailBreakDetection.isJailBroken() 26 | } 27 | 28 | 29 | /** 30 | Detect when device is SIMULATOR 31 | 32 | - returns: Bool 33 | - warning: none 34 | 35 | # Example # 36 | ``` 37 | // 38 | let deviceSimulator = SecurityKit.isDeviceSimulator() 39 | ``` 40 | */ 41 | public static func isDeviceSimulator() -> Bool { 42 | return Platform.isSimulator() 43 | } 44 | 45 | 46 | /** 47 | Detect when REVERSE ENGINEERING tools have executed like : Frida, Cynject 48 | 49 | - returns: Bool 50 | - warning: none 51 | 52 | # Example # 53 | ``` 54 | // 55 | let reverseEngineering = SecurityKit.isReverseEngineeringToolsExecuted() 56 | ``` 57 | */ 58 | public static func isReverseEngineeringToolsExecuted() -> Bool { 59 | return ReverseEngineering.isReverseEngineeringTools() 60 | } 61 | 62 | 63 | /** 64 | Detect when VPN is Connected in device 65 | 66 | - returns: Bool 67 | - warning: none 68 | 69 | # Example # 70 | ``` 71 | // 72 | let vpnConnected = SecurityKit.isVPNConnected() 73 | ``` 74 | */ 75 | public static func isVPNConnected() -> Bool { 76 | return VPNChecker.isVPNConnected() 77 | } 78 | 79 | 80 | /** 81 | Before your app enters the background you can go and adjust the this UI to simply not show the user’s sensitive data 82 | by addSubview UIImage layer 83 | 84 | - parameter UIWindow? 85 | - parameter UIImage? 86 | - warning: none 87 | 88 | # Notes: # 89 | Use this methods for detect when app goes to background 90 | 1. applicationWillResignActive(_:) method in the AppDelegate 91 | 2. sceneWillResignActive(_ scene:) method in SceneDelegate 92 | 93 | # Example # 94 | ``` 95 | // 96 | SecurityKit.createSecureScreenShot(window : window, image : image) 97 | ``` 98 | */ 99 | public static func createSecureScreenShot(window : UIWindow?, image : UIImage) { 100 | SecureLayer.showImage(window: window, with: image) 101 | } 102 | 103 | 104 | /** 105 | Before your app become active you can remove added overlay from UIWindow 106 | 107 | - parameter UIWindow 108 | - warning: none 109 | 110 | # Notes: # 111 | Use this methods for detect when app goes to foreground 112 | 1. applicationWillEnterForeground(_:) method in the AppDelegate 113 | 2. sceneDidBecomeActive(_ scene:) method in SceneDelegate 114 | 115 | # Example # 116 | ``` 117 | // 118 | SecurityKit.removeSecureScreenShot(window:inout window) 119 | ``` 120 | */ 121 | public static func removeSecureScreenShot(window:inout UIWindow?) { 122 | SecureLayer.removeOverlayImage(&window) 123 | } 124 | 125 | /** 126 | Hide Sensitive String data from run time binary 127 | 128 | - parameter String 129 | - parameter String 130 | - returns [UInt8] 131 | - warning: none 132 | 133 | # Notes: # 134 | Use this method use for encrypt string 135 | base on XOR alghorithm 136 | # Example # 137 | ``` 138 | // 139 | SecurityKit.stringEncryption(plainText : "String", encryptionKey: "String") 140 | ``` 141 | */ 142 | public static func stringEncryption(plainText : String, encryptionKey: String) -> [UInt8] { 143 | return XOREncryption.encryption(plainText: plainText, encryptionKey: encryptionKey) 144 | } 145 | 146 | /** 147 | Hide Sensitive String data from run time binary 148 | 149 | - parameter String 150 | - parameter String 151 | - returns String 152 | - warning: none 153 | 154 | # Notes: # 155 | Use this method use for array of [UInt8] 156 | # Example # 157 | ``` 158 | // 159 | SecurityKit.stringDecryption(cypherText: [UInt8]?, decryptionKey : "String") 160 | ``` 161 | */ 162 | public static func stringDecryption(cypherText: [UInt8]?, decryptionKey : String?) -> String { 163 | return XOREncryption.decryption(cypherText: cypherText, decryptionKey: decryptionKey) 164 | } 165 | } 166 | -------------------------------------------------------------------------------- /SecurityKit/SecurityKit/SimulatorDetection.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SimulatorDetection.swift 3 | // SecurityKit 4 | // 5 | // Created by Mehran on 4/5/1401 AP. 6 | // 7 | 8 | import Foundation 9 | 10 | internal class Platform { 11 | 12 | internal static func isSimulator() -> Bool { 13 | return runTime() || compileTime() 14 | } 15 | 16 | private static func runTime() -> Bool { 17 | return ProcessInfo().environment["SIMULATOR_DEVICE_NAME"] != nil 18 | } 19 | 20 | private static func compileTime() -> Bool { 21 | #if targetEnvironment(simulator) 22 | // We're on the simulator 23 | return true 24 | #else 25 | // We're on a device 26 | return false 27 | #endif 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /SecurityKit/SecurityKit/StringEncryption.swift: -------------------------------------------------------------------------------- 1 | // 2 | // StringEncryption.swift 3 | // SecurityKit 4 | // 5 | // Created by Mehran on 6/15/1401 AP. 6 | // 7 | 8 | import Foundation 9 | 10 | internal class XOREncryption { 11 | 12 | static func encryption(plainText: String?, encryptionKey : String?) -> [UInt8] { 13 | 14 | guard let plainText = plainText, 15 | let encryptionKey = encryptionKey 16 | else { return [UInt8]() } 17 | 18 | var encrypted = [UInt8]() 19 | let text = [UInt8](plainText.utf8) 20 | let key = [UInt8](encryptionKey.utf8) 21 | let length = key.count 22 | 23 | // encrypt bytes base on XOR data encryption 24 | for t in text.enumerated() { 25 | encrypted.append(t.element ^ key[t.offset % length]) 26 | } 27 | return encrypted 28 | } 29 | 30 | static func decryption(cypherText: [UInt8]?, decryptionKey : String?) -> String { 31 | 32 | guard let cypherText = cypherText, 33 | let decryptionKey = decryptionKey 34 | else { return "" } 35 | 36 | var decrypted = [UInt8]() 37 | let cypher = cypherText 38 | let key = [UInt8](decryptionKey.utf8) 39 | let length = key.count 40 | 41 | /// decrypt bytes base on XOR data encryption 42 | for c in cypher.enumerated() { 43 | decrypted.append(c.element ^ key[c.offset % length]) 44 | } 45 | return String(bytes: decrypted, encoding: .utf8)! 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /SecurityKit/SecurityKit/TestableStringEncryption.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TestableStringEncryption.swift 3 | // SecurityKit 4 | // 5 | // Created by Mehran on 6/18/1401 AP. 6 | // 7 | 8 | import Foundation 9 | 10 | protocol XOREncryptionProtocol { 11 | func encryption(plainText: String?, encryptionKey : String?) -> [UInt8] 12 | func decryption(cypherText: [UInt8]?, decryptionKey : String?) -> String 13 | } 14 | // this class helps to write unit test for encryption process 15 | internal class TestableStringEncryption: XOREncryptionProtocol { 16 | func encryption(plainText: String?, encryptionKey: String?) -> [UInt8] { 17 | XOREncryption.encryption(plainText: plainText, encryptionKey: encryptionKey) 18 | } 19 | 20 | func decryption(cypherText: [UInt8]?, decryptionKey: String?) -> String { 21 | return XOREncryption.decryption(cypherText: cypherText, decryptionKey: decryptionKey) 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /SecurityKit/SecurityKit/VPNChecker.swift: -------------------------------------------------------------------------------- 1 | // 2 | // VPNChecker.swift 3 | // SecurityKit 4 | // 5 | // Created by Mehran on 4/5/1401 AP. 6 | // 7 | 8 | import Foundation 9 | 10 | internal class VPNChecker { 11 | 12 | internal static func isVPNConnected() -> Bool { 13 | return vpnStatus() 14 | } 15 | // Check vpn status 16 | private static func vpnStatus() -> Bool { 17 | let cfDict = CFNetworkCopySystemProxySettings() 18 | let nsDict = cfDict!.takeRetainedValue() as NSDictionary 19 | let keys = nsDict["__SCOPED__"] as! NSDictionary 20 | 21 | for key: String in keys.allKeys as! [String] { 22 | if (key == "tap" || 23 | key == "tun" || 24 | key == "ppp" || 25 | key == "ipsec" || 26 | key == "ipsec0" || 27 | key == "utun1" || 28 | key == "utun2") { 29 | return true 30 | } 31 | } 32 | return false 33 | } 34 | } 35 | 36 | -------------------------------------------------------------------------------- /SecurityKit/SecurityKitTests/StringEncryptionTest.swift: -------------------------------------------------------------------------------- 1 | // 2 | // StringEncryptionTest.swift 3 | // SecurityKitTests 4 | // 5 | // Created by Mehran on 6/18/1401 AP. 6 | // 7 | 8 | import XCTest 9 | @testable import SecurityKit 10 | 11 | class StringEncryptionTest: XCTestCase { 12 | 13 | var sut : XOREncryptionProtocol! 14 | 15 | override func setUp() { 16 | sut = TestableStringEncryption() 17 | } 18 | 19 | override func tearDown() { 20 | sut = nil 21 | super.tearDown() 22 | } 23 | 24 | func testBytesByXOREncryption_WhenCelled_ShouldReturnValidByteArray() { 25 | let plain = "PlainText" 26 | let key = "key" 27 | let result = sut.encryption(plainText: plain, encryptionKey: key) 28 | XCTAssertTrue(result as Any is [UInt8]) 29 | XCTAssertEqual(result.count, "PlainText".count) 30 | } 31 | 32 | func testBytesByXORDecryption_WhenCelled_ShouldReturnValidString() { 33 | let cypher : [UInt8] = [59, 9, 24, 2, 11, 45, 14, 29, 13] 34 | let key = "key" 35 | let result = sut.decryption(cypherText: cypher, decryptionKey: key) 36 | XCTAssertTrue(result as Any is String) 37 | XCTAssertEqual(result, "PlainText") 38 | } 39 | } 40 | --------------------------------------------------------------------------------