Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add functioning debug build for iOS device #1396

Closed
1 task done
saifahn opened this issue Aug 5, 2019 · 6 comments
Closed
1 task done

Add functioning debug build for iOS device #1396

saifahn opened this issue Aug 5, 2019 · 6 comments

Comments

@saifahn
Copy link

saifahn commented Aug 5, 2019

Scope of the feature

Currently, installing the app from Xcode onto a iOS has a few problems:

  1. The app does not manage to connect to the Metro Bundler server.
  2. If you exit the app, it will not run when opened again.
  3. The Xcode debugger shows something like:
2019-08-05 12:39:11.791678+0200 JolocomWallet[296:10004] [] nw_socket_handle_socket_event [C25.2:1] Socket SO_ERROR [61: Connection refused]
2019-08-05 12:39:11.792320+0200 JolocomWallet[296:9857] [] nw_connection_get_connected_socket [C25] Client called nw_connection_get_connected_socket on unconnected nw_connection
2019-08-05 12:39:11.792388+0200 JolocomWallet[296:9857] TCP Conn 0x283874cc0 Failed : error 0:61 [61]

These may all be due to the configuration within the AppDelegate.m file, where the jsBundleURLForBundleRoot is incorrect.

It would be ideal to have a functioning debug version of the app that runs on an attached iOS device.

Tasks

  • Research errors
@saifahn
Copy link
Author

saifahn commented Sep 10, 2019

The problem is in AppDelegate.m:

#if DEBUG
  return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index" fallbackResource:nil];

As stated here, this will try and work out your device's IP address and connect to it.

This works fine with an emulator as it is running on the same system and the IP might default to localhost. It does not work at with the device as it cannot find the development environment.

  • Test if this only happens on the betahaus network

Solution 1

We can replace this line with our own local tunnel thing, for example if we use ngrok:

#if DEBUG
  return [NSURL URLWithString:@"https://73c05e9e.ngrok.io/index.bundle?platform=ios"];

This works. It must https and the actual URL needs to be adjusted to your currently running ngrok process. This is fine for just loading the bundle, but will not work with the 'Debug JS Remotely'.

Debug JS Remotely

In RCTWebSocketExecutor.m from line 54 we originally have:

if (!_url) {
  NSInteger port = [[[_bridge bundleURL] port] integerValue] ?: RCT_METRO_PORT;
  NSString *host = [[_bridge bundleURL] host] ?: @"localhost";
  NSString *URLString = [NSString stringWithFormat:@"http://%@:%lld/debugger-proxy?role=client", host, (long long)port];
  _url = [RCTConvert NSURL:URLString];
}

host will use the URL from AppDelegate.m, so will be your ngrok URL. This original URLString calculation adds in the port, and we don't need that as the ngrok will connect to the port directly. Instead we can use this:

if (!_url) {
  NSString *host = [[_bridge bundleURL] host] ?: @"localhost";
  NSString *URLString = [NSString stringWithFormat:@"http://%@/debugger-proxy?role=client", host];
  _url = [RCTConvert NSURL:URLString];
}

Now pressing 'Debug JS Remotely' will bring up an error of Runtime is not ready for debugging!. The debugger-ui will not open automatically, and you will have to open http://localhost:8081/debugger-ui/ manually. Reloading the app should allow a connection to the remote debugger now.

REFERENCE:

facebook/react-native#6682

Notes

This current solution doesn't seem optimal, as it requires updating the AppDelegate.m every time we wish to use it. It may be a reasonable option for now, however.

Additionally, we still have a repeating log in Xcode similar to this issue

  • There is a chance that a future version of react-native fixes these issues.

@saifahn
Copy link
Author

saifahn commented Sep 10, 2019

As RCTWebSocket.xcodeproj and its contents are not committed to our repository, this requires manual updating:

Search for RCTWebSocketExecutor.m, line 54.

If you are developing on simulator, use the default:

// FOR SIMULATOR DEVELOPMENT VERSION, REMOTE DEBUGGER
if (!_url) {
  NSInteger port = [[[_bridge bundleURL] port] integerValue] ?: RCT_METRO_PORT;
  NSString *host = [[_bridge bundleURL] host] ?: @"localhost";
  NSString *URLString = [NSString stringWithFormat:@"http://%@:%lld/debugger-proxy?role=client", host, (long long)port];
  _url = [RCTConvert NSURL:URLString];
}

If you are developing on device, use this version:

// FOR DEVICE DEVELOPMENT VERSION, REMOTE DEBUGGER
if (!_url) {
  NSString *host = [[_bridge bundleURL] host] ?: @"localhost";
  NSString *URLString = [NSString stringWithFormat:@"http://%@/debugger-proxy?role=client", host];
  _url = [RCTConvert NSURL:URLString];
}

saifahn added a commit that referenced this issue Sep 10, 2019
To run a development build on an iOS device, some settings need to be
tweaked. Some comments have been added to AppDelegate.m to help with
this. More information is available at the issue:

#1396

Notion should also hold some documentation.
@mnzaki
Copy link
Contributor

mnzaki commented Sep 10, 2019

Is this related to the react native update to 0.59? How was it functioning before?

@saifahn
Copy link
Author

saifahn commented Sep 10, 2019

We never had a development version on iOS. We had a set-up similar to this.

We would comment out the development line and comment in the production line to load from the main bundle that is bundled in, rather than use a development server.

@mnzaki
Copy link
Contributor

mnzaki commented Sep 11, 2019

Is there any way to pass in things from build-time environment variables? Probably must be done through some form of generated file, if there are any such files for iOS builds. That would be optimal, to avoid changing things in the code itself just for building, and also because the IP can be directly baked in and no need to go through ngrok

@saifahn
Copy link
Author

saifahn commented Sep 11, 2019

There is a script that actually runs in the original config of our AppDelegate.m:

https://github.com/facebook/react-native/blob/master/scripts/react-native-xcode.sh

This is meant to get the IP and use it. I was meant to test this today at home to see if it is another betahaus problem, but I forgot to bring an iOS device home. Also my wifi at home uses WPS for its password with some really long password and there is no easy way of using this on iOS.

mnzaki added a commit that referenced this issue Jan 30, 2020
iOS devices access the dev server over the network, and the device needs
to be on the same network for this to work. And the network needs to
allow it of course, so this was non-functional in Betahaus. This is
probably the only reference to Betahaus in our git logs; this is their
legacy.
Anyway, there's an xcode build phase script
(node_modules/react-native/scripts/react-native-xcode.sh) which
"guesses" the build machine's IP and writes it to a text file inside the
.ipa, which is then loaded by the react bridge.

Closes #1396
@mnzaki mnzaki closed this as completed in 66b1b78 Feb 3, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants