Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
The new WebKit is awesome
Search
Sponsored
·
Ship Features Fearlessly
Turn features on and off without deploys. Used by thousands of Ruby developers.
→
Cesare Rocchi
March 28, 2015
Technology
400
1
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
The new WebKit is awesome
Slides for my presentation about CocoaConf Chicago 2015
Cesare Rocchi
March 28, 2015
More Decks by Cesare Rocchi
See All by Cesare Rocchi
In the customer's shoes
funkyboy
0
150
What the heck is JavaScriptCore?
funkyboy
0
190
The new WebKit is AWESOME
funkyboy
0
540
Designing with Cognitive Science in Mind
funkyboy
0
190
The new WebKit is AWESOME
funkyboy
0
200
Choosing a back end for your mobile app:
funkyboy
0
690
Apps and Mental Models
funkyboy
0
260
Auto Layout? Oh boy!
funkyboy
1
290
Auto Layout? Oh boy!
funkyboy
0
150
Other Decks in Technology
See All in Technology
AI 時代のスタートアップエコシステ厶から考究する技術的負債との向き合い方
m3m0r7
PRO
2
2.1k
[2026-09-11]SREは誰のもの?運用エンジニアが始める 「SRE領域への越境」とチームの進化の軌跡 〜Road to NEXT CRE
tosite
0
260
2026_devsumi_ozono.pdf
o3
3
510
AI時代の「技術的負債」の変質ー概念の終焉と再解釈、エージェントと共に向かう先
nwiizo
0
2.6k
20260912_スクラムにジェネラリストは必要か
ryugen04
0
420
TinyGo 開発サイクルを高速化する:Go で作るエミュレータ入門
zozotech
PRO
1
740
フルカイテン株式会社 エンジニア向け採用資料
fullkaiten
0
12k
Screen Lens - 今見てる画面を翻訳する
komagata
0
310
Minecraft JavaのMODをSwiftで作る
1mash0
0
160
例外の正しい扱い方 そのエラー try-catchして大丈夫?
jinwatanabe
3
510
アクセスキーこわい やめかたと漏らさない工夫
sassssan68
1
250
AIによるクリエイティブ生成を行う上での試行錯誤
plaidtech
PRO
0
150
Featured
See All Featured
Context Engineering - Making Every Token Count
addyosmani
9
1.1k
The SEO Collaboration Effect
kristinabergwall1
1
560
The Cult of Friendly URLs
andyhume
79
7k
Impact Scores and Hybrid Strategies: The future of link building
tamaranovitovic
0
440
jQuery: Nuts, Bolts and Bling
dougneiner
66
8.6k
Winning Ecommerce Organic Search in an AI Era - #searchnstuff2025
aleyda
2
2.1k
コードの90%をAIが書く世界で何が待っているのか / What awaits us in a world where 90% of the code is written by AI
rkaga
63
46k
Digital Projects Gone Horribly Wrong (And the UX Pros Who Still Save the Day) - Dean Schuster
uxyall
1
2.9k
エンジニアに許された特別な時間の終わり
watany
109
250k
BBQ
matthewcrist
89
10k
Being A Developer After 40
akosma
91
590k
Organizational Design Perspectives: An Ontology of Organizational Design Elements
kimpetersen
PRO
1
830
Transcript
The new Webkit is AWESOME Cesare Rocchi @_funkyboy
TOC • History • What’s new • Demo
Who am I?
UX designer and developer
studiomagnolia.com
upbeat.it
appversion.io
@_funkyboy
Who are you?
History
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 “ ”
History • No plugins • Flash • Applets
None
Adobe, don’t even think about it!
None
None
History • Nitro was introduced in iOS 4.3 • Uses
JIT • Transform JS into native code Needs to mark memory w+x • Security issues
None
var temp = {}; temp[10123] = "cocoaconf";
Progress
iOS 3.2 -> iOS4 https://developer.apple.com/LIBRARY/ios/releasenotes/General/iPhone40APIDiffs/index.html Added UIWebView.allowsInlineMediaPlayback Added UIWebView.mediaPlaybackRequiresUserAction
iOS 4.3 -> iOS5 https://developer.apple.com/LIBRARY/ios/releasenotes/General/iOS50APIDiff/index.html Added UIWebView.mediaPlaybackAllowsAirPlay Added UIWebView.scrollView
iOS 5.1 -> iOS6 https://developer.apple.com/LIBRARY/ios/releasenotes/General/iOS60APIDiffs/index.html Added UIWebView.keyboardDisplayRequiresUserAction Added UIWebView.suppressesIncrementalRendering
iOS 6.1 -> iOS7 https://developer.apple.com/library/IOS/releasenotes/General/iOS70APIDiffs/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
iOS 6.1 -> iOS7 https://developer.apple.com/library/IOS/releasenotes/General/iOS70APIDiffs/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 }
None
iOS7 -> iOS8 https://developer.apple.com/library/prerelease/ios/releasenotes/General/iOS80APIDiffs/frameworks/WebKit.html
1 Class 1 Protocol
UIWebView UIWebViewDelegate
14 Classes 3 Protocols
WKWebView WKFrameInfo WKBackForwardList WKBackForwardListItem WKNavigation WKNavigationAction WKNavigationResponse WKPreferences WKProcessPool WKUserContentController
WKWebViewConfiguration WKWindowFeatures WKScriptMessage WKUserScript WKNavigationDelegate WKScriptMessageHandler WKUIDelegate
XPC • Greatly improved in iOS8 • Third party keyboards
• Sharing extensions
XPC find /Applications -name \*.xpc | grep Web | wc
-l
XPC • Split app in multiple processes • E.g. Sourcekit
• http://www.jpsim.com/uncovering-sourcekit/
r167958
None
Optimizing JS
Fun with JS
jsc sudo ln -s /System/Library/Frameworks/ JavaScriptCore.framework/Versions/Current/Resources/jsc /bin/jsc
None
JS bytecode LLInt JIT DFG optimization
function sum(a, b) { return a + b; }
LLInt JIT DFG optimization function sum(a, b) { return a
+ b; }
LLInt JIT DFG
LLVM
LLVM • Infrastructure • Meant to optimize *time • Started
by Mr. Swift
LLInt JIT DFG
LLInt JIT DFG FTL
What’s new
Observable values
Observable values • loading • title • URL • estimatedProgress
Observable values webView.addObserver(self, forKeyPath: "loading", options: .New, context: nil)
Observable values override func observeValueForKeyPath(...) { switch keyPath { case
"loading": println("\(webView.loading)") case "estimatedProgress": println("\(webView.estimatedProgress)") … } }
Injecting
Action Request Response Rendering
Action Request Response Rendering
Action Request
Action Request webView:decidePolicyForNavigationAction:decisionHandler
Response Rendering
Response Rendering webView:decidePolicyForNavigationResponse:decisionHandler:
func webView(webView: WKWebView!, decidePolicyForNavigationAction navigationAction: WKNavigationAction!, decisionHandler: ((WKNavigationActionPolicy) -> Void)!)
{ if (navigationAction.navigationType == .LinkActivated && navigationAction.request.URL.host?. lowercaseString.hasPrefix("cocoaconference.com/") != nil) { // Open Safari UIApplication.sharedApplication().openURL(navigationAction.request.URL); decisionHandler(.Cancel) } else { decisionHandler(.Allow) } }
Native code HTML Page JS Data
Data is serialized into native objects!
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
let speakersWebViewConfiguration = WKWebViewConfiguration()
let scriptURL = NSBundle.mainBundle().pathForResource("fetchSpeakers", ofType: “js") let jsScript = String(contentsOfFile:scriptURL!,
encoding:NSUTF8StringEncoding, error: nil) let fetchAuthorsScript = WKUserScript(source: jsScript!, injectionTime: .AtDocumentEnd, forMainFrameOnly: true)
speakersWebViewConfiguration. userContentController. addUserScript(fetchAuthorsScript)
speakersWebViewConfiguration. userContentController. addScriptMessageHandler(self, name: MESSAGE_HANDLER)
speakersWebView = WKWebView(frame: CGRectZero, configuration: speakersWebViewConfiguration)
speakersWebView!.addObserver(self, forKeyPath: "loading", options: .New, context: nil) speakersWebView!.addObserver(self, forKeyPath: "estimatedProgress",
options: .New, context: nil)
let speakersRequest = NSURLRequest(URL:speakersURL) speakersWebView!.loadRequest(speakersRequest)
None
None
None
None
None
Demo
https://github.com/ funkyboy/Cocoaconf- Chicago-2015
Caution
https://developer.apple.com/app-store/review/guidelines/
https://developer.apple.com/app-store/review/guidelines/
https://developer.apple.com/app-store/review/guidelines/
https://developer.apple.com/app-store/review/guidelines/
Building a native app is like building a custom browser
Building a native app is like building a custom browser
Me, now
Summing up
None
Links • https://www.webkit.org/blog/3362/ introducing-the-webkit-ftl-jit/ • http://trac.webkit.org/changeset/167958 • https://www.destroyallsoftware.com/ talks/wat •
WWDC Video #206
Contact •
[email protected]
• @_funkyboy