WKWebView XMLHttpRequest fails with custom url scheme - ios

I'm building a mobile app using WKWebView. I register custom url schemes image:// and thumb:// to serve assets from the native part to the web part of the app.
webViewConfiguration.setURLSchemeHandler(handler, forURLScheme: "image")
webViewConfiguration.setURLSchemeHandler(handler, forURLScheme: "thumb")
This approach works well if urls with a custom scheme are used in HTML. For example, <img src="thumb://watermarkly.com/1.jpg" /> works properly - WKWebView invokes my handler and displays the result. However, WKWebView blocks requests if I try to fetch these urls using XMLHttpRequest:
[Warning] The page at https://watermarkly.com/app/watermark/ was allowed to display insecure content from thumb://watermarkly.com/1.jpg.
[Warning] [blocked] The page at https://watermarkly.com/app/watermark/ was not allowed to display insecure content from image://watermarkly.com/1.jpg.
[Error] Not allowed to request resource
[Error] XMLHttpRequest cannot load image://watermarkly.com/1.jpg due to access control checks.
The only difference here is that "thumb:" url was assigned to an img tag, while "image:" url were fetched via XMLHttpRequest. Unfortunately, no other info provided in Safari Developer Tools.
The problem appears on a real devices only - everything works properly in iOS Simulator.
Is there something I need to configure to make it work for XMLHttpRequests as well?
Update
We switched from HTTPS to HTTP to make XHR to solve the problem.
Unfortunately, custom url schemes seems not to work on some iPhones. We have 5 customers with iPhones where nor switching to HTTP, nor sending Access-Control-Allow-Origin header help. We weren't able to identify which setting causes the issue - the problem cannot be reproduced on any of devices we have. Apple reviewer didn't have any complaints as well. Nor XHR, not getting images through urls work on these phones. One of the customers has two phones. Custom url schemes work on one of them and they don't work on the second one at all. He says they are identical and there is no Safari extensions installed. Unfortunately, we weren't able to identify what causes the problem. Beware custom url schemes may not work on some phones.

Related

iOS - in app with SFSafariViewController unable to load another host in iframe

I am trying to load the host1 page, it contains iframe and the URL for the iframe is host2. But iframe with URL host2 is not loading properly.
I am loading host1 page through SFSafariViewController. If I load the same thing with the iPhone safari browser then it is working fine but not working with SFSafariViewController. As per my understanding, WKWebview has some limitations but SFSafariViewController doesn't have but still facing the issue.
I have tried the below options also in iOS14.5.1 but still, it is not working:
Enabled Allow Cross-Website Tracking by using NSCrossWebsiteTrackingUsageDescription in info.plist
Enabled Allow Tracking by using Privacy - Tracking Usage Description in info.plist
used WKAppBoundDomains also.
am I missing anything, please help me out?
Adding few more details:
When I am inspecting the code got the below errors with the mobile app SFSafariViewCotroller and the required content is not loading, but it is working fine with mobile, desktop Safari browsers and not showing any errors.
Refused to load {URL://_csrfRefresh=1} because it does not appear in the frame-ancestors directive of the Content Security Policy.
Sandbox access violation: Blocked a frame at {URL} from accessing a cross-origin frame. Ther being accessed is sandboxed and lacks the "allow-same-origin" flag
Attaching a screenshot below for reference,

URL scheme in iOS with WebView

I'm developing an iOS application in which I want to provide users with a payment gateway, which is a web page. I'm showing this web page in a WebView.
The payment gateway accepts 2 URL params - success and failure URL, which are the URLs users is redirected to after completing purchase. Redirect is done via JavaScript location.href property and works properly in desktop browser and Android app.
I've set the URLs to let's say tft://redirect/success?id=123 resp. tft://redirect/failure?id=123
I want my app to handle this redirect and show Success or Failure message to user.
I followed many tutorials including Apple's docs.
First of all I'm not sure why Apple docs show scheme without slashes (myphotoapp: instead of myphotoapp:// - does it make a real difference?)
I've registered custom scheme tft and implemented the func application(..) function according to the docs.
Now when the redirect should happen, nothing really happens, the func application is not called at all.
I started development with iOS 12 and recently switched deployment target to 13.5, however, the project structure didn't change (scene delegate missing - is it an issue?).
Can you please give me any direction?
Thanks in advance.
According to https://stackoverflow.com/a/37240425/9046249 custom scheme behaves somewhat wierd. When I switched the scheme to http or https it works like a charm.

Do Universal Links hit my server?

I've set up Universal Links on my iOS app using an aliased subdomain of my backend with a scheme like sudomain.mydomain.com. I want users that DON'T have the app installed to be redirected to our page in the App Store rather than hitting some nonexistent endpoint on our server (we don't have a webapp only a mobile backend).
I was thinking about doing something like this:
app.get('*', (request, response) => {
const domain = request.headers.host,
subdomain = domain.split('.');
if ( subdomain[0] === 'subdomain'){
response.redirect('www.linktoappstore.com');
}
...
});
However I don't want this to interfere with Universal Linking for people who DO have the app installed. Are Universal Link get requests sent to my server or does iOS intercept them before that happens?
This should work just fine.
When Universal Links are configured and your app is installed, the device does NOT hit the server before launching the app. This is because iOS caches the apple-app-site-association file when the app is initially installed, and if the URL being opened matches a path defined there, Universal Links kick in. In that situation, iOS completely bypasses any web request and immediately launches your app.
Of course, this means you can't track Universal Link traffic, which can become a major pain point. To work around this, you need something like Branch.io (full disclosure: I'm on the Branch team) to fill in the missing data.
Separately, if you're proxying the subdomain, make sure iOS doesn't see that as any sort of redirect. Otherwise the apple-app-site-association file won't be scraped at all (common Universal Link implementation issue).

Are URL Schemes on iOS case-sensitive?

The official Apple documentation doesn't seem to specify whether iOS URL schemes are case-sensitive or not.
Can I register myApp and still get opened for someone calling openURL: on MyApp://params?
They are not case-sensitive.
You can verify this by entering both sms:// and sMs:// into the URL box in Safari.
Also, it seems that third-party URL schemes in the Safari address bar now lead to a page not found error. This must be new in iOS 9.3.x, because it did not do this before. Entering the URL into another app (e.g. Notes) and then opening it still works.
Edit: the above hypothesis about iOS 9.3.x is actually a bit more nuanced...
They work if…
You are starting from a ​blank​ screen
A page is still loading when you request the custom URL scheme
They do NOT work if…
You are on a webpage that has fully loaded before you request the custom URL scheme
Go figure

iOS App with Webview inspecting > find URL

I'm using an iPhone App that has some important information on it, but I also figured out that it uses a webview. And I'm not sure if it's safe; like; is it over https? What URL is being called?
Is there a way you can find out what Website is being called in the webview? Like you can do inspect element when using Safari from OSX with usb-connected iPhone.
UIWebview works for any url you call it with. If your site is https, the communication will be encrypted. Not all requests on UIWebView are not https. You can't inspect element from iPhone/iPad/Simulator. You can do it in web in the mobile view (by using useragent).

Resources