Getting started building WS client for iPhone

Getting started building WS client for iPhone

by Michael Baldock -
Number of replies: 23

Hi All,

I've spent all afternoon trying to understand how I might be able to build a Client to a Moodle site. I believe I have configured my moodle site correctly, but from looking at the list of functions available, it doesn't seem like the standard set of functions will be able to do what I'd like it to anyway.

I'd like to give the whole 'student' experience from an iPhone, so the functions would ideally include; logging on, looking at course material, uploading course material, taking quizzes, posting to the forums etc.

I've read about OKTech, is this a moodle module that extends the functionality of the web service?

How would I install OKTech? (I'm new to moodle as of yesterday!)

I'm also quite confused about how function calls are actually submitted, I tried constructing a URL to test if my webservice was working at all:

http://mymoodlesite.net/webservice/xmlrpc/server.php?wstoken=5f5f35f3064122b05de3b67a66707931&wsfunction=moodle_course_get_courses

but this returned:

<name>faultCode 630 - Unable to read request</string>

Am I missing something major in terms of actually accessing the webService?

Apologies this message is a bit rambling! Any help appreciated.

Mike B

Average of ratings: -
In reply to Michael Baldock

Re: Getting started building WS client for iPhone

by Patrick Pollet -

OKTech is a WS that's allow remote access to most Moodle1.9 (and more and more Moodle 2.0) entities using the SOAP Web Service protocol. All possible operations are described in a WSDL file sent by http://yourmoodle/wspp/wsdl_pp2.php

So to get it it running you must  :

1) install the OKTech in your Moodle directory as described in the README file on https://github.com/patrickpollet/moodlews

