30

I'm working on a development environment without HTTPS setup. Is it possible to automatically disable ATS just for the development (debug) mode?

Andree
  • 3,033
  • 6
  • 36
  • 56

4 Answers4

63

My solution is to keep ATS disable option at the default NO value and add a New Run Script Phase to change it in the app bundle's Info.plist when building the app.

enter image description here

This is the script:

#Disables ATS in debug builds.
INFOPLIST="${TARGET_BUILD_DIR}"/"${INFOPLIST_PATH}"
case "${CONFIGURATION}" in
"Release"|"Adhoc")
/usr/libexec/PlistBuddy -c "Set :NSAppTransportSecurity:NSAllowsArbitraryLoads NO" "${INFOPLIST}"
;;
"Debug")
/usr/libexec/PlistBuddy -c "Set :NSAppTransportSecurity:NSAllowsArbitraryLoads YES" "${INFOPLIST}"
;; 
esac
Rafael Nobre
  • 5,062
  • 40
  • 40
  • This is better than @MaciekCzarnik's answer, because you don't copy all other settings as well in a second .plist file. – meaning-matters Sep 27 '15 at 18:18
  • 4
    Hi there, I've tried your suggestion and it works great on devices, but it seems that it doesn't work on Simulator. It's strange because when I check the output Info.plist file in the build folder, the NSAllowArbitraryLoads setting is correctly set to YES. Any clues? – Andree Oct 09 '15 at 02:56
  • @Andree we've been using it in the Simulator without problems – Rafael Nobre Oct 14 '15 at 20:11
  • 3
    Note: leave the "Run Script" as the last phase. I started moving it around and broke it. – lionello Sep 01 '16 at 11:03
  • Note to get this to work we had to explicitly include NSAllowsArbitraryLoads set to false in the Info.plist file (the default value). Without it there the script raised an error. – Marcus Leon Sep 18 '16 at 11:51
  • Hmm this will make the git repo dirty, right? Lets say that we want AllowArbitraryLoads to be `false` per default, and then running the app will change the value to `true`, the the git repo i dirty. How can we set it back to false after having compiled and pushed the Debug build to device/simulator? – Sajjon Dec 05 '16 at 17:45
  • 3
    @Sajjon this does not make the repo dirty, it changes the compiled plist inside the app's bundle, not the original project's plist file. – Rafael Nobre Dec 06 '16 at 04:03
  • I had to set my `INFOPLIST="${PRODUCT_SETTINGS_PATH}"` – Adam Johns Jul 02 '18 at 21:49
  • 3
    I had to pair this solution with [another one](https://stackoverflow.com/a/52936167/5739507). Then it worked. – Andrew Kirna Jun 03 '20 at 20:05
  • As stated by @Andree the solution does not work for simulator. – Lorenzo B Aug 01 '20 at 15:06
  • Just spent far longer on this than I would like to admit but can confirm it does work, it *does* work for Simulator contrary to comments above, and to work reliably it did require adding `$(TARGET_BUILD_DIR)/$(INFOPLIST_PATH)` to Input Files for the Run Script as @AndrewKirna mentioned. I also had to additionally use PlistBuddy to delete the key `NSAllowsArbitraryLoadsInWebContent` as this (and other keys) completely override NSAllowsArbitraryLoads - so that could be another thing to check. – ryanp Mar 19 '21 at 13:22
  • This didn't work for me, as I got `Set: Entry, ":NSAppTransportSecurity:NSAllowsArbitraryLoads", Does Not Exist. Command PhaseScriptExecution failed with a nonzero exit code` – Ben Butterworth Mar 20 '21 at 16:28
  • I fixed it by replacing `NSAllowsArbitraryLoads` with `NSAllowsLocalNetworking` in the code written by Rafael, but [this doesn't disable ATS](https://developer.apple.com/documentation/bundleresources/information_property_list/nsapptransportsecurity/nsallowsarbitraryloads), it allows me to [load local resources](https://developer.apple.com/documentation/bundleresources/information_property_list/nsapptransportsecurity/nsallowslocalnetworking) (e.g. Firebase emulator). – Ben Butterworth Mar 20 '21 at 16:31
14

Another solution. By using INFOPLIST_PREPROCESS = YES and INFOPLIST_PREPROCESSOR_DEFINITIONS = DEBUG=1,

enter image description here

it can be conditional preprocess like C code using #ifdef or #if directly in Info.plist.

<key>UIMainStoryboardFile</key>
<string>Main</string>
#if DEBUG
<key>NSAppTransportSecurity</key>
<dict>
    <key>NSAllowsArbitraryLoads</key>
    <true/>
</dict>
#endif
<key>UIRequiredDeviceCapabilities</key>
<array>

Cons: Unable to open Xcode's property list editor because it is not well-formed XML :(

kishikawa katsumi
  • 10,418
  • 1
  • 41
  • 53
  • 1
    I really like this approach, despite it not being (pre-processed) well-formed XML. – Craig Otis Dec 19 '16 at 12:40
  • This is a bad ideia once Xcode won't be able to open and render it properly. If you need to do another change in the future, you will only see that something is wrong at compile time. @nobre has the better approach. – Salmo Oct 26 '17 at 09:37
  • This also breaks the _Identity_ section of the project settings (i.e. where the display name, bundle identifier, version, and build are typically set), since the plist is malformed. In my case, this also caused some warnings related to the launch screen. – Isaac Overacker Jan 22 '19 at 01:10
5

Yes, you can configure your project settings to use different Info.plist file for Debug, Release or whatever configuration you use in your project (similar to the way Provisioning Profiles are set), so in your Debug plist you can disable ATS totally.

Go to Project -> Your Target -> Build Settings -> Info.plist File

Maciek Czarnik
  • 5,950
  • 2
  • 37
  • 50
  • 2
    This way, I would need multiple copies of Info.plist file whose contents are pretty much similar, except ATS-related settings. Is there any way I can reduce this duplications? – Andree Sep 04 '15 at 06:24
  • 1
    Hmmm, I know :) You can create a shell script that will be invoked with every build (Run Script build phase). What it needs to do is: 1. Create a copy original plist file 2. Delete `NSAppTransportSecurity` key from copy 3. Add `NSAppTransportSecurity` with `NSAllowsArbitraryLoads` Use PlistBuddy, and feel free to update my answer :) – Maciek Czarnik Sep 04 '15 at 06:32
  • Hey that's interesting, I'll try that out. Meanwhile, I'll just accept your answer. Thanks! – Andree Sep 04 '15 at 06:39
1

I've made the solution based on above but working smoothly with git repo. The idea is to maintain the original Info.plist for the Release configuration with the only difference with Debug in NSAllowsArbitraryLoads made automatically on build.

My Xcode version is 11.3.1. There are 3 simple steps:

  1. Add Info.debug.plist for Debug configuration at Build settings - Packaging - Info.plist File:

Info.debug.plist

  1. Add this Run script at Build phase:
    # Disables ATS in debug configuration
    if [ "${CONFIGURATION}" = "Debug" ]; then
        plist=$PRODUCT_SETTINGS_PATH
        src="`dirname $plist`/Info.plist"
        cp -f $src $plist
        /usr/libexec/PlistBuddy -c "Set :NSAppTransportSecurity:NSAllowsArbitraryLoads YES" "${plist}"
    fi

Run script

  1. Put Info.debug.plist to the .gitignore:

echo Info.debug.plist >> .gitignore

Denis
  • 302
  • 4
  • 7