Sean Moody
Sean Moody

Reputation: 380

Ionic/Capacitor React App API Requests returning HTML on iOS

The current behavior:

All API requests to the localhost server are returning the index.html file of the React.js app on the iOS build, but requests work fine on browser and PWA builds.

The expected behavior:

Requests return the intended data (usually JSON).


Details

Typically, API requests go to http://localhost:3000/api/[route]. In the iOS build, they are going to capacitor://localhost/api/[route]

Because the route is returning HTML and not JSON data, I am getting the following error (one of many, as each API route, has the same error) which causes a white screen:

TypeError: undefined is not a function (near '...a.map...')

I tried adding a hostname (location where the production server is hosted) to the capacitor.config.json file in my root directory, but it still fails. Dev API server is running on localhost:3000.

Tried setting the server hostname to "localhost:3000" in the config as well.

"server": {
    "hostname": "localhost:3000"
  },

"http" is not allowed as a iosScheme as mentioned in the docs for the capacitor config: Can't be set to schemes that the WKWebView already handles, such as http or https](https://developer.apple.com/documentation/webkit/wkwebviewconfiguration/2875766-seturlschemehandler)

Because the site works on every other build other than this iOS build, the issue should be here...

How can I route my requests on the iOS build to direct to the correct location?

Update

If I set the server.url option in the capacitor.config.json file to https://www.website.com, I'm able to pull data from my production server, but when the authorization check returns a 401, the app seems to hang on the splash screen and the only error-like message I get in the console is that the response returned a 401 (as expected)

Device console output: Device console output

XCode console output: Xcode console output

Upvotes: 2

Views: 2156

Answers (2)

Sean Moody
Sean Moody

Reputation: 380

The first issue was fixed by setting the server.url parameter in the capacitor.config.json file to the URL of the production server:

"server":{
    "url":"https://www.website.com"
}

Second issue was making sure the splash screen hide code from @capacitor/splash-screen was actually deployed onto prod in the index.js file.

import { SplashScreen } from '@capacitor/splash-screen';
setTimeout(() => {
  SplashScreen.hide();
}, 2000);

Upvotes: 1

jcesarmobile
jcesarmobile

Reputation: 53341

By the little information you have provided I'll try to guess what's wrong.

  1. You are using relative urls instead of absolute urls. If you make a XHR/fetch call to /api/[route], the browser will append the scheme and host name to it and will turn it into capacitor://localhost:3000/api/[route]. That url belongs to the app, not to the web server where you API is running.
  2. You are using localhost, localhost means "this machine", if you run the app in a browser or iOS simulator, localhost is the machine where the browser and simulator and browser are running, and the local server is also running on the same machine, so they don't have any problem accessing it. But if you run on a real device, localhost is the device, and the device doesn't have a server running. You should use the local IP (numbers) of the computer where the server is running, and the device should be connected to the same network for being able to access it.
  3. Capacitor apps are "affected" by CORS, you need special server configurations to allow the connections https://ionicframework.com/docs/troubleshooting/cors.

Looks like you are on the point 1, once you fix it you'll hit point 2 and then probably point 3 after that.

Upvotes: 1

Related Questions