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
·
SiteGround - Reliable hosting with speed, security, and support you can count on.
→
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
ブラウザ研修 2026
recruitengineers
PRO
6
930
TypeScript入門 2026
recruitengineers
PRO
3
550
生成 AI の基礎 〜 サンプル実装で学ぶ基本原理
enakai00
7
4.4k
Redmine 7.0 新機能・機能強化解説(OSC2026京都ダイジェスト版)
vividtone
1
250
事業価値と Engineering 2026年度版
recruitengineers
PRO
48
23k
Model Studio CLI × Token Plan
maigo999
0
150
サイバー捜査員研修(後半)
nomizone
1
850
20260804_Q4AzureUpdateBite_FabricDataAgentの精度を高める設計.pdf
matayuuu
1
130
第3回しろおびセキュリティスポンサーセッション
log0417
0
170
ボトムアップ文化が強い組織で セキュリティをどう根付かせていくかの現在進行形の話 / Making Security Stick in a Bottom-Up Organization
yamaguchitk333
0
210
Breaking the Seal: Static Deobfuscation of Compiled V8 JavaScript Bytecode Malware
hshrzd
0
720
私がブラウザを自作したくなった理由
supurazako
1
170
Featured
See All Featured
Odyssey Design
rkendrick25
PRO
2
750
Leadership Guide Workshop - DevTernity 2021
reverentgeek
1
330
Speed Design
sergeychernyshev
33
2k
Navigating the Design Leadership Dip - Product Design Week Design Leaders+ Conference 2024
apolaine
1
390
Building an army of robots
kneath
306
46k
We Are The Robots
honzajavorek
0
300
We Have a Design System, Now What?
morganepeng
55
8.3k
Build The Right Thing And Hit Your Dates
maggiecrowley
39
3.4k
Creating an realtime collaboration tool: Agile Flush - .NET Oxford
marcduiker
35
2.5k
Bash Introduction
62gerente
615
220k
The AI Search Optimization Roadmap by Aleyda Solis
aleyda
1
6k
Crafting Experiences
bethany
1
250
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.