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
レシート印刷が途中で止まる?Stream APIとBluetooth接続のルールを守って楽しく...
Search
satoryo56
September 19, 2025
Programming
350
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
レシート印刷が途中で止まる?Stream APIとBluetooth接続のルールを守って楽しくレシートプリンターで印刷しよう! / iOSDC Japan 2025 satoryo
https://fortee.jp/iosdc-japan-2025/proposal/95648833-0e4f-4dfd-ba87-60b739a7dabe
satoryo56
September 19, 2025
More Decks by satoryo56
See All by satoryo56
WWDC25に現地参加してきました / satoryo attended WWDC25 onsite
satoryo56
0
130
STORES Tech Conf 2024 “New Engineering” - 複数のScrollViewが連動!STORES レジ でスプレッドシート風UIを実装しました
satoryo56
0
2.1k
Gemini in Android Studio 使ってますか?
satoryo56
0
1.1k
Other Decks in Programming
See All in Programming
Modding RubyKaigi for Myself
yui_knk
0
890
Webフレームワークの ベンチマークについて
yusukebe
0
140
運用エージェントは "作る" から "育てる" へ - 記憶と自己進化の3層設計パターン / self-evolving-agents-three-layer-agent-design
gawa
12
3.5k
AI駆動開発勉強会 広島支部 第一回勉強会 AI駆動開発概要とワークショップ
hayatoshimiu
0
450
tsserverとは何だったのか、これからどうなるのか
nowaki28
1
450
作って学ぶ、 JSX (TSX) ランタイムの基本
syumai
7
1.5k
ローカルLLMを使ってB2Bサービスを作っていての学び
yaotti
0
150
Swiftのレキシカルスコープ管理
kntkymt
0
210
PHPで使える日時の表現と、その知り方 #frontend_phpcon_do
o0h
PRO
0
190
エージェンティックRAGにAWSで入門しよう!
har1101
8
1.2k
TAKTでAI駆動開発の品質を設計する
j5ik2o
6
1k
oxlintはeslint/typescript-eslintを置き換えられるのか
shomafujita
2
320
Featured
See All Featured
Navigating Algorithm Shifts & AI Overviews - #SMXNext
aleyda
1
1.3k
Kristin Tynski - Automating Marketing Tasks With AI
techseoconnect
PRO
0
270
The B2B funnel & how to create a winning content strategy
katarinadahlin
PRO
1
380
Exploring anti-patterns in Rails
aemeredith
3
400
What’s in a name? Adding method to the madness
productmarketing
PRO
24
4.1k
Ten Tips & Tricks for a 🌱 transition
stuffmc
0
130
Scaling GitHub
holman
464
140k
[RailsConf 2023] Rails as a piece of cake
palkan
59
6.7k
Templates, Plugins, & Blocks: Oh My! Creating the theme that thinks of everything
marktimemedia
31
2.8k
"I'm Feeling Lucky" - Building Great Search Experiences for Today's Users (#IAC19)
danielanewman
231
23k
Marketing to machines
jonoalderson
1
5.4k
How Software Deployment tools have changed in the past 20 years
geshan
0
34k
Transcript
J04%$+BQBO Ϩγʔτҹ్͕தͰࢭ·Δʁ 4USFBN"1*ͱ#MVFUPPUIଓͷϧʔϧΛ कָͬͯ͘͠ϨγʔτϓϦϯλʔͰҹ͠Α͏ʂ CZTBUPSZP!TBUPSZP
satoryo STORES גࣜձࣾ iOSɾAndroidΤϯδχΞ ࣗݾհ X(Twitter): @satoryo056 ࠓͷ WWDC25
ʹॳࢀՃʂ iOSDC ॳొஃͰ40τʔΫʂ
ళฮͰ͓ձܭ͢Δͱ Β͑Δͷʁ
Ϩγʔτ🧾
αʔϏεհɿ4503&4Ϩδ ɾখചۀɾαʔϏεۀͷళฮ͚ΞϓϦ ɾݱͰͷ͓ձܭͰΦʔφʔɾελοϑ͕༻
αʔϏεհɿ4503&4Ϩδ ɾখചۀɾαʔϏεۀͷళฮ͚ΞϓϦ ɾݱͰͷ͓ձܭͰΦʔφʔɾελοϑ͕༻ ɾ͓ձܭޙͷϨγʔτ ྖऩॻҹͷχʔζ͕ߴ͍
αʔϏεհɿ4503&4Ϩδ ɾখചۀɾαʔϏεۀͷళฮ͚ΞϓϦ ɾݱͰͷ͓ձܭͰΦʔφʔɾελοϑ͕༻ ɾ͓ձܭޙͷϨγʔτ ྖऩॻҹͷχʔζ͕ߴ͍ ɾϨγʔτϓϦϯλʔͱଓ͠ ϨγʔτҹΛαϙʔτ
ຊτʔΫͰ͢͜ͱ ϨγʔτϓϦϯλʔͷհ ෳͷϝʔΧʔΛαϙʔτ Ϩγʔτҹ్͕தͰࢭ·Δෆ۩߹ ·ͱΊ
ຊτʔΫͰ͢͜ͱ ϨγʔτϓϦϯλʔͷհ ෳͷϝʔΧʔΛαϙʔτ Ϩγʔτҹ్͕தͰࢭ·Δෆ۩߹ ·ͱΊ
ϨγʔτϓϦϯλʔͷհ
ϨγʔτϓϦϯλʔʹ͍ͭͯ ɾϨγʔτ ྖऩॻΛൃߦ͢ΔͨΊͷઐ༻ϓϦϯλʔ ɾ#MVFUPPUI64#έʔϒϧ ༗ઢ-"/ͳͲͰͱଓ ɾϢʔεέʔεʹ߹Θͤͯෳͷछྨ͕ଘࡏ Ҿ༻ɿIUUQTSFHJGBRTUPSFTKQIDKBBSUJDMFT
ϞόΠϧΞϓϦͰϨγʔτҹΛ͢Δʹʁ
ϞόΠϧΞϓϦͰϨγʔτҹΛ͢Δʹʁ ֤ϝʔΧʔͷ4%,Λར༻
4%,Λར༻ͨ͠Ϩγʔτҹͷ࣮ྫ // 1. ϓϦϯλʔݕࡧ let manager = StarDeviceDiscoveryManager() let
printers = try await manager.discoverPrinters() // 2. ϓϦϯλʔଓ guard let printer = printers.first else { return } let starPrinter = StarPrinter(connectionSettings: printer.connectionSettings) ελʔਫ਼ີ4UBS9QBOE4%,ͷ߹ // 3. Ϩγʔτ࡞ let builder = StarXpandCommand.DocumentBuilder() builder.addPrinter( StarXpandCommand.PrinterBuilder() .styleAlignment(.center) .styleBold(true) .actionPrintText("Ϩγʔτ\n") .styleBold(false) .styleAlignment(.left) .actionPrintText("໊: ίʔώʔ\n") .actionPrintText("ֹۚ: ¥300\n") .actionCut(.partial) ) // 4. ҹ࣮ߦ let commands = builder.getCommands() try await starPrinter.print(command: commands) Ҿ༻ɿIUUQTHJUIVCDPNTUBSNJDSPOJDT4UBS9QBOE4%,J04
4%,Λར༻ͨ͠Ϩγʔτҹͷ࣮ྫ // 1. ϓϦϯλʔݕࡧ let manager = StarDeviceDiscoveryManager() let
printers = try await manager.discoverPrinters() // 2. ϓϦϯλʔଓ guard let printer = printers.first else { return } let starPrinter = StarPrinter(connectionSettings: printer.connectionSettings) ελʔਫ਼ີ4UBS9QBOE4%,ͷ߹ // 3. Ϩγʔτ࡞ let builder = StarXpandCommand.DocumentBuilder() builder.addPrinter( StarXpandCommand.PrinterBuilder() .styleAlignment(.center) .styleBold(true) .actionPrintText("Ϩγʔτ\n") .styleBold(false) .styleAlignment(.left) .actionPrintText("໊: ίʔώʔ\n") .actionPrintText("ֹۚ: ¥300\n") .actionCut(.partial) ) // 4. ҹ࣮ߦ let commands = builder.getCommands() try await starPrinter.print(command: commands) Ҿ༻ɿIUUQTHJUIVCDPNTUBSNJDSPOJDT4UBS9QBOE4%,J04
4%,Λར༻ͨ͠Ϩγʔτҹͷ࣮ྫ // 1. ϓϦϯλʔݕࡧ let manager = StarDeviceDiscoveryManager() let
printers = try await manager.discoverPrinters() // 2. ϓϦϯλʔଓ guard let printer = printers.first else { return } let starPrinter = StarPrinter(connectionSettings: printer.connectionSettings) ελʔਫ਼ີ4UBS9QBOE4%,ͷ߹ // 3. Ϩγʔτ࡞ let builder = StarXpandCommand.DocumentBuilder() builder.addPrinter( StarXpandCommand.PrinterBuilder() .styleAlignment(.center) .styleBold(true) .actionPrintText("Ϩγʔτ\n") .styleBold(false) .styleAlignment(.left) .actionPrintText("໊: ίʔώʔ\n") .actionPrintText("ֹۚ: ¥300\n") .actionCut(.partial) ) // 4. ҹ࣮ߦ let commands = builder.getCommands() try await starPrinter.print(command: commands) Ҿ༻ɿIUUQTHJUIVCDPNTUBSNJDSPOJDT4UBS9QBOE4%,J04
4%,Λར༻ͨ͠Ϩγʔτҹͷ࣮ྫ // 1. ϓϦϯλʔݕࡧ let manager = StarDeviceDiscoveryManager() let
printers = try await manager.discoverPrinters() // 2. ϓϦϯλʔଓ guard let printer = printers.first else { return } let starPrinter = StarPrinter(connectionSettings: printer.connectionSettings) ελʔਫ਼ີ4UBS9QBOE4%,ͷ߹ // 3. Ϩγʔτ࡞ let builder = StarXpandCommand.DocumentBuilder() builder.addPrinter( StarXpandCommand.PrinterBuilder() .styleAlignment(.center) .styleBold(true) .actionPrintText("Ϩγʔτ\n") .styleBold(false) .styleAlignment(.left) .actionPrintText("໊: ίʔώʔ\n") .actionPrintText("ֹۚ: ¥300\n") .actionCut(.partial) ) // 4. ҹ࣮ߦ let commands = builder.getCommands() try await starPrinter.print(command: commands) Ҿ༻ɿIUUQTHJUIVCDPNTUBSNJDSPOJDT4UBS9QBOE4%,J04
4%,Λར༻ͨ͠Ϩγʔτҹͷ࣮ྫ // 1. ϓϦϯλʔݕࡧ let manager = StarDeviceDiscoveryManager() let
printers = try await manager.discoverPrinters() // 2. ϓϦϯλʔଓ guard let printer = printers.first else { return } let starPrinter = StarPrinter(connectionSettings: printer.connectionSettings) ελʔਫ਼ີ4UBS9QBOE4%,ͷ߹ // 3. Ϩγʔτ࡞ let builder = StarXpandCommand.DocumentBuilder() builder.addPrinter( StarXpandCommand.PrinterBuilder() .styleAlignment(.center) .styleBold(true) .actionPrintText("Ϩγʔτ\n") .styleBold(false) .styleAlignment(.left) .actionPrintText("໊: ίʔώʔ\n") .actionPrintText("ֹۚ: ¥300\n") .actionCut(.partial) ) // 4. ҹ࣮ߦ let commands = builder.getCommands() try await starPrinter.print(command: commands) Ҿ༻ɿIUUQTHJUIVCDPNTUBSNJDSPOJDT4UBS9QBOE4%,J04
4%,Λར༻ͨ͠Ϩγʔτҹͷ࣮ྫ // 1. ϓϦϯλʔݕࡧ let manager = StarDeviceDiscoveryManager() let
printers = try await manager.discoverPrinters() // 2. ϓϦϯλʔଓ guard let printer = printers.first else { return } let starPrinter = StarPrinter(connectionSettings: printer.connectionSettings) ελʔਫ਼ີ4UBS9QBOE4%,ͷ߹ // 3. Ϩγʔτ࡞ let builder = StarXpandCommand.DocumentBuilder() builder.addPrinter( StarXpandCommand.PrinterBuilder() .styleAlignment(.center) .styleBold(true) .actionPrintText("Ϩγʔτ\n") .styleBold(false) .styleAlignment(.left) .actionPrintText("໊: ίʔώʔ\n") .actionPrintText("ֹۚ: ¥300\n") .actionCut(.partial) ) // 4. ҹ࣮ߦ let commands = builder.getCommands() try await starPrinter.print(command: commands) ࢀߟɿIUUQTHJUIVCDPNTUBSNJDSPOJDT4UBS9QBOE4%,J04 গͳ͍ߦͰ Ϩγʔτҹ͕Մೳʂ
ຊτʔΫͰ͢͜ͱ ϨγʔτϓϦϯλʔͷհ ෳͷϝʔΧʔΛαϙʔτ Ϩγʔτҹ్͕தͰࢭ·Δෆ۩߹ ·ͱΊ
ෳͷϝʔΧʔΛαϙʔτ ϨγʔτϓϦϯλʔͰҹ͢Δ
ͳͥෳͷϝʔΧʔΛαϙʔτʁ ɾ4503&4ϨδΛར༻͢Δళฮ͝ͱʹϢʔεέʔε͕ҟͳΔ ɾݻఆͰஔ͖͍ͨPS࣋ͪӡͼ͍ͨ ɾݱۚΛҰॹʹཧ͍ͨ͠ ɾಛఆͷϨγʔτ෯ʹ͍ͨ͠ɹͳͲ ɾ͞·͟·ͳϢʔεέʔεʹԠ͑ΔͨΊ ෳͷϝʔΧʔΛαϙʔτ
4503&4Ϩδ͕αϙʔτ͢ΔϨγʔτϓϦϯλʔͷҰ෦ &QTPO ελʔਫ਼ີ ͦͷଞ ਾ͑ஔ͖ܕ ਾ͑ஔ͖ܕ υϩϫʔҰମܕ ख࣋ͪܕ ηΠίʔΠϯεπϧ
ख࣋ͪܕ ख࣋ͪܕ λϒϨοτҰମܕ Ҿ༻ɿIUUQTSFHJGBRTUPSFTKQIDKBBSUJDMFT
4503&4Ϩδ͕αϙʔτ͢ΔϨγʔτϓϦϯλʔͷҰ෦ &QTPO ελʔਫ਼ີ ͦͷଞ ਾ͑ஔ͖ܕ ਾ͑ஔ͖ܕ υϩϫʔҰମܕ ख࣋ͪܕ ηΠίʔΠϯεπϧ
ख࣋ͪܕ ख࣋ͪܕ λϒϨοτҰମܕ Ҿ༻ɿIUUQTSFHJGBRTUPSFTKQIDKBBSUJDMFT
4503&4Ϩδ͕αϙʔτ͢ΔϨγʔτϓϦϯλʔͷҰ෦ &QTPO ελʔਫ਼ີ ͦͷଞ ਾ͑ஔ͖ܕ ਾ͑ஔ͖ܕ υϩϫʔҰମܕ ख࣋ͪܕ ηΠίʔΠϯεπϧ
ख࣋ͪܕ ख࣋ͪܕ λϒϨοτҰମܕ Ҿ༻ɿIUUQTSFHJGBRTUPSFTKQIDKBBSUJDMFT
4503&4Ϩδ͕αϙʔτ͢ΔϨγʔτϓϦϯλʔͷҰ෦ &QTPO ελʔਫ਼ີ ͦͷଞ ਾ͑ஔ͖ܕ ਾ͑ஔ͖ܕ υϩϫʔҰମܕ ख࣋ͪܕ ηΠίʔΠϯεπϧ
ख࣋ͪܕ ख࣋ͪܕ λϒϨοτҰମܕ Ҿ༻ɿIUUQTSFHJGBRTUPSFTKQIDKBBSUJDMFT
4503&4Ϩδ͕αϙʔτ͢ΔϨγʔτϓϦϯλʔͷҰ෦ &QTPO ελʔਫ਼ີ ͦͷଞ ਾ͑ஔ͖ܕ ਾ͑ஔ͖ܕ υϩϫʔҰମܕ ख࣋ͪܕ ηΠίʔΠϯεπϧ
ख࣋ͪܕ ख࣋ͪܕ λϒϨοτҰମܕ Ҿ༻ɿIUUQTSFHJGBRTUPSFTKQIDKBBSUJDMFT
4503&4Ϩδ͕αϙʔτ͢ΔϨγʔτϓϦϯλʔͷҰ෦ &QTPO ελʔਫ਼ີ ͦͷଞ ਾ͑ஔ͖ܕ ਾ͑ஔ͖ܕ υϩϫʔҰମܕ ख࣋ͪܕ ηΠίʔΠϯεπϧ
ख࣋ͪܕ ख࣋ͪܕ λϒϨοτҰମܕ Ҿ༻ɿIUUQTSFHJGBRTUPSFTKQIDKBBSUJDMFT
ϝʔΧʔͷαϙʔτΛ૿͢ʹʁ
ϝʔΧʔͷαϙʔτΛ૿͢ʹʁ શͯͷϝʔΧʔͷ4%,Λ ΞϓϦʹΈࠐΉ
શͯͷϝʔΧʔͷ4%,ΛΈࠐΉ͜ͱ ϝϦοτ ɾ֤ϝʔΧʔͷϓϦϯλʔΛશͯαϙʔτͰ͖Δ σϝϦοτ ɾ4%,͝ͱʹ"1*༷͕ҟͳΔ ɾڞ௨ΠϯλʔϑΣʔεԽͷқ͕ߴ͍ ɾͦͦ4%,͕ͳ͍ϝʔΧʔ͕ଘࡏ͢Δ
શͯͷϝʔΧʔͷ4%,ΛΈࠐΉ͜ͱ ϝϦοτ ɾ֤ϝʔΧʔͷϓϦϯλʔΛશͯαϙʔτͰ͖Δ σϝϦοτ ɾ4%,͝ͱʹ"1*༷͕ҟͳΔ ɾڞ௨ΠϯλʔϑΣʔεԽͷқ͕ߴ͍ ɾͦͦ4%,͕ଘࡏ͠ͳ͍ϝʔΧʔ͕ଘࡏ͢Δ 4%,͚ͩͰ શͯͷϝʔΧʔʹ
ରԠͰ͖ͳ͍
શͯͷϝʔΧʔͷ4%,ΛΈࠐΉ͜ͱ ϝϦοτ ɾ֤ϝʔΧʔͷϓϦϯλʔΛશͯαϙʔτͰ͖Δ σϝϦοτ ɾ4%,͝ͱʹ"1*༷͕ҟͳΔ ɾڞ௨ΠϯλʔϑΣʔεԽͷқ͕ߴ͍ ɾͦͦ4%,͕ଘࡏ͠ͳ͍ϝʔΧʔ͕ଘࡏ͢Δ ࣗͨͪͰ ࡞Δ͔͠ͳ͍🦌
શͯͷϝʔΧʔͷ4%,ΛΈࠐΉ͜ͱ ϝϦοτ ɾ֤ϝʔΧʔͷϓϦϯλʔΛશͯαϙʔτͰ͖Δ σϝϦοτ ɾ4%,͝ͱʹ"1*༷͕ҟͳΔ ɾڞ௨ΠϯλʔϑΣʔεԽͷқ͕ߴ͍ ɾͦͦ4%,͕ଘࡏ͠ͳ͍ϝʔΧʔ͕ଘࡏ͢Δ 4%,ΛΘͣʹ ෳϝʔΧʔΛαϙʔτ
4%,ΛΘͣϨγʔτϓϦϯλʔͰҹ͢ΔྲྀΕ ϨγʔτϓϦϯλʔΛ୳͢ ҹ͢ΔϨγʔτσʔλΛ࡞͢Δ ϨγʔτϓϦϯλʔʹσʔλΛૹΔ
4%,ΛΘͣϨγʔτϓϦϯλʔͰҹ͢ΔྲྀΕ ϨγʔτϓϦϯλʔΛ୳͢ ҹ͢ΔϨγʔτσʔλΛ࡞͢Δ ϨγʔτϓϦϯλʔʹσʔλΛૹΔ
ϨγʔτϓϦϯλʔΛ୳͢ ɾ4503&4ϨδͰ#MVFUPPUI$MBTTJDΛར༻ ɾ&""DDFTTPSZ.BOBHFSΛ༻͠ϨγʔτϓϦϯλʔͱଓ
طଘͷଓࡁΈΞΫηαϦΛεΩϟϯ͢Δ߹ // ௨ొ EAAccessoryManager.shared().registerForLocalNotifications() let accessories = EAAccessoryManager.shared().connectedAccessories for
accessory in accessories { // accessory: EAAccessory ͔ΒϨγʔτϓϦϯλʔΛݕࡧ } ϨγʔτϓϦϯλʔΛ୳͢
طଘͷଓࡁΈΞΫηαϦΛεΩϟϯ͢Δ߹ // ௨ొ EAAccessoryManager.shared().registerForLocalNotifications() let accessories = EAAccessoryManager.shared().connectedAccessories for
accessory in accessories { // accessory: EAAccessory ͔ΒϨγʔτϓϦϯλʔΛݕࡧ } ϨγʔτϓϦϯλʔΛ୳͢
طଘͷଓࡁΈΞΫηαϦΛεΩϟϯ͢Δ߹ // ௨ొ EAAccessoryManager.shared().registerForLocalNotifications() let accessories = EAAccessoryManager.shared().connectedAccessories for
accessory in accessories { // accessory: EAAccessory ͔ΒϨγʔτϓϦϯλʔΛݕࡧ } ϨγʔτϓϦϯλʔΛ୳͢ ଓࡁΈΞΫηαϦΛऔಘ
طଘͷଓࡁΈΞΫηαϦΛεΩϟϯ͢Δ߹ // ௨ొ EAAccessoryManager.shared().registerForLocalNotifications() let accessories = EAAccessoryManager.shared().connectedAccessories for
accessory in accessories { // accessory: EAAccessory ͔ΒϨγʔτϓϦϯλʔΛݕࡧ } ϨγʔτϓϦϯλʔΛ୳͢ ଓࡁΈΞΫηαϦ͔Βݕࡧ
ϨγʔτϓϦϯλʔΛ୳͢ ৽نΞΫηαϦΛεΩϟϯ͢Δ߹ /// BluetoothΞΫηαϦϐοΧʔΛදࣔ public func showBluetoothAccessoryPicker( nameFilter:
NSPredicate? = nil ) async throws { try await EAAccessoryManager .shared() .showBluetoothAccessoryPicker( withNameFilter: nameFilter ) }
ϨγʔτϓϦϯλʔΛ୳͢ ৽نΞΫηαϦΛεΩϟϯ͢Δ߹ /// BluetoothΞΫηαϦϐοΧʔΛදࣔ public func showBluetoothAccessoryPicker( nameFilter:
NSPredicate? = nil ) async throws { try await EAAccessoryManager .shared() .showBluetoothAccessoryPicker( withNameFilter: nameFilter ) }
ϨγʔτϓϦϯλʔΛ୳͢ ৽نΞΫηαϦΛεΩϟϯ͢Δ߹ /// BluetoothΞΫηαϦϐοΧʔΛදࣔ public func showBluetoothAccessoryPicker( nameFilter:
NSPredicate? = nil ) async throws { try await EAAccessoryManager .shared() .showBluetoothAccessoryPicker( withNameFilter: nameFilter ) } ΞΫηαϦ໊ͰߜΓࠐΈՄೳ
ϨγʔτϓϦϯλʔΛ୳͢ ৽نΞΫηαϦΛεΩϟϯ͢Δ߹ /// BluetoothΞΫηαϦϐοΧʔΛදࣔ public func showBluetoothAccessoryPicker( nameFilter:
NSPredicate? = nil ) async throws { try await EAAccessoryManager .shared() .showBluetoothAccessoryPicker( withNameFilter: nameFilter ) }
ଓ௨ͷࢹ let connectToken = NotificationCenter.default.addObserver( forName: .EAAccessoryDidConnect, object: nil,
queue: .main ) { [weak self] notification in // ଓͨ͠ϨγʔτϓϦϯλʔΛอ࣋ let accessory = notification.object as? EAAccessory … } notificationTokens.append(connectToken) ϨγʔτϓϦϯλʔΛ୳͢
ଓ௨ͷࢹ let connectToken = NotificationCenter.default.addObserver( forName: .EAAccessoryDidConnect, object: nil,
queue: .main ) { [weak self] notification in // ଓͨ͠ϨγʔτϓϦϯλʔΛอ࣋ let accessory = notification.object as? EAAccessory … } notificationTokens.append(connectToken) ϨγʔτϓϦϯλʔΛ୳͢ ΞΫηαϦͱଓͨ࣌͠ʹ௨
ଓ௨ͷࢹ let connectToken = NotificationCenter.default.addObserver( forName: .EAAccessoryDidConnect, object: nil,
queue: .main ) { [weak self] notification in // ଓͨ͠ϨγʔτϓϦϯλʔΛอ࣋ let accessory = notification.object as? EAAccessory … } notificationTokens.append(connectToken) ϨγʔτϓϦϯλʔΛ୳͢
அ௨ͷࢹ let disconnectToken = NotificationCenter.default.addObserver( forName: .EAAccessoryDidDisconnect, object: nil,
queue: .main ) { [weak self] notification in // அͨ͠ϨγʔτϓϦϯλʔΛআ } notificationTokens.append(disconnectToken) ϨγʔτϓϦϯλʔΛ୳͢
அ௨ͷࢹ let disconnectToken = NotificationCenter.default.addObserver( forName: .EAAccessoryDidDisconnect, object: nil,
queue: .main ) { [weak self] notification in // அͨ͠ϨγʔτϓϦϯλʔΛআ } notificationTokens.append(disconnectToken) ϨγʔτϓϦϯλʔΛ୳͢ ΞΫηαϦͱஅͨ࣌͠ʹ௨
4%,ΛΘͣϨγʔτϓϦϯλʔͰҹ͢ΔྲྀΕ ϨγʔτϓϦϯλʔΛ୳͢ ҹ͢ΔϨγʔτσʔλΛ࡞͢Δ ϨγʔτϓϦϯλʔʹσʔλΛૹΔ
Ϩγʔτσʔλͷੜ4503&4Ϩδͷ߹ ɾϨγʔτσʔλͷߏ ɾϔομʔใɿλΠτϧը૾ͳͲ ɾใɿ໊Ձ֨ͳͲ ɾձܭใɿ߹ܭֹۚ੫ۚͳͲ ɾϑολʔใɿ23ίʔυͳͲ ҹ͢ΔϨγʔτσʔλΛ࡞͢Δ
ϓϦϯλʔίϚϯυϓϩτίϧ ɾϝʔΧʔ͝ͱʹϨγʔτϓϦϯλʔ༻ͷίϚϯυମܥ͕ଘࡏ ɾ&QTPO͕։ൃͨ͠ʮ&4$104ܗࣜʯ ɾελʔਫ਼ີ͕։ൃͨ͠ʮ4UBS 13/5ܗࣜʯ ɾίϚϯυਐͰදݱʢྫɿY"ʣ ɾςΩετը૾ͷҹͳͲ༷ʑͳίϚϯυΛઃఆՄೳ ҹ͢ΔϨγʔτσʔλΛ࡞͢Δ
// վߦίϚϯυ public func lineFeedCommand() -> Data { Data([0x0A])
} // ςΩετҹίϚϯυ public func textCommand(_ text: String) -> Data { text.data(using: .utf8) ?? Data() } // ςΩετΛଠࣈʹ͢ΔίϚϯυ public func boldCommand(_ enabled: Bool) -> Data { let value: UInt8 = enabled ? 0x01 : 0x00 return Data([0x1B, 0x45, value]) } ϝʔΧʔڞ௨ίϚϯυͷྫ ҹ͢ΔϨγʔτσʔλΛ࡞͢Δ
// վߦίϚϯυ public func lineFeedCommand() -> Data { Data([0x0A])
} // ςΩετҹίϚϯυ public func textCommand(_ text: String) -> Data { text.data(using: .utf8) ?? Data() } // ςΩετΛଠࣈʹ͢ΔίϚϯυ public func boldCommand(_ enabled: Bool) -> Data { let value: UInt8 = enabled ? 0x01 : 0x00 return Data([0x1B, 0x45, value]) } ϝʔΧʔڞ௨ίϚϯυͷྫ ҹ͢ΔϨγʔτσʔλΛ࡞͢Δ %BUBܕΛฦ͢
// ϨγʔτΛΧοτʢஅʣ͢ΔίϚϯυ public func cutPaperCommand() -> Data { Data([0x1D,
0x56, 0x00]) } // ը૾Λҹ͢ΔͨΊͷίϚϯυ public func bitmapCommand(_ data: Data, width: Int, height: Int) -> Data { var command = Data() // ϏοτϚοϓҹίϚϯυ command.append(Data([0x1D, 0x76, 0x30, 0x00])) // ෯ͱߴ͞ command.append(Data([UInt8(width & 0xFF), UInt8((width >> 8) & 0xFF)])) command.append(Data([UInt8(height & 0xFF), UInt8((height >> 8) & 0xFF)])) // ϏοτϚοϓσʔλ command.append(data) return command } &QTPOϨγʔτϓϦϯλʔ༻ίϚϯυͷྫ ҹ͢ΔϨγʔτσʔλΛ࡞͢Δ
// ϨγʔτΛΧοτʢஅʣ͢ΔίϚϯυ public func cutPaperCommand() -> Data { Data([0x1B,
0x64, 0x00]) } // ը૾Λҹ͢ΔͨΊͷίϚϯυ public func bitmapCommand(_ data: Data, width: Int, height: Int) -> Data { var command = Data() // ϏοτϚοϓҹίϚϯυ command.append(Data([0x1B, 0x58])) // ෯ͱߴ͞ command.append(Data([UInt8(width & 0xFF), UInt8((width >> 8) & 0xFF)])) command.append(Data([UInt8(height & 0xFF), UInt8((height >> 8) & 0xFF)])) // ϏοτϚοϓσʔλ command.append(data) return command } ελʔਫ਼ີϨγʔτϓϦϯλʔ༻ίϚϯυͷྫ ҹ͢ΔϨγʔτσʔλΛ࡞͢Δ
// ϨγʔτΛΧοτʢஅʣ͢ΔίϚϯυ public func cutPaperCommand() -> Data { Data([0x1D,
0x56, 0x00]) } // ը૾Λҹ͢ΔͨΊͷίϚϯυ public func bitmapCommand(_ data: Data, width: Int, height: Int) -> Data { var command = Data() // ϏοτϚοϓҹίϚϯυ command.append(Data([0x1D, 0x76, 0x30, 0x00])) // ෯ͱߴ͞ command.append(Data([UInt8(width & 0xFF), UInt8((width >> 8) & 0xFF)])) command.append(Data([UInt8(height & 0xFF), UInt8((height >> 8) & 0xFF)])) // ϏοτϚοϓσʔλ command.append(data) return command } &QTPOϨγʔτϓϦϯλʔ༻ίϚϯυͷྫ ҹ͢ΔϨγʔτσʔλΛ࡞͢Δ
// ϨγʔτΛΧοτʢஅʣ͢ΔίϚϯυ public func cutPaperCommand() -> Data { Data([0x1B,
0x64, 0x00]) } // ը૾Λҹ͢ΔͨΊͷίϚϯυ public func bitmapCommand(_ data: Data, width: Int, height: Int) -> Data { var command = Data() // ϏοτϚοϓҹίϚϯυ command.append(Data([0x1B, 0x58])) // ෯ͱߴ͞ command.append(Data([UInt8(width & 0xFF), UInt8((width >> 8) & 0xFF)])) command.append(Data([UInt8(height & 0xFF), UInt8((height >> 8) & 0xFF)])) // ϏοτϚοϓσʔλ command.append(data) return command } ελʔਫ਼ີϨγʔτϓϦϯλʔ༻ίϚϯυͷྫ ҹ͢ΔϨγʔτσʔλΛ࡞͢Δ
// ϨγʔτΛΧοτʢஅʣ͢ΔίϚϯυ public func cutPaperCommand() -> Data { Data([0x1B,
0x64, 0x00]) } // ը૾Λҹ͢ΔͨΊͷίϚϯυ public func bitmapCommand(_ data: Data, width: Int, height: Int) -> Data { var command = Data() // ϏοτϚοϓҹίϚϯυ command.append(Data([0x1B, 0x58])) // ෯ͱߴ͞ command.append(Data([UInt8(width & 0xFF), UInt8((width >> 8) & 0xFF)])) command.append(Data([UInt8(height & 0xFF), UInt8((height >> 8) & 0xFF)])) // ϏοτϚοϓσʔλ command.append(data) return command } ελʔਫ਼ີϨγʔτϓϦϯλʔ༻ίϚϯυͷྫ ҹ͢ΔϨγʔτσʔλΛ࡞͢Δ %BUBܕΛฦ͢
4%,ΛΘͣϨγʔτϓϦϯλʔͰҹ͢ΔྲྀΕ ϨγʔτϓϦϯλʔΛ୳͢ ҹ͢ΔϨγʔτσʔλΛ࡞͢Δ ϨγʔτϓϦϯλʔʹσʔλΛૹΔ
ϨγʔτίϚϯυ%BUBܕ public func cutPaperCommand() -> Data { Data([0x1D, 0x56,
0x00]) } ϨγʔτϓϦϯλʔʹσʔλΛૹΔ
ϨγʔτίϚϯυ%BUBܕ public func cutPaperCommand() -> Data { Data([0x1D, 0x56,
0x00]) } %BUBܕΛόΠτྻʹม extension Data { func toBytes() -> [UInt8] { withUnsafeBytes { (pointer: UnsafeRawBufferPointer) -> [UInt8] in let unsafeBufferPointer = pointer.bindMemory(to: UInt8.self) let unsafePointer = unsafeBufferPointer.baseAddress! return [UInt8](UnsafeBufferPointer(start: unsafePointer, count: count)) } } } ϨγʔτϓϦϯλʔʹσʔλΛૹΔ
var bytes: [UInt8] = data.toByte() ϨγʔτϓϦϯλʔʹσʔλΛૹΔ %BUBܕΛόΠτྻʹม͠0VUQVU4USFBNʹॻ͖ࠐΉ
var bytes: [UInt8] = data.toByte() func write() { let
session: EASession let failedLimit: UInt = 10 var failedCount: UInt = 0 while let outputStream = session.outputStream, failedCount < failedLimit { let writtenBytes = outputStream.write(bytes, maxLength: bytes.count) if writtenBytes > 0 { let toRange = min(bytes.count, Int(writtenBytes)) bytes.removeSubrange(0 ..< toRange) } else { failedCount += 1 } } } ϨγʔτϓϦϯλʔʹσʔλΛૹΔ %BUBܕΛόΠτྻʹม͠0VUQVU4USFBNʹॻ͖ࠐΉ
var bytes: [UInt8] = data.toByte() func write() { let
session: EASession let failedLimit: UInt = 10 var failedCount: UInt = 0 while let outputStream = session.outputStream, failedCount < failedLimit { let writtenBytes = outputStream.write(bytes, maxLength: bytes.count) if writtenBytes > 0 { let toRange = min(bytes.count, Int(writtenBytes)) bytes.removeSubrange(0 ..< toRange) } else { failedCount += 1 } } } ϨγʔτϓϦϯλʔʹσʔλΛૹΔ &"4FTTJPO͔Β 0VUQVU4USFBNΛநग़ %BUBܕΛόΠτྻʹม͠0VUQVU4USFBNʹॻ͖ࠐΉ
var bytes: [UInt8] = data.toByte() func write() { let
session: EASession let failedLimit: UInt = 10 var failedCount: UInt = 0 while let outputStream = session.outputStream, failedCount < failedLimit { let writtenBytes = outputStream.write(bytes, maxLength: bytes.count) if writtenBytes > 0 { let toRange = min(bytes.count, Int(writtenBytes)) bytes.removeSubrange(0 ..< toRange) } else { failedCount += 1 } } } ϨγʔτϓϦϯλʔʹσʔλΛૹΔ σʔλʢίϚϯυʣΛ 0VUQVU4USFBNʹॻ͖ࠐΉ %BUBܕΛόΠτྻʹม͠0VUQVU4USFBNʹॻ͖ࠐΉ
var bytes: [UInt8] = data.toByte() func write() { let
session: EASession let failedLimit: UInt = 10 var failedCount: UInt = 0 while let outputStream = session.outputStream, failedCount < failedLimit { let writtenBytes = outputStream.write(bytes, maxLength: bytes.count) if writtenBytes > 0 { let toRange = min(bytes.count, Int(writtenBytes)) bytes.removeSubrange(0 ..< toRange) } else { failedCount += 1 } } } ϨγʔτϓϦϯλʔʹσʔλΛૹΔ ॻ͖ࠐΜͩͷσʔλΛ CZUFT͔ΒऔΓআ͘ %BUBܕΛόΠτྻʹม͠0VUQVU4USFBNʹॻ͖ࠐΉ
var bytes: [UInt8] = data.toByte() func write() { let
session: EASession let failedLimit: UInt = 10 var failedCount: UInt = 0 while let outputStream = session.outputStream, failedCount < failedLimit { let writtenBytes = outputStream.write(bytes, maxLength: bytes.count) if writtenBytes > 0 { let toRange = min(bytes.count, Int(writtenBytes)) bytes.removeSubrange(0 ..< toRange) } else { failedCount += 1 } } } ϨγʔτϓϦϯλʔʹσʔλΛૹΔ ॻ͖ࠐΈ͕ྃ͢Δ͔ ճࣦഊ͢Δ·Ͱϧʔϓ %BUBܕΛόΠτྻʹม͠0VUQVU4USFBNʹॻ͖ࠐΉ
J04ΞϓϦ͔ΒϨγʔτϓϦϯλʔʹϨγʔτσʔλΛૹ৴͢Δํ๏ ϨγʔτϓϦϯλʔʹσʔλΛૹΔ
J04ΞϓϦ͔ΒϨγʔτϓϦϯλʔʹϨγʔτσʔλΛૹ৴͢Δํ๏ ϨγʔτϓϦϯλʔʹσʔλΛૹΔ ˠ4USFBN"1*Λར༻
J04ΞϓϦ͔ΒϨγʔτϓϦϯλʔʹϨγʔτσʔλΛૹ৴͢Δํ๏ ϨγʔτϓϦϯλʔʹσʔλΛૹΔ ˠ4USFBN"1*Λར༻ 🤔
ෳͷϝʔΧʔΛαϙʔτ 4USFBN"1*Λར༻͢Δ
4USFBN"1*ͱ ɾ'PVOEBUJPOϑϨʔϜϫʔΫͷΈ ɾ4XJGUͰσʔλͷಡΈॻ͖ΛඇಉظͰ࣮ࢪ ɾެࣜʹ'PVOEBUJPO4USFBNTͱදݱ ɾຊτʔΫͰ૯শͱͯ͠4USFBN"1*ͱදݱ
ɾ&YUFSOBM"DDFTTPSZ'SBNFXPSLʹ͓͚Δඪ४తͳΠϯλʔϑΣʔε ɾϨγʔτϓϦϯλʔҰʹେྔͷσʔλͷड৴͕ෆՄ ˠ4USFBN"1*Ͱૹड৴Մೳ͔Ͳ͏͔ΠϕϯτͰཧ͍ͨ͠ ɾϨγʔτϓϦϯλʔͱͷ௨৴ͰํͷΓͱΓ͕ॏཁ ˠΞϓϦ͔ΒҹσʔλΛૹ৴͠ͳ͕ΒҹྃɾΤϥʔΛड৴͍ͨ͠ ͳͥ4USFBN"1*ʁ
4USFBN"1*ͱ 0VUQVU4USFBN ɾΞϓϦ͔ΒσʔλΛૹ৴͢ΔͨΊͷ௨৴νϟϯωϧ ɾྫɿϓϦϯλʔҹίϚϯυΛૹ৴ *OQVU4USFBN ɾ֎෦͔ΒΞϓϦʹσʔλΛड৴͢ΔͨΊͷ௨৴νϟϯωϧ ɾྫɿϓϦϯλʔ͔ΒҹྃɾΤϥʔ௨Λड৴
4USFBN"1*ͱ 0VUQVU4USFBN Ҿ༻ɿIUUQTSFHJGBRTUPSFTKQIDKBBSUJDMFT *OQVU4USFBN ϨγʔτҹίϚϯυ ҹྃɾΤϥʔ௨
4USFBN"1*ͱ 4USFBN%FMFHBUF ɾΠϕϯτۦಈͰ4USFBNͷঢ়ଶΛࢹ ɾΠϕϯτ 4USFBN&WFOU ͷछྨ PQFO$PNQMFUFE 4USFBNΛ։࢝ͨ͠ IBT#ZUFT"WBJMBCMF
*OQVU4USFBNͰಡΈऔΓՄೳͳσʔλ͕౸ணͨ͠ IBT4QBDF"WBJMBCMF 0VUQVU4USFBNͷॻ͖ࠐΈ͕Մೳʹͳͬͨ FSSPS0DDVSSFE 4USFBNͷૢ࡞தʹΤϥʔ͕ൃੜͨ͠ FOE&ODPVOUFSFE 4USFBN͕ਖ਼ৗʹऴྃͨ͠
4USFBNͷ࣮ྫɿΫϥεશମ final class PrinterStream: NSObject, StreamDelegate { private let
session: EASession init(session: EASession) { self.session = session } func openStreams() { // OutputStreamઃఆ session.outputStream?.delegate = self session.outputStream?.schedule( in: .main, forMode: .common ) session.outputStream?.open() // InputStreamઃఆ session.inputStream?.delegate = self session.inputStream?.schedule( in: .main, forMode: .common ) session.inputStream?.open() } func closeStreams() { // OutputStreamऴྃ session.outputStream?.close() session.outputStream?.remove( from: .main, forMode: .common ) session.outputStream?.delegate = nil // InputStreamऴྃ session.inputStream?.close() session.inputStream?.remove( from: .main, forMode: .common ) session.inputStream?.delegate = nil } func stream(_ aStream: Stream, handle eventCode: Stream.Event) { switch aStream { case _ as OutputStream: // OutputStream ͷϋϯυϦϯά case _ as InputStream: // inputStream ͷϋϯυϦϯά default: break } }
4USFBNͷϥΠϑαΠΫϧ &"4FTTJPOͷ࡞ $PO fi HVSBUJPOͷઃఆ 4USFBNͷ։࢝ σʔλͷૹड৴ɾΠϕϯτॲཧ 4USFBNͷऴྃ
4USFBNͷϥΠϑαΠΫϧ &"4FTTJPOͷ࡞ $PO fi HVSBUJPOͷઃఆ 4USFBNͷ։࢝ σʔλͷૹड৴ɾΠϕϯτॲཧ 4USFBNͷऴྃ
4USFBNͷϥΠϑαΠΫϧ &"4FTTJPOͷ࡞ $PO fi HVSBUJPOͷઃఆ 4USFBNͷ։࢝ σʔλͷૹड৴ɾΠϕϯτॲཧ 4USFBNͷऴྃ func
startSession() { guard let session = EASession( accessory: accessory, forProtocol: protocolString) else { return } … }
4USFBNͷϥΠϑαΠΫϧ &"4FTTJPOͷ࡞ $PO fi HVSBUJPOͷઃఆ 4USFBNͷ։࢝ σʔλͷૹड৴ɾΠϕϯτॲཧ 4USFBNͷऴྃ func
startSession() { guard let session = EASession( accessory: accessory, forProtocol: protocolString) else { return } … } ֎෦ଓΞΫηαϦ ϨγʔτϓϦϯλʔ
4USFBNͷϥΠϑαΠΫϧ &"4FTTJPOͷ࡞ $PO fi HVSBUJPOͷઃఆ 4USFBNͷ։࢝ σʔλͷૹड৴ɾΠϕϯτॲཧ 4USFBNͷऴྃ func
startSession() { guard let session = EASession( accessory: accessory, forProtocol: protocolString) else { return } … } ௨৴ϓϩτίϧจࣈྻ ɾ&QTPODPNFQTPOFTDQPT ɾελʔਫ਼ີKQTUBSNTUBSQSP
4USFBNͷϥΠϑαΠΫϧ &"4FTTJPOͷ࡞ $PO fi HVSBUJPOͷઃఆ 4USFBNͷ։࢝ σʔλͷૹड৴ɾΠϕϯτॲཧ 4USFBNͷऴྃ
4USFBNͷϥΠϑαΠΫϧ &"4FTTJPOͷ࡞ $PO fi HVSBUJPOͷઃఆ 4USFBNͷ։࢝ σʔλͷૹड৴ɾΠϕϯτॲཧ 4USFBNͷऴྃ
4USFBNͷϥΠϑαΠΫϧ &"4FTTJPOͷ࡞ $PO fi HVSBUJPOͷઃఆ 4USFBNͷ։࢝ σʔλͷૹड৴ɾΠϕϯτॲཧ 4USFBNͷऴྃ private
let session: EASession func openStreams() { session.outputStream?.delegate = self session.outputStream?.schedule( in: .main, forMode: .common ) …
4USFBNͷϥΠϑαΠΫϧ &"4FTTJPOͷ࡞ $PO fi HVSBUJPOͷઃఆ 4USFBNͷ։࢝ σʔλͷૹड৴ɾΠϕϯτॲཧ 4USFBNͷऴྃ private
let session: EASession func openStreams() { session.outputStream?.delegate = self session.outputStream?.schedule( in: .main, forMode: .common ) … 4USFBN%FMFHBUFͷઃఆ
4USFBNͷϥΠϑαΠΫϧ &"4FTTJPOͷ࡞ $PO fi HVSBUJPOͷઃఆ 4USFBNͷ։࢝ σʔλͷૹड৴ɾΠϕϯτॲཧ 4USFBNͷऴྃ private
let session: EASession func openStreams() { session.outputStream?.delegate = self session.outputStream?.schedule( in: .main, forMode: .common ) … 3VO-PPQΛొ
4USFBNͷϥΠϑαΠΫϧ &"4FTTJPOͷ࡞ $PO fi HVSBUJPOͷઃఆ 4USFBNͷ։࢝ σʔλͷૹड৴ɾΠϕϯτॲཧ 4USFBNͷऴྃ private
let session: EASession func openStreams() { session.outputStream?.delegate = self session.outputStream?.schedule( in: .main, forMode: .common ) … 3VO-PPQΛొ 4USFBNΛ ϝΠϯεϨουͰॲཧ
4USFBNͷϥΠϑαΠΫϧ &"4FTTJPOͷ࡞ $PO fi HVSBUJPOͷઃఆ 4USFBNͷ։࢝ σʔλͷૹड৴ɾΠϕϯτॲཧ 4USFBNͷऴྃ
4USFBNͷϥΠϑαΠΫϧ &"4FTTJPOͷ࡞ $PO fi HVSBUJPOͷઃఆ 4USFBNͷ։࢝ σʔλͷૹड৴ɾΠϕϯτॲཧ 4USFBNͷऴྃ
4USFBNͷϥΠϑαΠΫϧ &"4FTTJPOͷ࡞ $PO fi HVSBUJPOͷઃఆ 4USFBNͷ։࢝ σʔλͷૹड৴ɾΠϕϯτॲཧ 4USFBNͷऴྃ private
let session: EASession func openStreams() { … session.outputStream?.open() }
4USFBNͷϥΠϑαΠΫϧ &"4FTTJPOͷ࡞ $PO fi HVSBUJPOͷઃఆ 4USFBNͷ։࢝ σʔλͷૹड৴ɾΠϕϯτॲཧ 4USFBNͷऴྃ private
let session: EASession func openStreams() { … session.outputStream?.open() } 4USFBNͷ։࢝
4USFBNͷϥΠϑαΠΫϧ &"4FTTJPOͷ࡞ $PO fi HVSBUJPOͷઃఆ 4USFBNͷ։࢝ σʔλͷૹड৴ɾΠϕϯτॲཧ 4USFBNͷऴྃ
4USFBNͷϥΠϑαΠΫϧ &"4FTTJPOͷ࡞ $PO fi HVSBUJPOͷઃఆ 4USFBNͷ։࢝ σʔλͷૹड৴ɾΠϕϯτॲཧ 4USFBNͷऴྃ
4USFBNͷϥΠϑαΠΫϧ &"4FTTJPOͷ࡞ $PO fi HVSBUJPOͷઃఆ 4USFBNͷ։࢝ σʔλͷૹड৴ɾΠϕϯτॲཧ 4USFBNͷऴྃ final
class PrinterStream: …, StreamDelegate { … func stream(_ aStream: Stream, handle eventCode: Stream.Event) { … switch aStream { case _ as OutputStream: // OutputStream ͷϋϯυϦϯά default: break …
4USFBNͷϥΠϑαΠΫϧ &"4FTTJPOͷ࡞ $PO fi HVSBUJPOͷઃఆ 4USFBNͷ։࢝ σʔλͷૹड৴ɾΠϕϯτॲཧ 4USFBNͷऴྃ final
class PrinterStream: …, StreamDelegate { … func stream(_ aStream: Stream, handle eventCode: Stream.Event) { … switch aStream { case _ as OutputStream: // OutputStream ͷϋϯυϦϯά default: break … 4USFBN&WFOU͕ ݺΕΔ PQFO$PNQMFUFE 4USFBNΛ։࢝ͨ͠ IBT#ZUFT"WBJMBCMF *OQVU4USFBNͰಡΈऔΓՄೳͳσʔλ͕౸ணͨ͠ IBT4QBDF"WBJMBCMF 0VUQVU4USFBNͷॻ͖ࠐΈ͕Մೳʹͳͬͨ FSSPS0DDVSSFE 4USFBNͷૢ࡞தʹΤϥʔ͕ൃੜͨ͠ FOE&ODPVOUFSFE 4USFBN͕ਖ਼ৗʹऴྃͨ͠
4USFBNͷϥΠϑαΠΫϧ &"4FTTJPOͷ࡞ $PO fi HVSBUJPOͷઃఆ 4USFBNͷ։࢝ σʔλͷૹड৴ɾΠϕϯτॲཧ 4USFBNͷऴྃ final
class PrinterStream: …, StreamDelegate { … func stream(_ aStream: Stream, handle eventCode: Stream.Event) { … switch aStream { case _ as OutputStream: // OutputStream ͷϋϯυϦϯά default: break … 4USFBNͷ ϋϯυϦϯάΛ࣮ࢪ PQFO$PNQMFUFE 4USFBNΛ։࢝ͨ͠ IBT#ZUFT"WBJMBCMF *OQVU4USFBNͰಡΈऔΓՄೳͳσʔλ͕౸ணͨ͠ IBT4QBDF"WBJMBCMF 0VUQVU4USFBNͷॻ͖ࠐΈ͕Մೳʹͳͬͨ FSSPS0DDVSSFE 4USFBNͷૢ࡞தʹΤϥʔ͕ൃੜͨ͠ FOE&ODPVOUFSFE 4USFBN͕ਖ਼ৗʹऴྃͨ͠
4USFBNͷϥΠϑαΠΫϧ &"4FTTJPOͷ࡞ $PO fi HVSBUJPOͷઃఆ 4USFBNͷ։࢝ σʔλͷૹड৴ɾΠϕϯτॲཧ 4USFBNͷऴྃ
4USFBNͷϥΠϑαΠΫϧ &"4FTTJPOͷ࡞ $PO fi HVSBUJPOͷઃఆ 4USFBNͷ։࢝ σʔλͷૹड৴ɾΠϕϯτॲཧ 4USFBNͷऴྃ
4USFBNͷϥΠϑαΠΫϧ &"4FTTJPOͷ࡞ $PO fi HVSBUJPOͷઃఆ 4USFBNͷ։࢝ σʔλͷૹड৴ɾΠϕϯτॲཧ 4USFBNͷऴྃ private
let session: EASession func closeStreams() { … session.outputStream?.close() session.outputStream?.remove( from: .main, forMode: .common ) session.outputStream?.delegate = nil }
4USFBNͷϥΠϑαΠΫϧ &"4FTTJPOͷ࡞ $PO fi HVSBUJPOͷઃఆ 4USFBNͷ։࢝ σʔλͷૹड৴ɾΠϕϯτॲཧ 4USFBNͷऴྃ private
let session: EASession func closeStreams() { … session.outputStream?.close() session.outputStream?.remove( from: .main, forMode: .common ) session.outputStream?.delegate = nil } 4USFBNͷऴྃ
4USFBNͷϥΠϑαΠΫϧ &"4FTTJPOͷ࡞ $PO fi HVSBUJPOͷઃఆ 4USFBNͷ։࢝ σʔλͷૹड৴ɾΠϕϯτॲཧ 4USFBNͷऴྃ private
let session: EASession func closeStreams() { … session.outputStream?.close() session.outputStream?.remove( from: .main, forMode: .common ) session.outputStream?.delegate = nil } $PO fi HVSBUJPOઃఆͷআ
4USFBNͷϥΠϑαΠΫϧ &"4FTTJPOͷ࡞ $PO fi HVSBUJPOͷઃఆ 4USFBNͷ։࢝ σʔλͷૹड৴ɾΠϕϯτॲཧ 4USFBNͷऴྃ
4USFBNͷϥΠϑαΠΫϧ &"4FTTJPOͷ࡞ $PO fi HVSBUJPOͷઃఆ 4USFBNͷ։࢝ σʔλͷૹड৴ɾΠϕϯτॲཧ 4USFBNͷऴྃ ϨγʔτϓϦϯλʔͱͷ
ηογϣϯ͕ܧଓ͍ͯ͠Ε ʙ܁Γฦ࣮͠ߦͰ͖Δ
ʢ࠶ܝʣ4USFBN"1*ͱ 0VUQVU4USFBN Ҿ༻ɿIUUQTSFHJGBRTUPSFTKQIDKBBSUJDMFT *OQVU4USFBN ϨγʔτҹίϚϯυ ҹྃɾΤϥʔ௨
ϨγʔτϓϦϯλʔʹσʔλΛૹΔ
Ϩγʔτҹͷઆ໌Λऴ͑ͯ w 4%,ΛΘͣʹϨγʔτϓϦϯλʔͰҹ͢Δํ๏Λհ͠·ͨ͠ w ͜ΕʹΑΓෳͷϝʔΧʔΛαϙʔτ͢Δ͜ͱ͕ՄೳʹͳΓ·ͨ͠
͓͠·͍ ຊτʔΫɺʂ
͓͠·͍ʜͰͳ͍ʂ ຊτʔΫɺ·ͩ·͖ͩͭͮ·͢
ຊτʔΫͰ͢͜ͱ ϨγʔτϓϦϯλʔͷհ ෳͷϝʔΧʔΛαϙʔτ Ϩγʔτҹ్͕தͰࢭ·Δෆ۩߹ ·ͱΊ
Ϩγʔτҹ్͕தͰࢭ·Δෆ۩߹
Ϩγʔτҹͷෆ۩߹ ɾ4XJGUରԠͰϨγʔτҹॲཧͷվमΛߦ͍2"Λ࣮ࢪ ɾϨγʔτҹ్͕தͰఀࢭ͢Δෆ۩߹͕ൃੜ ɾվमલ·Ͱਖ਼ৗʹಈ࡞͠ ϨγʔτϓϦϯλʔͱͷଓྑ
Ϩγʔτҹͷෆ۩߹
ҹ͕ਖ਼ৗʹྃ ҹ్͕தͰఀࢭ Ϩγʔτҹͷෆ۩߹
ҹ͕ਖ਼ৗʹྃ ҹ్͕தͰఀࢭ Ϩγʔτҹͷෆ۩߹ ͍͍ͬͨͳͥఀࢭ͢Δʁ
ݪҼΛௐࠪ ɾෳͷϨγʔτϓϦϯλʔͰ࠶ݱ͢Δ͔ݕূ ɾϨγʔτҹ࣌ͷΤϥʔϩά͕ग़ྗ͞Ε͍ͯΔ͔֬ೝ ɾҹॲཧͷͲ͜Ͱఀࢭ͍ͯ͠Δ͔ௐࠪ
ௐࠪΛͯ͠Θ͔ͬͨ͜ͱ ɾෳͷϝʔΧʔϓϦϯλʔͰಉ༷ͷෆ۩߹͕ൃੜ ɾϓϦϯλʔͷϨγʔτσʔλͷૹ৴͕Ұ࣌ఀࢭ͍ͯ͠Δ͜ͱ͕ൃ֮
var bytes: [UInt8] = data.toByte() func write() { let session:
EASession let failedLimit: UInt = 10 var failedCount: UInt = 0 while let outputStream = session.outputStream, failedCount < failedLimit { let writtenBytes = outputStream.write(bytes, maxLength: bytes.count) if writtenBytes > 0 { let toRange = min(bytes.count, Int(writtenBytes)) bytes.removeSubrange(0 ..< toRange) } else { failedCount += 1 } } } ௐࠪΛͯ͠Θ͔ͬͨ͜ͱ ॻ͖ࠐΈΛϧʔϓͰॲཧ
var bytes: [UInt8] = data.toByte() func write() { let session:
EASession let failedLimit: UInt = 10 var failedCount: UInt = 0 while let outputStream = session.outputStream, failedCount < failedLimit { let writtenBytes = outputStream.write(bytes, maxLength: bytes.count) if writtenBytes > 0 { let toRange = min(bytes.count, Int(writtenBytes)) bytes.removeSubrange(0 ..< toRange) } else { failedCount += 1 } } } ௐࠪΛͯ͠Θ͔ͬͨ͜ͱ ॻ͖ࠐΈ͕#ZUFͷͨΊࣦഊ
var bytes: [UInt8] = data.toByte() func write() { let session:
EASession let failedLimit: UInt = 10 var failedCount: UInt = 0 while let outputStream = session.outputStream, failedCount < failedLimit { let writtenBytes = outputStream.write(bytes, maxLength: bytes.count) if writtenBytes > 0 { let toRange = min(bytes.count, Int(writtenBytes)) bytes.removeSubrange(0 ..< toRange) } else { failedCount += 1 } } } ௐࠪΛͯ͠Θ͔ͬͨ͜ͱ ճࣦഊͨͨ͠Ίϧʔϓऴྃ
var bytes: [UInt8] = data.toByte() func write() { let session:
EASession let failedLimit: UInt = 10 var failedCount: UInt = 0 while let outputStream = session.outputStream, failedCount < failedLimit { let writtenBytes = outputStream.write(bytes, maxLength: bytes.count) if writtenBytes > 0 { let toRange = min(bytes.count, Int(writtenBytes)) bytes.removeSubrange(0 ..< toRange) } else { failedCount += 1 } } } ௐࠪΛͯ͠Θ͔ͬͨ͜ͱ ճࣦഊͨͨ͠Ίϧʔϓऴྃ ॻ͖ࠐΈʹࣦഊ͠ଓ͚ͯ ϧʔϓ͕ऴྃ͠ ์ஔঢ়ଶʹͳ͍ͬͯͨ
var bytes: [UInt8] = data.toByte() func write() { let session:
EASession let failedLimit: UInt = 10 var failedCount: UInt = 0 while let outputStream = session.outputStream, failedCount < failedLimit { let writtenBytes = outputStream.write(bytes, maxLength: bytes.count) if writtenBytes > 0 { let toRange = min(bytes.count, Int(writtenBytes)) bytes.removeSubrange(0 ..< toRange) } else { failedCount += 1 } } } ͪͳΈʹҹ͕ఀࢭ͢Δͱʜ ॻ͖ࠐΈͨ͠ΛCZUFT͔Βআ
var bytes: [UInt8] = data.toByte() func write() { let session:
EASession let failedLimit: UInt = 10 var failedCount: UInt = 0 while let outputStream = session.outputStream, failedCount < failedLimit { let writtenBytes = outputStream.write(bytes, maxLength: bytes.count) if writtenBytes > 0 { let toRange = min(bytes.count, Int(writtenBytes)) bytes.removeSubrange(0 ..< toRange) } else { failedCount += 1 } } } ͪͳΈʹҹ͕ఀࢭ͢Δͱʜ ϧʔϓऴ͕ྃͨ͠σʔλଘ
ҹ͕ఀࢭͷঢ়ଶͰ͞ΒʹҹΛ͢Δͱʜ
ʢ࠶ܝʣௐࠪΛͯ͠Θ͔ͬͨ͜ͱ ɾෳͷϝʔΧʔϓϦϯλʔͰಉ༷ͷෆ۩߹͕ൃੜ ɾϓϦϯλʔͷϨγʔτσʔλͷૹ৴͕Ұ࣌ఀࢭ͍ͯ͠Δ͜ͱ͕ൃ֮
ʢ࠶ܝʣௐࠪΛͯ͠Θ͔ͬͨ͜ͱ ɾෳͷϝʔΧʔϓϦϯλʔͰಉ༷ͷෆ۩߹͕ൃੜ ɾϓϦϯλʔͷϨγʔτσʔλͷૹ৴͕Ұ࣌ఀࢭ͍ͯ͠Δ͜ͱ͕ൃ֮ ͦͦͳͥ ॻ͖ࠐΈʹࣦഊ͢Δʁ
ϨγʔτҹͷσʔλྔΛϩάͰ֬ೝ Ϩγʔτσʔλ૯ྔɹɹ #ZUF ճͷॻ͖ࠐΈ #ZUF ʙճͷॻ͖ࠐΈ
#ZUF ճͷॻ͖ࠐΈ #ZUF ճҎ߱ͷॻ͖ࠐΈ #ZUF Γͷσʔλྔ #ZUF &QTPO5.Nͷ߹
ϨγʔτҹͷσʔλྔΛϩάͰ֬ೝ Ϩγʔτσʔλ૯ྔɹɹ #ZUF ճͷॻ͖ࠐΈ #ZUF ʙճͷॻ͖ࠐΈ
#ZUF ճͷॻ͖ࠐΈ #ZUF ճҎ߱ͷॻ͖ࠐΈ #ZUF Γͷσʔλྔ #ZUF &QTPO5.Nͷ߹ ɾճ ճͰॻ͖ࠐΈ༗ ɾॻ͖ࠐΈࣦഊཱ͕ͭ ɾ͕ॻ͖ࠐΈͰ͖ͣ
Ϩγʔτσʔλͷॻ͖ࠐΈ͕ਐ·ͳ͍ݪҼ ɾॻ͖ࠐΉσʔλྔͷཧతͳ੍ݶɿ #ZUF CJU ͷʣ ɾճͷ #ZUFͷॻ͖ࠐΈͰ੍ݶʹ౸ୡͯ͠͠·ͬͨ ɾ੍ݶʹ౸ୡ͢ΔओͳཁҼ ɾ&"4FTTJPOͷ0VUQVU4USFBNόοϑΝαΠζ੍ݶ
ɾϓϦϯλʔϋʔυΣΞଆͷड৴όοϑΝ੍ݶ ɾ#MVFUPPUI௨৴ϓϩτίϧͷ੍ݶ
Ϩγʔτσʔλͷॻ͖ࠐΈ͕ਐ·ͳ͍ݪҼ Ϩγʔτσʔλ૯ྔɹɹ #ZUF ճͷॻ͖ࠐΈ #ZUF ʙճͷॻ͖ࠐΈ
#ZUF ճͷॻ͖ࠐΈ #ZUF ճҎ߱ͷॻ͖ࠐΈ #ZUF Γͷσʔλྔ #ZUF
Ϩγʔτσʔλͷॻ͖ࠐΈ͕ਐ·ͳ͍ݪҼ Ϩγʔτσʔλ૯ྔɹɹ #ZUF ճͷॻ͖ࠐΈ #ZUF ʙճͷॻ͖ࠐΈ
#ZUF ճͷॻ͖ࠐΈ #ZUF ճҎ߱ͷॻ͖ࠐΈ #ZUF Γͷσʔλྔ #ZUF 🤔
Ϩγʔτσʔλͷॻ͖ࠐΈ͕ਐ·ͳ͍ݪҼ 0VUQVU4USFBN
Ϩγʔτσʔλͷॻ͖ࠐΈ͕ਐ·ͳ͍ݪҼ ɾճɹɿ #ZUFॻ͖ࠐΈʢຬഋʣ 0VUQVU4USFBN
Ϩγʔτσʔλͷॻ͖ࠐΈ͕ਐ·ͳ͍ݪҼ ɾճɹɿ #ZUFॻ͖ࠐΈʢຬഋʣ ɾʙճɿຬഋͷͨΊॻ͖ࠐΈෆՄ 0VUQVU4USFBN
Ϩγʔτσʔλͷॻ͖ࠐΈ͕ਐ·ͳ͍ݪҼ ɾճɹɿ #ZUFॻ͖ࠐΈʢຬഋʣ ɾʙճɿຬഋͷͨΊॻ͖ࠐΈෆՄ ɾճɹɹϓϦϯλʔ͕Ұ෦σʔλΛॲཧ ɹɹɹɹɹɹۭ͖͕ൃੜ͠ #ZUFॻ͖ࠐΈ 0VUQVU4USFBN
Ϩγʔτσʔλͷॻ͖ࠐΈ͕ਐ·ͳ͍ݪҼ ɾճɹɿ #ZUFॻ͖ࠐΈʢຬഋʣ ɾʙճɿຬഋͷͨΊॻ͖ࠐΈෆՄ ɾճɹɹϓϦϯλʔ͕Ұ෦σʔλΛҹ ɹɹɹɹɹɹۭ͖͕ൃੜ͠ #ZUFॻ͖ࠐΈ ɾճʙɹ ϓϦϯλʔҹ͕σʔλॲཧʹ͍͔ͭͳ͍
ಉظతͳϙʔϦϯά XIJMFจ Ͱ 0VUQVU4USFBNͷۭ͖Λదʹݕग़Ͱ͖ͳ͍ 0VUQVU4USFBN
Ϩγʔτσʔλͷॻ͖ࠐΈ͕ਐ·ͳ͍ݪҼ ɾճɹɿ #ZUFॻ͖ࠐΈʢຬഋʣ ɾʙճɿຬഋͷͨΊॻ͖ࠐΈෆՄ ɾճɹɹϓϦϯλʔ͕Ұ෦σʔλΛҹ ɹɹɹɹɹɹۭ͖͕ൃੜ͠ #ZUFॻ͖ࠐΈ ɾճʙɹ ϓϦϯλʔҹ͕σʔλॲཧʹ͍͔ͭͳ͍
ಉظతͳϙʔϦϯά XIJMFจ Ͱ 0VUQVU4USFBNͷۭ͖Λదʹݕग़Ͱ͖ͳ͍ 0VUQVU4USFBN
var bytes: [UInt8] = data.toByte() func write() { let
session: EASession let failedLimit: UInt = 10 var failedCount: UInt = 0 while let outputStream = session.outputStream, failedCount < failedLimit { let writtenBytes = outputStream.write(bytes, maxLength: bytes.count) if writtenBytes > 0 { let toRange = min(bytes.count, Int(writtenBytes)) bytes.removeSubrange(0 ..< toRange) } else { failedCount += 1 } } } 0VUQVU4USFBNͷۭ͖Λݕग़Ͱ͖ͳ͍ཧ༝ ʢ࠶ܝʣ%BUBܕΛ6*OUܕྻʹม͠Ҿʹ͢
var bytes: [UInt8] = data.toByte() func write() { let
session: EASession let failedLimit: UInt = 10 var failedCount: UInt = 0 while let outputStream = session.outputStream, failedCount < failedLimit { let writtenBytes = outputStream.write(bytes, maxLength: bytes.count) if writtenBytes > 0 { let toRange = min(bytes.count, Int(writtenBytes)) bytes.removeSubrange(0 ..< toRange) } else { failedCount += 1 } } } 0VUQVU4USFBNͷۭ͖Λݕग़Ͱ͖ͳ͍ཧ༝ ʢ࠶ܝʣ%BUBܕΛ6*OUܕྻʹม͠Ҿʹ͢
var bytes: [UInt8] = data.toByte() func write() { let
session: EASession let failedLimit: UInt = 10 var failedCount: UInt = 0 while let outputStream = session.outputStream, failedCount < failedLimit { let writtenBytes = outputStream.write(bytes, maxLength: bytes.count) if writtenBytes > 0 { let toRange = min(bytes.count, Int(writtenBytes)) bytes.removeSubrange(0 ..< toRange) } else { failedCount += 1 } } } Ϩγʔτσʔλͷॻ͖ࠐΈ͕ਐ·ͳ͍ݪҼ ʢ࠶ܝʣ%BUBܕΛ6*OUܕྻʹม͠Ҿʹ͢ ɾಉظతͳϧʔϓॲཧͰ0VUQVU4USFBNΛϙʔϦϯά ɾ0VUQVU4USFBNͷঢ়ଶมԽΛϦΞϧλΠϜͰࢹͰ͖ͳ͍ʂ ɾϓϦϯλʔͷॲཧͱΞϓϦؒͰಉظ͕औΕͳ͍
var bytes: [UInt8] = data.toByte() func write() { let
session: EASession let failedLimit: UInt = 10 var failedCount: UInt = 0 while let outputStream = session.outputStream, failedCount < failedLimit { let writtenBytes = outputStream.write(bytes, maxLength: bytes.count) if writtenBytes > 0 { let toRange = min(bytes.count, Int(writtenBytes)) bytes.removeSubrange(0 ..< toRange) } else { failedCount += 1 } } } Ϩγʔτσʔλͷॻ͖ࠐΈ͕ਐ·ͳ͍ݪҼ ʢ࠶ܝʣ%BUBܕΛ6*OUܕྻʹม͠Ҿʹ͢ ɾಉظతͳϧʔϓॲཧͰ0VUQVU4USFBNΛϙʔϦϯάʜ ɾ0VUQVU4USFBNͷঢ়ଶมԽΛϦΞϧλΠϜͰࢹͰ͖ͳ͍ʂ ɾϓϦϯλʔͷॲཧͱಉظ͕औΕͳ͍ 0VUQVU4USFBNͷ ঢ়ଶมԽΛࢹ͢Δ Έ͕ඞཁʂ
var bytes: [UInt8] = data.toByte() func write() { let
session: EASession let failedLimit: UInt = 10 var failedCount: UInt = 0 while let outputStream = session.outputStream, failedCount < failedLimit { let writtenBytes = outputStream.write(bytes, maxLength: bytes.count) if writtenBytes > 0 { let toRange = min(bytes.count, Int(writtenBytes)) bytes.removeSubrange(0 ..< toRange) } else { failedCount += 1 } } } Ϩγʔτσʔλͷॻ͖ࠐΈ͕ਐ·ͳ͍ݪҼ ʢ࠶ܝʣ%BUBܕΛ6*OUܕྻʹม͠Ҿʹ͢ ɾಉظతͳϧʔϓॲཧͰ0VUQVU4USFBNΛϙʔϦϯάʜ ɾ0VUQVU4USFBNͷঢ়ଶมԽΛϦΞϧλΠϜͰࢹͰ͖ͳ͍ʂ ɾϓϦϯλʔͷॲཧͱಉظ͕औΕͳ͍ 4USFBN&WFOUͷग़൪ʂ
0VUQVU4USFBNͷঢ়ଶมԽΛࢹ͢Δղܾࡦ final class PrinterStream: …, StreamDelegate { … func
stream(_ aStream: Stream, handle eventCode: Stream.Event) { … switch aStream { case _ as OutputStream: // OutputStream ͷϋϯυϦϯά default: break } }
0VUQVU4USFBNͷঢ়ଶมԽΛࢹ͢Δղܾࡦ final class PrinterStream: …, StreamDelegate { … func
stream(_ aStream: Stream, handle eventCode: Stream.Event) { … switch aStream { case _ as OutputStream: switch eventCode { case .hasSpaceAvailable: // OutputStreamͷॻ͖ࠐΈΛ࠶։ write() } default: break }
0VUQVU4USFBNͷঢ়ଶมԽΛࢹ͢Δղܾࡦ final class PrinterStream: …, StreamDelegate { … func
stream(_ aStream: Stream, handle eventCode: Stream.Event) { … switch aStream { case _ as OutputStream: switch eventCode { case .hasSpaceAvailable: // OutputStreamͷॻ͖ࠐΈΛ࠶։ write() } default: break } 0VUQVU4USFBNͷ ॻ͖ࠐΈ͕Մೳʹͳͬͨ
0VUQVU4USFBNͷঢ়ଶมԽΛࢹ͢Δղܾࡦ final class PrinterStream: …, StreamDelegate { … func
stream(_ aStream: Stream, handle eventCode: Stream.Event) { … switch aStream { case _ as OutputStream: switch eventCode { case .hasSpaceAvailable: // OutputStreamͷॻ͖ࠐΈΛ࠶։ write() } default: break }
ෆ۩߹ͷमਖ਼ޙʜ
ෆ۩߹ͷमਖ਼ޙʜ ϨγʔτҹͰ͖ͨ👏
ຊτʔΫͰ͢͜ͱ ϨγʔτϓϦϯλʔͷհ ෳϝʔΧʔΛαϙʔτ Ϩγʔτҹ్͕தͰࢭ·Δෆ۩߹ ·ͱΊ
·ͱΊ
·ͱΊ ɾ#MVFUPPUIଓͨ͠ϨγʔτϓϦϯλʔͷҹํ๏Λղઆ͠·ͨ͠ ɾ4USFBN"1*ͰෳϝʔΧʔϨγʔτϓϦϯλʔͷαϙʔτΛ࣮ݱ͠·ͨ͠ ɾϨγʔτҹ్͕தͰࢭ·Δෆ۩߹ͷݪҼௐࠪΛߦ͍·ͨ͠ ɾݪҼ0VUQVU4USFBNͷॻ͖ࠐΈʹ੍ݶ͕͋ͬͨ͜ͱ ɾղܾࡦ4USFBN&WFOUΛࢹ͠ҹॲཧΛ࠶࣮ߦ͢Δ͜ͱ
εϙϯαʔϒʔεʹͯϨγʔτҹମݧͰ͖·͢
࠷ޙʹͻͱ͜ͱ ϧʔϧΛकָͬͯ͘͠ ϨγʔτΛҹ͠Α͏ʂ
͝ਗ਼ௌ͋Γ͕ͱ͏͍͟͝·ͨ͠ʂ ΞϑλʔΠϕϯτΓ·͢ʂͥͻ͝ࢀՃ͍ͩ͘͞ʂ