If you want to create a new page for developers, you should create it on the Moodle Developer Resource site.

Talk:Mobile app

From MoodleDocs

Obtain web service token

In Moodle Mobile apps or other web service clients, we need a secure method to transmit token.

  • The easiest way would be using https for token request script, user enter username and password, send them to HTTPS protected script to obtain the token, the disadvantage of this method is the limit of HTTP server, for some shared hosts, HTTPS is not available.
  • I looked OAuth, it's getting popular, and secure. But it has a few disadvantage:
  1. Moodle for iPhone will support multi Moodle instances, so we have to save api and secret for each website, it's very annoying for mobile users to type such long keys
  2. The major problem is OAuth will need two keys: access key and access secret during transmission, then generate a signature using a few factors, the signature will embedded in http header, moodle will need to verify this signature. It looks like another security layer besides web service subsystem, if we only use it for obtaining web service token, I am not sure if worth to use it, we will have to implement OAuth server, and a few scripts to handle access keys exchange, and database tables including oauth_log, oauth_consumer (store consumer key and secret), consumer_token, access token(store access key) we need at least three new tables, probably another two to store nonce and activity logs.
  • RSA algorithm can be alternative method of HTTPS, before we add a website in moodle app, we request the public key from the website, encrypt the username, password and user secret by public key, then send them to server, moodle will decrypt it by private key, if success, encrypt the key by the user secret (use 3DES or AES), 1024-2048 bits public key is considered to be safe, but it could be slow for mobile device because of the long key. ECC algorithm use shorter key and strong, but it's more difficult to implement.

My proposal would be the combination of HTTPS and RSA.

It's related to

--Dongsheng Cai 11:08, 20 April 2011 (WST)

Upload and download files from moodle

We already implemented "upload" web service, which only allow users to upload files to user private, the problem is we need to use base64 encoding binary file so it can fit into xml payload, it theoretically works, but in the real world, if we pick a file from iphone photo library, it's usually around 1.2Mb, encoding will enlarge the file by 33%, not too bad, but encoding the picture will take more than a minute, it's very bad user experience.

For better performance, we'd better use POST and GET the upload and download files, then we need to setup session, what we need to do:

  1. Assume user already got token, then user send token and file to a special script in Moodle, for example Moodle verify the token, if true, setup session, check permission, then allow uploading
  2. If users intend to download a moodle file served by pluginfile.php, first users request a special script with token, if token is valid, grant the session, then users will be able to access the files served by pluginfile.php, we need to http request in this case, if we can verify the token in pluginfile.php to reduce the http traffic, I'm not sure if it's acceptable.

It's related to

--Dongsheng Cai 11:08, 20 April 2011 (WST)

Juan explaining the all new HTML5 app structure

