Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Concurrency in JavaScriptCore.framework
Search
Sponsored
·
Ship Features Fearlessly
Turn features on and off without deploys. Used by thousands of Ruby developers.
→
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
540
UICollectionViewCompositionalLayoutできれいなGrid Layoutをつくる
imk2o
1
1k
Other Decks in Technology
See All in Technology
PdMをやめて、 "プロダクトビルダー"という 働き方に変えました / PdM to Product Builder
shikichee
2
680
作り直せるコードは迅速に 作り直せないDBは慎重に - AI時代のプロダクトエンジニアが「判断の不可逆性」で開発速度を変える話
kinosuke01
0
190
20260903 Tokyo Jazug Night #62 | Azure エンジニアよ、 その環境は本当にセキュアか?
olivia_0707
1
610
【試作】IoT x AIエージェント
happysamurai294
0
120
JAWS-UG初心者支部#88わいわい初心塾(夏休みの宿題やったかGit編)
otsuki
0
120
DMMブックスのNext.js化を加速させるAI活用 / Migrating DMM Books to Next.js with AI
kentarom
1
330
Bet AI Day 2026丨AIを「使う」から、AIが「働く」へ ― LayerXが進める「組織AI」の社会実装
layerx
PRO
2
2.1k
DGX Sparkを2台使って いろいろ動かす話
sonoda_mj
1
120
APIセキュリティを組織で実現するには~注力する点と設計・実装に入れたい対策~
riiimparm
3
930
生成AI時代の クレデンシャルとパーミッション設計
nrinetcom
PRO
3
1.5k
PM領域でのAI Agentの活用
lycorptech_jp
PRO
0
260
最新技術に積極チャレンジ!EKS共通基盤のこれまでとこれから
daitak
0
300
Featured
See All Featured
How to Think Like a Performance Engineer
csswizardry
28
2.8k
Dealing with People You Can't Stand - Big Design 2015
cassininazir
367
27k
Neural Spatial Audio Processing for Sound Field Analysis and Control
skoyamalab
0
460
JAMstack: Web Apps at Ludicrous Speed - All Things Open 2022
reverentgeek
1
590
We Are The Robots
honzajavorek
0
330
What the history of the web can teach us about the future of AI
inesmontani
PRO
1
680
The Hidden Cost of Media on the Web [PixelPalooza 2025]
tammyeverts
2
490
jQuery: Nuts, Bolts and Bling
dougneiner
66
8.6k
Are puppies a ranking factor?
jonoalderson
2
3.9k
Making Projects Easy
brettharned
120
6.7k
How to audit for AI Accessibility on your Front & Back End
davetheseo
0
520
Easily Structure & Communicate Ideas using Wireframe
afnizarnur
194
17k
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.