Best Practices
Follow these best practices to get the most out of Shield while maintaining a smooth development workflow.
Use Build Profiles
Never protect Debug builds. Use Build Profiles to skip protection during development and only apply it to Release and distribution builds. This keeps your development cycle fast and ensures you can debug normally with Xcode.
{
"build_integration": {
"skip_debug": true,
"skip_simulator": true
}
}{
"build_integration": {
"skip_debug": true,
"skip_simulator": true
}
}Start with Basic Protections
Begin with the protections that provide the most value with the least complexity:
{
"protections": {
"symbol_renaming": true,
"string_encryption": true,
"swift_stripping": true,
"anti_debug": true
}
}{
"protections": {
"symbol_renaming": true,
"string_encryption": true,
"swift_stripping": true,
"anti_debug": true
}
}Test your application thoroughly with these protections before adding more. This makes it easy to identify if a specific protection causes issues.
Add Protections Incrementally
Add one protection at a time and test your application after each addition. This approach makes it straightforward to identify which protection is causing any issues and to configure the appropriate exclusions.
Configure Exclusions Carefully
Symbols that are referenced by name at runtime must be excluded from renaming. Common cases include Interface Builder outlets and actions, Codable and NSCoding conformances, classes accessed via NSClassFromString, Objective-C selectors used with #selector, and third-party SDK entry points.
See Exclusions for detailed patterns.
Use RASP Protections Together
Runtime protections are most effective when used together. Enable the full rasp block rather than individual detections:
{
"protections": {
"rasp": {
"enabled": true,
"hook_detection": true,
"trace_detection": true,
"tamper_detection": true,
"action": "exit"
},
"anti_debug": true,
"anti_jailbreak": true
}
}{
"protections": {
"rasp": {
"enabled": true,
"hook_detection": true,
"trace_detection": true,
"tamper_detection": true,
"action": "exit"
},
"anti_debug": true,
"anti_jailbreak": true
}
}This ensures that all common attack vectors are covered.
Combine Code and Data Protections
The strongest protection comes from combining code obfuscation with data protection. Code obfuscation alone still leaves strings readable, and string encryption alone still leaves code structure visible:
{
"protections": {
"symbol_renaming": true,
"string_encryption": true,
"swift_stripping": true,
"control_flow": "medium",
"class_encryption": true,
"resource_encryption": true
}
}{
"protections": {
"symbol_renaming": true,
"string_encryption": true,
"swift_stripping": true,
"control_flow": "medium",
"class_encryption": true,
"resource_encryption": true
}
}Test on Real Devices
Always test your protected application on real iOS devices before distribution. Some protections, particularly Anti-Jailbreak, may behave differently on physical devices compared to the simulator.
Keep Mapping Files
Shield automatically uploads mapping files to the Cloud Panel for every build. These are essential for debugging production crashes. If you use offline mode, manually archive the generated mapping files with each release.
Update Shield Regularly
Keep Shield updated to benefit from new protections, improved performance, and compatibility with the latest iOS and Xcode versions:
pip install --upgrade shield-iospip install --upgrade shield-iosRelated
- Protections Overview - All available protections
- Exclusions - Configure exclusion patterns
- Troubleshooting - Common issues and solutions