iphone web development with grails from codemash 2009
TRANSCRIPT
Web Development with
Christopher M. Judd
Christopher M. JuddPresident/Consultant of
leader
Creator of open source projects FallME and Fiddle
December 2008 issue
Columbus iPhone User Group
http://groups.google.com/group/cidug
Going the conversation
iPhone
2008 Third Quarter Smart Phone Sales
iPhone Uniqueness
Screen
480
320
Portrait
Landscape
Input
Multi-touch
Virtual Keyboard
Always Connected
EDGE3G
Unlimited data
Location Aware
Accelerometer
Camera
Browser
Mobile Safari (WebKit)
HTML 4.01XHTML 1.0JavaScript 3
CSS 2.1 (partial 3.0)
DOM Level 2AJAX (XMLHTTPrequest)
Browser
Mobile Safari (WebKit)
HTML 4.01XHTML 1.0JavaScript 3
CSS 2.1 (partial 3.0)
XHTML Mobile Profile (MP)WAP 2.0
WAP/WML
DOM Level 2AJAX (XMLHTTPrequest)
Browser
Mobile Safari (WebKit)
HTML 4.01XHTML 1.0JavaScript 3
CSS 2.1 (partial 3.0)
XHTML Mobile Profile (MP)WAP 2.0
WAP/WML
DOM Level 2AJAX (XMLHTTPrequest)
iPhone Development
vs
Advantages:Access native features
cameralocation awareness3D supportaccelerometer (fine grain)off-line access
Performance
Disadvantages:Must know Objective-CNeed Mac and OSX LeopardGive up first born child in mountain of legal agreementsMust have application approved and vetted before distribution in App StoreProcess is on Apple’s timeline not yours
Advantages:Develop with Server-side technology of choice
Java Groovy/GrailsRuby.NETPHPPerl
Don’t have to deal with syncing data with cloudDeployment and schedule is under your controlEasier to deal with versioning
Disadvantages:Don’t have access to native featuresNot as glamorousNetwork performance
Support Levels
IncompatibleCompatible
Optimized
Mouse and keyboard eventsAbsolute positioning
XHTML Mobile Profile (MP)WAP 2.0
WAP/WML
Incompatible Websites
No plug-in support
No mobile technology support
Avoid
HTML Frames
There is not much Mobile Safari doesn’t support
Compatible Websites
Looks good and proportioned Home screen icon (Web Clip Icon)
Optimized Websites
Grails
•Web Application Framework• Development Environment• Open Source under Apache 2.0 License• Current version 1.0.4 (1.1 is around the corner)• Best Practices– Convention over configuration– Don’t repeat yourself (DRY)– Default is what you expect (DIWYE)– Agile– Scaffolding– AJAX– Plug-ins– Unit testing– Web Services
Grails MVC
Controller
GSP
Dom
ain DB
• JDK• Web Container/App Server• Build System• Application Stack• Persistence Framework• Web Framework• Unit Test Framework• AJAX Framework• Database• Scheduling Framework• XML Framework• Logging Framework• View• IDE
JDK 1.4
GORM
Grails Development Environment
Installing Grails
1. Download from http://www.grails.org/Download• 1.0.4 - Stable Release• 1.1-BETA2 - Development Release
2. Unzip archive3. Set GRAILS_HOME environment variable4. Add %GRAILS_HOME%\bin to system path
Depends on JDK 1.4 or greater
Creating a Grails App
grails create-app mynotes
Running a Grails App
grails run-app
Navigate to http://localhost:8080/mynotes
Add Domain Classes
grails create-domain-class note
Note.groovy
class Note {
}
NoteTests.groovy
class NoteTests extends GroovyTestCase {
void testSomething() {
}}
class Note { String title String content Date dateCreated Date lastUpdated
static constraints = { title(blank:false, nullable:false, size:5..150) content(nullable:false, maxSize:1000) }
String toString() { title } }
Implement DomainsAdd properties, methods, constraints, relationships
Generate Scaffolding
grails generate-all note
Generate Scaffolding
grails generate-all note
• Controller• Views
• create• edit• list• show
Grails Request Flowhttp://localhost:8080/mynotes/note/list
class NoteController { def index = { redirect(action:list,params:params) }
def list = { if(!params.max) params.max = 10 [ noteList: Note.list( params ) ] }
// ... code removed for brevity}
<html> <head> <meta name="layout" content="main" /> <title>Note List</title> </head> <body> <div class="body"> <h1>Note List</h1> <div class="list"> <!-- code remove for brevity --> </div> </div> </body></html>
grails-app/views/note/list.gsp grails-app/views/layout/main.gsp<html> <head> <title><g:layoutTitle default="Grails" /></title> <link rel="stylesheet" href="${createLinkTo(dir:'css',file:'main.css')}" /> <link rel="shortcut icon" href="${createLinkTo(dir:'images',file:'favicon.ico')}" type="image/x-icon" /> <g:layoutHead /> <g:javascript library="application" /> </head> <body> <div id="spinner" class="spinner" style="display:none;"> <img src="${createLinkTo(dir:'images',file:'spinner.gif')}" alt="Spinner" /> </div> <div class="logo"><img src="${createLinkTo(dir:'images',file:'grails_logo.jpg')}" alt="Grails" /></div> <g:layoutBody /> </body> </html>
Minimal iPhone Support
Home Screen Icon (Web Clip Icon)
Home Screen Icon (Web Clip Icon)
Home Screen Icon (Web Clip Icon)
<link rel="apple-touch-icon" href="images/apple-touch-icon.png"/>
Home Screen Icon (Web Clip Icon)
iPhone Adds• Rounded corners• Drop shadow• Reflective shine
<link rel="apple-touch-icon" href="images/apple-touch-icon.png"/>
Home Screen Icon (Web Clip Icon)
iPhone Adds• Rounded corners• Drop shadow• Reflective shine
<link rel="apple-touch-icon" href="images/apple-touch-icon.png"/>
Home Screen Icon (Web Clip Icon)
iPhone Adds• Rounded corners• Drop shadow• Reflective shine
png image 57x57
<link rel="apple-touch-icon" href="images/apple-touch-icon.png"/>
Scaling
Default width is 980 and scaled down by 2:1 or 3:1
Custom Viewport
<meta name="viewport" content="width=device-width; initial-scale=1.0; maximum-scale=1.0; user-scalable=0;">
Custom iPhone Applications
with iUI
iUI
Open Source library containingCascading Style Sheets (CSS)JavaScriptImages
Provide a native iPhone application look and feel
Lists Forms
http://code.google.com/p/iui/
Transitions
iUI is AJAXCommonly implemented as a single page
Named anchors URLs transition to named elementsStandard URLs make AJAX requests to server for snippetFull page requests must use target of _selfGet more URLs must use target of _replace
Setting up iUI
<html> <head> <title>Note List</title> <style type="text/css" media="screen">@import "/mynotes/js/iui/iui.css";</style> <meta name="viewport" content="width=device-width; initial-scale=1.0; maximum-scale=1.0; user-scalable=0;"> <link rel="apple-touch-icon" href="/mynotes/images/apple-touch-icon.png"/> <script type="text/javascript" src="/mynotes/js/iui/iui.js"></script> <script type="text/javascript" src="/mynotes/js/application.js"></script> </head> <body> <!-- code removed for brevity --> </body> </html>
1.Download tar2.Uncompress3.Copy images, iui.css, iui.js and iuix.js to web project4.Import iui.css and iui.js
Toolbar
<html> <head> <!-- code removed for brevity --> </head> <body> <div class="toolbar"> <h1 id="pageTitle"></h1> <a id="backButton" class="button" href="#"></a> <a href="/mynotes/note/create" class="button">+</a> </div> </body> </html>
Manages state and history
List<html> <head> <!-- code removed for brevity --> </head> <body> <div class="toolbar"> <h1 id="pageTitle"></h1> <a id="backButton" class="button" href="#"></a> <a href="/mynotes/note/create" class="button">+</a> </div>
<ul id="notes" title="Notes" selected="true"> <li><a href="/mynotes/note/show/46">Grocery list</a></li> <li><a href="/mynotes/note/show/47">Chrismas wish list</a></li> <li> <a href="/mynotes/note/more?offset=8" target="_replace"> Show 8 More Notes... </a> </li> </ul> </body> </html>
Just an HTML unordered list
Forms<html> <body>
<div style="left: 0%;" id="Notes" title="Notes" class="panel"> <h2>Show Note</h2> <fieldset> <div class="row"> <label>Title</label> <input type="text" name="title" value="Grocery list"/> </div> <div class="row"> <label>Content</label> <textarea rows="5" cols="30" name="content"> Eggs Milk Coffee </textarea> </div> </fieldset>
<form id="deleteForm" name="deleteForm" action="delete" method="post"> <input type="hidden" name="id" value="46" /> <a class="whiteButton" href="#" target="_self" onclick="document.deleteForm.submit()">Delete</a> </form>
</div> </body></html>
Grails and iUI
Grails iUI Plug-in
http://grails.org/iUI+Plugin
A plug-in for simplifying using iUI with Grails.
grails install-plugin iui
iPhone layoutiUI CSS, JavaScript and imagesGrails apple-touch-iconAutomatically uses optimized JavaScript in production mode
Determine iPhoneUser-Agents
iPhone - Mozilla/5.0 (iPhone; U; CPU like Mac OS X; en) AppleWebKit/420.1 (KHTML, like Gecko) Version/3.0 Mobile/4A93 Safari/419.3
iPod Touch - Mozilla/5.0 (iPod; U; CPU like Mac OS X; en) AppleWebKit/420.1 (KHTML, like Gecko) Version/3.0 Mobile/4A93 Safari/419.3
Use Regular Express - Mobile.*Safariclass IPhoneFilters { def filters = { all(controller:'*', action:'*') { before = { if (request.getHeader("User-Agent") =~ "Mobile.*Safari") request['fromIPhone'] = true }
} }}
Render iPhone View
def list = { if(!params.max) params.max = 8 if (request.fromIPhone) render(view:'iphone_list', model:[noteList: Note.list( params )]) else render(view:'list', model: [ noteList: Note.list( params ) ]) }
SnippetsUse templates
<g:each in="${noteList}" status="i" var="note"> <li><g:link action="show" id="${note?.id}"> ${fieldValue(bean:note, field:'title')} </g:link></li></g:each><li> <g:link action="more" target="_replace" params="[offset: 8]"> Show 8 More Notes... </g:link></li>
_iphone_notes.gsp
<ul id="notes" title="Notes" selected="true"> <g:render template="iphone_notes" /> </ul>
Testing
iPhone/iPod Touch
Should definitely use for final testing
Challenges• Corporate Network Access• Hands of keyboard• Difficult to debug
SDK iPhone Simulator
Included with SDK/XCode
Challenges• Only works on Leopard OSX• Difficult to debug
Safari
Mac or Windows
Challenges• Renders things the iPhone won’t
iPhone Spoofing
Debugging
iPhone Bookmarkletshttp://www.manifestinteractive.com/iphone/#_Webdev
Unique JavaScript solutionView sourceDump scriptsView cookiesetc
Resources
Web Development Guidelines for the iPhone (Safari Web Content Guide for iPhone OS)- https://developer.apple.com/webapps/docs/documentation/AppleApplications/Reference/SafariWebContent/
Safari HTML Reference- http://developer.apple.com/documentation/AppleApplications/Reference/SafariHTMLRef/
Safari CSS Reference- http://developer.apple.com/documentation/AppleApplications/Reference/SafariCSSRef/
WebKit DOM Programming Topic- http://developer.apple.com/documentation/AppleApplications/Conceptual/SafariJSProgTopics/