There is no way to understand the capabilities of apps

Web apps don't love each other



Web-apps are from Venus.

Web-apps are from Mars.

It starts with an image

How do I bring the image into my app?

  • Download image from other app or site
  • Move to app
  • Click button
  • Scan hard drive for file
  • Hit head on table
  • Find file, click "ok"

How do I edit the image in my app?

How do I save the image to my cloud store?



  • Direct API integration
  • Server 2 Server
  • Oauth

How do I send an image to my grandmother?

  • Your app won't know the recipient



  • Download from an app
  • Open up a new mail
  • Click attach
  • Scan hard drive for file
  • Hit head on table
  • Find file, click "ok"

How do I share an image to the world?

Over 300 Sharing services

Widget:

  • Slows your site down
  • Introduces a tight coupling

Server 2 server:

  • Complex auth dance
  • Requires a connection

It's not easy

What if we can do better?



What would a solution look like?

Client-side first

Client-side first

Enable Offline

Loosely Coupled

Familiar

Introducing Web Intents

What is a "web in tent"?

Stuart Heath: http://www.flickr.com/photos/misteraitch/4959098093/

What are Web Intents?

A client-side framework that allows users to use their preferred applications for actions on content-types.
— Paul Kinlan, just now

How it works

How to build a Service



Handling the users intent

Services handle user intent

Two simple steps

  1. Tell the web what you can do
    • Pick Image
    • Edit Document
    • Share Link
  2. Handle incoming data

1. Tell the web what you can do

The declaration

{
  "name": "An app", "version": "1",
  "intents": {
    "http://webintents.org/save": [{
      "type":["image/*"],
      "href":"save.html",
      "disposition": "inline"
    }]
  }
} 
<intent
  action="http://webintents.org/save"
  type="image/*"
  href="save.html"
  disposition="inline" />

1. Tell the web what you can do

Action

{
  "name": "An app", "version": "1",
  "intents": {
    "http://webintents.org/save": [{
      "type":["image/*"],
      "href":"save.html",
      "disposition": "inline"
    }]
  }
} 
<intent
  action="http://webintents.org/save"
  type="image/*"
  href="save.html"
  disposition="inline" />

Why are you using a URL for the action?

1. Tell the web what you can do

What data you can handle

{
  "name": "An app", "version": "1",
  "intents": {
    "http://webintents.org/save": [{
      "type":["image/*"],
      "href":"/save.html",
      "disposition": "inline"
    }]
  }
} 
<intent
  action="http://webintents.org/save"
  type="image/*"
  href="save.html"
  disposition="inline" />

1. Tell the web what you can do

What to open

{
  "name": "An app", "version": "1",
  "intents": {
    "http://webintents.org/save": [{
      "type":["image/*"],
      "href":"/save.html",
      "disposition": "inline"
    }]
  }
} 
<intent
  action="http://webintents.org/save"
  type="image/*"
  href="save.html"
  disposition="inline" />

1. Tell the web what you can do

How to open it

{
  "name": "An app", "version": "1",
  "intents": {
    "http://webintents.org/save": [{
      "type":["image/*"],
      "href":"/save.html",
      "disposition": "inline"
    }]
  }
}
<intent
  action="http://webintents.org/save"
  type="image/*"
  href="save.html"
  disposition="inline" />

2. Get ready to receive data

if(window.webkitIntent) {
  var i = window.webkitIntent;
  if(i.action == "http://webintents.org/save") {
    if(i.type == "image/png") {
      img.src = i.data; // the data
    }
  }
} 

How to Build a Client

Ask for a service

var i = new WebKitIntent({
  "action": "http://webintents.org/share",
  "type": "text/uri-list",
  "data": "http://paul.kinlan.me" });

window.navigator.webkitStartActivity(i); 

That's all there is

Seriously.

Simplex communication isn't cool.


You know what's cool?

Duplex communication!

Client