2) on the client side you must have a library that talks SOAP and is able to translate the WSDL content to helper classes by some utility called wsdl2xxx depending of your language such as :

  • wsdl2php for php php-soap on Linux, Windows, Mac
  • wsdl2java for java Axis 1.4 (almost any desktop) or wsdl2ksoap2 for KSoap2  (any desktop system or Android smartphones see https://github.com/patrickpollet/moodlews_ksoap2)
  • for python : soap-py
  • SOAP is native in Microsoft .NET aware applications (Visual Studio, Excel...)

So your problem resumes to : is an Apple iPhone in Objective-C able to talk SOAP. If yes, you win, otherwise you must turn to other protocols such as REST or XML-RPC. see http://iphone.moodle.com.au/

Cheers.

Average of ratings: Useful (2)
In reply to Patrick Pollet

Re: Getting started building WS client for iPhone

by Michael Baldock -

Hey Patrick, Thanks for the explanations, that helps a lot, I'll ask around to see if Obj-C can to SOAP, but that has put the problem into context for me.

Cheers

In reply to Patrick Pollet

Re: Getting started building WS client for iPhone

by Michael Baldock -

Hi Patrick, thanks for your help so far, but I've got a bit stuck again!

I've installed OKTech as per instructions on the git page,

ran : php ../wsdl2php.php http://my_moodle/wspp/wsdl_pp.php

which created many classes.

changed auth.php.dist to auth.php

ran the test "php test_get_roles.php"

which returned all the courses I'd set up - So far so good!!

Next though - when trying to access the wsdl_pp with SoapUI (http://yourmoodle/wspp/wsdl_pp.php) this just keeps returning an error in SoapUI - here's a sample

Mon Apr 18 10:10:33 BST 2011:ERROR:Failed to load url [http:/my_moodle/wspp/wsdl2_pp.php]

com.eviware.soapui.support.SoapUIException: Error importing wsdl

at com.eviware.soapui.impl.WsdlInterfaceFactory.importWsdl(WsdlInterfaceFactory.java:80)

at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:2028)

----------

I've got a feeling this could be because I'm behind a firewall, but I'm not sure.

Now without my wsdl_pp working does this mean I'm also unable to issue requests to the webservice? Is this an essential part of the process, or is this just a means of getting info about the functions?

Again, without a functioning SoapUI project is there any way I can test if it's working? I've tried just entereing urls into a browser, such as

http://my_moodle/wspp/classes/getCoursesReturn.php

but unsurprisingly this returns nothing, I feel I'm stabbing inthe dark somewhat.

The eventual aim is to understand how to format the url request that I need to use when building my client.

Any help would be very much appreciated

Mike

In reply to Michael Baldock

Re: Getting started building WS client for iPhone

by Patrick Pollet -

Mike ,

>Mon Apr 18 10:10:33 BST 2011:ERROR:Failed to load url [http:/my_moodle/wspp/wsdl2_pp.php]

is'nt simply because you mispelled the URL in SoapUi ?

I should be either http://my_moodle/wspp/wsdl_pp.php for the old style WSDL or http://my_moodle/wspp/wsdl_pp2.php for the new style wink

Cheers.

In reply to Patrick Pollet

Re: Getting started building WS client for iPhone

by Michael Baldock -

Hi Patrick,

Thanks for the help, a good idea, but sadly still no cigar!

Mon Apr 18 13:14:45 BST 2011:ERROR:Failed to load url [http://my_moodle/wspp/wsdl_pp2.php]

Should I also have ran

php ../wsdl2php.php http://yourmoodle/wspp/wsdl_pp2.php

from my server?

I think as instructed in the install file I just did

php ../wsdl2php.php http://yourmoodle/wspp/wsdl_pp.php

can I now run the above script with wsdl_pp2.php ? Or do I somehow need to rollback the changes made by running wsdl_pp.php ?

Cheers,

Mike

In reply to Michael Baldock

Re: Getting started building WS client for iPhone

by Patrick Pollet -

No. The wsdl2php utility is only needed for php clients. You should not have to run it at all if you plan to call the WS from java like SoapUI. And normally you do not run it on the server but on a client workstation to get all the PHP helper classes.

So I suspect you have something else. Are you sure that the directory wspp has been uncompressed at the right place ? i.e. in the moodle's main directory

the end of a Linux ls -l  command should give :

..
drwxr-xr-x  6 ppollet ppollet    4096 2011-04-08 16:51 user
drwxr-xr-x  3 ppollet ppollet    4096 2010-10-26 14:09 userpix
-rw-r--r--  1 ppollet ppollet     589 2011-04-15 12:42 version.php
drwxr-xr-x 14 ppollet ppollet    4096 2011-04-18 13:32 wspp

Cheers.

Average of ratings: Useful (1)
In reply to Patrick Pollet

Re: Getting started building WS client for iPhone

by Michael Baldock -

No. The wsdl2php utility is only needed for php clients. You should not have to run it at all if you plan to call the WS from java like SoapUI. And normally you do not run it on the server but on a client workstation to get all the PHP helper classes.

OK, I didn't get that at all!

So I suspect you have something else. Are you sure that the directory wspp has been uncompressed at the right place ? i.e. in the moodle's main directory

the end of a Linux ls -l  command should give :

..
drwxr-xr-x  6 ppollet ppollet    4096 2011-04-08 16:51 user
drwxr-xr-x  3 ppollet ppollet    4096 2010-10-26 14:09 userpix
-rw-r--r--  1 ppollet ppollet     589 2011-04-15 12:42 version.php
drwxr-xr-x 14 ppollet ppollet    4096 2011-04-18 13:32 wspp

YEP here's mine :

drwxr-xr-x  6 scetftp psacln    4096 Apr 11 12:08 user

drwxr-xr-x  2 scetftp psacln      22 Apr 11 11:56 userpix

-rwxr-xr-x  1 scetftp psacln    1574 Apr 11 11:53 version.php

drwxr-xr-x  7 scetftp psacln     117 Apr 11 12:09 webservice

drwxr-xr-x  9 scetftp psacln    4096 Apr 15 17:03 wspp

-----

Exactly the same except I have 'webservice', which was what I first tried to get going, it comes wth moodle.

Still I have nothing from SoapUI

I've been trying a different tack. This post explains a way of accessing SOAP services

http://www.iphonedevsdk.com/forum/iphone-sdk-development/2841-resolved-how-call-soap-service.html

It boils down to issuing a request to a url with a dictionary of keys and objects, their example is:

NSArray *keys = [NSArray arrayWithObjects:@"USZip", nil];

NSArray *keyvalues = [NSArray arrayWithObjects:@"11235", nil];

[self generateWebServiceURLRequest: @"http://www.mywebsite.com/mywebservice.asmx" : @"getMyData": keys: keyvalues];

If my OKTech moodle webservice was running properly, what url would I point at anyway??

I've been trying:

"http://my_moodle_site/wspp"

but I'm not sure if that's correct.

And what would I need in the objects and keys, @"username", @"password" ???

If this is all documented somewhere please forgive me, but I have spent a long time looking!!

Thanks again

 

 

 

 

 

 

 

In reply to Michael Baldock

Re: Getting started building WS client for iPhone

by Patrick Pollet -

1) SoapUi problem : real strange . You should get it... Is the URL of your Moodle server correct ?  If you can reach your Moodle server and see a course with a browser, which I think you do, you should be able to get its  wspp/wsdl_pp.php in the same browser by replacing the ending 'course/view.php?id=xxx' by 'wspp/wsdl_pp.php' or 'wspp/wsdl_pp2.php'  and download the XML document  that SoapUi is expecting  Of course you don't use http://mymoodle but the real URL  wink

 

2) I have no experience in Obj-C but as far as I can see  from your sample code it does not use a WSDL but  there is some magic that assembles a SOAP request from parameters (keys and keyvalues) and send them to a service URL.... In that case the 'service URL' of OKTech is

