The new Webkit is AWESOME Cesare Rocchi @_funkyboy TOC History - - PowerPoint PPT Presentation

the new webkit is awesome
SMART_READER_LITE
LIVE PREVIEW

The new Webkit is AWESOME Cesare Rocchi @_funkyboy TOC History - - PowerPoint PPT Presentation

The new Webkit is AWESOME Cesare Rocchi @_funkyboy TOC History Whats new Demo Who am I? UX designer and developer studiomagnolia.com baasbox.com upbeat.it @_funkyboy Who are you? History The full Safari engine is


slide-1
SLIDE 1

The new Webkit is AWESOME

Cesare Rocchi @_funkyboy

slide-2
SLIDE 2

TOC

  • History
  • What’s new
  • Demo
slide-3
SLIDE 3

Who am I?

slide-4
SLIDE 4

UX designer and developer

slide-5
SLIDE 5

studiomagnolia.com

slide-6
SLIDE 6

baasbox.com

slide-7
SLIDE 7

upbeat.it

slide-8
SLIDE 8

@_funkyboy

slide-9
SLIDE 9

Who are you?

slide-10
SLIDE 10

History

slide-11
SLIDE 11

The full Safari engine is inside of

  • iPhone. And so, you can write

amazing Web 2.0 and Ajax apps that look exactly and behave exactly like apps on the iPhone.

SJ, 2007

“ ”

slide-12
SLIDE 12

History

  • No plugins
  • Flash
  • Applets
slide-13
SLIDE 13
slide-14
SLIDE 14

Adobe, don’t you even think about it!

slide-15
SLIDE 15
slide-16
SLIDE 16
slide-17
SLIDE 17

History

  • Nitro was introduced in iOS 4.3
  • Uses JIT
  • Transform JS into native code Needs to

mark memory w+x

  • Security issues
slide-18
SLIDE 18
slide-19
SLIDE 19

var temp = {}; temp[10123] = "yow";

slide-20
SLIDE 20

Progress

slide-21
SLIDE 21

iOS 3.2 -> iOS4

https://developer.apple.com/LIBRARY/ios/releasenotes/General/iPhone40APIDifgs/index.html

Added UIWebView.allowsInlineMediaPlayback Added UIWebView.mediaPlaybackRequiresUserAction

slide-22
SLIDE 22

iOS 4.3 -> iOS5

https://developer.apple.com/LIBRARY/ios/releasenotes/General/iOS50APIDifg/index.html

Added UIWebView.mediaPlaybackAllowsAirPlay Added UIWebView.scrollView

slide-23
SLIDE 23

iOS 5.1 -> iOS6

https://developer.apple.com/LIBRARY/ios/releasenotes/General/iOS60APIDifgs/index.html

Added UIWebView.keyboardDisplayRequiresUserAction Added UIWebView.suppressesIncrementalRendering

slide-24
SLIDE 24

iOS 6.1 -> iOS7

https://developer.apple.com/library/IOS/releasenotes/General/iOS70APIDifgs/index.html Added UIWebView.gapBetweenPages Added UIWebView.pageCount Added UIWebView.pageLength Added UIWebView.paginationBreakingMode Added UIWebView.paginationMode Added UIWebPaginationBreakingMode Added UIWebPaginationBreakingModeColumn Added UIWebPaginationBreakingModePage Added UIWebPaginationMode Added UIWebPaginationModeBottomToTop Added UIWebPaginationModeLeftToRight Added UIWebPaginationModeRightToLeft Added UIWebPaginationModeTopToBottom Added UIWebPaginationModeUnpaginated

slide-25
SLIDE 25

iOS 6.1 -> iOS7

https://developer.apple.com/library/IOS/releasenotes/General/iOS70APIDifgs/index.html

