How can I disable App Transport Security only when I run my app on the simulator (while still keeping it enabled when I run my app on my device, even in Debug mode)? Is there a way to disable it with Swift code instead of by modifying the Info.plist file?
I'm asking because I've configured things (via the code snippet below) so that the simulator connects (over HTTP) to a development server running on localhost and the device connects (over HTTPS) to the production server running in the cloud.
#if arch(x86_64) || arch(i386) // simulator
let apiBaseURLString = "http://localhost:3000"
#else // device
let apiBaseURLString = "https://api.example.com"
#endif
Ideally, I'd like keep App Transport Security enabled on the simulator and have the simulator connect over HTTPS to the development server running on localhost. I had that working, but I just updated Xcode, and it broke.
App Transport Security is configured at compile time by reading in the Info.plist. Changing it at runtime would actually have no effect on ATS enforcement, even if you could change the Info.plist at runtime (which you can't).
I can only think of two solutions:
Simulator build config -You could create two versions of the Info.plist, one of which disables ATS altogether, the other is used for running on devices. You can then create a specific build config for running on the simulator. In your Build settings, choose the new Info-Simulator.plist which disables ATS. The downside of this is that you would need to change your build config before running on the simulator - it would not automatically use the correct build config for simulator vs. devices.
Don't have different ATS settings for the simulator. Configure ATS to handle both the Simulator and physical devices. There are many options for ATS exceptions that should work for most scenarios. Need exceptions for local network connections? Look into NSAllowsLocalNetworking. Need more flexibility in a webview? Try NSAllowsArbitraryLoadsInWebContent.
Unfortunately, you can detect the simulator at runtime, but you can't change ATS behavior at runtime. You'll need to find another way, or re-evaluate if you really need a different config on simulators vs. devices.
I think this Code should work to access the .plist file, upon this code you can make changes what you need and put condition for that.
Bundle.main.object(forInfoDictionaryKey: key_name)
UPDATE
Here I'm Posting an Image please folow it:
Here you can get the value for:
NSAllowsArbitraryLoads = 1;
And through this you can put a condition according to your requirement.
Thanks
Related
I'm trying to set up Associated Domains in my unpublished app for iOS 14. I followed the documentation as good as possible. I'm testing locally with my local dev web server and the app itself in simulator and a real iPhone.
Not only are links not opening in my app, the app does not even attempt to request the file https://mycomputer.local/.well-known/apple-app-site-association from my local web server (I let the web server print a debug message whenever it is requested, but the message is only printed when I manually load it from a web browser).
This is a list of things I have done/checked:
Xcode 12.2:
Under Signing & Capabilities added Associated Domains
Added to Domains: applinks:mycomputer.local?mode=developer (I also tried IP address)
I disabled Automatically manage signing and instead created a Profile on https://developer.apple.com/account/resources/profiles/list (type Development, platform iOS, it has Associated Domains amongst other enabled capabilities and it's linked to my app bundle ID) and selected that profile for the debug build.
I made sure that the URL https://mycomputer.local/.well-known/apple-app-site-association is accessible from all devices involved, i.e. my computer, Safari in simulator, Safari on real iPhone (all are connected to the local network and successfully display my JSON file).
Screenshot:
As mentioned above, I can pretty much rule out that the problem lies with the JSON file itself as I can proof that the device is not even accessing it. Am I missing something or misunderstanding the concept?
My own answer: Using the query string ?mode=developer in the entitlement as described in the documentation simply appears not to work at all.
To verify this I have set up a real server that can be publicly reached on the internet and tried both variants:
applinks:example.com
applinks:example.com?mode=developer
Number 1 works, but the JSON is loaded via Apple's CDN and you cannot use it for local development or for quickly testing different versions of the JSON file as Apple will cache the file for probably one day.
Number 2 does not work at all, no request to the server will be made.
Also, good to know these requirements when testing on actual devices. (And using a domain thats not publicly available in testing period.)
Turn on Developer Mode on the device.
Turn on Associated Domains Development in the Developer settings. (Developer settings will first occur after you have turned on Developer Mode).
Build the app using developer certificate. (Enterprise will not work).
Add ?mode=developer to the domain in entitlements if you are testing with a domain thats not publicly available (Behind VPN..)
I am setting up the production, staging and development stacks/configurations modes for my iOS and API (backend).
I figure the "RELEASE" mode definitely be when the application is public on the app store. I would like to know which configuration mode is used when the iOS application is distributed on TestFlight ?
I understood that the scheme is what determines which configuration mode is used. While I upload the .ipa to TestFlight the Archive scheme is used.
Therefore, now I would like to know if there is a way to have a different configuration for what is on TestFlight and what is released.
What I am trying to solve
We use TestFight to distribute the application to our external testers and stake holders. Therefore would like that application to have a different configuration (e.g. SERVER_ENDPOINT_URL)
Thanks!
Well, I found out that I what I want to accomplish is not possible. Nor was the system built in a way to address my issue.
So what I am doing now is.
Archiving a build with "debug" configuration
Uploading to TestFlight and distributing the executable
After testing is complete
Recompile / re archive the build with "release" configuration
Upload to iTunesConnect and publish the application
Thanks!
Apps are distributed to TestFlight in release mode. If I understand your question right, which I'm not sure I do, at the basic level you want to use a different endpoint URL in your release version. You can differentiate between debug and release using the following
#if DEBUG
static let baseURLString = "https://mydebugurl.com"
#else
static let baseURLString = "https://myreleaseurl.com/"
#endif
However for that to work you need to add custom flags to your build settings, see this question for more info
I hope that answers your question
As far as I know, you won't be able to provide "a different set of variables" for builds pushed to testFlight and app release. That is what it is there for, to test the same byte code that will be published to the public.
With that said, what you could do: Create a "version" endpoint. So if you know that when you first push build 1.2, you will want stakeholders/external testers to see it first. Send a request to your prod server, passing along the build version that is being used, if version == 1.2, point all endpoint traffic to your special "development" endpoints(creating a hostName variable in your SessionManager device side, and setting that accordingly will make that really simple), else push the user on to use prod data.
I have set App Transport Security for my iPad App with exception domains for few open api like weather online traffic etc., which we display it in a cordova webview. If I run it directly into iPad, it is working fine. But it is not loading correctly if I archive and distribute it.
Any idea ?
Actually, it looks like you are incorrectly adding exception domains. Don't include http:// in your exception domain entries.
Are you testing locally on an iOS 10 device (which would use the NSAllowsArbitraryLoadsInWebContentto ignore ATS in your web view altogether)? It would work on an iOS 10 device, but maybe the enterprise distribution fails on a device because the device is iOS9, which would try to use your exception domains, which are formatted incorrectly.
Another possible reason for a difference in behavior is that you have a different Info.plist specified for debug vs. release builds. Verify in your project settings that you are referencing the same Info.plist file for both build configs.
I created a new feature that should load a remote URL connection. I also whitelisted the domain, just to be sure. The problem is that when I deploy it on my iPhone, it does not load that URL. On the contrary, on the simulator, it loads the URL without any issues.
What can be the problem?
Thank you in advance,
Razvan
I found the answer I needed. Since MAF 2.2.1, non-HTTPS connections seem to fail to run on iOS. So if you disable Application Transport Security (APS) , the problem should be solved. You can do it like this in JDeveloper :
Disabling App Transport Security for MAF Applications on iOS Devices
MAF applications that you migrate to this release of MAF enable ATS by default. You can disable ATS in your MAF application as follows:
In JDeveloper, choose Application > Application Properties > Deployment.
In the Deployment page, double-click the iOS deployment profile.
Choose iOS Options.
Select Disable Application Transport Security and click OK.
Hope to be helpful for others.
Thanks,
Razvan
Is there a standard way to build iOS apps in xcode such that, when running on a test iphone, the app can connect to a dev server running on my laptop?
For context, I'm making GET/POST requests to a remote server, so I need to choose the right host depending on whether or not it's a prod build.
I started off with #ifdef DEBUG to toggle between http://localhost and https://proddomain.com, but obviously localhost resolves correctly only on the simulator and not on the iphone.
I was hoping there'd be some scheme where you do port forwarding, etc to get it to work the same between simulator and test device. I'm currently hardcoding my local IP in the DEBUG build, and that won't work once more people are working on it.
I like registering a URL handler then using that to configure the app. It can be as simple as typing your custom URL into mobile Safari.
See Implementing Custom URL Schemes and this step-by-step guide.
e.g. if you type myapp://config?endpoint=192.168.0.123:8080 (correctly quoted, of course),
your app will be launched and you can extract the endpoint, overriding your production version.