var param = { 
  "action": "http://webintents.org/edit", 
  "type": "image/png" , "data":blob };
var i = new WebKitIntent(param);
var onSuccess = function(data) { ... };
var onFailure = function() { ... };

navigator.webkitStartActivity(i, onSuccess, onFailure);

Service

if(window.webkitIntent) {
  // read data in 
  var data = window.webkitIntent.data;
  // do magic on data, add text etc. 
  window.webkitIntent.postResult(newImage);
}

Apps that love each other



The how

Pick

The File > Open of the web

var i = new WebKitIntent({
  "action": "http://webintents.org/pick",
  "type": "image/*" });

var imgData;

var onSuccess = function(data) {
  imgData = data; // Cache it for use in app
  img.src = data;
};

window.navigator.webkitStartActivity(i, onSuccess);

Edit

Do what you do best

var i = new WebKitIntent({
  "action": "http://webintents.org/edit",
  "type": "image/*",
  "data": imgData });

var onSuccess = function(data) {
  imgData = data;
  img.src = data;
};

window.navigator.webkitStartActivity(i, onSuccess);

Save

The File > Save of the web

var i = new WebKitIntent({
  "action": "http://webintents.org/save",
  "type": "image/png",
  "data": imgData });

var onSuccess = function(data) {
  imgData = data;
  img.src = data;
};

window.navigator.webkitStartActivity(i, onSuccess);

Share

No more Nascar UI's

var i = new WebKitIntent({
  "action": "http://webintents.org/share",
  "type": "image/*",
  "data": imgData });

window.navigator.webkitStartActivity(i);

View

"Open with" of the web

<a href="http://blog.chromium.org/feeds/posts/default">An RSS/ATOM Feed</a>
An RSS/ATOM Feed

Other examples

Subscribe

var p = {
  "action": "http://webintents.org/subscribe", 
  "type": "text/uri-list", "data": "http://paul.kinlan.me"
};
var i = new WebKitIntent(p);

Shorten

var i = new WebKitIntent({
  "action": "http://webintents.org/shorten", 
  "type":"text/uri-list", 
  "data":location.href});

Lets dig a little deeper



[Imagine a Matrix or Inception joke here]

Handling Large data the wrong way

Structured Clone

var i = new WebKitIntent({
  "action": "http://webintents.org/save",
  "type": "image/png",
  "data": blob
 });

window.navigator.webkitStartActivity(i); 
  • Client + Service have copies of the data

Handling Large data the correct way

Transferable Objects

var i = new WebKitIntent({
  "action": "http://webintents.org/save",
  "type": "image/png",
  "data": blob,
  "transfer": [blob] });

window.navigator.webkitStartActivity(i); 
  • Zero memory copy
  • FAST!

Explicit intents

var i = new WebKitIntent({
  "action": "http://webintents.org/save",
  "type": "text/uri-list",
  "service": "http://example.com/save",
  "data": location.href });

window.navigator.webkitStartActivity(i);
  • Targeted

Service Suggestions

var i = new WebKitIntent({
  "action": "http://webintents.org/share",
  "type": "text/uri-list",
  "suggestions": ["http://example.com/share", "http://anotherexample.com/share"],
  "data": location.href });

window.navigator.webkitStartActivity(i); 
  • Avoids finger printing

Closing thoughts

Web intents is designed to:

  • Give users choice
  • Make it super easy for developers


Do for apps what links did for the web.
— Greg Billock

More Information

Links

CodeLab

28th June 2012 - Codelab 1 - 13:45 - 15:45

We will help you integrate Web Intents in to your app:

Created by:

  • Greg Billock
  • Rachel Blum

Technical Assistants

  • James Hawkins
  • Renato Dias
  • Eiji Kitamura
  • Mandy Waite
  • Paul Kinlan

Thank You!


Go forth and Intentify!



We would love your feedback

+Web Intents

+Paul Kinlan

+James Hawkins