Mobile Applications at NOCCCD

1,506 views

Published on

3CBG presentation on mobile development at North Orange County Community College District using Sungard's Mobile Connection 1.0.1. http://www.nocccd.edu/mobile

Published in: Technology, Design
  • Be the first to comment

  • Be the first to like this

Mobile Applications at NOCCCD

  1. 1. Mobile Applications at NOCCCD<br />Brad RippeNOCCCD<br />
  2. 2. Goal<br />Provide insight into developing and deploying mobile applications with Sungard’s Mobile Connection.<br />
  3. 3. Brad Rippe<br />IT Project LeaderNorth Orange County Community College Districtbrippe@nocccd.edu<br />
  4. 4. Smartphone Statistics<br />Source: Google Analytics<br />Source: University Colorado Boulder<br />
  5. 5. Mobile Connection 1.0<br /><ul><li>1.0 Release
  6. 6. Support multiple mobile platforms
  7. 7. Built on Open Source Software
  8. 8. Integrates with LDAP and Banner Data
  9. 9. Quick Start
  10. 10. m-Apps (Feeds, Grades, Schedule, Restaurant)</li></li></ul><li>What features?<br />22 College/University iPhone apps<br />News - 21<br />Directory - 18<br />Maps - 18<br />Events - 13<br />Videos - 9<br />Courses - 6<br />Sports - 6<br />Photos - 5<br />Library - 5<br />Twitter - 4<br />8 vendor solutions<br />University Texas at Austin; Stanford; Harvard; Boston College; Saddleback; Irvine Valley College; Mt. Hood College; Rice University; more<br />
  11. 11. 1.0 Planned Features<br /><ul><li>m-Apps
  12. 12. Student’s Daily Schedule
  13. 13. Grades
  14. 14. Restaurants
  15. 15. News Feed
  16. 16. Staff Directory
  17. 17. Class Schedule
  18. 18. Campus Map</li></li></ul><li>Mobile Connection 1.0.1<br /><ul><li>Java Development Kit (JDK) 1.6.21+
  19. 19. Grails 1.3.6 - http://www.grails.org
  20. 20. Spring
  21. 21. Hibernate
  22. 22. Groovy
  23. 23. Rhodes Framework 2.2.5- http://rhomobile.com/projects/rhodes
  24. 24. Ruby/Rails
  25. 25. Android SDK and NDK
  26. 26. Blackberry JDE
  27. 27. iOS SDK/Xcode</li></li></ul><li>Android Requirements<br /><ul><li>Android SDK Android 2.2, API 8http://developer.android.com/sdk/index.html
  28. 28. Android NDK r4bWindows -http://dl.google.com/android/ndk/android-ndk-r4b-windows.zipMac - http://dl.google.com/android/ndk/android-ndk-r4b-darwin-x86.zipLinux - http://dl.google.com/android/ndk/android-ndk-r4b-linux-x86.zip</li></li></ul><li>MC Architecture<br />Mobile Server<br />request<br />API<br />response<br />Banner<br />Luminis IV LDAP<br />NOCCCD Basic Configuration<br />
  29. 29. “The Plan”<br />3 institutions<br />3 platforms<br />~ 4 months<br />
  30. 30. Setting up the “Team”<br />TEST<br />Cypress<br />District/SCE<br />Fullerton<br />
  31. 31. Collaborating<br />
  32. 32. Collaborating<br />
  33. 33. Repository Structure<br />
  34. 34. MC Directory Structure<br />
  35. 35. Android Emulator<br /># Android config - android doesn't respond to localhost<br />security_service_url= 'http://10.0.2.2:8001/mobileserver/rest/security'<br />grade_service_url= 'http://10.0.2.2:8001/mobileserver/rest/grade'<br />schedule_service_url= 'http://10.0.2.2:8001/mobileserver/rest/schedule'<br />feed_service_url= 'http://10.0.2.2:8001/mobileserver/rest/feed/'<br />http://bit.ly/psZ8G7<br />
  36. 36. News Feeds<br />
  37. 37. Updated Feed<br />
  38. 38. Feed Client<br />2.<br />
  39. 39. Feed – show.erb<br /><form action="<%= url_for :action => :index %>"><br /> <select name="id" onchange="submit()"><br /> <% if ::Rho.get_app.feedId&& ::Rho.get_app.feedId== 'cypress'%><br /> <option selected value="cypress">Cypress College News</option><br /> <% else %><br /> <option value="cypress">Cypress College News</option><br /> <%end%><br /> <% if ::Rho.get_app.feedId && ::Rho.get_app.feedId == 'fullerton'%><br /> <option selected value="fullerton">Fullerton College News</option><br /> <% else %><br /> <option value="fullerton">Fullerton College News</option><br /> <%end%></select></form><hr/><br />… More …<br />
  40. 40. Feed – application.rb<br />require 'rho/rhoapplication'<br />class AppApplication < Rho::RhoApplication<br />attr_accessor:feedId<br /> # more code in here<br />def initialize<br /> super<br /> end<br />end<br />
  41. 41. Feed – feed_controller.rb<br />def index <br />::Rho.get_app.feedId = @params['id']<br />url= "#{@serviceUrl}"<br />url << "/#{::Rho.get_app.feedId}.json" <br /> #More code<br /> result = Rho::AsyncHttp.get( :url => url, :callback => (url_for: action => :feed_callback))<br /> redirect :action => :wait<br />end<br />
  42. 42. Feed – Config.groovy<br />feed.location = <br />[ <br />cypress:"http://cypresscollege.edu/rss.xml", fullerton:"http://www.fullcoll.edu/rss.xml",<br />sce:"http://sce.edu/rss.xml<br />]<br />sghe{<br /> plugins {<br /> banner {<br />jdbc{ … }<br /> }<br /> }<br />}<br />
  43. 43. Back Issue<br />
  44. 44. Back Issue – feed_controller.rb<br />def index <br /> ::Rho.get_app.feedId = @params['id']<br />url= "#{@serviceUrl}"<br />url << "/#{::Rho.get_app.feedId}.json" <br /> #More code<br /> result = Rho::AsyncHttp.get(:url => url, :callback => (url_for: action => :feed_callback))<br /> redirect :action => :wait<br /> end<br />
  45. 45. Back Issue – feed_controller.rb<br /># Original Method<br />deffeed_callback<br />app_info "feed_callback: #{@params}“ # log feedId<br /> # parse json response<br /> # send browser to show view but still have wait in history??<br />WebView.navigate(url_for :action => :show)<br />end<br />
  46. 46. Fix Back Issue<br />deffeed_callback<br />app_info "feed_callback: #{@params}“<br /> # parse json response<br /> # send browser to show_feed method<br />WebView.navigate(url_for :action => :show_feed)<br />end<br />defshow_feed<br /> render :action => :show, :back => '/app/Mshell'<br />end<br />http://bit.ly/p44ghq<br />
  47. 47. MC 1.1.1 – Back Issue<br />def index <br />feedId= @params['id‘]<br /> Rho::AsyncHttp.get( :url => url, <br /> :callback => (url_for :action => :feed_callback)) <br />@response["headers"]["Wait-Page"] = "true" redirect :action => :wait <br />end<br />
  48. 48. Server Side Of Things<br />
  49. 49. Class Schedule Plugin<br />
  50. 50. ClassScheduleUrlMappings<br />class ClassScheduleUrlMappings {<br /> static mappings = {<br /> "/rest/getCampuses"(controller:"search", action:"getCampuses")<br /> "/rest/getAllTerms"(controller:"search", action:"getAllTerms")<br />// continued…<br />}<br />}<br />
  51. 51. SearchController<br />class SearchController {<br />defclassScheduleService<br />defgetCampuses= {<br /> if ( classScheduleService == null ) {<br /> // code here, handle null classScheduleService<br /> } else {defcamps = classScheduleService.getCampuses()<br /> if (camps != null && camps.size() > 0) {<br />response.setContentType("text/json")<br /> render camps as JSON<br /> } else {<br /> // send no information 404 error<br /> }<br /> }<br /> } …<br />
  52. 52. ClassScheduleService<br />class ClassScheduleService {<br />defdataSourceBanner//defined in the server’s Config.groovy file<br />defgetCampuses() {<br />defsql = Sql.newInstance (dataSourceBanner)<br />defquery = " " "select stvcamp_code, stvcamp_desc from stvcampwhere <br />stvcamp_codein ('1', '2', '3') order by stvcamp_desc"" "<br />defcampuses = [] // list of Campus objects<br /> try {<br />sql.eachRow(query) { defcampus = new Campus()<br />campus.campusCode= it.stvcamp_code<br />campus.campusDesc= it.stvcamp_desc<br />campuses.add(campus) }<br /> } catch(Exception e) { log.error"Exception ${query} - ${e}“ }<br /> return campuses<br /> } // end getCampuses<br />
  53. 53. ClassSchedule Request<br />/service/rest/getCampuses<br />GrailsDispatcherServlet<br />request<br />ClassScheduleService<br />response<br />SearchController<br />Campus<br />
  54. 54. Automatic Marshalling<br />import grails.converters.*<br />class SearchController{<br />defgetCampuses = {<br /> if ( classScheduleService == null ) {<br /> // code here, handle null classScheduleService<br />} else {def camps = classScheduleService.getCampuses()<br /> if (camps != null && camps.size() > 0) {<br />response.setContentType("text/json")<br />render camps as JSON<br />} else {<br />// send no information 404 error<br />}<br /> }<br /> } …<br />1<br />2<br />
  55. 55. JSON output?<br />[<br />{"class":"edu.nocccd.Campus","id":null,"campusCode":"1","campusDesc":"Cypress College"},<br />{"class":"edu.nocccd.Campus","id":null,"campusCode":"2","campusDesc":"Fullerton College"},<br />{"class":"edu.nocccd.Campus","id":null,"campusCode":"3","campusDesc":"School of Continuing Education"}<br />]<br />
  56. 56. Server BootStrap.groovy<br />import grails.converters.JSON<br />import org.codehaus.groovy.grails.plugins.GrailsPluginUtils<br />import edu.nocccd.Campus<br />class BootStrap {<br />definit= { <br /> }<br />def destroy = {<br /> }<br />}<br />
  57. 57. Init – Override Converters<br />class BootStrap {<br />definit= { servletContext -><br />JSON.registerObjectMarshaller(Campus) {<br />defreturnArray = [:]<br />returnArray['campusCode'] = it.campusCode<br />returnArray['campusDesc'] = it.campusDesc<br /> return returnArray<br /> }<br /> // continued for each domain object<br /> } …<br />}<br />
  58. 58. Result JSON<br />[<br />{"campusCode":"1","campusDesc":"Cypress College"},<br />{"campusCode":"2","campusDesc":"Fullerton College"},<br />{"campusCode":"3","campusDesc":"School of Continuing Education"}<br />]<br />
  59. 59. Objects with in Objects<br /><ul><li>Sections
  60. 60. Multiple buildings
  61. 61. Multiple meeting times
  62. 62. Default converters
  63. 63. Skip internal data</li></ul>render sections as JSON<br />Bldg 1<br />MATH 030 F<br />Bldg2<br />Meet 1<br />Meet 2<br />MATH 100 F<br />
  64. 64. SearchController<br />def sections = classScheduleService.getSections(cCode, tCode, subCode, courNum)<br />if (sections != null && sections.size() > 0) {<br />defsectionList = new ArrayList()<br />sections.each{ section -> defsectionMap = new HashMap()<br />sectionMap.put "crn", section.crn<br />def bldgs = new ArrayList() // Done for meetings too!<br />section.buildings.each{ bldg-> defbldgMap = new HashMap()<br />bldgMap.put"bldgCode", bldg.bldgCode<br />bldgMap.put"bldgDesc", bldg.bldgDesc<br />bldgMap.put"roomCode", bldg.roomCode<br />bldgs.addbldgMap<br /> }<br />sectionMap.put"bldgs", bldgs<br /> }<br />sectionList.addsectionMap<br />
  65. 65. JSON Response<br />[{"instructor":"Danufsky, Joshua","wDropDate":"11/20/2011","waitAvailable":10,"bldgs":[{"roomCode":"624","bldgDesc":"Math/Comp Science - FC","bldgCode":"600"}] ,"meetings":[{"startDate":"08/15/2011","wednesday":null,"thursday":null,"monday":null,"sunday":null,"beginTime":null,"saturday":null,"endDate":"12/16/2011","friday":null,"tuesday":null,"endTime":null,"arrangedHrs":"Plus arranged hours"},{"startDate":"08/15/2011","wednesday":" Wed ","thursday":null,"monday":" Mon ","sunday":null,"beginTime":"1:00","saturday":null,"endDate":"12/16/2011","friday":null,"tuesday":null,"endTime":"2:50 PM","arrangedHrs":null}]]<br />
  66. 66. Render Results<br />
  67. 67. Mobile Server<br /><ul><li>Apache Tomcat 6.0.32
  68. 68. Run Non-Root User
  69. 69. Apache JMeter
  70. 70. JVM Options
  71. 71. VisualVMhttp://visualvm.java.net/</li></li></ul><li>PSI-Probe<br />http://code.google.com/p/psi-probe/<br />
  72. 72. Tips - Build for Devices<br /><ul><li>Rhoconfig.txt
  73. 73. MaxLogFileSize=0 to 50
  74. 74. MinSeverity=1 to 3
  75. 75. local_server_port=8080
  76. 76. build.yml
  77. 77. version: 1.0 to 1.0.0</li></ul>rake device:android:production<br />
  78. 78. version: 1.0<br />AndroidManifest.xml<br /><manifest xmlns:android='http://schemas.android.com/apk/res/android' package='com.north_orange_county_community_college_district.cypresscollege' android:installLocation='auto' android:versionCode='26' android:versionName='2.2.5'><br />…<br /></manifest><br />
  79. 79. version: 1.0.0<br />AndroidManifest.xml<br /><manifest xmlns:android='http://schemas.android.com/apk/res/android' package='com.north_orange_county_community_college_district.cypresscollege' android:installLocation='auto' android:versionCode='10000' android:versionName='1.0.0'><br />…<br /></manifest><br />
  80. 80. Demo<br />
  81. 81. Mobile Connection<br /><ul><li>Version 1.1.1
  82. 82. mApps
  83. 83. Campus Directory
  84. 84. Event Calendar
  85. 85. Campus Map
  86. 86. iPad Support
  87. 87. JQuery Mobile
  88. 88. Active Directory Support</li></ul>1.1 Release Notes - http://bit.ly/oq90m6<br />
  89. 89. Things to Take Away<br /><ul><li>Collaborative Environment
  90. 90. Team Commitment
  91. 91. Developer Environment
  92. 92. JQuery Mobile
  93. 93. Steering Committee
  94. 94. Limited Feature Set</li></li></ul><li>Questions<br />
  95. 95. Resources<br />Grails Tutorial<br />http://www.ibm.com/developerworks/java/library/j-grails02128/<br />Ruby Tutorialhttp://www.ruby-lang.org/en/documentation/quickstart/<br />RhoMobile Docshttp://docs.rhomobile.com/<br />JMeterhttp://jakarta.apache.org/jmeter/<br />PSI-Probehttp://code.google.com/p/psi-probe/<br />VisualVMhttp://visualvm.java.net/<br />NOCCCD Mobile Apps<br />http://www.nocccd.edu/mobile<br />

×