http://yourmoodle_real_url/wspp/service_pp.php

or

http://yourmoodle_real_url/wspp/service_pp2.php

I recommends the second that's use simplified parameters upon return  (directly returns arrays)

3) To use OKTech you MUST first succeed a login operation sending over a login and a password. Upon return you receive a clientid (int) and a sessionkey (string) that must be resent  with any subsequent calls, until session expires (30minutes) or you call logout operation.

 

Here is a typical sequence (in Java using the KSoap2 library) :

private static final String MOODLE_SERVICE=Constantes.MOODLE_URL+"wspp/service_pp2.php"; 
 private static final String MOODLE_NAMESPACE=Constantes.MOODLE_URL+"wspp/wsdl2/";

Mdl_soapserverBindingStub moodle = new Mdl_soapserverBindingStub(MOODLE_SERVICE,MOODLE_NAMESPACE, Constantes.WS_DEBUG);
LoginReturn lr = moodle.login(Constantes.LOGIN, Constantes.PWD);
if (lr != null) { 
      int me = moodle.get_my_id(lr.getClient(),lr.getSessionkey());
     System.out.println("me " + me); 
      CourseRecord[] ret = moodle.get_my_courses(lr.getClient(), lr .getSessionkey(), "" + me, null);
     if (ret != null) {  
         System.out.println(Arrays.toString(ret));
     }
     moodle.logout(lr.getClient(),lr.getSessionkey());
}

 

Cheers.

Average of ratings: Useful (1)
In reply to Patrick Pollet

Re: Getting started building WS client for iPhone

by Michael Baldock -

"1) SoapUi problem : real strange . You should get it... Is the URL of your Moodle server correct ?....."

The SoapUI problem I now believe is because of the proxy server / firewall I'm working behind in the office. (the source of all evil) I've been home, installed it on my home machine, pointed it at the exact same url and bingo - all the methods with params / attributes pop up no problem, I've tried logging in, and had success in that it returned a token.

I had been the correct url, not www.my_moodle!tongueout I didn't want to advertise it too much, as from reading around there's some security I need to do before making it public.

http://yourmoodle_real_url/wspp/service_pp2.php

I believe this URL is the key I've been looking for! (Of course now SoapUI is working that becomes more obivous.

Here is a typical sequence (in Java using the KSoap2 library)....

Thanks for this, as far as I can tell there isn't a similar Soap library for Obj-C, I wish! people seem to be mostly "hand writing" their own requests.

Just to clarify... I send a block of text that looks something like this:

<soapenv:Header/>
<soapenv:Body>
<wsd:login soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<username xsi:type="xsd:string">USERNAME</username>
<password xsi:type="xsd:string">P@$$word!</password>
</wsd:login>
</soapenv:Body>
</soapenv:Envelope>

To a url like this:

http://yourmoodle_real_url/wspp/service_pp2.php

And I need this to hapen in a more or less sensible way using Obj-C. Is that the idea, sort of!!???

Thanks so much for your help with all this.

Mike

 

 

 

 

 

 

 

In reply to Michael Baldock

Re: Getting started building WS client for iPhone

by Patrick Pollet -

Hi Mike,

Glad SoapUi got wspp at home. Now you just have to convince somedody to open the firewall wink

 

Concerning your idea, that's looks good, but you will have to do everything by hand : emitting the SOAP enveloppe and parsing the XML response. Terrible...especially with all operations that requires arrays as input and return arrays of objects...

I did a little search and found this blog post talking about generating C++ helper classes against a WSDL using gSoap, and after that using them in Obj-C. that's may be the solution ?

see http://www.sebhoerner.fr/?p=127 (Google translator gave me an english version quite readable wink)

So I tried on my Ubuntu :

got gsoap from http://www.cs.fsu.edu/~engelen/soap.html
make && make install after adding g++, bison, byacc and flex 

and I runned the two 'magic commands' :

wsdl2h -o moodlewsv2.h -s http://localhost/moodle.195/wspp/wsdl_pp2.php
soapcpp2 -c -s moodlewsv2.h

and got 5.9Mo  of quite sound C++ code !!!  that looks very similar to what I am used to in Java ...  I know nothing about C++ so I stopped here but I guess it is worth a try ?

