Drupal, Android and iPhone

  • 4,325 views
Uploaded on

Talk given at Drupalcamp Bucharest 2011.

Talk given at Drupalcamp Bucharest 2011.

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

Views

Total Views
4,325
On Slideshare
0
From Embeds
0
Number of Embeds
1

Actions

Shares
Downloads
43
Comments
0
Likes
1

Embeds 0

No embeds

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
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n

Transcript

  • 1. DRUPAL, ANDROID AND IPHONE Badiu Alexandru Fratu Mihai Drupalcamp Bucharest 2011
  • 2. ABOUT US• We work at Adulmec• We do fine products such as Dealfever, Urbo and Adulmec• We sometime build mobile apps• Ataxi, Urbo, games and soon the Adulmec app Drupalcamp Bucharest 2011
  • 3. CONNECTI• You expose some functionality as REST or some sort of web service• Your mobile application makes HTTP calls• Authentication? Access control? Drupalcamp Bucharest 2011
  • 4. CONNECTI• Two ways• Use the Services module• Use a custom solution• Depends on your requirements Drupalcamp Bucharest 2011
  • 5. FOR• Adulmec Coupon Redeem - custom• Urbo - Services Drupalcamp Bucharest 2011
  • 6. CUSTOM• Write php pages• Without Drupal• Lightweight Drupal• Full Drupal• Output XML or JSON• Make HTTP call and parse result Drupalcamp Bucharest 2011
  • 7. CUSTOM• Latest news app• Shows a list of the latest posts on a site• Click on a post, go to the site Drupalcamp Bucharest 2011
  • 8. <?php CUSTOMchdir(../);require_once ./includes/bootstrap.inc;drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL);$response = array();$result = db_query_range(SELECT nid, title FROM {node} WHERE type="story" ORDERBY created DESC, 0, 10);while ($row = db_fetch_object($result)) { $response[] = array(title => $row->title, url => node/ . $row->nid);}drupal_json($response); Drupalcamp Bucharest 2011
  • 9. CUSTOM[   {      "title":"Illum Verto Fere Esse Secundum Cui Zelus Luctus",      "url":"node/2"   },   {      "title":"Uxor Eu Camur Voco Refero Fere",      "url":"node/7"   },] Drupalcamp Bucharest 2011
  • 10. CUSTOMURI uri = new URI("http://0001.ro/alex/drupalcamp/services/pages/list.php");HttpClient client = new DefaultHttpClient();HttpGet request = new HttpGet(uri);HttpResponse response = client.execute(request);InputStream is = response.getEntity().getContent();BufferedReader br = new BufferedReader(new InputStreamReader(is));String result = br.readLine();adapter.clear();JSONArray r = new JSONArray(result);for (int i = 0; i < r.length(); i++) { JSONObject jitem = r.getJSONObject(i); SubtitleItem item = new SubtitleItem(jitem.getString("title"),jitem.getString("url")); adapter.add(item);}adapter.notifyDataSetChanged(); Drupalcamp Bucharest 2011
  • 11. SERVICES• Creates web services out of Drupal functions• Concepts: service and server• Autenthication plugins• Pluggable Drupalcamp Bucharest 2011
  • 12. SERVICES• Out of the box: Comments, Files, Menu, Node, Search, System, Taxonomy, User, Views• XMLRPC Server• Key based authentication Drupalcamp Bucharest 2011
  • 13. SERVICES• We use XMLRPC in iOS apps• We use JSON in Android apps• json_server• Demo with standard json parser• GSON and Jackson• Streaming and mapping Drupalcamp Bucharest 2011
  • 14. SERVICES• Drupalcloud for Android• Custom code for iOS• drupal-ios-sdk Drupalcamp Bucharest 2011
  • 15. SERVICES• Key auth allows you to grant access just to some specific apps• Fine-grained: user authentication• Session id is used in every call• system.connect Drupalcamp Bucharest 2011
  • 16. SERVICES• hash - sha of domain, time and nonce• domain• timestamp• nonce• session Drupalcamp Bucharest 2011
  • 17. SERVICES• call system.connect - get session• use session in every call• call user.login - get new session• use new session in every call• call user.logout• call system.connect - get session• repeat Drupalcamp Bucharest 2011
  • 18. SERVICES• What about saving session across app launches?• Save session and timestamp to prefs after login or connect• At launch check that the saved session has not expired• If not, use that session• Otherwise system.connect Drupalcamp Bucharest 2011
  • 19. WTFS• userLogin returns new session• no user uid• no way to set it in the client• we create our own• json_server does not work Drupalcamp Bucharest 2011
  • 20. public void setSessionId(String sessionId) { SharedPreferences auth = mCtx.getSharedPreferences(mPREFS_AUTH, 0); SharedPreferences.Editor editor = auth.edit(); editor.putString("sessionid", sessionId); editor.putLong("sessionid_timestamp", new Date().getTime() / 100); editor.commit();} Drupalcamp Bucharest 2011
  • 21. WTFS • Services is inconsistent or weird • You’re already logged in as... • Error is false or true? • Where’s the error?{ "#error": false, "#data": { "#error": true, "#message": "Wrongusername or password." } }{ "#error": false, "#data": { "sessid":"02fd1c8a9d37ed9709ba154320340e8a", "user": { "uid": "1", ... Drupalcamp Bucharest 2011
  • 22. DRUPALCLclient = new JSONServerClient(this, getString(R.string.sharedpreferences_name), getString(R.string.SERVER), getString(R.string.API_KEY), getString(R.string.DOMAIN), getString(R.string.ALGORITHM), Long.parseLong(getString(R.string.SESSION_LIFETIME)));<string name="app_name">AndroidDemo</string><string name="sharedpreferences_name">AndroidDemoPrefs</string><string name="SERVER">http://0001.ro/alex/drupalcamp/services/services/json</string><string name="API_KEY">85255b11393bc0ee19d29758a043a698</string><string name="DOMAIN">http://mobile.0001.ro</string><string name="ALGORITHM">HmacSHA256</string><string name="SESSION.LIFETIME">1209600</string> Drupalcamp Bucharest 2011
  • 23. DRUPALCL• Has some methods built in• Just parse the response• For other methods do client.call() Drupalcamp Bucharest 2011
  • 24. DRUPALCLString result = client.userLogin(userText.getText().toString(),passText.getText().toString());JSONObject r = new JSONObject(result).getJSONObject("#data");boolean error;try { error = d.getBoolean("#error");}catch (Exception e) { error = false;}if (!error) { String session = d.getString("sessid"); client.setSessionId(session);}else { finish();} Drupalcamp Bucharest 2011
  • 25. DRUPALCLtry { JSONObject node = new JSONObject(); node.put("type", "story"); node.put("title", title.getText().toString()); node.put("body", body.getText().toString()); BasicNameValuePair[] params = new BasicNameValuePair[1]; params[0] = new BasicNameValuePair("node", node.toString()); String result = client.call("node.save", params); } catch (Exception e) { Log.v("drupalapp", e.toString()); e.printStackTrace(); } Drupalcamp Bucharest 2011
  • 26. RESOURCE• https://github.com/skyred/ DrupalCloud• https://github.com/workhabitinc/ drupal-ios-sdk• http://commons.apache.org/codec/• http://drupal.org/project/services• http://drupal.org/project/ Drupalcamp Bucharest 2011
  • 27. THANK andu@ctrlz.ro http://ctrlz.roDrupalcamp Bucharest 2011