71
How I built our first commercial SharePoint hosted app Lessons learnt from building the KWizCom Cascading LookApp

Building real o365 SharePoint apps

Embed Size (px)

DESCRIPTION

My presentation for #SPSNY About my experience building commercial apps for office 365 hosted SharePoint

Citation preview

Page 1: Building real o365 SharePoint apps

How I built our first commercial SharePoint hosted app

Lessons learnt from building the KWizCom Cascading LookApp

Page 2: Building real o365 SharePoint apps

KWizCom Corporation

• Founded in 2005

• Headquartered in Toronto

• Global vendor of SharePoint Add-Ons

• 5000+ customers worldwide

Page 3: Building real o365 SharePoint apps

Shai Petel

Director of Research and Development at KWizCom

MCPD, MVP: SharePoint

[email protected] | @shaibs | http://kwizcom.blogspot.com

Page 4: Building real o365 SharePoint apps

Overview

Page 5: Building real o365 SharePoint apps

OVERVIEWSharePoint apps, your options

Page 6: Building real o365 SharePoint apps

SharePoint app store

Provided Hosted?

SharePoint Hosted?

Page 7: Building real o365 SharePoint apps

Use JSLink to customize columns and list views

Build app parts to display information whoever you wish, from any data source you want.

Page 8: Building real o365 SharePoint apps

OVERVIEWApp licensing

Page 9: Building real o365 SharePoint apps

Use Microsoft Store licensing

Per seat, unlimited threshold

Subscription or Purchase*

Auto generate trial liense

Or, build your own licensing service.

Page 10: Building real o365 SharePoint apps

OVERVIEWPublish a new version

Page 11: Building real o365 SharePoint apps
Page 12: Building real o365 SharePoint apps
Page 13: Building real o365 SharePoint apps

OVERVIEWUpdates, upgrades

Page 14: Building real o365 SharePoint apps

Go to site contents

Updates will show up here, next to the app. Click the link

to update your app.

Page 15: Building real o365 SharePoint apps

App web vs. Host web

Page 16: Building real o365 SharePoint apps

APP WEB VS. HOST WEBApp login problem, single sign on

Page 17: Building real o365 SharePoint apps

App login problem, single sign on

App web on different url, requires separate login

Single sign on in place for most cases

Single sign on will not work for resource files (css, js, images, etc…) but only in iframes

Page 18: Building real o365 SharePoint apps

APP WEB VS. HOST WEBIE 8,9 known issue with trusted sites

Page 19: Building real o365 SharePoint apps

IE 8,9 known issue with trusted sites

Known issue on IE 8, 9

Requires adding both domains to trusted sites

Read more: KWizCom KB http://support.kwizcom.com/KnowledgebaseArticle50208.aspx

Page 20: Building real o365 SharePoint apps

APP WEB VS. HOST WEBProvisioning files to host web

Page 21: Building real o365 SharePoint apps

Provisioning files to host web

Find site assets library, create a sub folder for your app and upload the files there

Cannot read files, only upload

Minimize your foot print as files are not cleaned up on uninstall

Page 22: Building real o365 SharePoint apps

APP WEB VS. HOST WEBLoading additional resources from app web

Page 23: Building real o365 SharePoint apps

Loading additional resources from app web

After single sign on issue resolved

In effort to minimize footprint, only provision the file that will handle the single sign on issue

Can use host web URL, will redirect to app web URL automatically

Page 24: Building real o365 SharePoint apps

APP WEB VS. HOST WEBCheck for app license from host web

Page 25: Building real o365 SharePoint apps

Check for app license from host web

Only for SharePoint hosted apps

Only within the app site itself

From host web, must use an iframe (licensechecker.aspx)

Page 26: Building real o365 SharePoint apps

Using JSLink

Page 27: Building real o365 SharePoint apps

USING JSLINKPower of client side rendering

Page 28: Building real o365 SharePoint apps

Customize the way your columns and views look

Add special logic in editing your lists

Page 29: Building real o365 SharePoint apps

USING JSLINKHow to register for specific field, not for type

