Build iOS native App with HTML5 (2)

Source: Internet
Author: User

This article reprinted to http://ju.outofmemory.cn/entry/18807

Sometimes we want to click a link in the embedded webview to trigger the iOS native event instead of the WebView page jump (because WebView's jump is stiff, and AJAX+JS simulation is not as smooth as native segue).

Sometimes we want to see the output in the console when the page is inside consloe.log(‘log something‘) , but there is no console in the phone, so we want to be able to use Xcode's console to output information.

Because iOS does not provide APIs that let us interact with the outside directly with HTML or JS, we have to use another ingenious way to achieve these two functions. This approach can meet both of our needs.

Console.log

Redefine in HTML page console.log :

<script>DebugConsole= New Object();Console.Log= function(Log) {VarIframe=Document.CreateElement("IFRAME");Iframe.SetAttribute("SRC", "Ios-log: #iOS #" +Log);Document.DocumentElement.AppendChild(Iframe);Iframe.ParentNode.RemoveChild(Iframe);Iframe= Null;}console.= Console.; Console. Info = Console.; Console. Warn = Console.; Console. Error = Console.; </SCRIPT>              

Then implement the protocol in the VIEWCONTROLLER.M that need to be captured:

- (BOOL)WebView: (UIWebView *)WebView Shouldstartloadwithrequest:(Nsurlrequest *)Request Navigationtype:(Uiwebviewnavigationtype)Navigationtype{ NSString *RequestString= [[[Request URL]Absolutestring]Stringbyreplacingpercentescapesusingencoding:Nsutf8stringencoding];NSLog (requeststring);If ([RequestString Hasprefix:@"Ios-log:"]) { nsstring* logstring = Span class= "pun" >[[requeststring componentsseparatedbystring:@  ": #iOS #" ] Objectatindex: 1 nslog (@ "UIWebView console:%@" , Logstringreturn No;}return Yes;               /span>                

Of course, the premise is that WebView needs to set the delegate as the current controller:

Self.WebView=[[UIWebViewAlloc]initWithFrame:CGRectMake (0.0f,0.0f self. View. Bounds. Size. Width,self.. Bounds. Size. Height-44)];self. Webview.=self         

The principle is simple, we redefineconsole.logFunctions, andconsole.debugconsole.infoconsole.warnconsole.error。 When we call in the page JSconsole.log, an IFRAME is created to make the request, and the requested protocol isios-log:, the path is our log string. After making the request, quickly clean out the IFRAME.

So, in the webview we made a request, and then we lost it. Externally we implemented a protocol with OBJECTIVE-C, which is the function that will be called before WebView starts making the request. In this function we filter all requests (because in addition ios-log , there are some "normal" requests such as HTTP and mailto), we can do so at ios-log the current prefix NSLog .

ifThe final return NO meaning is that the WebView request is captured and no longer requested (the page that does not actually exist). We want some legitimate requests (such as HTTP, mailto, etc.) not to be captured, so we ended if up missing one return YES .

Using chain contact to send scene transform

iOS native scene transformation called Segue,xcode for our built-in several native animations, such as the navigation bar is always fixed on the push, so that the page before and after the push, the navigation bar remains the same (of course, the contents can be changed), the content of the switch is also very smooth. Segue can also animate in Interface Builder, including full-screen flipping or progressive.

There are some third-party JS libraries can let us simulate this scene transformation in WebView, that is, CSS design a navigation bar in the WebView, and then use JS or CSS3 to simulate the effect of push or flip3d. For example, Iscroll is a simulated top and bottom fixed, jQtouch (this to FQ search) is simulated push and flip3d effect.

I strongly oppose the use of JS library in the native application to achieve scene transformation animation, because very not fluent, not with the finger, animation effect and the original, there is a last reason, we can trigger the external scene transformation in the WebView, the native! The key to making a smooth native app with HTML5 is the ability to easily invoke native interfaces or effects that we use natively rather than in clumsy ways.

Code in WebView:

<ahref="Myapp://somepagename"> a button </a>     

Very simple, MyApp this protocol you can name it yourself and later we will capture it in Objective-c.

Or to implement the Protocol method of the WebView delegate controller, if you have already defined this method (as in the example above), you just need to add the contents of the method body to the method body, otherwise you will be reminded to repeat the definition.

- (BOOL)WebView: (UIWebView *)WebView Shouldstartloadwithrequest:(Nsurlrequest *)Request Navigationtype:(Uiwebviewnavigationtype)Navigationtype{Nsurl*Url= [Request URL];If ( [[URL scheme]Isequaltostring:@"MyApp"] { nsstring*slug = [;  [self Performseguewithidentifier:@ "Herosegue"  Sender:slug< Span class= "pun" >;  return No;}return Yes;               /span>                

In addition I have dragged a new controller in Interface Builder, between the new controller and the navigation controller, I dragged a segue, named ID heroSegue , so here can be used performSegueWithIdentifier to invoke segue.

Now, or in this controller, we implement another delegate method:

/* * triggered when page is converted/*- (void)Prepareforsegue:(Uistoryboardsegue *)Segue Sender:(Id)Sender{If ([Segue.Identifier isequaltostring:@"Herosegue"]) { NSLog(@"%@",sender);  [self. WebView stoploading yugherodetailviewcontroller *= Segue.; Destviewcontroller.=  (nsstring Span class= "pun" >*) sender;}}          /span>                

In other words, the occurrence of segue changes before the implementation of this method, first of all to determine whether identifier is equal to Herosegue, if it is, their webview no longer loaded, Set the value of the public property Heroslug in the target controller (that is, the controller that will switch past sub-pages).

We then define the controller's h in the target page:

@property(strong)nsstring*heroslug;      

Finally, in the target page, the m in our defined Congroller can get the Heroslug parameter.

NSLog(@"%@",self.  Heroslug);      

So, after we get slug, we can actually invoke a local page, take the slug parameter, and then read the remote page or JSON data through Ajax, which is not part of this article.

If you are a novice, you may miss one or two steps when doing the above, the editor will error, read and proofread your code carefully. If not really, explain the operation and error messages, and then give me a message.

Exercise: The advantage of the native title is that it is centered when the number of characters is shorter, and the character is longer when it is displayed on the right, and the ellipsis is displayed longer. So how do I set the native title of a page loaded with Ajax data when the page loads successfully, WebView?

Prompt, or a custom protocol.

Build iOS native App with HTML5 (2)

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.