building real o365 sharepoint apps
DESCRIPTION
My presentation for #SPSNY About my experience building commercial apps for office 365 hosted SharePointTRANSCRIPT
![Page 1: Building real o365 SharePoint apps](https://reader033.vdocuments.net/reader033/viewer/2022061218/54b6d9e54a795945068b457c/html5/thumbnails/1.jpg)
How I built our first commercial SharePoint hosted app
Lessons learnt from building the KWizCom Cascading LookApp
![Page 2: Building real o365 SharePoint apps](https://reader033.vdocuments.net/reader033/viewer/2022061218/54b6d9e54a795945068b457c/html5/thumbnails/2.jpg)
KWizCom Corporation
• Founded in 2005
• Headquartered in Toronto
• Global vendor of SharePoint Add-Ons
• 5000+ customers worldwide
![Page 3: Building real o365 SharePoint apps](https://reader033.vdocuments.net/reader033/viewer/2022061218/54b6d9e54a795945068b457c/html5/thumbnails/3.jpg)
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](https://reader033.vdocuments.net/reader033/viewer/2022061218/54b6d9e54a795945068b457c/html5/thumbnails/4.jpg)
Overview
![Page 5: Building real o365 SharePoint apps](https://reader033.vdocuments.net/reader033/viewer/2022061218/54b6d9e54a795945068b457c/html5/thumbnails/5.jpg)
OVERVIEWSharePoint apps, your options
![Page 6: Building real o365 SharePoint apps](https://reader033.vdocuments.net/reader033/viewer/2022061218/54b6d9e54a795945068b457c/html5/thumbnails/6.jpg)
SharePoint app store
Provided Hosted?
SharePoint Hosted?
![Page 7: Building real o365 SharePoint apps](https://reader033.vdocuments.net/reader033/viewer/2022061218/54b6d9e54a795945068b457c/html5/thumbnails/7.jpg)
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](https://reader033.vdocuments.net/reader033/viewer/2022061218/54b6d9e54a795945068b457c/html5/thumbnails/8.jpg)
OVERVIEWApp licensing
![Page 9: Building real o365 SharePoint apps](https://reader033.vdocuments.net/reader033/viewer/2022061218/54b6d9e54a795945068b457c/html5/thumbnails/9.jpg)
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](https://reader033.vdocuments.net/reader033/viewer/2022061218/54b6d9e54a795945068b457c/html5/thumbnails/10.jpg)
OVERVIEWPublish a new version
![Page 11: Building real o365 SharePoint apps](https://reader033.vdocuments.net/reader033/viewer/2022061218/54b6d9e54a795945068b457c/html5/thumbnails/11.jpg)
![Page 12: Building real o365 SharePoint apps](https://reader033.vdocuments.net/reader033/viewer/2022061218/54b6d9e54a795945068b457c/html5/thumbnails/12.jpg)
![Page 13: Building real o365 SharePoint apps](https://reader033.vdocuments.net/reader033/viewer/2022061218/54b6d9e54a795945068b457c/html5/thumbnails/13.jpg)
OVERVIEWUpdates, upgrades
![Page 14: Building real o365 SharePoint apps](https://reader033.vdocuments.net/reader033/viewer/2022061218/54b6d9e54a795945068b457c/html5/thumbnails/14.jpg)
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](https://reader033.vdocuments.net/reader033/viewer/2022061218/54b6d9e54a795945068b457c/html5/thumbnails/15.jpg)
App web vs. Host web
![Page 16: Building real o365 SharePoint apps](https://reader033.vdocuments.net/reader033/viewer/2022061218/54b6d9e54a795945068b457c/html5/thumbnails/16.jpg)
APP WEB VS. HOST WEBApp login problem, single sign on
![Page 17: Building real o365 SharePoint apps](https://reader033.vdocuments.net/reader033/viewer/2022061218/54b6d9e54a795945068b457c/html5/thumbnails/17.jpg)
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](https://reader033.vdocuments.net/reader033/viewer/2022061218/54b6d9e54a795945068b457c/html5/thumbnails/18.jpg)
APP WEB VS. HOST WEBIE 8,9 known issue with trusted sites
![Page 19: Building real o365 SharePoint apps](https://reader033.vdocuments.net/reader033/viewer/2022061218/54b6d9e54a795945068b457c/html5/thumbnails/19.jpg)
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](https://reader033.vdocuments.net/reader033/viewer/2022061218/54b6d9e54a795945068b457c/html5/thumbnails/20.jpg)
APP WEB VS. HOST WEBProvisioning files to host web
![Page 21: Building real o365 SharePoint apps](https://reader033.vdocuments.net/reader033/viewer/2022061218/54b6d9e54a795945068b457c/html5/thumbnails/21.jpg)
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](https://reader033.vdocuments.net/reader033/viewer/2022061218/54b6d9e54a795945068b457c/html5/thumbnails/22.jpg)
APP WEB VS. HOST WEBLoading additional resources from app web
![Page 23: Building real o365 SharePoint apps](https://reader033.vdocuments.net/reader033/viewer/2022061218/54b6d9e54a795945068b457c/html5/thumbnails/23.jpg)
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](https://reader033.vdocuments.net/reader033/viewer/2022061218/54b6d9e54a795945068b457c/html5/thumbnails/24.jpg)
APP WEB VS. HOST WEBCheck for app license from host web
![Page 25: Building real o365 SharePoint apps](https://reader033.vdocuments.net/reader033/viewer/2022061218/54b6d9e54a795945068b457c/html5/thumbnails/25.jpg)
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](https://reader033.vdocuments.net/reader033/viewer/2022061218/54b6d9e54a795945068b457c/html5/thumbnails/26.jpg)
Using JSLink
![Page 27: Building real o365 SharePoint apps](https://reader033.vdocuments.net/reader033/viewer/2022061218/54b6d9e54a795945068b457c/html5/thumbnails/27.jpg)
USING JSLINKPower of client side rendering
![Page 28: Building real o365 SharePoint apps](https://reader033.vdocuments.net/reader033/viewer/2022061218/54b6d9e54a795945068b457c/html5/thumbnails/28.jpg)
Customize the way your columns and views look
Add special logic in editing your lists
![Page 29: Building real o365 SharePoint apps](https://reader033.vdocuments.net/reader033/viewer/2022061218/54b6d9e54a795945068b457c/html5/thumbnails/29.jpg)
USING JSLINKHow to register for specific field, not for type
![Page 30: Building real o365 SharePoint apps](https://reader033.vdocuments.net/reader033/viewer/2022061218/54b6d9e54a795945068b457c/html5/thumbnails/30.jpg)
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](https://reader033.vdocuments.net/reader033/viewer/2022061218/54b6d9e54a795945068b457c/html5/thumbnails/31.jpg)
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](https://reader033.vdocuments.net/reader033/viewer/2022061218/54b6d9e54a795945068b457c/html5/thumbnails/32.jpg)
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](https://reader033.vdocuments.net/reader033/viewer/2022061218/54b6d9e54a795945068b457c/html5/thumbnails/33.jpg)
USING JSLINKSupport MDS
![Page 34: Building real o365 SharePoint apps](https://reader033.vdocuments.net/reader033/viewer/2022061218/54b6d9e54a795945068b457c/html5/thumbnails/34.jpg)
Notice it always stay on the same page
![Page 35: Building real o365 SharePoint apps](https://reader033.vdocuments.net/reader033/viewer/2022061218/54b6d9e54a795945068b457c/html5/thumbnails/35.jpg)
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](https://reader033.vdocuments.net/reader033/viewer/2022061218/54b6d9e54a795945068b457c/html5/thumbnails/36.jpg)
USING JSLINKStore additional settings
![Page 37: Building real o365 SharePoint apps](https://reader033.vdocuments.net/reader033/viewer/2022061218/54b6d9e54a795945068b457c/html5/thumbnails/37.jpg)
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](https://reader033.vdocuments.net/reader033/viewer/2022061218/54b6d9e54a795945068b457c/html5/thumbnails/38.jpg)
App License
![Page 39: Building real o365 SharePoint apps](https://reader033.vdocuments.net/reader033/viewer/2022061218/54b6d9e54a795945068b457c/html5/thumbnails/39.jpg)
APP LICENSECheck for license using script
![Page 40: Building real o365 SharePoint apps](https://reader033.vdocuments.net/reader033/viewer/2022061218/54b6d9e54a795945068b457c/html5/thumbnails/40.jpg)
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](https://reader033.vdocuments.net/reader033/viewer/2022061218/54b6d9e54a795945068b457c/html5/thumbnails/41.jpg)
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](https://reader033.vdocuments.net/reader033/viewer/2022061218/54b6d9e54a795945068b457c/html5/thumbnails/42.jpg)
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](https://reader033.vdocuments.net/reader033/viewer/2022061218/54b6d9e54a795945068b457c/html5/thumbnails/43.jpg)
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](https://reader033.vdocuments.net/reader033/viewer/2022061218/54b6d9e54a795945068b457c/html5/thumbnails/44.jpg)
Prompt user on license issues, once is enough
![Page 45: Building real o365 SharePoint apps](https://reader033.vdocuments.net/reader033/viewer/2022061218/54b6d9e54a795945068b457c/html5/thumbnails/45.jpg)
APP LICENSETest licenses
![Page 46: Building real o365 SharePoint apps](https://reader033.vdocuments.net/reader033/viewer/2022061218/54b6d9e54a795945068b457c/html5/thumbnails/46.jpg)
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](https://reader033.vdocuments.net/reader033/viewer/2022061218/54b6d9e54a795945068b457c/html5/thumbnails/47.jpg)
![Page 48: Building real o365 SharePoint apps](https://reader033.vdocuments.net/reader033/viewer/2022061218/54b6d9e54a795945068b457c/html5/thumbnails/48.jpg)
![Page 49: Building real o365 SharePoint apps](https://reader033.vdocuments.net/reader033/viewer/2022061218/54b6d9e54a795945068b457c/html5/thumbnails/49.jpg)
![Page 50: Building real o365 SharePoint apps](https://reader033.vdocuments.net/reader033/viewer/2022061218/54b6d9e54a795945068b457c/html5/thumbnails/50.jpg)
Adding a ribbon button
![Page 51: Building real o365 SharePoint apps](https://reader033.vdocuments.net/reader033/viewer/2022061218/54b6d9e54a795945068b457c/html5/thumbnails/51.jpg)
ADDING A RIBBON BUTTONCheck for license using script
![Page 52: Building real o365 SharePoint apps](https://reader033.vdocuments.net/reader033/viewer/2022061218/54b6d9e54a795945068b457c/html5/thumbnails/52.jpg)
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}&SPListItemId={ItemId}&SPListId={ListId}"/>
Open as popup option<CustomAction … HostWebDialog="TRUE"HostWebDialogHeight="600" HostWebDialogWidth="1050"
Scripts are blocked
![Page 53: Building real o365 SharePoint apps](https://reader033.vdocuments.net/reader033/viewer/2022061218/54b6d9e54a795945068b457c/html5/thumbnails/53.jpg)
![Page 54: Building real o365 SharePoint apps](https://reader033.vdocuments.net/reader033/viewer/2022061218/54b6d9e54a795945068b457c/html5/thumbnails/54.jpg)
Single sign on issue cause image to be missing…
![Page 55: Building real o365 SharePoint apps](https://reader033.vdocuments.net/reader033/viewer/2022061218/54b6d9e54a795945068b457c/html5/thumbnails/55.jpg)
Will start working once the user had the iframe log him
into the app web.
![Page 56: Building real o365 SharePoint apps](https://reader033.vdocuments.net/reader033/viewer/2022061218/54b6d9e54a795945068b457c/html5/thumbnails/56.jpg)
Protecting your code
![Page 57: Building real o365 SharePoint apps](https://reader033.vdocuments.net/reader033/viewer/2022061218/54b6d9e54a795945068b457c/html5/thumbnails/57.jpg)
PROTECTING YOUR CODEProtect JS code
![Page 58: Building real o365 SharePoint apps](https://reader033.vdocuments.net/reader033/viewer/2022061218/54b6d9e54a795945068b457c/html5/thumbnails/58.jpg)
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 59: Building real o365 SharePoint apps](https://reader033.vdocuments.net/reader033/viewer/2022061218/54b6d9e54a795945068b457c/html5/thumbnails/59.jpg)
Protect JS code
http://javascriptobfuscator.com/default.aspx
![Page 60: Building real o365 SharePoint apps](https://reader033.vdocuments.net/reader033/viewer/2022061218/54b6d9e54a795945068b457c/html5/thumbnails/60.jpg)
PROTECTING YOUR CODEDebug
![Page 61: Building real o365 SharePoint apps](https://reader033.vdocuments.net/reader033/viewer/2022061218/54b6d9e54a795945068b457c/html5/thumbnails/61.jpg)
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](https://reader033.vdocuments.net/reader033/viewer/2022061218/54b6d9e54a795945068b457c/html5/thumbnails/62.jpg)
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](https://reader033.vdocuments.net/reader033/viewer/2022061218/54b6d9e54a795945068b457c/html5/thumbnails/63.jpg)
On prem vs. o365
![Page 64: Building real o365 SharePoint apps](https://reader033.vdocuments.net/reader033/viewer/2022061218/54b6d9e54a795945068b457c/html5/thumbnails/64.jpg)
ON PREM VS. O365API is different
![Page 65: Building real o365 SharePoint apps](https://reader033.vdocuments.net/reader033/viewer/2022061218/54b6d9e54a795945068b457c/html5/thumbnails/65.jpg)
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](https://reader033.vdocuments.net/reader033/viewer/2022061218/54b6d9e54a795945068b457c/html5/thumbnails/66.jpg)
ON PREM VS. O365Updates
![Page 67: Building real o365 SharePoint apps](https://reader033.vdocuments.net/reader033/viewer/2022061218/54b6d9e54a795945068b457c/html5/thumbnails/67.jpg)
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](https://reader033.vdocuments.net/reader033/viewer/2022061218/54b6d9e54a795945068b457c/html5/thumbnails/68.jpg)
ON PREM VS. O365Maintenance
![Page 69: Building real o365 SharePoint apps](https://reader033.vdocuments.net/reader033/viewer/2022061218/54b6d9e54a795945068b457c/html5/thumbnails/69.jpg)
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](https://reader033.vdocuments.net/reader033/viewer/2022061218/54b6d9e54a795945068b457c/html5/thumbnails/70.jpg)
QUESTION?
![Page 71: Building real o365 SharePoint apps](https://reader033.vdocuments.net/reader033/viewer/2022061218/54b6d9e54a795945068b457c/html5/thumbnails/71.jpg)
Shai Petel
Director of Research and Development at KWizCom
MCPD, MVP: SharePoint
[email protected] | @shaibs | http://kwizcom.blogspot.com