Added #def JSC_OBJC_API_ENABLED Added JSCheckScriptSyntax() Added JSClassRef Added JSContextGroupRef Added JSContextRef Added JSEvaluateScript() Added JSGarbageCollect() Added JSGlobalContextRef Added JSObjectRef Added JSPropertyNameAccumulatorRef Added JSPropertyNameArrayRef Added JSStringRef Added JSValueRef Added #def WTF_EXPORT_PRIVATE Added #def WTF_PLATFORM_IOS Added JSContext Added -[JSContext JSGlobalContextRef] Added +[JSContext contextWithJSGlobalContextRef:] Added +[JSContext currentArguments] Added +[JSContext currentContext] Added +[JSContext currentThis] Added -[JSContext evaluateScript:] Added JSContext.exception Added JSContext.exceptionHandler Added -[JSContext globalObject] Added -[JSContext init] Added -[JSContext initWithVirtualMachine:] Added -[JSContext objectForKeyedSubscript:] Added -[JSContext setObject:forKeyedSubscript:] Added JSContext.virtualMachine Added JSContext(JSContextRefSupport) Added JSContext(SubscriptSupport) Added #def JSContext_h Added JSContextGetGlobalObject() Added JSContextGetGroup() Added JSContextGroupCreate() Added JSContextGroupRelease() Added JSContextGroupRetain() Added JSGlobalContextCreate() Added JSGlobalContextCreateInGroup() Added JSGlobalContextRelease() Added JSGlobalContextRetain() Added JSExport Added #def JSExportAs Added JSManagedValue Added -[JSManagedValue initWithValue:] Added +[JSManagedValue managedValueWithValue:] Added -[JSManagedValue value] Added #def JSManagedValue_h Added JSClassAttributes Added JSClassCreate() Added JSClassDefinition Added JSClassRelease() Added JSClassRetain() Added JSObjectCallAsConstructor() Added JSObjectCallAsConstructorCallback Added JSObjectCallAsFunction() Added JSObjectCallAsFunctionCallback Added JSObjectConvertToTypeCallback Added JSObjectCopyPropertyNames() Added JSObjectDeleteProperty() Added JSObjectDeletePropertyCallback Added JSObjectFinalizeCallback Added JSObjectGetPrivate() Added JSObjectGetProperty() Added JSObjectGetPropertyAtIndex() Added JSObjectGetPropertyCallback Added JSObjectGetPropertyNamesCallback Added JSObjectGetPrototype() Added JSObjectHasInstanceCallback Added JSObjectHasProperty() Added JSObjectHasPropertyCallback Added JSObjectInitializeCallback Added JSObjectIsConstructor() Added JSObjectIsFunction() Added JSObjectMake() Added JSObjectMakeArray() Added JSObjectMakeConstructor() Added JSObjectMakeDate() Added JSObjectMakeError() Added JSObjectMakeFunction() Added JSObjectMakeFunctionWithCallback() Added JSObjectMakeRegExp() Added JSObjectSetPrivate() Added JSObjectSetProperty() Added JSObjectSetPropertyAtIndex() Added JSObjectSetPropertyCallback Added JSObjectSetPrototype() Added JSPropertyAttributes Added JSPropertyNameAccumulatorAddName() Added JSPropertyNameArrayGetCount() Added JSPropertyNameArrayGetNameAtIndex() Added JSPropertyNameArrayRelease() Added JSPropertyNameArrayRetain() Added JSStaticFunction Added JSStaticValue Added kJSClassAttributeNoAutomaticPrototype Added kJSClassAttributeNone Added kJSClassDefinitionEmpty Added kJSPropertyAttributeDontDelete Added kJSPropertyAttributeDontEnum Added kJSPropertyAttributeNone Added kJSPropertyAttributeReadOnly Added JSChar Added JSStringCreateWithCharacters() Added JSStringCreateWithUTF8CString() Added JSStringGetCharactersPtr() Added JSStringGetLength() Added JSStringGetMaximumUTF8CStringSize() Added JSStringGetUTF8CString() Added JSStringIsEqual() Added JSStringIsEqualToUTF8CString() Added JSStringRelease() Added JSStringRetain() Added JSStringCopyCFString() Added JSStringCreateWithCFString() Added JSValue Added -[JSValue JSValueRef] Added -[JSValue callWithArguments:] Added -[JSValue constructWithArguments:] Added JSValue.context Added -[JSValue defineProperty:descriptor:] Added -[JSValue deleteProperty:] Added -[JSValue hasProperty:] Added -[JSValue invokeMethod:withArguments:] Added -[JSValue isBoolean] Added -[JSValue isEqualToObject:] Added -[JSValue isEqualWithTypeCoercionToObject:] Added -[JSValue isInstanceOf:] Added -[JSValue isNull] Added -[JSValue isNumber] Added -[JSValue isObject] Added -[JSValue isString] Added -[JSValue isUndefined] Added -[JSValue objectAtIndexedSubscript:] Added -[JSValue objectForKeyedSubscript:] Added -[JSValue setObject:atIndexedSubscript:] Added -[JSValue setObject:forKeyedSubscript:] Added -[JSValue setValue:atIndex:] Added -[JSValue setValue:forProperty:] Added -[JSValue toArray] Added -[JSValue toBool] Added -[JSValue toDate] Added -[JSValue toDictionary] Added -[JSValue toDouble] Added -[JSValue toInt32] Added -[JSValue toNumber] Added -[JSValue toObject] Added -[JSValue toObjectOfClass:] Added -[JSValue toPoint] Added -[JSValue toRange] Added -[JSValue toRect] Added -[JSValue toSize] Added -[JSValue toString] Added -[JSValue toUInt32] Added -[JSValue valueAtIndex:] Added -[JSValue valueForProperty:] Added +[JSValue valueWithBool:inContext:] Added +[JSValue valueWithDouble:inContext:] Added +[JSValue valueWithInt32:inContext:] Added +[JSValue valueWithJSValueRef:inContext:] Added +[JSValue valueWithNewArrayInContext:] Added +[JSValue valueWithNewErrorFromMessage:inContext:] Added +[JSValue valueWithNewObjectInContext:] Added +[JSValue valueWithNewRegularExpressionFromPattern:flags:inContext:] Added +[JSValue valueWithNullInContext:] Added +[JSValue valueWithObject:inContext:] Added +[JSValue valueWithPoint:inContext:] Added +[JSValue valueWithRange:inContext:] Added +[JSValue valueWithRect:inContext:] Added +[JSValue valueWithSize:inContext:] Added +[JSValue valueWithUInt32:inContext:] Added +[JSValue valueWithUndefinedInContext:] Added JSPropertyDescriptorConfigurableKey Added JSPropertyDescriptorEnumerableKey Added JSPropertyDescriptorGetKey Added JSPropertyDescriptorSetKey Added JSPropertyDescriptorValueKey Added JSPropertyDescriptorWritableKey Added JSValue(JSValueRefSupport) Added JSValue(StructSupport) Added JSValue(SubscriptSupport) Added #def JSValue_h Added JSType Added JSValueCreateJSONString() Added JSValueGetType() Added JSValueIsBoolean() Added JSValueIsEqual() Added JSValueIsInstanceOfConstructor() Added JSValueIsNull() Added JSValueIsNumber() Added JSValueIsObject() Added JSValueIsObjectOfClass() Added JSValueIsStrictEqual() Added JSValueIsString() Added JSValueIsUndefined() Added JSValueMakeBoolean() Added JSValueMakeFromJSONString() Added JSValueMakeNull() Added JSValueMakeNumber() Added JSValueMakeString() Added JSValueMakeUndefined() Added JSValueProtect() Added JSValueToBoolean() Added JSValueToNumber() Added JSValueToObject() Added JSValueToStringCopy() Added JSValueUnprotect() Added kJSTypeBoolean Added kJSTypeNull Added kJSTypeNumber Added kJSTypeObject Added kJSTypeString Added kJSTypeUndefined Added JSVirtualMachine Added -[JSVirtualMachine addManagedReference:withOwner:] Added -[JSVirtualMachine init] Added -[JSVirtualMachine removeManagedReference:withOwner:] Added #def AVAILABLE_AFTER_WEBKIT_VERSION_5_1 Added #def AVAILABLE_WEBKIT_VERSION_1_3_AND_LATER_BUT_DEPRECATED_AFTER_WEBKIT_VERSION_5_1 Added #def WEBKIT_OBJC_METHOD_ANNOTATION Added #def WEBKIT_VERSION_1_0 Added #def WEBKIT_VERSION_1_1 Added #def WEBKIT_VERSION_1_2 Added #def WEBKIT_VERSION_1_3 Added #def WEBKIT_VERSION_2_0 Added #def WEBKIT_VERSION_3_0 Added #def WEBKIT_VERSION_3_1 Added #def WEBKIT_VERSION_4_0 Added #def WEBKIT_VERSION_LATEST Added #def WEBKIT_VERSION_MAX_ALLOWED Added #def WEBKIT_VERSION_MIN_REQUIRED

