zoukankan      html  css  js  c++  java
  • HOWTO: Create native-looking iPhone/iPad applications from HTML, CSS and JavaScript

    HOWTO: Create native-looking iPhone/iPad applications from HTML, CSS and JavaScript

    Though it's not widely known, you can write native-feeling iOS apps for the iPhone and iPad in JavaScript (+ HTML and CSS).

    In this article, I'll explain how to:

    • strip away the browser chrome (the url bar and button bar);
    • prevent viewport scrolling and scaling;
    • respond to multi-touch and gesture events;
    • use webkit CSS to get the iPhone OS look and feel;
    • cache the app so it runs without internet access;
    • get a custom icon on the home screen; and
    • have a splash screen load at the start.
    If you want to put it in the app store, you can even package your web app as a "native" Objective-C app. (Although, why you'd want to subject yourself to the app store approval process when you don't have to is beyond me.)

    I've put this HOWTO together, because--even on Apple's site--there's not one centralized page that tells you how to do all this. I've included templates, examples and a stubbed-out XCode project.

    If you want to go deeper than what's in this post, I recommend the bookBuilding iPhone Apps with HTML, CSS, and JavaScript.

    My motivation for finally building an iPhone app was frustration with a paper-based medical logging system. My wife and I have to keep a medical log of just about everything my son does: seizure types/lengths, caloric intake/composition, hydration, medication doses, sleep, urine chemistry, blood pressure, heart rate, weight, activities and bowel movements. Naturally, we're always trying to remember where we last had the log book. An iPhone/iPad app seemed like the perfect solution for medical logging, so I took the plunge.

    Update: I built a second iOS app out of JavaScript, also for my son: it's amultitouch remote control for a robot: use the rotate gesture to rotate the robot; use the swipe to move it forward and back; tilt to take a picture with its camera.

    Read on for the details, tips and tricks I've learned.

     

    More resources

    On top of the information below, I can recommend a few other resources:

    Making it full-screen

    Normally, if you press "+" in mobile Safari and then "Add to Home Screen," the icon it creates acts like a bookmark into Safari. When the browser opens up, you've got the URL bar at the top and the button bar at the bottom. If you're trying to deploy a real app, this just wastes screen real estate and detracts from its professional feel.

    To get rid of the URL and button bars, just add a meta tag:

    <meta name="apple-mobile-web-app-capable"
          content="yes" />

    This is what my log app looks like when launched from the home screen:

    Changing the phone status bar

    You can also change how the phone's status bar is displayed with a meta tag. You can make it white, black or translucent:

    <meta name="apple-mobile-web-app-status-bar-style"
          content="default" />

    The values for content are defaultblack and black-translucent.

    Preventing scaling

    If you pinch on a web app, it still responds like it's in a browser and zooms in. This can be a giveaway that the app isn't native. If you want to prevent scaling, use the viewport meta tag:

    <meta name="viewport"
        content="user-scalable=no, width=device-width" />

    You'll almost certainly want to set the viewport width to the device width as well, so that the app shows up at its natural resolution.

    Preventing elastic scrolling

    If you a flick a web app past the bottom or top of the page, the page itself gets elastically tugged away from the URL bar or the button bar (or the bottom/top of the screen if it's in full-screen mode).

    This behavior is another giveaway that your app isn't native, and it's rarely the behavior you want in a native app.

    To stop this behavior, capture touchmove events on the document in JavaScript and cancel them. You can do this by adding a handler to the bodytag, and invoking the preventDefault method on the event object:

    <script>
     function BlockMove(event) {
      // Tell Safari not to move the window.
      event.preventDefault() ;
     }
    </script>
     
    <body ontouchmove="BlockMove(event);" >
      ...
    </body>

    Creating a home screen icon

    To add a home screen icon, create a 114x114 .png file, and then link to it in the header:

    <link rel="apple-touch-icon"
          href="./apple-touch-icon.png" />

    The iPhone automatically applies the glossy finish.

    On older iPhones, which used 56x56 icons, and the iPad, which uses 72x72 icons, the graphic automatically scales down.

    If you don't want the glossy finish applied automatically, use apple-touch-icon-precomposed instead of apple-touch-icon.

    Creating a splash screen

    To add a splash screen during loading, create a 320x460 .png file, and then link to it in the header:

    <link rel="apple-touch-startup-image"
          href="./startup.png" />

    The file must be exactly 320x460, or else the iPhone ignores it. (The iPad requires 1004x768.)

    Caching application files

    If you want to be able to use your application without internet, or you want to improve its load time, create a cache manifest file, and link to it from the main file for the web app:

    <html manifest="cache.manifest">

    Make sure your web server serves up .manifest files with the MIME typetext/cache-manifest, or else this won't work. If you're using apache, put the following in your .htaccess file:

     AddType text/cache-manifest .manifest
    

    And then check using wget -S that the content type in the response headers is correct.

    Inside the cache.manifest file, list which files should be cached and which should be retrieved from the network:

    CACHE MANIFEST
    local1.file
    local2.file
    
    NETWORK:
    network1.php
    network2.cgi
    

    If you find your app suddenly stopped working when you started using a cache manifest, make sure every URL you use is in the right section.

    When a cache manifest is in use, the app launches with the last version of the files.

    It pulls a new version of the manifest in the background if network connectivity is available, and on the next launch you'll see the new version if the manifest has changed. You'll want to include a serial number in a comment in the cache manifest, so that you can up it every time you release a new version; for example, here's my logging application's manifest:

    CACHE MANIFEST
    
    # Bump this with each release:
    # Serial number 7
    
    apple-touch-icon.png
    jquery.js
    scroll-bg.jpg
    startup.png
    medical-log.css
    medical-log.js
    cached.html
    
    NETWORK:
    show-log.php
    insert-into-log.php
    delete-log-entry.php
    update-log-entry.php
    

    I recommend renaming the manifest file so that it 404s during iterative development.

    Detecting touch and gesture events

    You can capture multi-touch and gesture events in JavaScript. And, there's a good reason to do this too: if you listen for traditional events like clicks, you'll get a one second delay while the iPhone highlights the element that was "clicked." If you're trying to mimic a real app, this behavior starts to feel tedious and slow. By capturing touch events directly, you can respond instantly to user input.

    There are two ways to track touch events. When you capture raw touch events, you're tracking individual fingers. When you capture gesture events, you're capturing interpretations of finger movement, like scaling and rotating.

    The touch handlers you can attach to are:

    • ontouchstart - a finger goes down.
    • ontouchmove - a finger moves.
    • ontouchend - a finger goes up.

    The gesture handlers you can attach to are:

    • ongesturestart - a scale or a rotation starts.
    • ongesturechange - a scale or a rotation.
    • ongestureend - a scale or a rotation ends.

    If you just want to use touching in place of clicking, then the target field of the event object contains the element that was touched.

    I created an example app that uses gestures to scale a graph.

    There's also a great write-up of touch and gesture events in JavaScript, if you want to provide deeper multi-touch support.

    For more code and a second JavaScript app that uses gestures heavily, see my second iPhone app post: a multitouch remote control for a robot.

    Detecting rotation events

    If you want to take an action when the phone is rotated, listen foronorientationchange events on the body tag. The current orientation is inwindow.orientation, and it is encoded as the angle (in degrees) that the iPhone is rotated--0, -90 or 90--away from vertically upright.

    Mimicking iPhone OS components

    The webkit rendering engine supports a lot of CSS extensions, and you can use these to simulate native Cocoa components; for example, buttons are easy:

    .button {
     font-family: Helvetica ;
     font-weight: bold ;
     padding: 15px; 
     border: 1px solid black ;
     -moz-border-radius: 8px ;
     -webkit-border-radius: 8px ; 
     margin-top: 10px ;
     margin-bottom: 10px ;
     background-color: white ;
    }
    

    I created the iPhone-like background for my logging app with a background-image for the document body.

    The book Building iPhone Apps with HTML, CSS, and JavaScript can show you how to simulate all of the standard iPhone UI elements.

    Creating a native "Objective-C" app

    If you want to publish your app in the app store, you'll need to write it in Objective-C. Fortunately, Cocoa includes a UIWebView class, which is just the Mobile Safari browser without its chrome. So, you can actually bundle your HTML/CSS/JavaScript app up natively by wrapping it in a few lines of canned Objective-C.

    Of course, once you wrap your web app up as a native app, you can use Objective-C to access more features of the iPhone. If you want to get into Objective-C programming, I recommend the book Cocoa and Objective-C: Up and Running as both a reference and a tutorial.

    Here are the bare bones steps to turning a web app into a native app:

    1. Open XCode.
    2. Create a new "View-based Application" iPhone project.
    3. Move the files for your web app into the Resources folder in XCode, but strip out the cache manifest. (You don't want the manifest screwing things up, since everything is now local.)
    4. Create a new instance variable, webView, inside the @interface ViewController header file:
         IBOutlet UIWebView* webView ;
         // IBOutlet means it's visible to Interface Builder.
      and create a property:
         @property (nonatomic, retain) UIWebView *webView;
        
    5. In the ViewController implementation file, synthesize webView:
         @synthesize webView; 
    6. Open the ViewController interface file from Interface Builder Files folder.
    7. From the Library's Objects menu, drag a Web View component into the layout/design window.
    8. Select the ViewController.xib window, and then File's Owner.
    9. Connect (by dragging) the webView outlet from the connections window to the Web View.
    10. Return to XCode.
    11. Implement the viewDidLoad method in the ViewController implementation file:
      - (void)viewDidLoad {
       [super viewDidLoad];
        NSString *filePath =
         [[NSBundle mainBundle] pathForResource:@"index" ofType:@"html"];
        NSData *htmlData = [NSData dataWithContentsOfFile:filePath];
      
        if (htmlData) {
         NSBundle *bundle = [NSBundle mainBundle]; 
         NSString *path = [bundle bundlePath];
         NSString *fullPath = [NSBundle pathForResource:@"index"
                                        ofType:@"html" inDirectory:path];
         [webView loadRequest:[NSURLRequest requestWithURL:
                                [NSURL fileURLWithPath:fullPath]]];
        }
      }
        
      This will load index.html from the Resources folder on launch.
    12. Fire it up in the simulator. You should now see your app.

    Confused? Just download my pre-configured web application XCode project, and drop your files into Resources.

    Tips

    • Download the iPhone SDK and test with the simulated iPhone/iPad Safari. Only do tests on the iPhone itself when you're checking to see if performance is good enough.
    • Install the app from an IP address rather than a hostname to cut out the DNS look-up time on application launch.
    • JavaScript on the iPhone doesn't handle lots of string manipulation well; prefer DOM tree manipulation for constructing user interfaces over mashing innerHTML.
    • Take advantage of JavaScript libraries like jQuery for cutting down on the tedium.

    iPad quirks

    Creating native iPad web apps is almost identical to creating native iPhone web apps. The biggest changes are that your start-up image must be exactly 1004x768. Other than that, it's mostly the same.

    Detecting iPhone OS

    You might want your app to behave a little differently depending on where it's run. I used the following JavaScript to detect if the app is running inside an iPhone, an iPod Touch or an iPad:

     var IsiPhone = navigator.userAgent.indexOf("iPhone") != -1 ;
     var IsiPod = navigator.userAgent.indexOf("iPod") != -1 ;
     var IsiPad = navigator.userAgent.indexOf("iPad") != -1 ;
    
     var IsiPhoneOS = IsiPhone || IsiPad || IsiPod ; 
    

    Hosting

    If you're looking for a hosting provider for your web app, I recommendlinode.com

    I've been running might.net on a linode for years, and I'm using them to host my medical logging app.

    They're hard to beat for price, performance, flexibility and customer service.

    Code

    Feel free to use my template.html, a stubbed-out blank web app.

    Example: Multi-touch graph navigation

    I wrote an app that creates a full screen canvas and then lets you zoom in and out of the graph of f(x) = sin(x) using the pinch-to-zoom gesture.

    This runs well on my iPad and in the simulator, but it's a little choppy on my first-gen iPhone.

    Feel free to poke around and modify the code: graph.html.

    Example: Medical logging application

    The medical logging app is a nice example because it caches much of itself locally, resorting to the network only for synchronization via PHP scripts that interact with a database.

    And, it's been a major quality-of-life improvement for me and my wife.

  • 相关阅读:
    加密和解密配置节(asp2.0以后)http://www.cnitblog.com/lby91772/archive/2008/03/04/40436.html
    多线程消息队列 (MSMQ) 触发器 http://blog.sina.com.cn/s/blog_405ad00201007rlw.html
    NUnit的使用
    HDU 1896 Stones
    POJ 1862 Stripies(哈夫曼)
    ZOJ 3230 Solving the Problems
    HDU 1242 Rescue(BFS)
    ZOJ 3410 Layton's Escape
    求逆序数
    HDU 1873 看病要排队
  • 原文地址:https://www.cnblogs.com/daishuguang/p/4214447.html
Copyright © 2011-2022 走看看