I have a ViewController which has multiple UIWebViews. I am using localstorage.setItem to store some variables. But the problem is that these variables are accessible only within the UIWebViews in which has been set. If i am trying to get( localstorage.getitem) the variable of other UIWebViews it's giving null value .
WebView1=====>>>>localStorage.setItem("var1","val");
WebView2=====>>>>alert(localstorage.getItem("var1")); ===>>is null
Sorry, but that's just how the framework is designed: every UIWebView is it's own instance, isolated from other instances in the same app (just like there is no built-in pop-up or tab functionality).
If there is absolute no other way around it, you could make the web views Cordova WebView's and programatically arrange for some way to transfer data between them via the native layer (there's also alternatives, like WebViewJavascriptBridge that accomplishes the same thing).
Maybe you could even get by just by injecting the data needed using stringByEvaluatingJavaScriptFromString into a known data structure beforehand. But having the Javascript in a UIWebView call the native side is a well known difficult-to-do thing that can only be solved by using bridging solutions like i mentioned in the second paragraph.
Related
I want to migrate my iOS hybrid app from UIWebView to WKWebView as the former has been deprecated. There are a number of similar questions to this on Stack Overflow that have already been answered but these questions focused on the rather simpler topic of just displaying a web view with out addressing the loading of local files nor the two way interaction required between the Objective C wrapper and the Javascript code for a hybrid app to deliver any functionality.
So far I have established that I need to do the following
Replace the import statement for UIKit with WebKit.
Before creating the wkwebview it is necessary to create a configuration object and set its key allowFileAccessFromFileURLs to TRUE.
After creating the wkwebview, setting its navigationDelegate and its UIDelegate to self.
When loading the url of the html/ccc/js file location, specifying allowingReadAccessToURL to delete the last path component (which I think is the file://)
Set the wkwebview as a sub view of the main view (I think this was not required in UIWebView)
Replacing the existing communications channel from the javascrtipt code to the Objective C code which made use of "shouldStartLoadWithRequest" by creating a script message handler in the wkwebview configuration object mentioned in 2 above and then using this message handler to invoke the processing that used to be done by "shouldStartLoadWithRequest".
Replacing all existing communications channels to the javascript code from the Objective C code which made use of "stringByEvaluatingJavaScriptFromString" with "evaluateJavaScript" which now requires a completion handler which can be set to nil as I am not using any callback values.
Adding a solution to allow the keyboard to be displayed without user selecting an input text field. The best I can see so far is Programmatically focus on a form in a webview (WKWebView). I am somewhat concerned that it appears to need changing every IOS release.
Addressing CORS issues. I understand that WKWebView is much stricter in its implementation of loading remote files from different URLs than UIWebView was, but I am not clear whether there is also a need to whitelist the local files to be loaded as well.
If anyone knows of a check list of things that need to be changed with tips/examples with exact details, or could provide such as an answer that would be superb.
In addition I would like to continue to support pre IOS 11 users by retaining UIWebView for these users as I believe WKWebView had issues in those earlier versions. Does anyone know if this going to cause any additional problems to resolve, and if so how?
Yes
allowFileAccessFromFileURLs is undocumented, so it may or may not work in iOS 13.
Yes
Yes
Yes, and it is required with UIWebViews as well. What might be different is that adding a WKWebView to a storyboard or nib was impossible or buggy, at least until very recent versions of Xcode, which may be why you have that impression.
No, the -webview:shouldStartLoadWithRequest:navigationType: method is a UIWebViewDelegate method. You want the corresponding WKNavigationDelegate method, which is -webView:decidePolicyForNavigationAction:decisionHandler:.
Yes
I can't answer to that, as I've never needed to do it.
See #8
WKWebView has been around since iOS 8, so unless you're targeting iOS 7, Apple still may reject your app once they start rejecting for use of UIWebView. I don't think there's any way to know if that is the case other than submitting the app to find out.
If your javascript makes use of custom schemes that rely on the webview delegate to handle them correctly (i.e., myscheme://some/callback), it can be flaky with Webkit. This is where the script message handler that you alluded to comes in. But you have to update your javascript to use window.webkit.messageHandlers.someCallback.postMessage(someParams) instead of using a custom URL scheme.
Many ios apps contain a FAQ or How to use page, when loaded, will display some FAQs in text format. The content is loaded from remote server rather than built in so the contents can be updated anytime with flexibility.
What's the best way to implement this type of page? My app does not contain any server side function except this page so I am really looking for a cheap (or free) way instead of renting a server just for this. Also, my FAQs will be static HTML.
Thank you for any suggestions.
The simplest way to display an HTML page is to use a UIWebView as the main view of your view controller and set its URL or file-path using the loadRequest() method of your view.
You can use this method for both remote FAQs (in this case you'll set an URL) and local and static ones for which you'll use a path to the file included in your project.
I have a use case where a complex UI hierarchy needs to be rendered in an iframe, but the logic handling it (creation, enter document, event handling, exit document) need to be in the main frame / app.
I face issues with getting a typed reference to the Document instance of the iframe. Is this possible at all? The code errors even with type casts.
Any advise would be helpful, except the one to use js interop - something as simple as extracting a UI branch and fitting it inside an iframe should not require this IMHO.
Also if this is not possible where should I go filling a bug?
Cross window access is very limited due to security concerns. There are open issues to allow it again because it can be circumvented by dart-js-interop anyway.
So the suggested solution is to use dart:js as workaround until the issues are fixed.
var ifrm = new js.JsObject.fromBrowserObject(dom.querySelector('#ifrm'));
print(ifrm['contentWindow']);
print(ifrm['contentDocument']);
Try to use window.postMessage() to transfer DOM updates between the frames. That might be a possiblity I guess?
I have a black box container. I love black boxes, they obfuscate things so well.
This black box is an encrypted zip (sort of) and has inside some html files (this is the short, not so painful to explain, version).
Those files need to be displayed in an UIWebView. Now, the easy way to do it, decrypt, unzip to filesystem, load file from filesystem. That's good, except, the black box contains secret stuff, and can't just lay around on the filesystem, not even a sec, so, I made a C library that actually streams the contents of the box (directly out of the box).
Now, I have this streaming capability and have to somehow make it work with UIWebView. First thing that comes in my mind would be to use a mini local HTTP server where the UIWebView can sent its requests. I would then manage the requests myself and return the contents the UIWebView requires using the streaming lib I've done. That would work I suppose well, but I think a mini HTTP server would somehow, maybe, be a little bit of a overkill.
So, I was wondering, is there another way to interfere between UIWebView and the filesystem? Maybe using a custom schema? Like myschema://? And every time the UIWebView makes a request to myschema://myfile.html I would somehow interfere and return the data it needs?
Is such a idea viable? Where should I look to start from? Maybe NSURLRequest?
EDIT: I found this: iPhone SDK: Loading resources from custom URL scheme. It sounds good, however, how will the browser know the size of the request, the type (xml/binary/xhtml) and all the info HTTP puts in its header?
Create a custom NSURLProtocol subclass and register it so it will handle the HTTP requests. This will allow you to handle the requests that come from the UIWebView however you see fit, including supplying the data from your library. You can examine an implementation of one that performs disk caching of requests to allow offline browsing by looking at RNCachingURLProtocol. I personally use a custom NSURLProtocol subclass that I wrote to handle injecting some javascript code into pages that are loaded in the UIWebView, and it works very well.
Does anyone have any ideas how I could package an external interactive slide that could be dynamically loaded by an iOS app? Is it at all possible?
e.g. Imagine having a presentation app on an iPad. There is a set of interactive slides held on the web somewhere, let's say they contain draggable elements.
Can I load one of these slide objects into the app and interact with it? If so, what format would the slide object be?
Thanks,
Mark
Technically it's possible to dynamically load bundles (NSBundle) components in an app. These bundles could even contain executable code, though AppStore guidelines prohibit use of dynamically loaded NSBundles in this way for security reasons.
Additionally you could just use a UIWebView to display some 'slides' on a webpage, though it will be very hard to make the app behave as if it's the same as the native slides - perhaps even impossible (due to how rendering of webpages work compared to native controls, for example).
Ok so lets say you have these "external interactive slides" on a web server somehow. Since you are not saying they are of a certain type (like powerpoint or such) I will just assume that these slides are of some rare format that is probably not supported by any existing apps or the Safari browser.
Then the answer to your question would be: Write your own iOS-app that can read, present and edit these slides. What format are they? Well it doesn't matter. Write an app that can download the slide data from the data and parse it, and present it on the phone.
Then let the user interact with it, and perhaps make the app upload the changes to the server.
You can do anything you like in your app, there are no limits. You just have to write the code for it. If there was some kind of standardised format, lets say you wanted your app to show powerpoint presentations, then you would have 3 choices. Use someone elseĀ“s app, or write your own app with a parser for the powerpoint files or make your own app that use some code that someone else wrote to do it (a third part library that you include in your app)
In your specific case, I can not tell if there are any third part librarys to interact with your slides, but my guess is that you will need to do most of it on your own. You could start with looking at how the web services that interact with the slides online works, and if you can interact with them from an iOS-app that you make yourself.
There is nothing stopping you from creating an app, read the slide data into the app, present it in any way you like, let the user change it, save it in your app, or upload the changes to a server. It's all up to you =)
Good luck!