232 APIs

}

slide-26
SLIDE 26
slide-27
SLIDE 27

iOS7 -> iOS8

https://developer.apple.com/library/prerelease/ios/releasenotes/General/iOS80APIDifgs/frameworks/WebKit.html
slide-28
SLIDE 28

1 Class 1 Protocol

slide-29
SLIDE 29

UIWebView UIWebViewDelegate

slide-30
SLIDE 30

14 Classes 3 Protocols

slide-31
SLIDE 31

WKWebView WKFrameInfo WKBackForwardList WKBackForwardListItem WKNavigation WKNavigationAction WKNavigationResponse WKPreferences WKProcessPool WKUserContentController WKWebViewConfiguration WKWindowFeatures WKScriptMessage WKUserScript

  • WKNavigationDelegate

WKScriptMessageHandler WKUIDelegate

slide-32
SLIDE 32

XPC

  • Greatly improved in iOS8
  • Third party keyboards
  • Sharing extensions
slide-33
SLIDE 33

XPC

find /Applications -name \*.xpc | grep Web | wc -l

slide-34
SLIDE 34

XPC

  • Split app in multiple processes
  • E.g. Sourcekit
  • http://www.jpsim.com/uncovering-sourcekit/
slide-35
SLIDE 35

r167958

slide-36
SLIDE 36
slide-37
SLIDE 37

