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
Concurrency in JavaScriptCore.framework
Search
Yuichi Kobayashi
July 24, 2023
Technology
2.4k
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Concurrency in JavaScriptCore.framework
Yuichi Kobayashi
July 24, 2023
More Decks by Yuichi Kobayashi
See All by Yuichi Kobayashi
RxSwiftからCombineへの移行準備とSwiftUIへの道標
imk2o
0
550
UICollectionViewCompositionalLayoutできれいなGrid Layoutをつくる
imk2o
1
1k
Other Decks in Technology
See All in Technology
「Docker Desktop不要の時代」は 来たのか?
ueponx
0
770
Conditional PED-ANOVA: Hyperparameter Importance in Hierarchical & Dynamic Search Spaces
pfn
PRO
0
130
ブラウザとサーバーから考えるAI時代のフロントエンド監視
shogo4131
3
940
Post AI時代のリファクタリング実践記 / Refactoring in the post AI era
kaminashi
1
230
その Valkey 使いこなしていますか?
onk
PRO
5
1.5k
無理せず続ける、子育てエンジニアの学び
codmoninc
PRO
0
860
アウトプット初心者、半年間のふりかえり
4o1sobblue
0
430
go-sqletch
moznion
0
140
実体験から学ぶ分析エージェントの開発と運⽤
recruitengineers
PRO
8
2.4k
DevelopersIO 2026 知識の地図を描く ─ オントロジーとは何か?
ishikawa_satoru
1
1.7k
継続的なAIコスト最適化
bgpat
1
340
宣言型部分更新は何を解決しどこへ向かうのか
shuta13
1
450
Featured
See All Featured
State of Search Keynote: SEO is Dead Long Live SEO
ryanjones
0
320
Designing for Performance
lara
612
70k
Speed Design
sergeychernyshev
33
2.2k
DevOps and Value Stream Thinking: Enabling flow, efficiency and business value
helenjbeal
2
410
Testing 201, or: Great Expectations
jmmastey
46
8.3k
We Have a Design System, Now What?
morganepeng
55
8.4k
Learning to Love Humans: Emotional Interface Design
aarron
275
41k
Rails Girls Zürich Keynote
gr2m
96
14k
How to Create Impact in a Changing Tech Landscape [PerfNow 2023]
tammyeverts
56
3.5k
Creating an realtime collaboration tool: Agile Flush - .NET Oxford
marcduiker
35
2.6k
Claude Code のすすめ
schroneko
67
230k
How to Talk to Developers About Accessibility
jct
2
580
Transcript
@imk 2 o Concurrency in JavaScriptCore.framework potatotips # 8 3
2 ⾃⼰紹介 ίόϠγ ϢΠν iOS Engineer@MedPeer Copyright(C) 2 0 2
3 ALL RIGHTS RESERVED, MedPeer, Inc. @imk 2 o
3 JavaScriptCore.framework使ったことあります?🙋 Copyright(C) 2 0 2 3 ALL RIGHTS RESERVED,
MedPeer, Inc.
基本のおさらい JavaScriptCore.frameworkͱʁ
5 JavaScriptCore.frameworkの今北産業 ΞϓϦʹJavaScriptίʔυͷ࣮ߦڥΛΈࠐΊΔϑϨʔϜϫʔΫ Swift/Objective-CͷܕؔΛΤΫεϙʔτͯ͠ར༻Մೳ ΞϓϦͷػೳΛJSͰ੍ޚͨ͠ΓɺৼΔ͍ΛΧελϚΠζͰ͖Δ Copyright(C) 2 0 2 3
ALL RIGHTS RESERVED, MedPeer, Inc.
6 JavaScriptコードの実⾏⽅法 1. JavaScriptCore.frameworkΛΠϯϙʔτ 2. JSContextΛ༻ҙ 3. evaluateScript()Λίʔϧ Copyright(C) 2
0 2 3 ALL RIGHTS RESERVED, MedPeer, Inc. import JavaScriptCore let jsContext = JSContext() jsContext.evaluateScript("JavaScript code here...")
7 JSValueについて JSڥ্ͷΛද͢ΦϒδΣΫτ Swiftͱ૬ޓʹσʔλΛΓͱΓ͢Δཁ Copyright(C) 2 0 2 3 ALL
RIGHTS RESERVED, MedPeer, Inc.
8 Swiftオブジェクトのエクスポート 1. JSExportʹ४ڌͨ͠@objc protocolͰΤΫεϙʔτϝιουΛఆٛ 2. ্هͷϓϩτίϧΛΫϥεͰ࣮ 3. JSContext#setObject()ͰΤΫεϙʔτ Copyright(C)
2 0 2 3 ALL RIGHTS RESERVED, MedPeer, Inc. @objc protocol ModuleJS: NSObjectProtocol, JSExport { static func foo(_ value: Double) -> JSValue } final class Module: NSObject, ModuleJS { static func foo(_ value: Double) -> JSValue { ... } } jsContext.setObject(Module.self, forKeyedSubscript: "module" as NSString) const result = module.foo(9.41); .swift .js
9 Tips: Swiftクラスのエクスポート 1. ΤΫεϙʔτ͍ͨ͠ΫϥεΛJSExportʹ४ڌ 2. ϑΝΫτϦؔΛ༻ҙ Copyright(C) 2 0
2 3 ALL RIGHTS RESERVED, MedPeer, Inc. @objc protocol ColorJS: NSObjectProtocol, JSExport { var r: CGFloat { get } var g: CGFloat { get } var b: CGFloat { get } var a: CGFloat { get } } final class ColorImp: NSObject, ColorJS { ... } @objc protocol ModuleJS: NSObjectProtocol, JSExport { static func Color(_ r: CGFloat, _ g: CGFloat, _ b: CGFloat, _ a: CGFloat) -> ColorJS } const color = module.Color(0.5, 0.6, 0.7); const red = color.r; .swift .js
だいたいわかったところで ຊʹೖΓ·͢ʂ
11 JavaScriptCore.frameworkでもConcurrencyやれんのか? Ͱ͖·͢ʂ ͨͩͪ͠ΐͬͱ͕ཁΓ·͢ Copyright(C) 2 0 2 3 ALL
RIGHTS RESERVED, MedPeer, Inc.
12 Promise, async/await@JS JavaScript(~ECMAScript 2015)ʹ͓͚ΔඇಉظॲཧͷΈ async/awaitPromise/thenͷγϯλοΫεγϡΨʔ Copyright(C) 2 0 2
3 ALL RIGHTS RESERVED, MedPeer, Inc. const process = new Promise((resolve, reject) => { ... resolve(result); }); process.then((result) => { ... }); .js async function process() { ... return result; } const result = await process();
13
[email protected]
JSValue(newPromiseIn:fromExecutor:)Λ͏ Copyright(C) 2 0 2 3 ALL RIGHTS
RESERVED, MedPeer, Inc. iOS 1 3 でしれっと追加されていた... final class Module: NSObject, JSModule { static func bar() -> JSValue { return .init(newPromiseIn: .current()) { resolve, reject in ... } } } const result = await module.bar(); .swift .js
14 できたッ! Copyright(C) 2 0 2 3 ALL RIGHTS RESERVED,
MedPeer, Inc.
15 ...と思ったらRuntime Error!! Copyright(C) 2 0 2 3 ALL RIGHTS
RESERVED, MedPeer, Inc.
16 なんでよ? Copyright(C) 2 0 2 3 ALL RIGHTS RESERVED,
MedPeer, Inc.
17 Top-level await ECMAScript 2022͔ΒରԠ JavaScriptCore.frameworkͰ·ͩରԠ͍ͯ͠ͳ͍ iOS17 SDKͰରԠͯ͠ͳͦ͞͏😢 Copyright(C) 2
0 2 3 ALL RIGHTS RESERVED, MedPeer, Inc. async関数の外、つまりメインコード中でもawaitできる仕組み evaluateScript() asyncが出るまでConcurrencyできないのか😇
18 じゃあ、Swiftでやればいい。 Copyright(C) 2 0 2 3 ALL RIGHTS RESERVED,
MedPeer, Inc.
SwiftͰTop-level awaitʹରԠ͢Δʹ
20 Top-level awaitの⽣存戦略 Copyright(C) 2 0 2 3 ALL RIGHTS
RESERVED, MedPeer, Inc. 1. JSͷϝΠϯίʔυͰͷawaitఘΊΔ 2. ೖΓޱͱͳΔJSඇಉظؔΛSwiftଆ͔Βݺͼग़͠ɺͦͷྃΛػ 3. ྃػʹSemaphoreΛ͏ // Swift͔Β͜ͷඇಉظؔΛݺͼग़͠ɺػͯ͠Β͏ async main() { const result = await module.bar(); } // Top-level awaitͰ͖ͳͷͰɺϝΠϯίʔυ͔Βͷݺͼग़͖͋͠ΒΊΔ // await main(); .js
21 SwiftからJS上の⾮同期関数を呼ぶ JSඇಉظؔΛPromiseͱͯ͠ࢀর͠ɺthen()ΛݺͿ Copyright(C) 2 0 2 3 ALL RIGHTS
RESERVED, MedPeer, Inc. // main()ϩʔυ͞ΕΔ͕ɺಈ࡞͠ͳ͍ jsContext.evaluateScript(code) let semaphore = DispatchSemaphore(value: 0) // JavaScript͔Βݺͼग़͠ՄೳͳClosureΛ༻ҙ // (@convention(block)ʹ͍ͭͯJSValueͷυΩϡϝϯτࢀর) let onFulfilled: @convention(block) (JSValue) -> Void = { _ in semaphore.signal() } let onRejected: @convention(block) (JSValue) -> Void = { _ in // TODO: Handle error semaphore.signal() } // main()͔ΒPromiseΦϒδΣΫτΛࢀর͠ɺthen()ΛݺͿ jsContext .objectForKeyedSubscript("main")?.call(withArguments: [])? .invokeMethod("then", withArguments: [ JSValue(object: onFulfilled, in: jsContext)!, JSValue(object: onRejected, in: jsContext)! ]) // signal()͞ΕΔ·ͰεϨουΛఀࢭͯ͠ػ _ = semaphore.wait(timeout: .distantFuture)
22 JSコード実⾏部をContinuationでConcurrency化 εϨουͷϒϩοΫΛࢭ Copyright(C) 2 0 2 3 ALL RIGHTS
RESERVED, MedPeer, Inc. func run(code: String) async throws { return try await withCheckedThrowingContinuation { continuation in jsContext.evaluateScript(code) let semaphore = DispatchSemaphore(value: 0) ... _ = semaphore.wait(timeout: .distantFuture) continuation.resume() } }
23 まとめ JavaScriptCore.frameworkͰConcurrencyʹରԠͰ͖Δ JSValueʹൿີ͕͍ͬͺ͍ ΤϥʔϋϯυϦϯάʹ͍ͭͯฐࣾςοΫϒϩάʹॻ͘(༧ఆ) Copyright(C) 2 0 2 3
ALL RIGHTS RESERVED, MedPeer, Inc.
24 Copyright(C) 2 0 2 3 ALL RIGHTS RESERVED, MedPeer,
Inc.