A summary of UIWebView

Source: Internet
Author: User

A summary of UIWebView

Objective

Today, we took part in a development lecture on PHONEGAP for Adobe and CSDN, and PhoneGap on IOS devices is to show HTML content through UIWebView controls and interact with native code.

We are doing the IPad version of cloud notes, because we also use UIWebView to display the notes, so we also need to do JS and native code to call each other things. So here's a summary of the details of UIWebView's use and the way I think about PhoneGap.

Mechanism

First we need to let UIWebView load local HTML. Complete with the following code:

 nsstring * path = [[nsbundle Mainbundle] bundlepath]; 
nsurl * BaseURL = [nsurl Fileurlwithpath:path] ;
nsstring * htmlfile = [[nsbundle MainBundle] Pathforresource:@ "index" Oftype:@ "html"];
nsstring * htmlstring = [nsstring Stringwithcontentsoffile:htmlfile encoding: (nsutf8stringencoding) Error: nil];
[self.webview loadhtmlstring:htmlstring Baseurl:baseurl];
/span>

Next, we need to allow JS to invoke the native side. The IOS SDK does not have native APIs that provide JS calling native code. But a delegate method of UIWebView allows us to make sure that JS needs to be called when it notifies native. After the native executes the corresponding call, the execution result can be returned to JS using the Stringbyevaluatingjavascriptfromstring method. In this way, the mutual invocation of JS and native code is realized.

The following is a sample code for PHONEGAP related calls:

Objective-c language
- (BOOL) WebView: (UIWebView *) WebView
Shouldstartloadwithrequest: (Nsurlrequest *) Request
Navigationtype: (uiwebviewnavigationtype) navigationtype {
nsurl * url = [request URL];
if ([[URL scheme] Isequaltostring:@ "gap"]) {
Span class= "line" > //here to do JS tune native things
//....
//after it is done, use the following method to recall JS
[WebView Stringbyevaluatingjavascriptfromstring:@ "alert (' Done ')"];
return no;
return yes;

/span>

Specifically let JS notify native method is to let JS launch a special network request. Here, both we and PHONEGAP are implemented by loading a hidden iframe, which is implemented by specifying the SRC as a special URL to intercept this request in the delegate method.

The following is a sample code for PHONEGAP related calls:

Javascript language//notification iPhone UIWebView load URL corresponding to the resource//URL in the format: gap:somethingfunction loadurl (URL) {    var iFrame;    iframe = document.createelement ("iframe");    Iframe.setattribute ("src", url);    Iframe.setattribute ("Style", "display:none;");    Iframe.setattribute ("height", "0px");    Iframe.setattribute ("width", "0px");    Iframe.setattribute ("frameborder", "0");    Document.body.appendChild (iFrame);    This iframe is useless after initiating the request, so remove the    iFrame.parentNode.removeChild (IFRAME)    from the DOM. IFrame = null;}

Here, some people may say that the same effect can be achieved by changing the document.location. About this, I and Zyc specifically tried, under normal circumstances, change document.location is can, but change document.location has a very serious problem, that is, if we continuously 2 JS native, 2 times in a row to change DOCUMENT.L Ocation, in the native delegate method, can only intercept the latter request, the previous request was quickly replaced, so it was ignored.

I also go to Github to find the relevant open source code, they are used by the IFRAME to implement the call, such as this: Https://github.com/marcuswestin/WebViewJavascriptBridge

On this, I also made a Demo to a simple example, the address is as follows: Https://github.com/tangqiaoboy/UIWebViewSample

Passing of parameters

The example code above is just an example of the simplest mutual invocation in order to clarify the mechanism. But in fact, when JS and native call each other, it is often necessary to pass parameters.

For example, Youdao Cloud notebook IPad version with UIWebView display the content of notes, when the user clicked on the attachment in the notes, this time, JS need to notify native to the background to download this note attachment, while notifying JS current download progress. For this requirement, when the JS layer obtains the user click event, it is necessary to pass the ID of the attachment of the current click to native, so that native can know which attachment to download.

The simplest way to pass a parameter is to place the parameter as part of the URL into the src of the iFrame. This allows the UIWebView to obtain parameters by intercepting the content behind the parsing URL. However, the problem is that the method can only pass simple parameter information, if the parameter is a very complex object, then the codec of this URL will be very complex. In this respect, our Youdao cloud notes and PhoneGap have adopted different technical solutions.

    • Our technical solution is to pass the parameters as JSON, but because we want to append them to the URL, we encode the JSON Base64 to ensure that there are no illegal characters in the URL.
    • The technical solution for PHONEGAP is to pass the parameters in JSON, but place the JSON in a global array in UIWebView, UIWebView to get the corresponding parameters by reading the global array when the parameter needs to be read.

By contrast, it should be said that the PHONEGAP scheme is more comprehensive and suitable for a variety of scenarios. Our solutions are simple and efficient, satisfying the needs of our own products.

Synchronous and asynchronous

Because the IOS SDK does not natively support JS and native call each other, everyone's technical solution is their own implementation of a set of call mechanism, so there is a synchronous asynchronous problem. Careful classmate will be able to find, JS call native by inserting an IFRAME, this iframe is finished inserting, the result of execution need native another stringbyevaluatingjavascriptfromstring method to inform JS , so this is an asynchronous call.

The Stringbyevaluatingjavascriptfromstring method itself directly returns the execution result of a nsstring type, so this is obviously a synchronous call.

So JS call native is asynchronous, native call JS is synchronous. When dealing with some logic, it is unavoidable to consider this feature.

Here by the way an Android, in fact, in Android development, JS Tune native is synchronous, but PhoneGap in order to make themselves a cross-platform framework, so on the Android JS call native native end, with new Thread creates a new thread of execution so that the Android JS call native becomes an asynchronous invocation.

UIWebView problems with thread blocking

We found in development that when calling the Stringbyevaluatingjavascriptfromstring method at the native layer, it is possible that JavaScript is a single thread, blocking the execution of the original JS code. Our solution here is to postpone the insertion of the IFRAME with defer on the JS side.

Problems with the main thread

The Stringbyevaluatingjavascriptfromstring method of the UIWebView must be executed in the main thread, and the main thread's execution time is too long to update the block UI. So we should try to keep the Stringbyevaluatingjavascriptfromstring method executing for a short time.

Youdao Cloud Note In the save, you need to call JS to get the full HTML content of notes, this time if the notes are very complex, it will take a long time, and because this operation must be the main thread execution, so we show "saving" Uialertview completely not normal display, the entire UI The interface is completely jammed. In the new editor, we updated the code to get the HTML content to solve the problem.

Keyboard control

As IOS developers know, when we need the keyboard to appear on a control, we can call the [obj Becomefirstresponder] method to get the keyboard out, and the cursor input focus appears on the control.

However, this method is not available for UIWebView. In other words, we cannot control the cursor input focus on UIWebView.
On this question, I asked a special question on the StackOverflow, still did not get a very good solution.

CommonJS specification

CommonJS is a specification for module-block loading. While AMD is a draft of the specification, the CommonJS AMD specification describes the modularity of definitions, dependencies, referential relationships, and loading mechanisms whose specifications are in the original text here. It is widely used by open source frameworks such as Requirejs,nodejs,dojo,jquery. There is also a good introduction to the Chinese article.

The AMD specification needs to use the directory hierarchy as the package hierarchy, which is just like Java. Before I thought the IOS packaged IPA resource file could not have the resource directory hierarchy, asked at the meeting today, it was my own mistake. If you need to bring the directory hierarchy into the IPA resource file, simply drag the directory into the project and select Create groups for any added folders. As shown, this allows the directory hierarchy to be packaged into an IPA file.

Debugging

debugging JavaScript on IOS devices is a very hard thing to do, take PW's words: "Suddenly back to the IE6 era." Of course, there are some debugging tools available in the industry.

The main use of weinre in our development is the framework. With this framework, you can do some basic debugging work, but it is now not as powerful as the JS debugger on the PC, for example, it can not break the breakpoint, and if there is a JS execution error, it will not be able to correctly report the error message. It also has some bugs, such as under Mac, if you are connected to both wired and wireless networks, then weinre will not be able to properly connect to the debug page.

But after all, it is now the only relatively available debugging tool in the industry. The first speaker of the PhoneGap lecture, Dong Long Fei has a blog very good introduction to the use of weinre, address is here, recommend interested students to see. Even without phonegap,weinre, you can make it easy to design your Web page on a mobile device.

(Updated October 22, 2013): About debugging This together, from WWDC2012, Apple has supported the use of Safari to connect the UIWebView inside the IPhone simulator to debug, so debugging has been a lot of convenience. Detailed tutorials can be viewed: WWDC2012 Session 600 "debuging uiwebviews and Websites on IOS"

My opinion on PhoneGap.

At today's conference, 2 speakers blew the PhoneGap into a rather bull. But actually the people who really used to know, PhoneGap still have quite a lot of problems. At least I know at NetEase there is a use of PHONEGAP and failed projects, so I think PhoneGap still has its considerable limitations.

I think PhoneGap has the following 3 major problems:

    1. First of all, PhoneGap's programming language is actually JavaScript, which for non-front-end workers, actually learning and learning native OBJECTIVE-C or Java programming language difficult, and for historical reasons, JavaScript The language itself has more problems than any other language. It's pretty hard to master JavaScript.

    2. Then, the goal of PHONEGAP is to easily create cross-platform applications. But both Apple and Google have published their own human-computer interaction guidelines. In some cases, Apple's programs and Android programs have different principles of interaction. Like the IPhone and Android versions of cloud notes, there is a completely different interface and interaction. Using PHONEGAP means that your program is both UI and interactive, unlike native iphone programs and native Android programs.

    3. Finally, performance issues. Javascript is ultimately not as efficient as the native program, which can be apparent when you want to do some animated effects.

Of course, the advantages of PHONEGAP is also obvious, if you are doing books, query classes, gadget applications, these application UI interaction is not complex, and does not occupy a high CPU resources, PHONEGAP will play its advantages. For this type of application:

    1. You only need to write once, you can complete the development of IOS, Android, Windows Phone and other versions at the same time.

    2. If the change is not big, just content upgrade, it only need to update the corresponding JS file upgrade, and do not need to submit the audit, and generally normal submission of Apple's App Store audit, it often takes a week time.

So PhoneGap is not omnipotent, but it is not useless, it has its area of expertise, everything depends on whether you use it reasonably.

Finally, we recommend PhoneGap China website, where you can find a few Chinese materials.

The impression of JS

The front-end engineers are pretty cool now. Front-end engineers can not only write the front page, but also use Flex to write desktop programs, you can use Nodejs to write server-side programs, you can write the mobile program with PHONEGAP, all of which are based on JavaScript language, and the latest Windows 8, native support JS to write Metro programs, the world has been unable to stop the front-end engineers.

A summary of UIWebView

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.