forcedotcom / SalesforceMobileSDK-CordovaPlugin

Cordova plugin for the Salesforce Mobile SDK
Other
47 stars 114 forks source link

Salesforce and WKWebView #229

Closed mopi1402 closed 7 years ago

mopi1402 commented 7 years ago

My project is working great with WKWebView until I inject Salesforce plugin in cordova (4.2.0).

In this case, the sales force login is displayed in the WKWebView, but after a successful login, when the application starts, the web engine is automatically switched to UIWebView.

I need WKWebView in my project (which use native scroll for increased performance). Is there a way to do it working as excepted ?

Thanks !

bhariharan commented 7 years ago

4.2.0 supports only UIWebView. 4.3.1 supports both WKWebView and UIWebView, but defaults to UIWebView. You can override the default setting and use WKWebView though. In our next release, we will support only WKWebView (check out the latest on our unstable branch for a sneak preview).

mopi1402 commented 7 years ago

Sorry, I was talking about cordova ios 4.2.0 which is a required, and I'm already using the last version 4.3.1 of SalesforceMobileSDK-CordovaPlugin. Furthemore, I'm using this plugin (https://github.com/apache/cordova-plugins/tree/master/wkwebview-engine-localhost) for WkWebView, because it's the only one which is compatible with cordova ios 4+.

Could you please explain how to select the WKWebView in the config please, because I don't found any clue in the salesforce website.

Thank you for your time.

bhariharan commented 7 years ago

@mopi1402 We have our own version of WKWebView plugin embedded in our SDK, so you don't need the Cordova one (see our plugin here). You can initialize SFHybridViewController with this to use WKWebView. However, keep in mind that local XHR requests won't work due to new WKWebView policies. We have fixes for that in our upcoming release, but not in 4.3.1.

mopi1402 commented 7 years ago

Thank you for your reply. Salesforce is fundamental for the project because it's contains all datas, and WKWebView is a require in our hybrid locale mobile application (ionic).

So, I'm waiting for your new release.

Thanks.

mopi1402 commented 7 years ago

Hi, could you please explain to me how to change useWKWebView value from Cordova ?

I've tried adding useWKWebView in differents ways but it's not working : from www/bootconfig.json :

from js/config.js : angular.module('config', [])

.constant('forcengOptions', { useWKWebView : true, loginURL : 'https://login.salesforce.com', appId : 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' })

// baseURL should be left to empty string. This value is only used when you want to use the same app in a Visualforce // page where you have to account for the path to the static resource. In that case the config module is created from // within index.vf where the path to the static resource can be obtained. .constant('baseURL', '');

Thank you for your help.

bhariharan commented 7 years ago

@mopi1402 It can't be passed in from Javascript, you need to modify native code to accomplish this in the current production release. Change this line to the following, and you'll be good to go.

return [self initWithConfig:viewConfig useWKWebView:YES];

mopi1402 commented 7 years ago

That's what I concluded. Thank you for your help, really appreciate ! Have a good day.

mopi1402 commented 7 years ago

@bhariharan So, I compiled the lib with useWKWebView:YES, but, as you know, it's useless because of Salesforce API CORS restriction...

I'm a bit frustrated because it's not allow to add "*" in the CORS whitelist.

So, is there a way to force salesforce API to return "Access-Control-Allow-Origin: *" in the header ?

If not, is there a way to set a proxy by modify something in the Salesforce Mobile SDK ? I don't know where to looking for, and I have only 4 days to finish my work :/

My last chance is to create a service which works as a proxy, and retrieve data with curl from the API with a patched header : Access-Control-Allow-Origin: *

In any case, the Mobile SDK did a great job at the container and oauth.

Thanks.

bhariharan commented 7 years ago

@mopi1402 Unfortunately, that won't work with WKWebView. The only workaround that I know of is to have a local proxy server running on the device that relays the request and acts as the origin. Otherwise, XHR requests from a hybrid_local app on iOS are a no go with WKWebView. In our next release, we're planning to provide a workaround by providing our own native network plugin, which allows XHR requests to go through the native network stack (see my PR here for more info). We haven't released this yet though, which is why UIWebView is still the default in 4.3.1. Is there any specific reason why you want to use WKWebView? You could potentially use UIWebView for now and switch to WKWebView when our next release is out.

mopi1402 commented 7 years ago

This is an amazing work ! it's sound great, and it's exactly what I need :) You're right because I never lent attention that I always use WKWebView + localserver in all my applications. But as soon as using MobileSDK, application will run in a container

In order to manage a lot of items (10.000) in lists, I'm using pulling trick and virtual dom in list. In UIWebView, scroll event is not dispatched during scroll, so the pulling can't works. Since IOS 8 and WKWebView, scroll event fire all over the time the user scroll, and javascript code is not interrupted. So, it's possible to cheat on the number of elements in the DOM. Furthermore, I'm using Ionic Native Transitions, and it's work better when I'm using WKWebView. Finally, the application looks like more smooth/native when I'm using WKWebView, may be because the Nitro Engine increase performance up to 10%.

For all this reason, I'm always using WKWebView, but in this project, Salesforce is the priority, so I think I will compose with UIWebView until you release the next Cordova Plugin.

Do you know when you plan to release this next release, please ?

bhariharan commented 7 years ago

Tentatively slated for the end of this year (Nov/Dec). #safeharbor

mopi1402 commented 7 years ago

Thank you for your answer.

mopi1402 commented 7 years ago

@bhariharan I'm not sure about that, but I think I have an alternative : https://github.com/wymsee/cordova-HTTP

For example : cordovaHTTP.get("https://api.flickr.com/services/feeds/photos_public.gne?", { format:"json", jsoncallback:"JSON_CALLBACK" }, {}, function (response) { console.log( response.data ); console.log(response.status); }, function (response) { console.error(response.error); });

I tried to retrieve datas from the flickr API and I got them, probably because the plugin is outside your container, and generally, outside the WKWebView which has restrictions...

I assume there is not anymore CORS restriction by this way but I didn't test on salesforce API.

What is your feeling about that? Hope this could help you to code something more easy than using http local server... It' using NSURLSession...

From my side, I think I can use it to retrieve data from the Salesforce API, and stay WKWebView!

bhariharan commented 7 years ago

I haven't tried that plugin, so I don't know how it works with our container. Theoretically, it should work for you though. Give it a shot. Good luck!

mopi1402 commented 7 years ago

Against all odds, it's working like a charm !

I edited forceng (a port of forcetk for Angular) in order to use cordovaHTTP instead of $http (which produce XHR requests) and I can communicate with Salesforce API without care about CORS (only tested soql query).

For information, used WKWebView had produce another bug : I had an infinite redirection loop with Ionic/angular because it wants to inject template during runtime from file:// protocol. I don't understand why, because my version of iOS is 9.0.2 but it's happened. To fix it, I'd used a gulptask to compile all my templates in one file templates.js and $templateCache to automaticly inject template when needed.

But if you really plan to use a HTTP server, I think this will not happen to you !

As I already said, thank your for your help. You given to me some piece of advise which helped me to go in the good way, and to look for viable solution until you release your new Mobile SDK.

bhariharan commented 7 years ago

Glad you got it working, and I'm happy that I could help! Thanks for posting the details here.

mopi1402 commented 7 years ago

@bhariharan, I just want to warn you that I was running a local HTTP server on my device in another project, but I'm figure out few days ago that it's not working as soon as I'm using 3G/4G.... because this is not the same interface than WIFI : no access to localhost !

I'm not sure about that but I think you will not be able to access to your local proxy from 3G/4G...

On the other hand, I can tell you that CordovaHTTP (that uses AFNetworking) is working though 3G/4G data, and bypass CORS because requests are conducted outside the WKWebView.

bhariharan commented 7 years ago

@mopi1402 We have a new library that's using our native network stack instead of using XHR, so it works on WKWebView as well.