This is not a duplicate question. Current "answers" to this problem use Objective-C, which allows for more expanded #Define
statements. The existing suggested solutions result in an IP address directly changing within a file; a build artifact I was trying to avoid.
I'm currently building some tests for a mobile app, built in Xcode with swift. This app uses a cloud service to get status of items, and store/retrieve login information.
---------- ---------
| Server | ---> | Cloud |
---------- ---------
When testing, however, I use a dummy server running on nodeJS to provide the expected responses, so I don't have to, say, register an account every time I want my UI tests to check the registration process.
---------- ---------
| Server | ---X | Cloud |
---------- ---------
| ----------
-------> | nodeJS |
----------
In order for this to work well on iOS simulator as well as on an external device, I need to specify the IP of the nodeJS server. I have been doing this manually, but I wanted to make it do so automatically.
Here's the rub: I want to be able to do this at runtime, or at least at buildtime without artifacts.
Solutions I've attempted:
PList Variables
I've created a variable in myinfo.plist
calledTestServerIP
. I then use a bash script at buildtime to change the value of the variable to myen0
address:#!/bin/bash localUrl=$(ipconfig getifaddr en0) plutil -replace TestServerIP -string \"$localUrl\" $SRCROOT/gdocntl/Info.plist
The problem with this is that I now have an IP address hardcoded in my .plist file.
New
plist
file
I wanted to simply make a newplist
file with only the IP var with bash, but you cannot create files outside of xcode and add them to the bundle easily. I started looking into this, but quickly found I'd be trying to do XML search/replacing... and we all know how well that works.- Swift script
I then tried using a modified swift script to pull the IP at runtime, from https://stackoverflow.com/a/25627545/9952260. The problem here is that when running on a physical iOS device, this grabs the IP of the iDevice, not the machine.
I've been trying to implement a variation of (1), where I instead define TestServerIP
to be something like ${NODE_JS_IP}
, but I'm not sure how I can define this using Xcode. I've been down a few rabbit holes:
- Adding variables at build time in Xcode (Only works with
#if
statements, not useful as my IP is not known before the build script runs) - Using compiler variables in Swift (according to this, I can't really do anything about my problem)
- https://medium.com/@danielgalasko/change-your-api-endpoint-environment-using-xcode-configurations-in-swift-c1ad2722200e (Really close, but ultimately falls back to using #if statements on pre-defined URLs, not arbitrary IPs)
TL;DR: How can I define the value of a custom swift flag or compiler variable, something I can assign to a variable in a plist
, at build time with a bash script?