Best practice to connect from test iphone to local server - ios

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.

Related

Associated Domains with `applinks:` is not working in development

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..)

Is there an way to Inspect a broken link in an app?

We have an iOS app that has a Watch Tutorial link to our website. We recently migrated our website and the page it points to is now showing a 404 error. We need to know what page the link points to so we can redirect it. Unfortunately in the app it just opens link to the page in the actual app and not in safari or any other browser so we can't see the website link.
Is there a way to "inspect" the link in our app like you can in a browser to see where it is pointed to? Maybe some debugging software that can pull the app down and let me look at it? Our app developers are unavailable right now and we want to get the app up and running correctly.
You can try with the Safari Web Inspector (Safari mac remotely debugging on an iPhone app/safari).
With this approach, you can inspect from you mac, any WebViews (or related) in actual apps.
Note : It won't work if you app make the request, but does not use web view to display the page.
See any tutorial on how to enable safari web inspector
Maybe some debugging software that can pull the app down and let me look at it?
You can use a web proxy such as Charles to easily see all the traffic going to and from the app:
Install the proxy software on your computer.
Set the device to proxy through your computer.
If needed, install SSL certificates that will let the proxy see the contents of TLS connections.
Fire up the proxy, launch the app, and watch the traffic.

how to test universal links on local server?

I am developing an app on Android and IOS and I would like it to support universal links.
I already have an apple-app-site-association file deployed on my PROD server (which is something like www.example.com), but I need to redeploy a new one with some restrictions inside (to NOT allow some paths).
Before redeploying it, I would like to test it on my test server. So I deployed it on the test server (which is www.example.test.local).
To test, I modified my IOS app by changing in Associated Domains the param applinks:.example.com by applinks:.example.test.local. Then I builded my app and tried to click on an url which is www.example.test.local/myPath?myQueryParam=toto (which is not a 'NOT allowed' one). But instead of opening the app, it opened the index of my test server (if I rollback everything and click on an url like www.example.com/myPath, it works perfectly but it is the old apple-app-site-association file).
So did I miss something? What do I have to change to make it work on my test server?
Late to the party here, but most likely your .local server was running on HTTP. You need to use HTTPS, with a valid certificate that the iOS device recognises (try fetching the AASA file by just typing in the URL, including https:// prefix, into Safari; if you get "This Connection Is Not Private", then your cert isn't good enough - stepping through warnings and forcing Safari to visit the site anyway may be enough to get the trust store updated and have the wider system accept your cert).
Unfortunately, like everything to do with app links on iOS and Android, it's a huge pain and exceptionally developer-hostile. There does not seem to be any kind of easier test option for local machine development - or at least, nothing that I can find documented.

React-Native: how to use "Remote JS Debugger" on real iOS-device?

I'm wondering if react-native's Remote Debugger mode would be possible also on real device. But it stops me with an error page stating
"Connecting to http://localhost:8081/debugger-proxy?role=client timed
out"
The interesting fact here is that this URL won't also work on my developer machine.
Opening this URL (http://localhost:8081/debugger-proxy?role=client) in a browser on my developer machine with running packager.js will respond with:
Cannot GET /debugger-proxy?role=client
When I turn off Remote debugger, everything works as expected.
Steps to reproduce:
react-native init testapp
cd testapp/ios
open the .xcodeproj-File with XCode
Select my connected iPhone as target device
Run the application
The application will fetch the source code from my local machine. In order to make this work, both, the iPhone-device and my iMac, are connected to the same WiFi.
The ReactNative-Application is executed on the iPhone as expected. With the shake-gesture I spawn the developer menu and select the option "Debug JS Remotely".
Now this error appears as mentioned above.
Following a side note in running-on-real device I changed the Host from localhost to the IP-Address of my Mac in RCTWebSocketExecutor.m, but this results in an endlos loop while fetching.
The Question is:
How can I use the Remote JS Debugging-Feature on real device?
Update
After further investigation I came to the conclusion that this might be a bug and opened the following issue on GitHub.
In chrome browser, I have changed
localhost:19001/debugger-ui
to
192.168.0.4:19001/debugger-ui
and it worked. Replace 192.168.0.4 with your ip address.
We had a similar issue here in 2020 and now there is a better solution which is to update the IP of the target machine directly from the app. Be on the same wifi with both the computer and the device - even if they are connected with a USB.
Shake the phone to get the menu
Select Configure Bundler
Insert the IP of the computer
Press Apply Changes
Now you should get debug data on the computer.
On iOS devices, open the file RCTWebSocketExecutor.m from react-native/Libraries/WebSocket/RCTWebSocketExecutor.m and change "localhost" to the IP address of your computer, (don't forget the correct port. eg: 192.168.1.6::8880) then select "Debug JS Remotely" from the Developer Menu.
NOTE: remove the app from your device, close the terminal that opened
for creating bundle.js. finally press the Play button from your Xcode.
here is the official guide from react-native website:

ReactNative - Why does a React Native App need to connect to Local Host?

I have been reading a book on React Native that builds a simple React Native App for IOS in the first few chapters. When compiling and running the project in Xcode, a packager runs in the background and I can also see my app trying to connect to local host.
My understanding is that React Native converts JSX elements to platform specific views. So my question is why does the App need to connect to a server and what is the purpose of the packager running in the background?
Also, how is running the app on an Xcode simulator different from deploying it on the app store?
I have tried to look online for answers, but no one has addressed them. It seems everyone is taking it for granted that all this is obvious.
After looking for an answer, I stumbled upon the following guide from Facebook that answers a different question but also addresses mine indirectly.
So apparently, the localhost is a development server used to link your javascript code to the app, which you use if you are testing on a physical device or a simulator. So the question that comes to one mind after reading this is why not bundle that javascript code with the compiled IOS files? Well, it is best to keep them separate because it enables you to simply change your javascript code from your computer and have it automatically sync with your IOS app.
Now, when it comes to deploying to the app store, you will need to bundle the javascript code and remove the implementation part where it connects to a localhost, which, again, is used for debugging purposes.
You answered your own question it appears! In development mode, the JavaScript bundle is served from the react-native packager server on your machine.
When making a release for the App Store and Google Play, the JavaScript is minified and bundled into the app file (.ipa/.app for iOS, .apk for Android).
Running the app in release mode is possible from Xcode. Depending on how your project is set up, release mode could be a different target, a different scheme within one target, or a build configuration within a target's scheme. For more on iOS targets/schemes, see: Xcode: What is a target and scheme in plain language?

Resources