<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Subhrojit Hore</title>
    <description>The latest articles on DEV Community by Subhrojit Hore (@quietquasar).</description>
    <link>https://dev.to/quietquasar</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4156899%2F99c07700-2f71-4414-a5cb-ea2bb945ede4.jpg</url>
      <title>DEV Community: Subhrojit Hore</title>
      <link>https://dev.to/quietquasar</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/quietquasar"/>
    <language>en</language>
    <item>
      <title>Ionic iOS app worked in Safari and as a PWA, but failed inside the native app. Migrating to CapacitorHttp fixed it.</title>
      <dc:creator>Subhrojit Hore</dc:creator>
      <pubDate>Fri, 02 Oct 2026 09:10:27 +0000</pubDate>
      <link>https://dev.to/quietquasar/ionic-ios-app-worked-in-safari-and-as-a-pwa-but-failed-inside-the-native-app-migrating-to-42gh</link>
      <guid>https://dev.to/quietquasar/ionic-ios-app-worked-in-safari-and-as-a-pwa-but-failed-inside-the-native-app-migrating-to-42gh</guid>
      <description>&lt;p&gt;Wanted to share a recent issue I ran into with an Ionic + Capacitor iOS app in case it helps someone else.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;The Problem&lt;/strong&gt;&lt;br&gt;
Users started reporting that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The app launched successfully.&lt;/li&gt;
&lt;li&gt;The home page loaded correctly.&lt;/li&gt;
&lt;li&gt;Screens behind the homepage were blank or failed to load data.&lt;/li&gt;
&lt;li&gt;Reinstalling the app didn't help.&lt;/li&gt;
&lt;li&gt;Restarting the device didn't help.
At first glance it looked like an API issue.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;What made it weird?&lt;/strong&gt;&lt;br&gt;
I quickly found that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Backend APIs were healthy.&lt;/li&gt;
&lt;li&gt;Safari could access the APIs.&lt;/li&gt;
&lt;li&gt;The PWA version worked fine.&lt;/li&gt;
&lt;li&gt;Direct API endpoint testing worked.&lt;/li&gt;
&lt;li&gt;Only the native IOS app failed.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So the pattern became:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Safari ✅
PWA ✅
Backend API ✅
Native iOS App ❌
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That immediately pushed me away from investigating the backend and toward the apps networking layer.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Architecture Before&lt;/strong&gt;&lt;br&gt;
The application was using Angular's standard HTTP implementation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Ionic App
   ⬇️
Angular HttpClient
   ⬇️
WKWebView
   ⬇️
XMLHttpRequest / Fetch
   ⬇️
Backend API
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The APIs themselves were hosted in Azure and showed no issues.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Things I Considered&lt;/strong&gt;&lt;br&gt;
I investigated:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Backend/API failures.&lt;/li&gt;
&lt;li&gt;Authentication issues. &lt;/li&gt;
&lt;li&gt;CORS.&lt;/li&gt;
&lt;li&gt;Caching. &lt;/li&gt;
&lt;li&gt;App build corruption. &lt;/li&gt;
&lt;li&gt;TLS/Certificate chain issues.
Because the browser and PWA worked, backend problems became increasingly unlikely.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;What I Changed&lt;/strong&gt;&lt;br&gt;
I migrated the API communication from:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;HttpClient
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CapacitorHttp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I implemented the requests using:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;CapacitorHttp&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@capacitor/core&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The application had previously relied on Angular's standard HTTP client:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;http&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(...)&lt;/span&gt;
&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;http&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(...)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;which executes requests through the iOS WebView networking stack.&lt;br&gt;
After the change, requests were made using:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;CapacitorHttp&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@capacitor/core&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;CapacitorHttp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;request&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;GET&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
  &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;apiUrl&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;Authorization&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`Bearer &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;token&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;POST example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;CapacitorHttp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;request&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;POST&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;apiUrl&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Content-Type&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;application/json&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;payload&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Also, enabled Capacitor's native HTTP handling via configuration (capacitor.config.ts) :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;plugins:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;CapacitorHttp:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;enabled:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; 
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The network path became:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Ionic App
   ⬇️
CapacitorHttp
   ⬇️
Native iOS URLSession
   ⬇️
Backend API
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Instead of relying on the WKWebView networking stack, requests now use native iOS networking.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Result&lt;/strong&gt;&lt;br&gt;
After the migration:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;API connection restored.&lt;/li&gt;
&lt;li&gt;Previously blank screens started loading data again.&lt;/li&gt;
&lt;li&gt;Navigation warps normally.&lt;/li&gt;
&lt;li&gt;Issue could no longer be reproduced. 
I Redistributed the build through Testflight and successfully validated the fix on physical IOS devices.&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;em&gt;&lt;strong&gt;Note:&lt;/strong&gt; I have not yet proven the exact root cause. However, after migrating from AngularHttpClient/WebView networking to CapacitorHttp/native networking, the issue could no longer be reproduced during TestFligh validation and user testing. That was sufficient for us to proceed with releasing the fix.&lt;/em&gt;&lt;br&gt;
&lt;em&gt;&lt;strong&gt;Possible contributers:&lt;/strong&gt;&lt;/em&gt; &lt;br&gt;
&lt;em&gt;- WKWebView networking behavior&lt;/em&gt;&lt;br&gt;
&lt;em&gt;- TLS/certificate handling differences&lt;/em&gt;&lt;br&gt;
&lt;em&gt;- Corporate proxy/security inspection&lt;/em&gt;&lt;br&gt;
&lt;em&gt;- URLSession vs WebView request handling&lt;/em&gt;&lt;br&gt;
&lt;em&gt;- iOS-specific networking quirksx1&lt;/em&gt;&lt;/p&gt;

</description>
      <category>api</category>
      <category>debugging</category>
      <category>ios</category>
      <category>mobile</category>
    </item>
  </channel>
</rss>