(18:05:06) I want to explain you the js libraries I used
(18:05:09) and how the plugins works
(18:05:10) etc..
(18:05:16) mouneyrac: ok :)
(18:05:22) ok, first
(18:05:28) mouneyrac: looking at it
(18:05:41) I mainly use: Backbone (template, routes, storage)
(18:05:55) jQuery : DOM, ajax, trim, etc...
(18:06:09) jqueryTouchSwipe extension for swipe gestures
(18:06:21) matchMedia.js for detecting mediaqueries at javascript level
(18:06:39) requirejs for creating modules (plugins)
(18:06:50) scroll.js for fixing the scroll in iPad
(18:07:09) text.js is a requirejs plugin
(18:07:21) underscore is a requeriment of backbone
(18:07:41) app.js is the js that launches the app and mm.js is the main lib
(18:08:06) now, if you look at
(18:08:32) you can see that there are two main divs, one for the login screen, and another one with the three panels app view
(18:08:43) also, you will notice that at the bottom of the document, there are javascript templates
(18:09:05) these are the templates for the core functionalities, like the participants list
(18:09:18) and the main menu template
(18:09:39) we have also a config.json file with some default settings
(18:10:00) as you can see, the plugins that the app is going to load are there
(18:10:39) this is because we need the list of plugins to load in the correct order and also because we can't read the filesystem for getting the plugins directory contents
(18:11:05) how the app bootstraps ?
(18:11:14) the file is responsible of this
(18:12:01) as you can see, we simply require the config.json file to be loaded, and then we load the plugins listed in the config.json file, when all the plugins are loaded (are async calls) we call the MM.loadLayout function that "fills" the three panels
(18:12:31) previously the MM.init functions is called when the config.json file is loaded
(18:13:24) the MM init function do setup options like initialize Backbone, detect the device type (phone or tablet), load the routes, models and settings from database
(18:14:09) and the MM.loadLayout function just fill the left menu panel calling the get_siteinfo and get_courses WebServices
(18:15:12) and what about plugins
(18:15:18) this is how a plugin should look
(18:15:19) Andrew Nicols: So we're sticking with jquery for the mobile site, even though we're sticking with YUI for moodle?
(18:15:43) hmm, at this stage Yes
(18:15:52) mainly because some of the plugins used
(18:16:12) Andrew Nicols: Out of interest, which plugins?
(18:16:15) sbut we can change it in core without affecting plugins
(18:17:47) I'm designing the app for be able to switch frameworks without affecting plugins
(18:18:07) Andrew Nicols: oh good stuff :)
(18:18:12) as you can see plugins are easy to implement (this is not implemented fully)
(18:18:36) we create a global object called plugin, that we register in the main app using the MM.registerPlugin function
(18:18:57) Andrew Nicols: Sounds a lot like the YUI loader
(18:19:00) the plugin has:
settings (name of the plugin, type and the main menu URL to point)
(18:19:22) routes, with the route to match, the route id and which function to call when a route matchs
(18:19:33) this is so good, we are using Backbone history and works very good
(18:19:45) and then the functions
(18:19:49) Andrew Nicols: Cool. I'll have to take a look at the routes and Backbone stuff
(18:20:01) and the templates (in the
(18:20:08) (in this example there are no templates)
(18:20:18) so the app works by URL matching 
(18:20:48) this is very clean, preserve history, and we don't have to bind to DOM elements using jquery
(18:20:58) and also, we can change the routes framework at any time
(18:21:09) mouneyrac: :yes::yes::yes:
(18:21:32) and how a plugin function should look like?
(18:22:02) showParticipants is in core, but it could be in a plugin
(18:22:40) as you can see, the only call to a framework specific is _.tempalte (underscore) but I'm going to create a wrapper for the function
(18:22:45) the function is very simple
(18:23:09) we show the loading icon in the panels we want (in tablet the two panels, in phone just one)
(18:23:31) and then we call to a WS using the moodleWSCall function (function, parameters, callback function)
(18:24:01) and then we create the HTML using the template, and loads the panels callen the function
(18:24:13) also if the device is a tablet, we preload the first participant in the right panel
(18:24:20) as you can see is very very simple
(18:25:01) No DOM manipulation, no jquery, 
(18:25:10) I'm going to show you how can we handle the storage
(18:25:42) models are also described in the plugin/main.js file but I don't have any examples
(18:25:43) just go here
(18:26:11) the var elements, has the list of models and collections ( a set of models)
(18:26:22) we just declare the name of the model, or collection
(18:26:33) and that's is
(18:27:03) as you can see, the setting has and attributte called bbproperties
(18:27:25) if you want to use backbone internals, you can declare it in this attribute 
(18:27:55) in this case, every time a setting is stored, the initialize function is called for performing some actions (caching the setting name and value)
(18:28:17) this is a way for using a framework agnostic approach but at the same time uses the framework functionalities
(18:29:01) as you can see when we declare a model, we don't have to specify the "fields" of the models, this is because are stored like objects
(18:29:35) so at any time we can manipulate the models without performing complex upgrades (thanks to not using SQL, just a key - value storage system)
(18:32:19) mouneyrac: I'm not sure to understand the loadModels yet, I need to use it :)
(18:32:35) Cindereloy [ unlockingme] entered the room.
(18:33:02) mouneyrac: The structure looks pretty awesome.
(18:33:20) mouneyrac: Copying all your info in the wiki for future reference
(18:34:54) Jerome, can you reload
(18:35:18) I've added a few things
(18:35:39) in the settings a new setting called lang
(18:35:49) for indicating where are the strings related to this plugin
(18:36:02) in this case, are in the main file 
(18:36:17) storage, where the models are collections are defined
(18:36:25) models and collections
(18:36:58) and also, templates
(18:37:36) as you can see you can bind a template to a model, this is a way for using Backbone Views
(18:37:52) in any case, next week I will show you plugins fully implemented