Optimizing JS

slide-38
SLIDE 38

Fun with JS

slide-39
SLIDE 39

jsc

sudo ln -s /System/Library/Frameworks/ JavaScriptCore.framework/Versions/Current/Resources/jsc /bin/jsc

slide-40
SLIDE 40
slide-41
SLIDE 41

JS bytecode

LLInt JIT DFG

  • ptimization
slide-42
SLIDE 42

function sum(a, b) { return a + b;

  • }
slide-43
SLIDE 43

LLInt JIT DFG

  • ptimization

function sum(a, b) { return a + b; }

slide-44
SLIDE 44

LLInt JIT DFG

slide-45
SLIDE 45

LLVM

slide-46
SLIDE 46

LLVM

  • Infrastructure
  • Meant to optimize *time
  • Started by Mr. Swift
slide-47
SLIDE 47

LLInt JIT DFG

slide-48
SLIDE 48

LLInt JIT DFG FTL

slide-49
SLIDE 49

What’s new

slide-50
SLIDE 50

Observable values

slide-51
SLIDE 51

Observable values

  • loading
  • title
  • URL
  • estimatedProgress
slide-52
SLIDE 52

Observable values

webView.addObserver(self, forKeyPath: "loading",

  • ptions: .New,

context: nil)

slide-53
SLIDE 53

Observable values

  • verride func observeValueForKeyPath(...) {

switch keyPath { case "loading": println("\(webView.loading)") case "estimatedProgress": println("\(webView.estimatedProgress)") …

  • }

}

slide-54
SLIDE 54

Injecting

slide-55
SLIDE 55

Action Request Response Rendering