Page 30: Building real o365 SharePoint apps

How to register for specific field, not for type(function () { var ageFiledContext = {}; ageFiledContext.Templates = {}; ageFiledContext.Templates.Fields = { "Age": { "NewForm": ageFiledTemplate, "EditForm": ageFiledTemplate } }; SPClientTemplates.TemplateManager.RegisterTemplateOverrides(ageFiledContext);})();function ageFiledTemplate(ctx) { var formCtx = SPClientTemplates.Utility.GetFormContextForCurrentField(ctx); formCtx.registerGetValueCallback(formCtx.fieldName, function () { return document.getElementById('inpAge').value; }); return "<input type='number' id='inpAge' min='18' max='110' value='" + formCtx.fieldValue + "'/>"; }

Register to field name “Age”, or field

type “choice”

Page 31: Building real o365 SharePoint apps

How to register for specific field, not for type Pass field name in query stringfield.set_jsLink("mycsr.js?FieldName=Status");field.update();

Catch it in the JS file, use it to register your templatevar scripts = document.getElementsByTagName('script');for (var i = 0; i < scripts.length; i++) { if (scripts[i].src.toLowerCase().indexOf("mycsr.js") >= 0) { var currentField = KWizComUtilities.GetQueryStringParameterByName("FieldName", scripts[i].src);… currentFieldRendering.Templates = {}; currentFieldRendering.Templates.Fields = {}; currentFieldRendering.Templates.Fields[currentField] = {}; currentFieldRendering.Templates.Fields[currentField].EditForm = myTemplate; currentFieldRendering.Templates.Fields[currentField].NewForm = myTemplate; SPClientTemplates.TemplateManager. RegisterTemplateOverrides(currentFieldRendering);}

Page 32: Building real o365 SharePoint apps

How to register for specific field, not for type

TIP: Query strings are very important. You need SharePoint to tell your external website important information about where in SharePoint it is coming from.

Page 33: Building real o365 SharePoint apps

USING JSLINKSupport MDS

Page 34: Building real o365 SharePoint apps

Notice it always stay on the same page

Page 35: Building real o365 SharePoint apps

Support MDS

On MDS enabled sites, most online samples will not work after few page navigations

When you revisit a page, document.ready event does not fire

Instead, you must register your init code here:RegisterModuleInit(jsfileName, initHandler);

Page 36: Building real o365 SharePoint apps

USING JSLINKStore additional settings

Page 37: Building real o365 SharePoint apps

Store additional settings Additional column settings can be stored in field schema or query string In schema, under<Customization> <ArrayOfProperty> <Property> <Name>x</Name> <Value>Y</Value> </Property> </ArrayOfProperty></Customization> Schema changes might break OneDrive support in document library For simple settings, you can use JSLink query string

Page 38: Building real o365 SharePoint apps

App License

Page 39: Building real o365 SharePoint apps

APP LICENSECheck for license using script

Page 40: Building real o365 SharePoint apps

Check for license using script

Check for license using script Requires adding remote endpoint to

https://verificationservice.officeapps.live.com Request must come from the app web Get a collection of licenses, sometimes expired

licenses as well

Page 41: Building real o365 SharePoint apps

licenseCollection = SP.Utilities.Utility .getAppLicenseInformation(context, '{cd8d046c-91d4-401f-825d-494e6c2776c5}'); context.executeQueryAsync(onRetSuccess, onRetFail);

On Success:if (licenseCollection.get_count() > 0) { license = licenseCollection.get_item(0) .get_rawXMLLicenseToken(); processRawXmlLicense(license);}

Page 42: Building real o365 SharePoint apps

Process license:

var request = new SP.WebRequestInfo();request.set_url("https://verificationservice.officeapps.live.com/ova/verificationagent.svc/rest/verify?token=" + encodedTopLicense);

request.set_method("GET");response = SP.WebProxy.invoke(context, request);

context.executeQueryAsync(onVerifySuccess, onVerifyFail);

Page 43: Building real o365 SharePoint apps

On Success:

var verificationResponse = response.get_body();var xmlDoc = $.parseXML(verificationResponse);var $xml = $(xmlDoc);var licenseType = $xml.find("EntitlementType").text();var licenseIsValid = $xml.find("IsValid").text().toLowerCase() == "true";var licenseIsTest = $xml.find("IsTest").text().toLowerCase() == "true";var isExpired = $xml.find("IsEntitlementExpired") .text().toLowerCase() == "true";

Page 44: Building real o365 SharePoint apps

Prompt user on license issues, once is enough

Page 45: Building real o365 SharePoint apps

APP LICENSETest licenses

Page 46: Building real o365 SharePoint apps

Test licenses

Create / Manage using code or tool: http://code.msdn.microsoft.com/office/SharePoint-2013-Import-f5f680a6/view/SourceCode#content

Don’t forget to check if a license is a test license

Block test licenses on production build, or show a message

SharePoint 2013 Import, validate, and manage app licenses.zip

Page 47: Building real o365 SharePoint apps
Page 48: Building real o365 SharePoint apps
Page 49: Building real o365 SharePoint apps
Page 50: Building real o365 SharePoint apps

Adding a ribbon button

Page 51: Building real o365 SharePoint apps

ADDING A RIBBON BUTTONCheck for license using script

Page 52: Building real o365 SharePoint apps

Adding a ribbon button Limited use of CustomAction element allows to add ribbon buttons

CommandAction can only open a page or a popup<CommandUIHandler Command="cmd1"CommandAction="~appWebUrl/Pages/ListDialog.aspx?{StandardTokens}&amp;SPListItemId={ItemId}&amp;SPListId={ListId}"/>

Open as popup option<CustomAction … HostWebDialog="TRUE"HostWebDialogHeight="600" HostWebDialogWidth="1050"

Scripts are blocked

Page 53: Building real o365 SharePoint apps
Page 54: Building real o365 SharePoint apps

Single sign on issue cause image to be missing…

Page 55: Building real o365 SharePoint apps

Will start working once the user had the iframe log him

into the app web.

Page 56: Building real o365 SharePoint apps

Protecting your code

Page 57: Building real o365 SharePoint apps

PROTECTING YOUR CODEProtect JS code

Page 58: Building real o365 SharePoint apps

Protect JS code

Have app.debug.js with your source

Upon publish, obfuscate it and save in app.js

Consider not publishing debug.js with your app to protect your full source

Page 60: Building real o365 SharePoint apps

PROTECTING YOUR CODEDebug

Page 61: Building real o365 SharePoint apps

Debug client code, or on your server. Nothing to debug on SharePoint since your app does not run on SharePoint.

Page 62: Building real o365 SharePoint apps

Debug

Use fiddler, IE developer tools

On your customer’s site you will still get the obfuscated script.– For files in the app site, live with it!– For provisioned files, upload the source file for easier

debug

Page 63: Building real o365 SharePoint apps

On prem vs. o365

Page 64: Building real o365 SharePoint apps

ON PREM VS. O365API is different

Page 65: Building real o365 SharePoint apps

API is different

Client side API is different and more hardened usually in O365

Basic changes in functionality, some APIs are blocked while other behave different

Example: field.update will cancel field.set_schemaxml on o365 only

Page 66: Building real o365 SharePoint apps

ON PREM VS. O365Updates

Page 67: Building real o365 SharePoint apps

Updates

On O365, updates are regularly pushed and installed throughout the farm.

Not all tenants are upgraded at the same time! Your dev/test might be older or newer than some tenants.

Page 68: Building real o365 SharePoint apps

ON PREM VS. O365Maintenance

Page 69: Building real o365 SharePoint apps

Maintenance

App break. You need to keep an eye out.

Updates sometime will break your app. (App / user throttling)

Support and publishing updates is key to success.

Page 70: Building real o365 SharePoint apps

QUESTION?

Page 71: Building real o365 SharePoint apps

Shai Petel

Director of Research and Development at KWizCom

MCPD, MVP: SharePoint

[email protected] | @shaibs | http://kwizcom.blogspot.com