Upgrade to Pro — share decks privately, control downloads, hide ads and more …

レシート印刷が途中で止まる?Stream APIとBluetooth接続のルールを守って楽しく...

Avatar for satoryo56 satoryo56
September 19, 2025

レシート印刷が途中で止まる?Stream APIとBluetooth接続のルールを守って楽しくレシートプリンターで印刷しよう! / iOSDC Japan 2025 satoryo

Avatar for satoryo56

satoryo56

September 19, 2025
Tweet

More Decks by satoryo56

Other Decks in Programming

Transcript

  1. 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
  2. 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
  3. 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. 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
  5. 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
  6. 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 গͳ͍ߦ਺Ͱ Ϩγʔτҹ࡮͕Մೳʂ
  7. 4503&4Ϩδ͕αϙʔτ͢ΔϨγʔτϓϦϯλʔͷҰ෦  &QTPO ελʔਫ਼ີ ͦͷଞ ਾ͑ஔ͖ܕ ਾ͑ஔ͖ܕ υϩϫʔҰମܕ ख࣋ͪܕ ηΠίʔΠϯεπϧ

    ख࣋ͪܕ ख࣋ͪܕ λϒϨοτҰମܕ Ҿ༻ɿIUUQTSFHJGBRTUPSFTKQIDKBBSUJDMFT
  8. 4503&4Ϩδ͕αϙʔτ͢ΔϨγʔτϓϦϯλʔͷҰ෦  &QTPO ελʔਫ਼ີ ͦͷଞ ਾ͑ஔ͖ܕ ਾ͑ஔ͖ܕ υϩϫʔҰମܕ ख࣋ͪܕ ηΠίʔΠϯεπϧ

    ख࣋ͪܕ ख࣋ͪܕ λϒϨοτҰମܕ Ҿ༻ɿIUUQTSFHJGBRTUPSFTKQIDKBBSUJDMFT
  9. 4503&4Ϩδ͕αϙʔτ͢ΔϨγʔτϓϦϯλʔͷҰ෦  &QTPO ελʔਫ਼ີ ͦͷଞ ਾ͑ஔ͖ܕ ਾ͑ஔ͖ܕ υϩϫʔҰମܕ ख࣋ͪܕ ηΠίʔΠϯεπϧ

    ख࣋ͪܕ ख࣋ͪܕ λϒϨοτҰମܕ Ҿ༻ɿIUUQTSFHJGBRTUPSFTKQIDKBBSUJDMFT
  10. 4503&4Ϩδ͕αϙʔτ͢ΔϨγʔτϓϦϯλʔͷҰ෦  &QTPO ελʔਫ਼ີ ͦͷଞ ਾ͑ஔ͖ܕ ਾ͑ஔ͖ܕ υϩϫʔҰମܕ ख࣋ͪܕ ηΠίʔΠϯεπϧ

    ख࣋ͪܕ ख࣋ͪܕ λϒϨοτҰମܕ Ҿ༻ɿIUUQTSFHJGBRTUPSFTKQIDKBBSUJDMFT
  11. 4503&4Ϩδ͕αϙʔτ͢ΔϨγʔτϓϦϯλʔͷҰ෦  &QTPO ελʔਫ਼ີ ͦͷଞ ਾ͑ஔ͖ܕ ਾ͑ஔ͖ܕ υϩϫʔҰମܕ ख࣋ͪܕ ηΠίʔΠϯεπϧ

    ख࣋ͪܕ ख࣋ͪܕ λϒϨοτҰମܕ Ҿ༻ɿIUUQTSFHJGBRTUPSFTKQIDKBBSUJDMFT
  12. 4503&4Ϩδ͕αϙʔτ͢ΔϨγʔτϓϦϯλʔͷҰ෦  &QTPO ελʔਫ਼ີ ͦͷଞ ਾ͑ஔ͖ܕ ਾ͑ஔ͖ܕ υϩϫʔҰମܕ ख࣋ͪܕ ηΠίʔΠϯεπϧ

    ख࣋ͪܕ ख࣋ͪܕ λϒϨοτҰମܕ Ҿ༻ɿIUUQTSFHJGBRTUPSFTKQIDKBBSUJDMFT
  13.  طଘͷ઀ଓࡁΈΞΫηαϦΛεΩϟϯ͢Δ৔߹ // ௨஌ొ࿥ EAAccessoryManager.shared().registerForLocalNotifications() let accessories = EAAccessoryManager.shared().connectedAccessories for

    accessory in accessories { // accessory: EAAccessory ͔ΒϨγʔτϓϦϯλʔΛݕࡧ }  ϨγʔτϓϦϯλʔΛ୳͢ ઀ଓࡁΈΞΫηαϦΛऔಘ
  14.  طଘͷ઀ଓࡁΈΞΫηαϦΛεΩϟϯ͢Δ৔߹ // ௨஌ొ࿥ EAAccessoryManager.shared().registerForLocalNotifications() let accessories = EAAccessoryManager.shared().connectedAccessories for

    accessory in accessories { // accessory: EAAccessory ͔ΒϨγʔτϓϦϯλʔΛݕࡧ }  ϨγʔτϓϦϯλʔΛ୳͢ ઀ଓࡁΈΞΫηαϦ͔Βݕࡧ
  15.  ϨγʔτϓϦϯλʔΛ୳͢  ৽نΞΫηαϦΛεΩϟϯ͢Δ৔߹ /// BluetoothΞΫηαϦϐοΧʔΛදࣔ public func showBluetoothAccessoryPicker( nameFilter:

    NSPredicate? = nil ) async throws { try await EAAccessoryManager .shared() .showBluetoothAccessoryPicker( withNameFilter: nameFilter ) }
  16.  ϨγʔτϓϦϯλʔΛ୳͢  ৽نΞΫηαϦΛεΩϟϯ͢Δ৔߹ /// BluetoothΞΫηαϦϐοΧʔΛදࣔ public func showBluetoothAccessoryPicker( nameFilter:

    NSPredicate? = nil ) async throws { try await EAAccessoryManager .shared() .showBluetoothAccessoryPicker( withNameFilter: nameFilter ) }
  17.  ϨγʔτϓϦϯλʔΛ୳͢  ৽نΞΫηαϦΛεΩϟϯ͢Δ৔߹ /// BluetoothΞΫηαϦϐοΧʔΛදࣔ public func showBluetoothAccessoryPicker( nameFilter:

    NSPredicate? = nil ) async throws { try await EAAccessoryManager .shared() .showBluetoothAccessoryPicker( withNameFilter: nameFilter ) } ΞΫηαϦ໊ͰߜΓࠐΈՄೳ
  18.  ϨγʔτϓϦϯλʔΛ୳͢  ৽نΞΫηαϦΛεΩϟϯ͢Δ৔߹ /// BluetoothΞΫηαϦϐοΧʔΛදࣔ public func showBluetoothAccessoryPicker( nameFilter:

    NSPredicate? = nil ) async throws { try await EAAccessoryManager .shared() .showBluetoothAccessoryPicker( withNameFilter: nameFilter ) }
  19.  ઀ଓ௨஌ͷ؂ࢹ let connectToken = NotificationCenter.default.addObserver( forName: .EAAccessoryDidConnect, object: nil,

    queue: .main ) { [weak self] notification in // ઀ଓͨ͠ϨγʔτϓϦϯλʔΛอ࣋ let accessory = notification.object as? EAAccessory … } notificationTokens.append(connectToken)  ϨγʔτϓϦϯλʔΛ୳͢
  20.  ઀ଓ௨஌ͷ؂ࢹ let connectToken = NotificationCenter.default.addObserver( forName: .EAAccessoryDidConnect, object: nil,

    queue: .main ) { [weak self] notification in // ઀ଓͨ͠ϨγʔτϓϦϯλʔΛอ࣋ let accessory = notification.object as? EAAccessory … } notificationTokens.append(connectToken)  ϨγʔτϓϦϯλʔΛ୳͢ ΞΫηαϦͱ઀ଓͨ࣌͠ʹ௨஌
  21.  ઀ଓ௨஌ͷ؂ࢹ let connectToken = NotificationCenter.default.addObserver( forName: .EAAccessoryDidConnect, object: nil,

    queue: .main ) { [weak self] notification in // ઀ଓͨ͠ϨγʔτϓϦϯλʔΛอ࣋ let accessory = notification.object as? EAAccessory … } notificationTokens.append(connectToken)  ϨγʔτϓϦϯλʔΛ୳͢
  22.  ੾அ௨஌ͷ؂ࢹ let disconnectToken = NotificationCenter.default.addObserver( forName: .EAAccessoryDidDisconnect, object: nil,

    queue: .main ) { [weak self] notification in // ੾அͨ͠ϨγʔτϓϦϯλʔΛ࡟আ } notificationTokens.append(disconnectToken)  ϨγʔτϓϦϯλʔΛ୳͢
  23.  ੾அ௨஌ͷ؂ࢹ let disconnectToken = NotificationCenter.default.addObserver( forName: .EAAccessoryDidDisconnect, object: nil,

    queue: .main ) { [weak self] notification in // ੾அͨ͠ϨγʔτϓϦϯλʔΛ࡟আ } notificationTokens.append(disconnectToken)  ϨγʔτϓϦϯλʔΛ୳͢ ΞΫηαϦͱ੾அͨ࣌͠ʹ௨஌
  24.  // վߦίϚϯυ 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]) } ϝʔΧʔڞ௨ίϚϯυͷྫ  ҹ࡮͢ΔϨγʔτσʔλΛ࡞੒͢Δ
  25.  // վߦίϚϯυ 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ܕΛฦ͢
  26.  // ϨγʔτΛΧοτʢ੾அʣ͢ΔίϚϯυ 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ϨγʔτϓϦϯλʔ༻ίϚϯυͷྫ  ҹ࡮͢ΔϨγʔτσʔλΛ࡞੒͢Δ
  27.  // ϨγʔτΛΧοτʢ੾அʣ͢ΔίϚϯυ 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 } ελʔਫ਼ີϨγʔτϓϦϯλʔ༻ίϚϯυͷྫ  ҹ࡮͢ΔϨγʔτσʔλΛ࡞੒͢Δ
  28.  // ϨγʔτΛΧοτʢ੾அʣ͢ΔίϚϯυ 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ϨγʔτϓϦϯλʔ༻ίϚϯυͷྫ  ҹ࡮͢ΔϨγʔτσʔλΛ࡞੒͢Δ
  29.  // ϨγʔτΛΧοτʢ੾அʣ͢ΔίϚϯυ 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 } ελʔਫ਼ີϨγʔτϓϦϯλʔ༻ίϚϯυͷྫ  ҹ࡮͢ΔϨγʔτσʔλΛ࡞੒͢Δ
  30.  // ϨγʔτΛΧοτʢ੾அʣ͢ΔίϚϯυ 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ܕΛฦ͢
  31.  ϨγʔτίϚϯυ͸%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)) } } }  ϨγʔτϓϦϯλʔʹσʔλΛૹΔ
  32.  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ʹॻ͖ࠐΉ
  33.  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ʹॻ͖ࠐΉ
  34.  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ʹॻ͖ࠐΉ
  35.  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ʹॻ͖ࠐΉ
  36.  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ʹॻ͖ࠐΉ
  37. 4USFBN"1*ͱ͸  4USFBN%FMFHBUF ɾΠϕϯτۦಈͰ4USFBNͷঢ়ଶΛ؂ࢹ ɾΠϕϯτ 4USFBN&WFOU ͷछྨ PQFO$PNQMFUFE 4USFBNΛ։࢝ͨ͠ IBT#ZUFT"WBJMBCMF

    *OQVU4USFBNͰಡΈऔΓՄೳͳσʔλ͕౸ணͨ͠ IBT4QBDF"WBJMBCMF 0VUQVU4USFBNͷॻ͖ࠐΈ͕Մೳʹͳͬͨ FSSPS0DDVSSFE 4USFBNͷૢ࡞தʹΤϥʔ͕ൃੜͨ͠ FOE&ODPVOUFSFE 4USFBN͕ਖ਼ৗʹऴྃͨ͠
  38. 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 } }
  39. 4USFBNͷϥΠϑαΠΫϧ  &"4FTTJPOͷ࡞੒ $PO fi HVSBUJPOͷઃఆ 4USFBNͷ։࢝ σʔλͷૹड৴ɾΠϕϯτॲཧ 4USFBNͷऴྃ func

    startSession() { guard let session = EASession( accessory: accessory, forProtocol: protocolString) else { return } … }
  40. 4USFBNͷϥΠϑαΠΫϧ  &"4FTTJPOͷ࡞੒ $PO fi HVSBUJPOͷઃఆ 4USFBNͷ։࢝ σʔλͷૹड৴ɾΠϕϯτॲཧ 4USFBNͷऴྃ func

    startSession() { guard let session = EASession( accessory: accessory, forProtocol: protocolString) else { return } … } ֎෦઀ଓΞΫηαϦ ϨγʔτϓϦϯλʔ
  41. 4USFBNͷϥΠϑαΠΫϧ  &"4FTTJPOͷ࡞੒ $PO fi HVSBUJPOͷઃఆ 4USFBNͷ։࢝ σʔλͷૹड৴ɾΠϕϯτॲཧ 4USFBNͷऴྃ func

    startSession() { guard let session = EASession( accessory: accessory, forProtocol: protocolString) else { return } … } ௨৴ϓϩτίϧจࣈྻ ɾ&QTPODPNFQTPOFTDQPT ɾελʔਫ਼ີKQTUBSNTUBSQSP
  42. 4USFBNͷϥΠϑαΠΫϧ  &"4FTTJPOͷ࡞੒ $PO fi HVSBUJPOͷઃఆ 4USFBNͷ։࢝ σʔλͷૹड৴ɾΠϕϯτॲཧ 4USFBNͷऴྃ private

    let session: EASession func openStreams() { session.outputStream?.delegate = self session.outputStream?.schedule( in: .main, forMode: .common ) …
  43. 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ͷઃఆ
  44. 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Λొ࿥
  45. 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Λ ϝΠϯεϨουͰॲཧ
  46. 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 …
  47. 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͕ਖ਼ৗʹऴྃͨ͠
  48. 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͕ਖ਼ৗʹऴྃͨ͠
  49. 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 }
  50. 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ͷऴྃ
  51. 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ઃఆͷ࡟আ
  52. 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 } } } ௐࠪΛͯ͠Θ͔ͬͨ͜ͱ  ॻ͖ࠐΈΛϧʔϓͰॲཧ
  53. 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ͷͨΊࣦഊ
  54. 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 } } } ௐࠪΛͯ͠Θ͔ͬͨ͜ͱ  ճࣦഊͨͨ͠Ίϧʔϓऴྃ
  55. 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 } } } ௐࠪΛͯ͠Θ͔ͬͨ͜ͱ  ճࣦഊͨͨ͠Ίϧʔϓऴྃ ॻ͖ࠐΈʹࣦഊ͠ଓ͚ͯ ϧʔϓ͕ऴྃ͠ ์ஔঢ়ଶʹͳ͍ͬͯͨ
  56. 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͔Β࡟আ
  57. 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 } } } ͪͳΈʹҹ࡮͕ఀࢭ͢Δͱʜ  ϧʔϓ͸ऴ͕ྃͨ͠σʔλ͸࢒ଘ
  58. Ϩγʔτҹ࡮ͷσʔλྔΛϩάͰ֬ೝ  Ϩγʔτσʔλ૯ྔɹɹ  #ZUF ճ໨ͷॻ͖ࠐΈ   #ZUF ʙճ໨ͷॻ͖ࠐΈ

    #ZUF ճ໨ͷॻ͖ࠐΈ  #ZUF ճ໨Ҏ߱ͷॻ͖ࠐΈ #ZUF ࢒Γͷσʔλྔ  #ZUF &QTPO5.Nͷ৔߹
  59. Ϩγʔτҹ࡮ͷσʔλྔΛϩάͰ֬ೝ  Ϩγʔτσʔλ૯ྔɹɹ  #ZUF ճ໨ͷॻ͖ࠐΈ   #ZUF ʙճ໨ͷॻ͖ࠐΈ

    #ZUF ճ໨ͷॻ͖ࠐΈ  #ZUF ճ໨Ҏ߱ͷॻ͖ࠐΈ #ZUF ࢒Γͷσʔλྔ  #ZUF &QTPO5.Nͷ৔߹ ɾճ໨ ճ໨Ͱॻ͖ࠐΈ༗ ɾॻ͖ࠐΈࣦഊ͕໨ཱͭ ɾ໿͕ॻ͖ࠐΈͰ͖ͣ
  60. Ϩγʔτσʔλͷॻ͖ࠐΈ͕ਐ·ͳ͍ݪҼ  Ϩγʔτσʔλ૯ྔɹɹ  #ZUF ճ໨ͷॻ͖ࠐΈ   #ZUF ʙճ໨ͷॻ͖ࠐΈ

    #ZUF ճ໨ͷॻ͖ࠐΈ  #ZUF ճ໨Ҏ߱ͷॻ͖ࠐΈ #ZUF ࢒Γͷσʔλྔ  #ZUF
  61. Ϩγʔτσʔλͷॻ͖ࠐΈ͕ਐ·ͳ͍ݪҼ  Ϩγʔτσʔλ૯ྔɹɹ  #ZUF ճ໨ͷॻ͖ࠐΈ   #ZUF ʙճ໨ͷॻ͖ࠐΈ

    #ZUF ճ໨ͷॻ͖ࠐΈ  #ZUF ճ໨Ҏ߱ͷॻ͖ࠐΈ #ZUF ࢒Γͷσʔλྔ  #ZUF 🤔
  62.  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ܕ഑ྻʹม׵͠Ҿ਺ʹ౉͢
  63.  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ܕ഑ྻʹม׵͠Ҿ਺ʹ౉͢
  64.  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ͷঢ়ଶมԽΛϦΞϧλΠϜͰ؂ࢹͰ͖ͳ͍ʂ ɾϓϦϯλʔͷॲཧͱΞϓϦؒͰಉظ͕औΕͳ͍
  65.  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ͷ ঢ়ଶมԽΛ؂ࢹ͢Δ ࢓૊Έ͕ඞཁʂ
  66.  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ͷग़൪ʂ
  67. 0VUQVU4USFBNͷঢ়ଶมԽΛ؂ࢹ͢Δղܾࡦ  final class PrinterStream: …, StreamDelegate { … func

    stream(_ aStream: Stream, handle eventCode: Stream.Event) { … switch aStream { case _ as OutputStream: // OutputStream ͷϋϯυϦϯά default: break } }
  68. 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 }
  69. 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ͷ ॻ͖ࠐΈ͕Մೳʹͳͬͨ
  70. 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 }