June 4th, 2015

Add Collaboration To Your Mobile Apps with SharePoint

Mayur Tendulkar
Technology Solutions Professional

Microsoft SharePoint is one of the most widely used, powerful collaboration tools in the workplace, providing countless features and seamless integration with other products in the Microsoft ecosystem. Now that SharePoint is provided as a cloud solution with Office 365, integrating Office 365 into your apps with Xamarin is a breeze. In recent blog posts, we covered adding Azure Active Directory Authentication, Outlook for Email, and OneDrive for Storage to your apps.

0001 SP 2013 Logo

In this blog post, we’ll see how easy it is to add SharePoint functionality to your mobile apps using the SharePoint APIs.

Step 1: Register Native Mobile App

Before SharePoint can be integrated into your app, you must register it using the Azure Active Directory.

Step 2: Provide Access to SharePoint APIs

Once you register the app, click on the ‘Configure’ tab. On this tab, you should see a green button with the text ‘Add application’. Click on it to access the SharePoint APIs.

Providing access to SharePoint ServicesOn the next screen, select ‘Office 365 SharePoint Online’ and click on the check mark button.

Providing access to SharePoint Services Pt. 2.After this, give the appropriate permissions to the SharePoint services, so users can access them from your mobile app.

Providing access to SharePoint Services Pt. 3Save the changes. Now it’s time to integrate SharePoint with our app. Make sure to copy the ‘Client Id’ and ‘Redirect URI’, which will be required in future steps.

Step 3: Authenticating to Azure Active Directory

With the latest Azure Active Directory Authentication Library (Azure ADAL) preview, the code from our previous blog post on ADAL changes slightly. As of the latest release, AuthorizationParameters has been renamed PlatformParameters, which govern the authentication mechanism on individual platforms. For Android, this is what the code to fetch access tokens should look like now:

public static async Task<AuthenticationResult> GetAccessToken(string serviceResourceId, PlatformParameters param)
{
    authContext = new AuthenticationContext(Authority);
    if (authContext.TokenCache.ReadItems ().Any ()) {
        authContext = new AuthenticationContext (authContext.TokenCache.ReadItems ().First ().Authority);

        var authResult = await authContext.AcquireTokenAsync(serviceResourceId, clientId, returnUri, param);
        return authResult;
    }
}

Here, serviceResourceId is your top-level SharePoint URL. For example, in my case it’s “http://mayurtendulkar.sharepoint.com/”, and once authenticated, the app can access any resources below that level. You can call this method from OnCreate, so whenever the app is launched, it will check for tokens (or launch the sign in process).

var authResult = await AuthenticationHelper.GetAccessToken (AuthenticationHelper.SharePointURL, new PlatformParameters (this));

Now, you can use this token from authResult to call the SharePoint APIs.

Step 4: Calling SharePoint APIs

Unlike objects like OutlookClient (which is responsible for Mail, Contacts, and Calendar) or SharePointClient (which is responsible for handling files in OneDrive), SharePoint APIs are REST APIs. Instead of using objects from the SDK, you will use HttpClient to call the SharePoint APIs.

Before discussing how to call the SharePoint APIs from your app, I want to revisit some SharePoint fundamentals. SharePoint contains SiteCollections, which can have sites and the sites can have sub-sites. Sites can be individual apps (e.g. HR Portal, Leave Portal, etc.) that contain libraries (for storing documents) as well as lists (task list, custom lists of data, etc.). Tasks can be shared with colleagues and marked as not started/started/complete/etc. Here, we’re going to create a Task List and add some items to it.

Step 4.a: Create a List in SharePoint Site

The code below will show you how to create a list within a SharePoint site. You can find detailed REST API documentation on SharePoint via MSDN.


protected async Task<bool> CreateList(string token)
{
    var client = new HttpClient();
    client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", token);

    var mediaType = new MediaTypeWithQualityHeaderValue ("application/json");
    mediaType.Parameters.Add (new NameValueHeaderValue ("odata", "verbose"));
    client.DefaultRequestHeaders.Accept.Add (mediaType);

    var body = "{\"__metadata\":{\"type\":\"SP.List\"},\"AllowContentTypes\":true,\"BaseTemplate\":107,\
        "ContentTypesEnabled\":true,\"Description\":\"Tasks by Xamarin.Android\",
        \"Title\":\"TasksByAndroid\"}";

    var contents = new StringContent (body);
    contents.Headers.ContentType = MediaTypeHeaderValue.Parse( "application/json;odata=verbose");

    try {
        var postResult = await client.PostAsync ("https://mayurtendulkar.sharepoint.com/_api/web/lists/", contents);
        var result = postResult.EnsureSuccessStatusCode();
        Toast.MakeText (this, "List created successfully! Seeding tasks.", ToastLength.Long).Show();

        return true;
    } catch (Exception ex) {
        Toast.MakeText (this, "List already exists! Fetching tasks.", ToastLength.Long).Show();
        return false;
    }
}

