Upgrading apps
The upgrade process designed by the SharePoint app model provides a
much better experience compared to the upgrade process used with
SharePoint solutions. When apps
are published, the Office Store and app catalog sites always track
their version number. When an app is installed, the SharePoint host
environment sees this version number and records it for the installed
app instance.
Take a simple example. Imagine you have uploaded version 1.0.0.0 of
an app. After that, the app is installed in several sites via
site-scoped installation. The SharePoint host environment remembers
that each of these sites has installed version 1.0.0.0 of the app.
Now, imagine that you want to further develop your app. Maybe you
need to fix a bug, improve its performance, or extend the app’s
functionality. After you have finished your testing, you decide to
update the version number to 2.0.0.0 and publish the new version in the
same app catalog site where you installed the original version.
One important aspect of the upgrade process of the SharePoint app
model is that an updated version of an app is never forced upon the
user that installed the app. Instead, the user is notified that a new
version of the app is available. This user can then decide to do
nothing or to update the app to the new version. Figure 8 shows the notification that the SharePoint host environment adds to the app tile on the Site Contents page.
The notification depicted in Figure 8
contains an update link that a user can click to be redirected to a
page with a button that activates the upgrade process. What actually
occurs during the upgrade process is different, depending on whether
the app is a SharePoint-hosted app or a cloud-hosted app.
When you are working on an updated version of a SharePoint-hosted app, you have the ability to change some of the metadata in the app manifest and to add new elements into the app web. For example, you could add a new page to the app web named startv2.aspx
and then modify the app manifest to use this start page instead of the
start page that was used in the original version of the app. You could
also add other, new app web elements such as JavaScript files, lists,
and document libraries. Many of the techniques used to upgrade elements
in the app web are based on the same techniques developers have been
using with feature upgrade in SharePoint solutions.
When it comes to updating a cloud-hosted app, things are different.
That’s because most of the important changes to the app’s
implementation are made to the remote web and not to anything inside
the SharePoint host environment. If you are working with a
provider-hosted app, you must roll out these changes to the remote web
before you publish the new version of the app to the Office Store or
any app catalog site.
It’s equally important that the updated version of the remote web
must continue to support customers that will continue to use the
original version of the app. Remember; there is nothing that forces the
user to accept an update. You should expect that some customers will be
happy with the original version and will be opposed to upgrading to a new version of an app.
Once you have pushed out more than one or more updates to a
provider-hosted app, you must begin to track what version each customer
is using. One technique to accomplish this task is to provide a
different start page for each version of the app. Many provider-hosted apps
will go a step further and store the current version of app in a
customer profile that is tracked in a custom database behind the remote
web.
Trapping app lifecycle events
One favorable aspect of the SharePoint app model for
developers is the ability to design a cloud-hosted app with custom
server-side code that is automatically executed when an app is
installed, upgraded, or uninstalled. By taking advantage of the ability
to add code behind these three app lifecycle events, you can program
against the host web and the app web with logic to initialize, update,
and cleanup site elements in the SharePoint environment. These app
lifecycle events also provide the necessary triggers for updating the
custom database used by provider-hosted apps and autohosted apps.
The architecture of app
events is based on registering app event handlers in the app manifest
that cause the SharePoint host environment to call out to a web service entry point in the remote web. Due to the architecture’s reliance on a server-side entry point, app
events are not supported in SharePoint-hosted apps. Therefore, you can
only use the app events in autohosted apps and provider-hosted apps.
It’s relatively simple to add support for app events to the project for an autohosted app or a provider-hosted app. The property sheet for the app project contains three properties named Handle App Installed, Handle App Uninstalling, and Handle App Upgrade, as shown in Figure 9.
The default value for each of these app event properties is false. The first time you change one of these properties to a value of true, Visual Studio 2012 adds a web service entry point into the web project with a name of AppEventReceiver.svc.
Visual Studio 2012 also adds the required configuration information
into the app manifest file, as well. If you enable all three events,
the <Properties> element within <App> element of the app manifest will be updated with the following three elements:
<InstalledEventEndpoint>~remoteAppUrl/AppEventReceiver.svc</InstalledEventEndpoint>
<UninstallingEventEndpoint>~remoteAppUrl/AppEventReceiver.svc</UninstallingEventEndpoint>
<UpgradedEventEndpoint>~remoteAppUrl/AppEventReceiver.svc</UpgradedEventEndpoint>
After you have enabled one or more of the app
events, you can then begin to write the code that will execute when the
events occur. You write this code in the code-behind file named AppEventReceiver.svc.cs.
If you examine this file, you will see that Visual Studio 2012 has
created a class shown in the following code that implements a special
interface that the SharePoint team created for remote event handling
named IRemoteEventService:
public class AppEventReceiver : IRemoteEventService {
public SPRemoteEventResult ProcessEvent(RemoteEventProperties properties) {}
public void ProcessOneWayEvent(RemoteEventProperties properties) { }
}
The IRemoteEventService interface is used with app events and also with other types of remote event handlers, as well. There are two methods named ProcessEvent and ProcessOneWayEvent. The SharePoint host environment makes a web service call which executes the ProcessEvent method when it needs to inspect the response returned from the remote web. The ProcessOneWayEvent method is called for cases in which the SharePoint host environment needs to trigger the execution of code in the remote web but doesn’t need to inspect the response. App events always trigger to the ProcessEvent method, so you can leave the ProcessOneWayEvent method empty in the AppEventReceiver.svc.cs file.
If you have registered for the AppInstalled event, the ProcessEvent method will execute whenever a user is installing the app.
It is critical to supply robust error handling because an unhandled
exception will be returned to the SharePoint host environment and cause
an error in the app installation process.
When you implement the ProcessEvent method, you must return an object created from the SPRemoteEventResult class, as demonstrated in the following:
public SPRemoteEventResult ProcessEvent(RemoteEventProperties properties) {
// return an SPRemoteEventResult object
SPRemoteEventResult result = new SPRemoteEventResult();
return result;
}
The SPRemoteEventResult
class was designed to make it possible for code in the remote web to
relay contextual information back to the SharePoint host environment.
For example, imagine that you have detected that the installer’s IP
address is located in a country that you do not want to support. You
can tell the SharePoint host environment to cancel the installation
process and pass an appropriate error message, such as shown here:
SPRemoteEventResult result = new SPRemoteEventResult();
result.Status = SPRemoteEventServiceStatus.CancelWithError;
result.ErrorMessage = "App cannot be installed due to invalid IP address";
return result;
The ProcessEvent method passes a parameter named properties, which is based on a type named RemoteEventProperties.
You can use this parameter to access important contextual information
such as the URL of host web and security access token required to call
back into the SharePoint host environment. Example 1 shows that the properties parameter also provides an EventType property with which you can determine which of the three app events has caused the ProcessEvent method to execute.
Example 1. Handling events
public SPRemoteEventResult ProcessEvent(RemoteEventProperties properties) {
// obtain context information from RemoteEventProperties property
string HostWeb = properties.AppEventProperties.HostWebFullUrl.AbsolutePath;
string AccessToken = properties.AccessToken;
// handle event type
switch (properties.EventType) {
case RemoteEventType.AppInstalled:
// add code here to handle app installation
break;
case RemoteEventType.AppUpgraded:
// add code here to handle app upgrade
break;
case RemoteEventType.AppUninstalling:
// add code here to handle app uninstallation
break;
default:
break;
}
// return an SPRemoteEventResult object
SPRemoteEventResult result = new SPRemoteEventResult();
return result;
}
Note that debugging app
event handlers can be especially tricky to set up and in many
situations it doesn’t work at all. That’s because the SharePoint host
environment must be able to call back into the remote web. For cases in
which you have installed the app into an Office 365 tenancy for
testing, it is a web server in the Office 365 environment that will be
issuing the call to the remote web. This web server hosted in the
Office 365 environment must be able to locate and access the web server
that is hosting the remote web. Therefore, attempting to debug an app
event handler for which the remote web is configured to use a host name
such as localhost or to use a host domain name that only resolves to
the proper IP address inside your testing environment will not work.