Cross-Platform Data Access for Android and iPhone
Upcoming SlideShare
Loading in...5
×

Like this? Share it with your network

Share

Cross-Platform Data Access for Android and iPhone

  • 5,621 views
Uploaded on

Many Apps need to access data online. This talk discusses problems and solutions when accessing remote data with Android and iPhone. After a brief review of a number of frameworks, an approach is......

Many Apps need to access data online. This talk discusses problems and solutions when accessing remote data with Android and iPhone. After a brief review of a number of frameworks, an approach is outlined to implement data access in a cross-platform manner using a DSL.

More in: Technology
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
No Downloads

Views

Total Views
5,621
On Slideshare
5,527
From Embeds
94
Number of Embeds
4

Actions

Shares
Downloads
110
Comments
1
Likes
5

Embeds 94

http://lanyrd.com 88
http://www.slideshare.net 3
http://www.linkedin.com 2
http://coderwall.com 1

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide

Transcript

  • 1. Cross-Platform Data Access for iPhone and Android MobileTechCon 2011 March 28th - 30th, Munich (c) 2011 @peterfriese / @itemismobile
  • 2. cell phone usage is ubiquitous
  • 3. s t e c n e o p h s p a r y u r o ve se e ifes u ge e a ur l w an o m ofto
  • 4. many services only make sense when connected to the web
  • 5. People are !fferent
  • 6. ... so #ey have !fferent ta$es!
  • 7. countless devices
  • 8. diversity of platforms
  • 9. Problems Solutions
  • 10. (Missing) Connectivity
  • 11. Solution: Detect Connectivity
  • 12. Detecting ConnectivityStates we need to detect:Device not connected to internetConnection slowServer(s) not reachableServer online, but requested service not available
  • 13. Detecting ConnectivityiPhone ReachabilityhostReach = [[ReachabilityreachabilityWithHostName:@"www.apple.com"] retain];[hostReach startNotifier];[self updateInterfaceWithReachability: hostReach];!internetReach = [[ReachabilityreachabilityForInternetConnection] retain];[internetReach startNotifier];[self updateInterfaceWithReachability: internetReach];wifiReach = [[Reachability reachabilityForLocalWiFi] retain];[wifiReach startNotifier];[self updateInterfaceWithReachability: wifiReach];http://developer.apple.com/library/ios/#samplecode/Reachability/
  • 14. Detecting ConnectivityAndroid ConnectivityManagerConnectivityManager connectivity = (ConnectivityManager) getSystemService (Context.CONNECTIVITY_SERVICE);NetworkInfo wifiInfo = connectivity.getNetworkInfo(ConnectivityManager.TYPE_WIFI);NetworkInfo mobileInfo = connectivity.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);http://developer.android.com/reference/android/net/ConnectivityManager.html
  • 15. Different Data Formats Proprietary XML SOAP JSON
  • 16. Solution: Use Different Parsers
  • 17. A Fine Selection of ParsersXMLSAXParser - (Android SDK)DocumentBuilder - (Android SDK)XmlPullParser - (Android SDK)JSONJSONTokener - (Android SDK)JSON Simple - http://code.google.com/p/json-simple/Jackson - http://jackson.codehaus.org/GSon - http://code.google.com/p/google-gson/
  • 18. Parsing JSONGsonpublic T transform(InputStream inputStream) { InputStreamReader reader = new InputStreamReader(inputStream); BufferedReader buffered = new BufferedReader(reader); Gson gson = new Gson(); Type clazz = getGenericType(); T results = gson.fromJson(buffered, clazz); try { buffered.close(); reader.close(); inputStream.close(); } catch (IOException e) { e.printStackTrace(); } return results;}private Type getGenericType() { Type type = ((ParameterizedType)getClass() .getGenericSuperclass()).getActualTypeArguments()[0]; return type;}
  • 19. A Fine Selection of ParsersXMLNSXMLParser - (iPhone SDK)libxml2 - (iPhone SDK)TouchXML - https://github.com/TouchCode/TouchXMLGDataXML - http://code.google.com/p/gdata-objectivec-client/JSONTouchJSON - https://github.com/TouchCode/TouchJSONjson-framework - http://stig.github.com/json-framework/YAJL - https://github.com/lloyd/yajlJSONKit - https://github.com/johnezang/JSONKit
  • 20. Parsing JSONJSONKit#import "JSONKit.h"/...- (id)transform:(NSString *)sourceString {! id input = [sourceString objectFromJSONString]; id result = nil; if ([input isKindOfClass:[NSArray class]]) { result = [self transformArray:input]; } else if ([input isKindOfClass:[NSDictionary class]]) { result = [self transformDictionary:input]; } return result;}
  • 21. Data Quality
  • 22. Solution: Massage Data
  • 23. Massaging !!In-App vs. OnlineIn-App massaging:- needs to be rewritten for each platform- ad-hoc enhancements virtually impossible (iPhone)Server-side massaging:- write once, re-use with every app- problem with authentication (man-in-the-middle)
  • 24. MassagingOnline toolsFeedSanitizer - http://feedsanitizer.appspot.com/HTML Tidy - http://infohound.net/tidy/JSONFormatter - http://jsonformatter.curiousconcept.com/Roll your ownYQL - http://developer.yahoo.com/yql/Node.js - http://nodejs.org/Google App Engine - http://code.google.com/appengine/
  • 25. Massaging withvar sponsorImageExpr = /Sponsored by:.*<img.*src="(.*)">?/;var sponsoredByFilter = new SimpleFilter(function(data) {! session = data;! if (session.title.match(sponsorImageExpr)) {! ! sponsorlogoURL = session.title.match(sponsorImageExpr);! ! session.sponsorLogoURL = sponsorlogoURL[1];! ! session.title = session.title.replace( sponsorImageExpr, );!!! }! return session;});var stripHTMLFilter = new SimpleFilter(function(string) {! return string.replace(/</?[^>]+(>|$)/g, );});var sessionsFilterChain =! new FilterChain()! ! .append(sponsoredByFilter)! ! .append(stripHTMLFilter);
  • 26. Massaging withapp.get(/sessions.:format, function(request, response) {! var isXML = (request.params.format == xml);! dataProvider.getAllSessions(function(sessions) {! ! if (isXML) {! ! ! response.header("Content-Type", "text/xml");! ! ! response.render(sessions.ejs, { layout: false, locals: { sessions: sessions } });! ! }! ! else {! ! ! response.header("Content-Type", "application/json");! ! ! response.send(JSON.decycle(shallow(sessions, 3)));! ! }! !! });});
  • 27. Offline Data Access
  • 28. Solution: Use Caching
  • 29. CachingStore in a local SQL databaseSQLite - (Android SDK)OrmLite - http://ormlite.com/db4o - http://db4o.com/ActiveAndroid - https://www.activeandroid.com/AndroidActiveRecord - http://code.google.com/p/android-active-record/Store in the local file systemUse cache directory - Context.getCacheDir()
  • 30. CachingStore in a local SQL databaseSQLite - (iPhone SDK)ActiveRecord - https://github.com/aptiva/activerecordCoreData - (iPhone SDK)Store in the local file systemURLCache sample - http://developer.apple.com/library/ios/#samplecode/URLCache
  • 31. Putting it all together
  • 32. Solution: Data Access Frameworks
  • 33. FeaturesHandle spotty connectivitySupport multiple data formats (XML / JSON)Massage dataProvide offline data accessMap data to language concepts
  • 34. Data AccessFrameworksActiveAndroid - https://www.activeandroid.com/AndroidActiveRecord - http://code.google.com/p/android-active-record/RESTProvider - https://github.com/novoda/RESTProvider
  • 35. Data AccessFrameworks / Features Flex. Mapping Connectivity Caching JSON XMLActiveAndroid ! ! ! " "AndroidActiveRecord ! ! ! " "RESTProvider # " " #* " * experimental
  • 36. Data AccessFrameworks / Features Flex. Mapping Connectivity Caching JSON XML ce sis tenActiveAndroid ! ! ! " er P" Ws FAndroidActiveRecord ! ! ! " "RESTProvider # " " #* " * experimental
  • 37. Data Access RESTProviderpublic class TwitterFeedExample extends ListActivity { @Override public void onCreate(Bundle b) { super.onCreate(b); CPAsyncHandler g = new CPAsyncHandler(getContentResolver()); g.startQuery(1, null, Uri.parse("content://novoda.rest.test.twitter"), null, "q=?", new String[] { "droidcon" }, null); } private class CPAsyncHandler extends AsyncQueryHandler { @Override protected void onQueryComplete(int token, Object cookie, Cursor c) { super.onQueryComplete(token, cookie, c); setListAdapter(new SimpleCursorAdapter(TwitterFeedExample.this, android.R.layout.simple_list_item_2, c, new String[] { "from_user", "text" }, new int[] { android.R.id.text1, android.R.id.text2 })); } }}
  • 38. Data AccessFrameworksiPhone on Rails - http://iphoneonrails.com/CoreResource - http://coreresource.org/RestKit - http://restkit.org/
  • 39. Data AccessFrameworks / Features Flex. Mapping Connectivity Caching JSON XMLiPhoneOnRails # " " ! "CoreResource " " " " "RESTKit " " " " "
  • 40. Data Access RESTKit- (void)loadContact { RKObjectManager* manager = [RKObjectManager objectManagerWithBaseURL:@"http://restkit.org"]; [manager loadObjectsAtResourcePath:@"/contacts/1" objectClass:[Contact class] delegate:self]}// RKObjectLoaderDelegate methods- (void)objectLoader:(RKObjectLoader*)objectLoader didLoadObjects:(NSArray*)objects{ Contact* contact = [objects objectAtIndex:0]; NSLog(@"Loaded Contact ID #%@ -> Name: %@, Company: %@", contact.id, contact.name, contact.company);}
  • 41. Plethora of Languages ?@#!Objective-C C# Java JavaScript
  • 42. Solution: Use A DSL
  • 43. Solution: Use A DSL Entities Data View Mappers Controllers Entity Descriptions DSL iOS / Objective-Cdescribes data model andmapping rules Entities DSL IDE Transformers Activities Content Providers Android / Java
  • 44. DSL Sample Fetching Blog Itemsentity BlogItem { String guid String title String link String description String creator}contentprovider Blogposts returns BlogItem[] fetches XML from (FEEDSANITIZER_URL "/sanitize?url=http%3A%2F%2Fblogs.itemis.de%2F%3Fshowfeed%3D1&format=rss") selects "rss.channel.item"
  • 45. http://mobile.itemis.de@peterfriese | http://peterfriese.de
  • 46. Image credits Tower bridge - http://www.flickr.com/photos/anirudhkoul/3499471010/ Little girl with cell - http://www.flickr.com/photos/spitzgogo/286917522/ Gray-haired guy on bench - http://www.flickr.com/photos/mr_t_in_dc/5524143121/ Girl with hoody, texting - http://www.flickr.com/photos/lanier67/2979124681/ Fast girl on bike - http://www.flickr.com/photos/pixel_addict/465394708/ NY Apple Store - http://www.flickr.com/photos/smoovey/3749038495/ Guy driving and texting - http://www.flickr.com/photos/lord-jim/4794895023/ Portraits: http://www.flickr.com/photos/46914331@N03/4312184861/ http://www.flickr.com/photos/pagedooley/4258558487/ http://www.flickr.com/photos/yuri-samoilov/4105603525/ http://www.flickr.com/photos/adriel_socrates/5560606768/ http://www.flickr.com/photos/adriel_socrates/5560592742/in/photostream/ http://www.flickr.com/photos/kkoshy/4729866481/ http://www.flickr.com/photos/pagedooley/4258558741/ http://www.flickr.com/photos/mescon/3668279183/ http://www.flickr.com/photos/mescon/2984454695/ http://www.flickr.com/photos/ter-burg/428205830/ http://www.flickr.com/photos/eudaimos/2107219904/ Mountains, Lake and Boat - http://www.flickr.com/photos/visulogik/2180603155/ Dead Sea Scrolls - http://www.flickr.com/photos/kjfnjy/5249145754/ Lines of communication - http://www.flickr.com/photos/ruudhein/4442182264/ Satellite dish - http://www.flickr.com/photos/26652703@N02/2502519971/