As you can see from the above code, the body of the request defines what needs to be done on the SharePoint side. In our case, we’re asking SharePoint to create a SP.List (list with template 107,) which is nothing but a Task List, and giving this list a title and description.

Step 4.b: Add Items to the List

Once the list is created, the same code shown above can be used to create ‘List Item’. To do so, changes need to be made in the request url and body. The following code can add a new task in ‘Task List’, which was just created above.


protected async Task<bool> CreateItems(string token)
{
    var client = new HttpClient();
    client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", token);
    var mediaType = new MediaTypeWithQualityHeaderValue ("application/json");
    mediaType.Parameters.Add (new NameValueHeaderValue ("odata", "verbose"));
    client.DefaultRequestHeaders.Accept.Add (mediaType);

    var itemToCreateTitle = "Item created on: " + DateTime.Now.ToString("dd/MM HH:mm");
    var body = "{\"__metadata\":{\"type\":\"SP.Data.TasksByAndroidListItem\"},\"Title\":\"" + itemToCreateTitle + "\",\"Status\": \"Not Started\"}";
    var contents = new StringContent (body);
    contents.Headers.ContentType = MediaTypeHeaderValue.Parse( "application/json;odata=verbose");

    try {
        var postResult = await client.PostAsync ("https://mayurtendulkar.sharepoint.com/_api/web/lists/GetByTitle('TasksByAndroid')/items", contents);
        var result = postResult.EnsureSuccessStatusCode();
        if (result.IsSuccessStatusCode) {
            Toast.MakeText (this, "List item created successfully!", ToastLength.Long).Show();
            return true;
        }
    } catch (Exception ex) {
        var msg = "Unable to create list item. " + ex.Message;
        Toast.MakeText (this, msg, ToastLength.Long).Show();
        return false;
}

Step 4.c: Fetch & Display List Items

Getting records from list requires nothing beyond calling a ‘GET’ request on list endpoint. Displaying these items in a list within your mobile app is easy: the request returns JSON data, which you can parse to objects using Json.NET and then you can create a custom adapter (in my case ListItemModels) and display it in a ListActivity.


protected async Task<bool> FetchListItems(string token)
{
    var client = new HttpClient();
    client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", token);
    var mediaType = new MediaTypeWithQualityHeaderValue ("application/json");
mediaType.Parameters.Add (new NameValueHeaderValue ("odata", "verbose"));
client.DefaultRequestHeaders.Accept.Add (mediaType);
    try {
        var result = await client.GetStringAsync("https://mayurtendulkar.sharepoint.com/_api/web/lists/GetByTitle('TasksByAndroid')/items");
        var data = JsonConvert.DeserializeObject<O365SharePoint.Models.ListItemModels>(result);
        ListAdapter = new ListItemAdapter(this, data.D.Results);
        ListView.ItemClick += async (sender, e) => {
            var _status = (e.View as CheckedTextView).Checked;
            var _id = (e.View).Tag.ToString();
            await ChangeStatus(token, _id, _status);
        };

        for (int item = 0; item < data.D.Results.Length; item++) {
            if(data.D.Results[item].Status == "Completed")
                ListView.SetItemChecked(item, true);
        }

    } catch (Exception ex) {
        var msg = "Unable to fetch list items. " + ex.Message;
        Toast.MakeText (this, msg, ToastLength.Long).Show();
    }

    return true;
}

Step 5: Run the App

Run this app using either the Xamarin Android Player or a physical device. If all of the steps above are executed correctly, you should see the same items from the list created in SharePoint in the Android app we built.

SharePoint List and List in a Mobile App

Conclusion

Once you understand the basics of the SharePoint REST APIs and how to call them from mobile apps, the possibilities are endless. Integrating existing SharePoint sites into your iOS and Android apps is easy with Xamarin.

To get started, download the SharePoint sample from GitHub and be sure to replace the client ID, redirect URI, and your resource URI with the ones you created in the tutorial before running the app.

Author

Mayur Tendulkar
Technology Solutions Professional

Mayur Tendulkar is Technology Solutions Professional working at Microsoft in Singapore, helping people with technology. Previously he was a Program Manager on Xamarin team at Microsoft, working from Pune, India. Before joining Microsoft, since 2013, he was awarded as Microsoft Most Valuable Professional on Windows Development and worked as Developer Evangelist with Xamarin. He is writing mobile applications since the days of Windows Mobile 5.0 and love to talk about everything mobile and cloud ...

More about author

1 comment

Discussion is closed. Login to edit/delete existing comments.

  • Jeroen van den Raadt

    How do I convert authResult, which is an AuthenticationResult, to string?
    Edit: you have to put .AccessToken behind your value to get the token.