The only drawback I see is that the service URL and the namespace are 'hardcoded' in all the generated classes and XML. I found 1035 occurences of the string 'localhost/moodle.195' in the generated code (that's the reason I dropped apache Axis for Java and swapped to KSoap2)

But that could be easily changed by using some global constants of your application.

Cheers

In reply to Patrick Pollet

Re: Getting started building WS client for iPhone

by Anthony Emery -

iPhone is more than capable of talking to SOAP, I have developed a basic working pattern for iOS -> Moodle communication using OKTech WebService for the final year project of my degree.

The screens below contain just basic UI, but represent data taken from Moodle Course/Sections/Resource/Messages and Event blocks.

 

The process is simple, but just requires some heavy parsing of the return XML, not an exciting prospect, I can assure you of that. Im not sure how valuable my techniques may be to the community but Im happy to give an overview to anybody that wants to listen. (After I have finished my project next week that is!)

Average of ratings: Useful (1)
In reply to Anthony Emery

Re: Getting started building WS client for iPhone

by Giulio Valente -

Hi Anthony,

I'm impressed smile It's really nice smile,

I have question do you show all the events or only the upcoming?

Do you know how to get only the upcoming events?

Thank you

In reply to Giulio Valente

Re: Getting started building WS client for iPhone

by Anthony Emery -
Those screens are just a proof of concept so they show all events (a few random bits of data I put in) It would be really easy to filter for any time period. Moodle returns the dated as UNIX time so you could just 1. Conditionally filter out time now + 3600*24*number of days upcoming you want to show 2. Reload Tableview
In reply to Anthony Emery

Re: Getting started building WS client for iPhone

by Giulio Valente -

Yes, but I would like to avoid to download all the events... can you imagine a students that should downloads thousand of events to filter then? I would ask to the webservice only the upcomings event.....

In reply to Giulio Valente

Re: Getting started building WS client for iPhone

by Anthony Emery -

You can specify the event type (user, course, site etc) and ownerid in the call to the webservice.

This would narrow the results down considerably before filtering by date, although it might be necessary to make several calls doing it this way.

Its all thats on offer from the webservice at the moment, unless you want to rewrite the get_events function to include a date range.

In reply to Anthony Emery

Re: Getting started building WS client for iPhone

by Giulio Valente -

At the moment I use 0 as event type... do you know which are all the events types?

Thank you for your help smile

In reply to Giulio Valente

Re: Getting started building WS client for iPhone

by Anthony Emery -

Just go to your Moodle install and try and create an event, you will get a list of the types there. I have used 'user', 'course', and 'site' events so far.

I think there is also 'group' and maybe some others but I can't quite remember off the top of my head.

In reply to Anthony Emery

Re: Getting started building WS client for iPhone

by Patrick Pollet -

Hello,

Supported values of eventtype are described at the beginning of file wspp/serverclass.php :

define('cal_show_global', 1);

define('cal_show_course', 2);

define('cal_show_group', 4);

define('cal_show_user', 8);

but if you set eventtype to something <> 0 or 1 you also must set the others parameters ownerid and owneridfield ...

eg :

get user's events identified by its username : get_events(client,sesskey,8,'johndoe','username')

get course's event identified by it's  shortname chem101 :  get_events(client,sesskey,2,'chem101','shortname')

get group's event identified by it's  id 42 : get_events(client,sesskey,4,'42,'id')

As far as the date range business is concerned, I guess it is  my fault. Currently get_events() returns all events of some type pertaining to  some owner/course/group  regardless of the starting date of that event.

I think it should default to 'future events', i.e.have in final  SQL something like  'where mdl_event.timestart >= now ()'  or have an extra parameter $timestart, that would default to now() if empty   ....

Let me known

 

Cheers.

In reply to Patrick Pollet

Re: Getting started building WS client for iPhone

by Giulio Valente -

Hi Patrick,

Thank you for your answer.

Now seems to be clear which are the different types. smile

But I've tried in different way to get the events and I get all the events only in the following way:

get_events(MoodleWSDL.getCLIENT(), MoodleWSDL.getSESSIONKEY(), 0, "id", "");

I've tried also with:

get_events(MoodleWSDL.getCLIENT(), MoodleWSDL.getSESSIONKEY(), 1,"""");

get_events(MoodleWSDL.getCLIENT(), MoodleWSDL.getSESSIONKEY(), 1,"id""");

get_events(MoodleWSDL.getCLIENT(), MoodleWSDL.getSESSIONKEY(), 1,"""");

But it always returns only a single events with all 0 inside :/

I suppose I should use 1 for the event type.

Do you have any suggestions?

Anyway it would be great to have the possibility to download only the upcoming events, otherwise I should filter as Anthony said smile

P.S.: Another extra question, do you know if it will be possible to upload the profile picture? (My idea is to use the camera the get it.

 

Thank you for your help smile

In reply to Anthony Emery

Re: Getting started building WS client for iPhone

by Michael Baldock -

@Anthony - Nice looking screenshots, I've actually decided on a different tact for my project, not using moodle as a web service any more, but hopefully if I get a bit of time I'll return to the idea, and I'd be iterest to know how you built your SOAP requests / documents / parser, my attempt with libxml became horrendously tedious, that I was going to write all the requests as long strings, but I'm sure there's a better way!

 

@Patrick - Just noticed you've implemented a REST protocol. Thank you so much for your hard work!!!smile

In reply to Anthony Emery

Re: Getting started building WS client for iPhone

by Imran Zulfiqar -

do you have the code for this shared somewhere, or can you possible email it.

In reply to Patrick Pollet

Re: Getting started building WS client for iPhone

by udhayakumar R -

Hi,

         MoodleWS for android, i can able to list the courses and categories but i want to get the course content, which will be use to render in the android webview. please help me to get the content(activities, images, and all). via web service, do i have to write any functions for this?

please explain how... . .

Average of ratings: Useful (1)
In reply to udhayakumar R

Re: Getting started building WS client for iPhone

by Yunus Luniwala -

Hi there,

My name is Yunus and I am totally a newbie for moodle. I assigned a task to integrate the moodle WS with Android client. For that I followed https://github.com/patrickpollet/moodlews_ksoap2 example.

But I am still not able to figure out the things as it should be. Can you please guide me how to implement a WS which list all available courses and display it in a list-view or expandable list-view. It will be much helpful if you can give me a small demo project.  My email id is : yunusluniwala@gmail.com.

Waiting for your kind response.

Thanks.

Regards.

Yunus