slide-56
SLIDE 56

Action Request Response Rendering

slide-57
SLIDE 57

Action Request

slide-58
SLIDE 58

Action Request

webView:decidePolicyForNavigationAction:decisionHandler

slide-59
SLIDE 59

Response Rendering

slide-60
SLIDE 60

Response Rendering

webView:decidePolicyForNavigationResponse:decisionHandler:

slide-61
SLIDE 61

func webView(webView: WKWebView!, decidePolicyForNavigationAction navigationAction: WKNavigationAction!, decisionHandler: ((WKNavigationActionPolicy) -> Void)!) {

  • if (navigationAction.navigationType == .LinkActivated &&

navigationAction.request.URL.host?. lowercaseString.hasPrefix("yowconference.com.au/") != nil) {

  • // Open Safari

UIApplication.sharedApplication().openURL(navigationAction.request.URL); decisionHandler(.Cancel)

  • } else {
  • decisionHandler(.Allow)
  • }
  • }
slide-62
SLIDE 62

Native code HTML Page JS Data

slide-63
SLIDE 63

Data is serialized into native objects!

slide-64
SLIDE 64

Injecting

  • 1. Create configuration
  • 2. Wrap JS script in a WKUserScript
  • 3. Add script to configuration controller
  • 4. Set up handler
  • 5. Use configuration to build a Web view
slide-65
SLIDE 65

let speakersWebViewConfiguration = WKWebViewConfiguration()

slide-66
SLIDE 66

let scriptURL = NSBundle.mainBundle().pathForResource("fetchSpeakers",

  • fType: “js")
  • let jsScript =

String.stringWithContentsOfFile(scriptURL!, encoding:NSUTF8StringEncoding, error: nil)

  • let fetchAuthorsScript =

WKUserScript(source: jsScript, injectionTime: .AtDocumentEnd, forMainFrameOnly: true)

slide-67
SLIDE 67

speakersWebViewConfiguration. userContentController. addUserScript(fetchAuthorsScript)

slide-68
SLIDE 68

speakersWebViewConfiguration. userContentController. addScriptMessageHandler(self, name: MESSAGE_HANDLER)

slide-69
SLIDE 69

speakersWebView = WKWebView(frame: CGRectZero, configuration: speakersWebViewConfiguration)

slide-70
SLIDE 70

speakersWebView!.addObserver(self, forKeyPath: "loading",

  • ptions: .New,

context: nil)

  • speakersWebView!.addObserver(self,

forKeyPath: "estimatedProgress",

  • ptions: .New,

context: nil)

slide-71
SLIDE 71

let speakersRequest = NSURLRequest(URL:speakersURL) speakersWebView!.loadRequest(speakersRequest)

slide-72
SLIDE 72
slide-73
SLIDE 73
slide-74
SLIDE 74
slide-75
SLIDE 75
slide-76
SLIDE 76
slide-77
SLIDE 77

Demo

slide-78
SLIDE 78

https://github.com/ funkyboy/YowSpeakers

slide-79
SLIDE 79

Caution

slide-80
SLIDE 80

https://developer.apple.com/app-store/review/guidelines/

slide-81
SLIDE 81

https://developer.apple.com/app-store/review/guidelines/

slide-82
SLIDE 82

https://developer.apple.com/app-store/review/guidelines/

slide-83
SLIDE 83

https://developer.apple.com/app-store/review/guidelines/

slide-84
SLIDE 84

Building a native app is like building a custom browser

slide-85
SLIDE 85

Building a native app is like building a custom browser

Me, now

slide-86
SLIDE 86

Summing up

slide-87
SLIDE 87
slide-88
SLIDE 88

Links

  • https://www.webkit.org/blog/3362/

introducing-the-webkit-ftl-jit/

  • http://trac.webkit.org/changeset/167958
  • https://github.com/funkyboy/

YowSpeakers

  • WWDC Video #206
slide-89
SLIDE 89

Contact

  • cesare@studiomagnolia.com
  • @_funkyboy